@link-foundation/sensitive-data-sanitizer 0.19.3 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +22 -2
- package/bin/sensitive-data-sanitizer.js +50 -28
- package/docs/API.md +355 -16
- package/docs/COVERAGE.md +19 -9
- package/docs/RULES.md +218 -0
- package/examples/second-pass-placeholders.mjs +28 -0
- package/package.json +12 -3
- package/src/allow-list.js +93 -0
- package/src/confidence.js +24 -9
- package/src/context.js +287 -40
- package/src/credential-spans.js +180 -0
- package/src/credentials-entry.d.ts +23 -0
- package/src/credentials-entry.js +62 -0
- package/src/credentials.js +51 -0
- package/src/crypto-addresses.js +74 -0
- package/src/detection.js +87 -41
- package/src/document-person-cues.js +1 -1
- package/src/encoded.js +137 -51
- package/src/encrypt.js +95 -0
- package/src/engines.js +33 -10
- package/src/entities.js +4 -3
- package/src/exempt.js +72 -0
- package/src/fake-memory.js +32 -0
- package/src/fake.js +33 -29
- package/src/features.js +29 -0
- package/src/files.js +57 -12
- package/src/gitleaks.js +82 -27
- package/src/html-tags.js +8 -0
- package/src/identifier-detector.js +36 -0
- package/src/identity-types.js +63 -0
- package/src/identity.js +3 -47
- package/src/index.d.ts +157 -3
- package/src/index.js +13 -0
- package/src/known.js +33 -15
- package/src/national-checks.js +209 -0
- package/src/national.js +310 -92
- package/src/pattern-detector.js +219 -0
- package/src/personal-context.js +3 -2
- package/src/personal-evidence.js +233 -0
- package/src/personal-features.js +39 -0
- package/src/personal.js +66 -10
- package/src/placeholder-types.js +154 -4
- package/src/placeholders.js +127 -45
- package/src/projection.js +78 -26
- package/src/proper-names.js +48 -5
- package/src/prose-words.js +120 -0
- package/src/record-worker.js +1 -0
- package/src/rule-catalog.js +426 -0
- package/src/rules.js +8 -0
- package/src/sanitizer.js +133 -23
- package/src/sarif.js +127 -0
- package/src/stream-worker.js +1 -0
- package/src/strict-attributes.js +48 -4
- package/src/strict.js +1 -1
- package/src/structured.js +2 -0
- package/src/token-checksum.js +49 -0
- package/src/transforms.js +146 -33
- package/src/vendor/betterleaks/LICENSE +21 -0
- package/src/vendor/betterleaks/provenance.json +11 -0
- package/src/vendor/betterleaks/rules-0.json +463 -0
- package/src/vendor/betterleaks/rules-1.json +454 -0
- package/src/vendor/betterleaks/rules-2.json +461 -0
- package/src/vendor/betterleaks/rules-3.json +455 -0
- package/src/vendor/betterleaks/rules-4.json +483 -0
- package/src/vendor/betterleaks/rules-5.json +35 -0
- package/src/vendor/entities/aws.json +1 -1
- package/src/vendor/entities/azure.json +6 -2
- package/src/vendor/entities/google.json +2 -1
- package/src/vocabulary.js +27 -1
- package/src/worker-options.js +1 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { isNameForm } from './russian-names.js';
|
|
2
|
+
import { compiledVocabulary, defaultVocabulary } from './vocabulary.js';
|
|
3
|
+
|
|
4
|
+
// Words that are capitalized by position or politeness in prose but identify
|
|
5
|
+
// nobody. `properNames: 'capitalized'` leaves them readable. Any word that is
|
|
6
|
+
// also a given name form (`Вера`, `Любовь`, `Will`) is removed from the lists,
|
|
7
|
+
// so a list entry can never keep a name.
|
|
8
|
+
const fold = (word) => word.toLowerCase().replaceAll('ё', 'е');
|
|
9
|
+
const words = (list) =>
|
|
10
|
+
new Set(
|
|
11
|
+
list
|
|
12
|
+
.split(/\s+/u)
|
|
13
|
+
.filter(Boolean)
|
|
14
|
+
.map(fold)
|
|
15
|
+
.filter((word) => !isNameForm(word))
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
// Pronouns are capitalized anywhere in polite Russian (`благодарим Вас`).
|
|
19
|
+
const pronouns = words(`
|
|
20
|
+
я меня мне мной мы нас нам нами ты тебя тебе тобой вы вас вам вами
|
|
21
|
+
ваш ваша ваше вашего вашей вашему вашим ваши ваших
|
|
22
|
+
наш наша наше нашего нашей нашему нашим наши наших
|
|
23
|
+
мой моя мое моего моей моему моим мои моих
|
|
24
|
+
твой твоя твое твои он она оно они его ее ему ей им ими их них нее него
|
|
25
|
+
i me my mine we us our you your he him his she her they them their
|
|
26
|
+
`);
|
|
27
|
+
// Role and label words stay beside the name they introduce
|
|
28
|
+
// (`Кандидат Петров Иван Сергеевич` -> `Кандидат Person-1`).
|
|
29
|
+
const cues = words(`
|
|
30
|
+
кандидат кандидатка кандидата кандидату соискатель соискательница соискателя
|
|
31
|
+
сотрудник сотрудница сотрудника клиент клиентка клиента пациент пациентка
|
|
32
|
+
пациента абонент абонента заявитель заявительница заявителя студент
|
|
33
|
+
студентка гражданин гражданка господин госпожа коллега коллеги менеджер
|
|
34
|
+
директор руководитель инженер аналитик разработчик специалист водитель врач
|
|
35
|
+
candidate employee client customer patient applicant student citizen
|
|
36
|
+
colleague manager director engineer developer analyst
|
|
37
|
+
`);
|
|
38
|
+
// Greetings and function words are left alone only at the start of a
|
|
39
|
+
// sentence, where capitalization says nothing about a name.
|
|
40
|
+
const sentenceWords = words(`
|
|
41
|
+
здравствуйте здравствуй привет приветствую добрый доброе доброго добрая
|
|
42
|
+
уважаемый уважаемая уважаемые дорогой дорогая дорогие спасибо благодарю
|
|
43
|
+
благодарим пожалуйста извините простите скажите подскажите прошу просьба
|
|
44
|
+
это этот эта эти тот та те то там тут здесь где когда как что кто чем
|
|
45
|
+
почему зачем если но и а или да нет не ни в во на по с со к ко у о об от до
|
|
46
|
+
из за для при без про после перед также тоже еще уже вот так все весь вся
|
|
47
|
+
каждый сейчас сегодня вчера завтра потом затем далее итак кроме однако
|
|
48
|
+
поэтому хотя возможно конечно хорошо ладно ок буду будет был была были было
|
|
49
|
+
есть могу можно нужно надо готов готова готовы имею хочу работаю живу
|
|
50
|
+
учусь зовут звать занимаюсь звоню пишу
|
|
51
|
+
нёс перенёс принёс вёз привёз мог смог помог умер рос вырос лёг шёл пришёл
|
|
52
|
+
ушёл перешёл нашёл
|
|
53
|
+
hello hi hey dear thanks thank please regards sincerely best the this that
|
|
54
|
+
these those a an it is are was were in on at for from to with and but or if
|
|
55
|
+
when where what who why how yes no not also
|
|
56
|
+
`);
|
|
57
|
+
// Past tense (`Работал`, `Звонила`, `Переехали`), first person present
|
|
58
|
+
// (`Работаю`, `Занимаюсь`) and third person present. A bare masculine `-л` form is also a surname shape
|
|
59
|
+
// (`Шагал`), so it is kept only before a lowercase word.
|
|
60
|
+
const pastTense = /^[а-яе]{2,}[аеиоуыя]л(?:а|о|и|ся|ась|ось|ись)$/u;
|
|
61
|
+
const masculinePast = /^[а-яе]{3,}[аеиуыя]л$/u;
|
|
62
|
+
const firstPerson = /^[а-яе]{3,}[аеуя]ю(?:сь)?$/u;
|
|
63
|
+
// Third person present (`Рекомендует`, `Работает`, `Говорит`, `Учатся`).
|
|
64
|
+
const thirdPerson =
|
|
65
|
+
/^[а-яе]{2,}(?:[аеиоуюя]ет|[аеиоуюя]ют|ит|ят|[аеиуя]ется|[аеиуя]ются|ится|атся|ятся)$/u;
|
|
66
|
+
|
|
67
|
+
function sentenceStart(text, start) {
|
|
68
|
+
let i = start - 1;
|
|
69
|
+
while (i >= 0 && /[ \t"'«„“(—–-]/u.test(text[i])) {
|
|
70
|
+
i--;
|
|
71
|
+
}
|
|
72
|
+
return i < 0 || /[.!?…\r\n:;]/u.test(text[i]);
|
|
73
|
+
}
|
|
74
|
+
function nextWordLowercase(text, end) {
|
|
75
|
+
return /^[ \t]+\p{Ll}/u.test(text.slice(end, end + 4));
|
|
76
|
+
}
|
|
77
|
+
function vocabularyCues(options) {
|
|
78
|
+
const lists = compiledVocabulary(options?.vocabulary)?.lists;
|
|
79
|
+
return lists ? [...lists.roles, ...lists.personalLabels] : [];
|
|
80
|
+
}
|
|
81
|
+
const defaultCues = new Set(
|
|
82
|
+
[...defaultVocabulary.roles, ...defaultVocabulary.personalLabels].map(fold)
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
// True when a word of the cue lists, including the configured `roles` and
|
|
86
|
+
// `personalLabels` vocabulary, is not part of a name.
|
|
87
|
+
export function isProseCue(word, options) {
|
|
88
|
+
const lower = fold(word);
|
|
89
|
+
return (
|
|
90
|
+
(cues.has(lower) ||
|
|
91
|
+
defaultCues.has(lower) ||
|
|
92
|
+
vocabularyCues(options).includes(lower)) &&
|
|
93
|
+
!isNameForm(word)
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
// True for a pronoun or cue word, which identify nobody wherever they stand.
|
|
97
|
+
export function isCommonProseWord(word, options) {
|
|
98
|
+
return pronouns.has(fold(word)) || isProseCue(word, options);
|
|
99
|
+
}
|
|
100
|
+
// Decides whether a capitalized prose token is an ordinary word of the
|
|
101
|
+
// sentence and not a name.
|
|
102
|
+
export function keepsProseWord(text, value, start, end, options) {
|
|
103
|
+
if (!/^\p{L}+$/u.test(value) || isNameForm(value)) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
if (isCommonProseWord(value, options)) {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
if (!sentenceStart(text, start)) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
const lower = fold(value);
|
|
113
|
+
return (
|
|
114
|
+
sentenceWords.has(lower) ||
|
|
115
|
+
pastTense.test(lower) ||
|
|
116
|
+
firstPerson.test(lower) ||
|
|
117
|
+
thirdPerson.test(lower) ||
|
|
118
|
+
(masculinePast.test(lower) && nextWordLowercase(text, end))
|
|
119
|
+
);
|
|
120
|
+
}
|
package/src/record-worker.js
CHANGED
package/src/rule-catalog.js
CHANGED
|
@@ -4,16 +4,221 @@ export const builtInRules = Object.freeze([
|
|
|
4
4
|
'anthropic',
|
|
5
5
|
'authorization',
|
|
6
6
|
'aws',
|
|
7
|
+
'betterleaks/abuseipdb-api-key.1',
|
|
8
|
+
'betterleaks/aikido-ci-token',
|
|
9
|
+
'betterleaks/aikido-client-secret',
|
|
10
|
+
'betterleaks/airtable-oauth-token',
|
|
11
|
+
'betterleaks/aiven-auth-token',
|
|
12
|
+
'betterleaks/alibaba-sts-access-key-secret',
|
|
13
|
+
'betterleaks/amplitude-secret-key',
|
|
14
|
+
'betterleaks/apify-api-token',
|
|
15
|
+
'betterleaks/apollo-api-key.1',
|
|
16
|
+
'betterleaks/asaas-api-token',
|
|
17
|
+
'betterleaks/assemblyai-api-key',
|
|
18
|
+
'betterleaks/auth0-client-secret.1',
|
|
19
|
+
'betterleaks/azure-app-configuration-connection-string',
|
|
20
|
+
'betterleaks/azure-servicebus-connection-string',
|
|
21
|
+
'betterleaks/azure-storage-account-key',
|
|
22
|
+
'betterleaks/bitbucket-data-center-token',
|
|
23
|
+
'betterleaks/bitly-access-token',
|
|
24
|
+
'betterleaks/bitrise-access-token',
|
|
25
|
+
'betterleaks/box-api-access-token',
|
|
26
|
+
'betterleaks/brave-search-api-key',
|
|
27
|
+
'betterleaks/browserstack-access-key.1',
|
|
28
|
+
'betterleaks/buildkite-service-token',
|
|
29
|
+
'betterleaks/buildkite-user-access-token',
|
|
30
|
+
'betterleaks/canadian-digital-service-notify-api-key',
|
|
31
|
+
'betterleaks/canva-client-secret',
|
|
32
|
+
'betterleaks/cartesia-api-key.1',
|
|
33
|
+
'betterleaks/cerebras-api-key',
|
|
34
|
+
'betterleaks/checkout-secret-key',
|
|
35
|
+
'betterleaks/circleci-personal-token',
|
|
36
|
+
'betterleaks/circleci-project-token',
|
|
37
|
+
'betterleaks/civo-api-key',
|
|
38
|
+
'betterleaks/clerk-secret-key',
|
|
39
|
+
'betterleaks/clickup-personal-api-token',
|
|
40
|
+
'betterleaks/cloudflare-api-key.2',
|
|
41
|
+
'betterleaks/cloudinary-api-secret',
|
|
42
|
+
'betterleaks/cloudsmith-api-key',
|
|
43
|
+
'betterleaks/cockroachlabs-cloud-api-key',
|
|
44
|
+
'betterleaks/configcat-sdk-key',
|
|
45
|
+
'betterleaks/configcat-sdk-key-extended',
|
|
46
|
+
'betterleaks/couchbase-capella-api-key',
|
|
47
|
+
'betterleaks/coveralls-personal-api-token',
|
|
48
|
+
'betterleaks/crates-io-api-key',
|
|
49
|
+
'betterleaks/cursor-api-key',
|
|
50
|
+
'betterleaks/databento-api-key',
|
|
51
|
+
'betterleaks/datadog-api-key',
|
|
52
|
+
'betterleaks/datadog-application-key',
|
|
53
|
+
'betterleaks/datagov-api-key',
|
|
54
|
+
'betterleaks/datastax-astra-application-token',
|
|
55
|
+
'betterleaks/deepgram-api-key',
|
|
56
|
+
'betterleaks/deepseek-api-key',
|
|
57
|
+
'betterleaks/deno-account-token',
|
|
58
|
+
'betterleaks/devcycle-client-sdk-key',
|
|
59
|
+
'betterleaks/devcycle-mobile-sdk-key',
|
|
60
|
+
'betterleaks/devcycle-server-sdk-key',
|
|
61
|
+
'betterleaks/devin-personal-api-key',
|
|
62
|
+
'betterleaks/devin-service-api-key',
|
|
63
|
+
'betterleaks/devin-service-user-token',
|
|
64
|
+
'betterleaks/disqus-api-key',
|
|
65
|
+
'betterleaks/docker-swarm-join-token',
|
|
66
|
+
'betterleaks/docker-swarm-unlock-key',
|
|
67
|
+
'betterleaks/dockerhub-organization-access-token',
|
|
68
|
+
'betterleaks/dockerhub-personal-access-token',
|
|
69
|
+
'betterleaks/ebay-client-secret',
|
|
70
|
+
'betterleaks/elastic-cloud-api-key',
|
|
71
|
+
'betterleaks/elevenlabs-api-key',
|
|
72
|
+
'betterleaks/endorlabs-api-key',
|
|
73
|
+
'betterleaks/endorlabs-api-secret',
|
|
74
|
+
'betterleaks/etsy-open-api-key',
|
|
75
|
+
'betterleaks/exoscale-api-key',
|
|
76
|
+
'betterleaks/fal-api-key.1',
|
|
77
|
+
'betterleaks/figma-personal-access-header-token',
|
|
78
|
+
'betterleaks/figma-personal-access-token',
|
|
79
|
+
'betterleaks/fullstory-api-key',
|
|
80
|
+
'betterleaks/gcp-application-default-credentials',
|
|
81
|
+
'betterleaks/gcp-gemini-api',
|
|
82
|
+
'betterleaks/gcp-service-account',
|
|
83
|
+
'betterleaks/gitea-access-token',
|
|
84
|
+
'betterleaks/gitlab-incoming-mail-address-token',
|
|
85
|
+
'betterleaks/gitlab-pat-routable-versioned',
|
|
86
|
+
'betterleaks/greptile-api-key',
|
|
87
|
+
'betterleaks/groq-api-key',
|
|
88
|
+
'betterleaks/gumroad-access-token',
|
|
89
|
+
'betterleaks/highnote-secret-live-key',
|
|
90
|
+
'betterleaks/honeycomb-api-key',
|
|
91
|
+
'betterleaks/hunter-api-key.1',
|
|
92
|
+
'betterleaks/ibm-cloud-user-api-key',
|
|
93
|
+
'betterleaks/influxdb-api-token',
|
|
94
|
+
'betterleaks/infomaniak-api-token',
|
|
95
|
+
'betterleaks/instantly-api-key.1',
|
|
96
|
+
'betterleaks/ionic-personal-access-token',
|
|
97
|
+
'betterleaks/jumpcloud-api-key',
|
|
98
|
+
'betterleaks/kagi-api-key',
|
|
99
|
+
'betterleaks/kimi-api-key',
|
|
100
|
+
'betterleaks/klaviyo-api-key',
|
|
101
|
+
'betterleaks/langchain-langsmith-personal-access-token',
|
|
102
|
+
'betterleaks/langchain-langsmith-service-key',
|
|
103
|
+
'betterleaks/langfuse-secret-key.1',
|
|
104
|
+
'betterleaks/lark-app-secret',
|
|
105
|
+
'betterleaks/lichess-personal-access-token',
|
|
106
|
+
'betterleaks/lighton-paradigm-api-key',
|
|
107
|
+
'betterleaks/llama-cloud-api-key.1',
|
|
108
|
+
'betterleaks/mailersend-api-token',
|
|
109
|
+
'betterleaks/mem0-api-key.1',
|
|
110
|
+
'betterleaks/mercury-production-api-token',
|
|
111
|
+
'betterleaks/mergify-application-key',
|
|
112
|
+
'betterleaks/midtrans-production-server-client-key',
|
|
113
|
+
'betterleaks/minimax-api-key',
|
|
114
|
+
'betterleaks/miro-access-token',
|
|
115
|
+
'betterleaks/miro-client-secret',
|
|
116
|
+
'betterleaks/mistral-api-key',
|
|
117
|
+
'betterleaks/monday-api-token.1',
|
|
118
|
+
'betterleaks/mongodb-atlas-service-account-secret',
|
|
119
|
+
'betterleaks/mongodb-connection-string',
|
|
120
|
+
'betterleaks/mux-access-token-secret.1',
|
|
121
|
+
'betterleaks/neon-api-key',
|
|
122
|
+
'betterleaks/ngrok-api-key.1',
|
|
123
|
+
'betterleaks/nuget-api-key',
|
|
124
|
+
'betterleaks/nvidia-api-key',
|
|
125
|
+
'betterleaks/nylas-api-key.1',
|
|
126
|
+
'betterleaks/ollama-api-key',
|
|
127
|
+
'betterleaks/onesignal-rich-authentication-token',
|
|
128
|
+
'betterleaks/onfido-live-api-token-ca',
|
|
129
|
+
'betterleaks/onfido-live-api-token-eu',
|
|
130
|
+
'betterleaks/onfido-live-api-token-us',
|
|
131
|
+
'betterleaks/openrouter-api-key',
|
|
132
|
+
'betterleaks/openweather-api-key',
|
|
133
|
+
'betterleaks/opsgenie-api-key.1',
|
|
134
|
+
'betterleaks/ovh-application-secret',
|
|
135
|
+
'betterleaks/paddle-live-api-key',
|
|
136
|
+
'betterleaks/pagerduty-authorization-token.1',
|
|
137
|
+
'betterleaks/paypal-client-secret.1',
|
|
138
|
+
'betterleaks/persona-production-api-key',
|
|
139
|
+
'betterleaks/pinecone-api-key.1',
|
|
140
|
+
'betterleaks/pinecone-api-key.2',
|
|
141
|
+
'betterleaks/pinterest-access-token',
|
|
142
|
+
'betterleaks/plivo-auth-token',
|
|
143
|
+
'betterleaks/polar-oauth-access-token',
|
|
144
|
+
'betterleaks/polar-organization-access-token',
|
|
145
|
+
'betterleaks/polar-personal-access-token',
|
|
146
|
+
'betterleaks/polymarket-api-key',
|
|
147
|
+
'betterleaks/polymarket-private-key',
|
|
148
|
+
'betterleaks/posthog-personal-api-key',
|
|
149
|
+
'betterleaks/posthog-project-api-key',
|
|
150
|
+
'betterleaks/postmark-api-token.1',
|
|
151
|
+
'betterleaks/proof-full-access-api-key',
|
|
152
|
+
'betterleaks/rainforest-pay-production-api-key',
|
|
153
|
+
'betterleaks/ramp-client-secret',
|
|
154
|
+
'betterleaks/razorpay-key-secret.1',
|
|
155
|
+
'betterleaks/redirect-pizza-api-token.1',
|
|
156
|
+
'betterleaks/render-api-key',
|
|
157
|
+
'betterleaks/replicate-api-token',
|
|
158
|
+
'betterleaks/resend-api-key.1',
|
|
159
|
+
'betterleaks/retell-api-key.1',
|
|
160
|
+
'betterleaks/rootly-api-key.1',
|
|
161
|
+
'betterleaks/runpod-api-key.1',
|
|
162
|
+
'betterleaks/salesforce-access-token.1',
|
|
163
|
+
'betterleaks/samsara-api-token.1',
|
|
164
|
+
'betterleaks/scaleway-secret-key',
|
|
165
|
+
'betterleaks/scalr-api-access-token.1',
|
|
166
|
+
'betterleaks/segment-public-api-token.1',
|
|
167
|
+
'betterleaks/slack-session-cookie',
|
|
168
|
+
'betterleaks/slack-session-token',
|
|
169
|
+
'betterleaks/snowflake-programmatic-access-token.1',
|
|
170
|
+
'betterleaks/sslmate-api-key.1',
|
|
171
|
+
'betterleaks/stability-ai-api-key',
|
|
172
|
+
'betterleaks/supabase-management-token',
|
|
173
|
+
'betterleaks/supabase-project-api-key',
|
|
174
|
+
'betterleaks/tableau-personal-access-token.1',
|
|
175
|
+
'betterleaks/tailscale-api-key.1',
|
|
176
|
+
'betterleaks/telnyx-api-v2-key.1',
|
|
177
|
+
'betterleaks/temporal-cloud-api-key.1',
|
|
178
|
+
'betterleaks/thunderstore-api-token.1',
|
|
179
|
+
'betterleaks/togetherai-api-key',
|
|
180
|
+
'betterleaks/unkey-root-key.1',
|
|
181
|
+
'betterleaks/upcloud-api-token',
|
|
182
|
+
'betterleaks/upstage-api-key',
|
|
183
|
+
'betterleaks/upstash-redis-rest-token.1',
|
|
184
|
+
'betterleaks/val-town-api-token.1',
|
|
185
|
+
'betterleaks/vercel-ai-gateway-key',
|
|
186
|
+
'betterleaks/vercel-api-token',
|
|
187
|
+
'betterleaks/vercel-app-access-token',
|
|
188
|
+
'betterleaks/vercel-app-refresh-token',
|
|
189
|
+
'betterleaks/vercel-integration-token',
|
|
190
|
+
'betterleaks/vercel-personal-access-token',
|
|
191
|
+
'betterleaks/virustotal-api-key.1',
|
|
192
|
+
'betterleaks/voyageai-api-key',
|
|
193
|
+
'betterleaks/vultr-api-key.1',
|
|
194
|
+
'betterleaks/wakatime-api-key.1',
|
|
195
|
+
'betterleaks/wakatime-api-key.2',
|
|
196
|
+
'betterleaks/weatherstack-api-key.1',
|
|
197
|
+
'betterleaks/weights-and-biases-api-key',
|
|
198
|
+
'betterleaks/weights-and-biases-api-key-v1',
|
|
199
|
+
'betterleaks/wiz-client-secret.1',
|
|
200
|
+
'betterleaks/woocommerce-consumer-secret.1',
|
|
201
|
+
'betterleaks/workato-developer-api-token.1',
|
|
202
|
+
'betterleaks/workos-production-api-key.1',
|
|
203
|
+
'betterleaks/xai-api-key',
|
|
204
|
+
'betterleaks/xendit-production-api-key.1',
|
|
205
|
+
'betterleaks/zai-api-key',
|
|
206
|
+
'betterleaks/zoho-client-secret.1',
|
|
207
|
+
'betterleaks/zoho-oauth-token.1',
|
|
208
|
+
'betterleaks/zoho-zapi-key.1',
|
|
209
|
+
'betterleaks/zuplo-consumer-api-key.1',
|
|
7
210
|
'birth-context',
|
|
8
211
|
'birth-year',
|
|
9
212
|
'booking-context',
|
|
10
213
|
'booking-filename',
|
|
214
|
+
'card-context',
|
|
11
215
|
'catalog/aws',
|
|
12
216
|
'catalog/azure',
|
|
13
217
|
'catalog/google',
|
|
14
218
|
'cli-password',
|
|
15
219
|
'context',
|
|
16
220
|
'cookie',
|
|
221
|
+
'credential-pair',
|
|
17
222
|
'databricks',
|
|
18
223
|
'detect-secrets',
|
|
19
224
|
'digitalocean',
|
|
@@ -307,6 +512,7 @@ export const builtInRules = Object.freeze([
|
|
|
307
512
|
'google',
|
|
308
513
|
'grafana',
|
|
309
514
|
'home-path',
|
|
515
|
+
'honorific-name',
|
|
310
516
|
'huggingface',
|
|
311
517
|
'iban-checksum',
|
|
312
518
|
'identity-number',
|
|
@@ -321,9 +527,12 @@ export const builtInRules = Object.freeze([
|
|
|
321
527
|
'location-gazetteer',
|
|
322
528
|
'location-label',
|
|
323
529
|
'location-residence',
|
|
530
|
+
'login-call',
|
|
324
531
|
'luhn',
|
|
325
532
|
'mac',
|
|
533
|
+
'mail-display-name',
|
|
326
534
|
'mailchimp',
|
|
535
|
+
'marker-token',
|
|
327
536
|
'messenger-handle',
|
|
328
537
|
'messenger-label',
|
|
329
538
|
'mrz',
|
|
@@ -334,6 +543,7 @@ export const builtInRules = Object.freeze([
|
|
|
334
543
|
'name-initials',
|
|
335
544
|
'name-title',
|
|
336
545
|
'name-variant',
|
|
546
|
+
'named-value',
|
|
337
547
|
'national-format',
|
|
338
548
|
'national-phone',
|
|
339
549
|
'ner/offline',
|
|
@@ -357,10 +567,13 @@ export const builtInRules = Object.freeze([
|
|
|
357
567
|
'passport-format',
|
|
358
568
|
'passport-issuer',
|
|
359
569
|
'passport-series',
|
|
570
|
+
'password-hash',
|
|
360
571
|
'personal-profile-url',
|
|
361
572
|
'phone-context',
|
|
573
|
+
'po-box',
|
|
362
574
|
'postal-address',
|
|
363
575
|
'postal-code',
|
|
576
|
+
'postal-label',
|
|
364
577
|
'presidio',
|
|
365
578
|
'private-key',
|
|
366
579
|
'profile-attribute',
|
|
@@ -370,12 +583,17 @@ export const builtInRules = Object.freeze([
|
|
|
370
583
|
'pypi',
|
|
371
584
|
'quoted-entropy',
|
|
372
585
|
'residence-prose',
|
|
586
|
+
'salutation',
|
|
373
587
|
'school-acronym-context',
|
|
374
588
|
'secretlint',
|
|
589
|
+
'self-introduction',
|
|
375
590
|
'sendgrid',
|
|
376
591
|
'shopify',
|
|
592
|
+
'sign-off',
|
|
377
593
|
'slack',
|
|
378
594
|
'square',
|
|
595
|
+
'ssn-label',
|
|
596
|
+
'state-zip',
|
|
379
597
|
'strict-age',
|
|
380
598
|
'strict-attribute',
|
|
381
599
|
'strict-date',
|
|
@@ -400,12 +618,216 @@ export const credentialRules = new Set([
|
|
|
400
618
|
'anthropic',
|
|
401
619
|
'authorization',
|
|
402
620
|
'aws',
|
|
621
|
+
'betterleaks/abuseipdb-api-key.1',
|
|
622
|
+
'betterleaks/aikido-ci-token',
|
|
623
|
+
'betterleaks/aikido-client-secret',
|
|
624
|
+
'betterleaks/airtable-oauth-token',
|
|
625
|
+
'betterleaks/aiven-auth-token',
|
|
626
|
+
'betterleaks/alibaba-sts-access-key-secret',
|
|
627
|
+
'betterleaks/amplitude-secret-key',
|
|
628
|
+
'betterleaks/apify-api-token',
|
|
629
|
+
'betterleaks/apollo-api-key.1',
|
|
630
|
+
'betterleaks/asaas-api-token',
|
|
631
|
+
'betterleaks/assemblyai-api-key',
|
|
632
|
+
'betterleaks/auth0-client-secret.1',
|
|
633
|
+
'betterleaks/azure-app-configuration-connection-string',
|
|
634
|
+
'betterleaks/azure-servicebus-connection-string',
|
|
635
|
+
'betterleaks/azure-storage-account-key',
|
|
636
|
+
'betterleaks/bitbucket-data-center-token',
|
|
637
|
+
'betterleaks/bitly-access-token',
|
|
638
|
+
'betterleaks/bitrise-access-token',
|
|
639
|
+
'betterleaks/box-api-access-token',
|
|
640
|
+
'betterleaks/brave-search-api-key',
|
|
641
|
+
'betterleaks/browserstack-access-key.1',
|
|
642
|
+
'betterleaks/buildkite-service-token',
|
|
643
|
+
'betterleaks/buildkite-user-access-token',
|
|
644
|
+
'betterleaks/canadian-digital-service-notify-api-key',
|
|
645
|
+
'betterleaks/canva-client-secret',
|
|
646
|
+
'betterleaks/cartesia-api-key.1',
|
|
647
|
+
'betterleaks/cerebras-api-key',
|
|
648
|
+
'betterleaks/checkout-secret-key',
|
|
649
|
+
'betterleaks/circleci-personal-token',
|
|
650
|
+
'betterleaks/circleci-project-token',
|
|
651
|
+
'betterleaks/civo-api-key',
|
|
652
|
+
'betterleaks/clerk-secret-key',
|
|
653
|
+
'betterleaks/clickup-personal-api-token',
|
|
654
|
+
'betterleaks/cloudflare-api-key.2',
|
|
655
|
+
'betterleaks/cloudinary-api-secret',
|
|
656
|
+
'betterleaks/cloudsmith-api-key',
|
|
657
|
+
'betterleaks/cockroachlabs-cloud-api-key',
|
|
658
|
+
'betterleaks/configcat-sdk-key',
|
|
659
|
+
'betterleaks/configcat-sdk-key-extended',
|
|
660
|
+
'betterleaks/couchbase-capella-api-key',
|
|
661
|
+
'betterleaks/coveralls-personal-api-token',
|
|
662
|
+
'betterleaks/crates-io-api-key',
|
|
663
|
+
'betterleaks/cursor-api-key',
|
|
664
|
+
'betterleaks/databento-api-key',
|
|
665
|
+
'betterleaks/datadog-api-key',
|
|
666
|
+
'betterleaks/datadog-application-key',
|
|
667
|
+
'betterleaks/datagov-api-key',
|
|
668
|
+
'betterleaks/datastax-astra-application-token',
|
|
669
|
+
'betterleaks/deepgram-api-key',
|
|
670
|
+
'betterleaks/deepseek-api-key',
|
|
671
|
+
'betterleaks/deno-account-token',
|
|
672
|
+
'betterleaks/devcycle-client-sdk-key',
|
|
673
|
+
'betterleaks/devcycle-mobile-sdk-key',
|
|
674
|
+
'betterleaks/devcycle-server-sdk-key',
|
|
675
|
+
'betterleaks/devin-personal-api-key',
|
|
676
|
+
'betterleaks/devin-service-api-key',
|
|
677
|
+
'betterleaks/devin-service-user-token',
|
|
678
|
+
'betterleaks/disqus-api-key',
|
|
679
|
+
'betterleaks/docker-swarm-join-token',
|
|
680
|
+
'betterleaks/docker-swarm-unlock-key',
|
|
681
|
+
'betterleaks/dockerhub-organization-access-token',
|
|
682
|
+
'betterleaks/dockerhub-personal-access-token',
|
|
683
|
+
'betterleaks/ebay-client-secret',
|
|
684
|
+
'betterleaks/elastic-cloud-api-key',
|
|
685
|
+
'betterleaks/elevenlabs-api-key',
|
|
686
|
+
'betterleaks/endorlabs-api-key',
|
|
687
|
+
'betterleaks/endorlabs-api-secret',
|
|
688
|
+
'betterleaks/etsy-open-api-key',
|
|
689
|
+
'betterleaks/exoscale-api-key',
|
|
690
|
+
'betterleaks/fal-api-key.1',
|
|
691
|
+
'betterleaks/figma-personal-access-header-token',
|
|
692
|
+
'betterleaks/figma-personal-access-token',
|
|
693
|
+
'betterleaks/fullstory-api-key',
|
|
694
|
+
'betterleaks/gcp-application-default-credentials',
|
|
695
|
+
'betterleaks/gcp-gemini-api',
|
|
696
|
+
'betterleaks/gcp-service-account',
|
|
697
|
+
'betterleaks/gitea-access-token',
|
|
698
|
+
'betterleaks/gitlab-incoming-mail-address-token',
|
|
699
|
+
'betterleaks/gitlab-pat-routable-versioned',
|
|
700
|
+
'betterleaks/greptile-api-key',
|
|
701
|
+
'betterleaks/groq-api-key',
|
|
702
|
+
'betterleaks/gumroad-access-token',
|
|
703
|
+
'betterleaks/highnote-secret-live-key',
|
|
704
|
+
'betterleaks/honeycomb-api-key',
|
|
705
|
+
'betterleaks/hunter-api-key.1',
|
|
706
|
+
'betterleaks/ibm-cloud-user-api-key',
|
|
707
|
+
'betterleaks/influxdb-api-token',
|
|
708
|
+
'betterleaks/infomaniak-api-token',
|
|
709
|
+
'betterleaks/instantly-api-key.1',
|
|
710
|
+
'betterleaks/ionic-personal-access-token',
|
|
711
|
+
'betterleaks/jumpcloud-api-key',
|
|
712
|
+
'betterleaks/kagi-api-key',
|
|
713
|
+
'betterleaks/kimi-api-key',
|
|
714
|
+
'betterleaks/klaviyo-api-key',
|
|
715
|
+
'betterleaks/langchain-langsmith-personal-access-token',
|
|
716
|
+
'betterleaks/langchain-langsmith-service-key',
|
|
717
|
+
'betterleaks/langfuse-secret-key.1',
|
|
718
|
+
'betterleaks/lark-app-secret',
|
|
719
|
+
'betterleaks/lichess-personal-access-token',
|
|
720
|
+
'betterleaks/lighton-paradigm-api-key',
|
|
721
|
+
'betterleaks/llama-cloud-api-key.1',
|
|
722
|
+
'betterleaks/mailersend-api-token',
|
|
723
|
+
'betterleaks/mem0-api-key.1',
|
|
724
|
+
'betterleaks/mercury-production-api-token',
|
|
725
|
+
'betterleaks/mergify-application-key',
|
|
726
|
+
'betterleaks/midtrans-production-server-client-key',
|
|
727
|
+
'betterleaks/minimax-api-key',
|
|
728
|
+
'betterleaks/miro-access-token',
|
|
729
|
+
'betterleaks/miro-client-secret',
|
|
730
|
+
'betterleaks/mistral-api-key',
|
|
731
|
+
'betterleaks/monday-api-token.1',
|
|
732
|
+
'betterleaks/mongodb-atlas-service-account-secret',
|
|
733
|
+
'betterleaks/mongodb-connection-string',
|
|
734
|
+
'betterleaks/mux-access-token-secret.1',
|
|
735
|
+
'betterleaks/neon-api-key',
|
|
736
|
+
'betterleaks/ngrok-api-key.1',
|
|
737
|
+
'betterleaks/nuget-api-key',
|
|
738
|
+
'betterleaks/nvidia-api-key',
|
|
739
|
+
'betterleaks/nylas-api-key.1',
|
|
740
|
+
'betterleaks/ollama-api-key',
|
|
741
|
+
'betterleaks/onesignal-rich-authentication-token',
|
|
742
|
+
'betterleaks/onfido-live-api-token-ca',
|
|
743
|
+
'betterleaks/onfido-live-api-token-eu',
|
|
744
|
+
'betterleaks/onfido-live-api-token-us',
|
|
745
|
+
'betterleaks/openrouter-api-key',
|
|
746
|
+
'betterleaks/openweather-api-key',
|
|
747
|
+
'betterleaks/opsgenie-api-key.1',
|
|
748
|
+
'betterleaks/ovh-application-secret',
|
|
749
|
+
'betterleaks/paddle-live-api-key',
|
|
750
|
+
'betterleaks/pagerduty-authorization-token.1',
|
|
751
|
+
'betterleaks/paypal-client-secret.1',
|
|
752
|
+
'betterleaks/persona-production-api-key',
|
|
753
|
+
'betterleaks/pinecone-api-key.1',
|
|
754
|
+
'betterleaks/pinecone-api-key.2',
|
|
755
|
+
'betterleaks/pinterest-access-token',
|
|
756
|
+
'betterleaks/plivo-auth-token',
|
|
757
|
+
'betterleaks/polar-oauth-access-token',
|
|
758
|
+
'betterleaks/polar-organization-access-token',
|
|
759
|
+
'betterleaks/polar-personal-access-token',
|
|
760
|
+
'betterleaks/polymarket-api-key',
|
|
761
|
+
'betterleaks/polymarket-private-key',
|
|
762
|
+
'betterleaks/posthog-personal-api-key',
|
|
763
|
+
'betterleaks/posthog-project-api-key',
|
|
764
|
+
'betterleaks/postmark-api-token.1',
|
|
765
|
+
'betterleaks/proof-full-access-api-key',
|
|
766
|
+
'betterleaks/rainforest-pay-production-api-key',
|
|
767
|
+
'betterleaks/ramp-client-secret',
|
|
768
|
+
'betterleaks/razorpay-key-secret.1',
|
|
769
|
+
'betterleaks/redirect-pizza-api-token.1',
|
|
770
|
+
'betterleaks/render-api-key',
|
|
771
|
+
'betterleaks/replicate-api-token',
|
|
772
|
+
'betterleaks/resend-api-key.1',
|
|
773
|
+
'betterleaks/retell-api-key.1',
|
|
774
|
+
'betterleaks/rootly-api-key.1',
|
|
775
|
+
'betterleaks/runpod-api-key.1',
|
|
776
|
+
'betterleaks/salesforce-access-token.1',
|
|
777
|
+
'betterleaks/samsara-api-token.1',
|
|
778
|
+
'betterleaks/scaleway-secret-key',
|
|
779
|
+
'betterleaks/scalr-api-access-token.1',
|
|
780
|
+
'betterleaks/segment-public-api-token.1',
|
|
781
|
+
'betterleaks/slack-session-cookie',
|
|
782
|
+
'betterleaks/slack-session-token',
|
|
783
|
+
'betterleaks/snowflake-programmatic-access-token.1',
|
|
784
|
+
'betterleaks/sslmate-api-key.1',
|
|
785
|
+
'betterleaks/stability-ai-api-key',
|
|
786
|
+
'betterleaks/supabase-management-token',
|
|
787
|
+
'betterleaks/supabase-project-api-key',
|
|
788
|
+
'betterleaks/tableau-personal-access-token.1',
|
|
789
|
+
'betterleaks/tailscale-api-key.1',
|
|
790
|
+
'betterleaks/telnyx-api-v2-key.1',
|
|
791
|
+
'betterleaks/temporal-cloud-api-key.1',
|
|
792
|
+
'betterleaks/thunderstore-api-token.1',
|
|
793
|
+
'betterleaks/togetherai-api-key',
|
|
794
|
+
'betterleaks/unkey-root-key.1',
|
|
795
|
+
'betterleaks/upcloud-api-token',
|
|
796
|
+
'betterleaks/upstage-api-key',
|
|
797
|
+
'betterleaks/upstash-redis-rest-token.1',
|
|
798
|
+
'betterleaks/val-town-api-token.1',
|
|
799
|
+
'betterleaks/vercel-ai-gateway-key',
|
|
800
|
+
'betterleaks/vercel-api-token',
|
|
801
|
+
'betterleaks/vercel-app-access-token',
|
|
802
|
+
'betterleaks/vercel-app-refresh-token',
|
|
803
|
+
'betterleaks/vercel-integration-token',
|
|
804
|
+
'betterleaks/vercel-personal-access-token',
|
|
805
|
+
'betterleaks/virustotal-api-key.1',
|
|
806
|
+
'betterleaks/voyageai-api-key',
|
|
807
|
+
'betterleaks/vultr-api-key.1',
|
|
808
|
+
'betterleaks/wakatime-api-key.1',
|
|
809
|
+
'betterleaks/wakatime-api-key.2',
|
|
810
|
+
'betterleaks/weatherstack-api-key.1',
|
|
811
|
+
'betterleaks/weights-and-biases-api-key',
|
|
812
|
+
'betterleaks/weights-and-biases-api-key-v1',
|
|
813
|
+
'betterleaks/wiz-client-secret.1',
|
|
814
|
+
'betterleaks/woocommerce-consumer-secret.1',
|
|
815
|
+
'betterleaks/workato-developer-api-token.1',
|
|
816
|
+
'betterleaks/workos-production-api-key.1',
|
|
817
|
+
'betterleaks/xai-api-key',
|
|
818
|
+
'betterleaks/xendit-production-api-key.1',
|
|
819
|
+
'betterleaks/zai-api-key',
|
|
820
|
+
'betterleaks/zoho-client-secret.1',
|
|
821
|
+
'betterleaks/zoho-oauth-token.1',
|
|
822
|
+
'betterleaks/zoho-zapi-key.1',
|
|
823
|
+
'betterleaks/zuplo-consumer-api-key.1',
|
|
403
824
|
'catalog/aws',
|
|
404
825
|
'catalog/azure',
|
|
405
826
|
'catalog/google',
|
|
406
827
|
'cli-password',
|
|
407
828
|
'context',
|
|
408
829
|
'cookie',
|
|
830
|
+
'credential-pair',
|
|
409
831
|
'databricks',
|
|
410
832
|
'digitalocean',
|
|
411
833
|
'discord',
|
|
@@ -645,12 +1067,16 @@ export const credentialRules = new Set([
|
|
|
645
1067
|
'jwt',
|
|
646
1068
|
'known-secret',
|
|
647
1069
|
'linear',
|
|
1070
|
+
'login-call',
|
|
648
1071
|
'mailchimp',
|
|
1072
|
+
'marker-token',
|
|
1073
|
+
'named-value',
|
|
649
1074
|
'netrc',
|
|
650
1075
|
'notion',
|
|
651
1076
|
'npm',
|
|
652
1077
|
'nuget',
|
|
653
1078
|
'openai',
|
|
1079
|
+
'password-hash',
|
|
654
1080
|
'private-key',
|
|
655
1081
|
'putty-private-key',
|
|
656
1082
|
'pypi',
|
package/src/rules.js
CHANGED
|
@@ -50,6 +50,14 @@ export const serviceRules = [
|
|
|
50
50
|
/[MN][A-Za-z0-9_-]{23}[A-Za-z0-9_-]*\.[A-Za-z0-9_-]{6}\.[A-Za-z0-9_-]{20}[A-Za-z0-9_-]*/g,
|
|
51
51
|
],
|
|
52
52
|
['huggingface', /hf_[A-Za-z0-9]{20}[A-Za-z0-9]*/g],
|
|
53
|
+
// All-caps CI/test credentials (`SYNTHETIC_TOKEN_ALPHA_123456`) carry only
|
|
54
|
+
// a semantic marker. A digit separates them from constant names
|
|
55
|
+
// (`KNOWN_LOCAL_TOKEN_ENV_VARS`); a key (`NAME_TOKEN_2=`) or a reference
|
|
56
|
+
// (`$NAME_TOKEN_2`, `secrets.NAME_TOKEN_2`) is a name, not a value.
|
|
57
|
+
[
|
|
58
|
+
'marker-token',
|
|
59
|
+
/(?<![A-Za-z0-9_$.{%-])(?=[A-Z_-]{0,200}\d)(?:[A-Z0-9]{1,32}[_-]){1,8}(?:TOKEN|SECRET|PASSWORD|CREDENTIAL|API[_-]?KEY)(?:[_-][A-Z0-9]{1,32}){1,8}(?![A-Za-z0-9_$-])(?![ \t]*(?:[:=]|\}))/g,
|
|
60
|
+
],
|
|
53
61
|
['shopify', /shp(?:at|ss|ca|pa)_[a-fA-F0-9]{32}/g],
|
|
54
62
|
['databricks', /dapi[a-fA-F0-9]{32}/g],
|
|
55
63
|
['square', /sq0(?:atp|csp)-[A-Za-z0-9_-]{20}[A-Za-z0-9_-]*/g],
|