Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/detect.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

const { rules } = require('./rules');
const { entropy } = require('./entropy');
const { isCamelIdentifier } = require('./forms');
const { isCamelIdentifier, commonForm } = require('./forms');

// Labels in English, Portuguese and Spanish. The value is the first run of
// non-space, non-quote characters after the separator.
Expand Down Expand Up @@ -495,6 +495,8 @@ function scanContextual(text, taken) {
if ((opens || closes) && opens !== next[0]) continue;
const p = profileOf(text, value, start, end);
if (!p || !contextToken(value, p.cued)) continue;
// `ref: <id>-<64 hex>` ends every monitor event: it names an event, so only a credential word right before it makes it a candidate.
if (!p.cued && commonForm(value) === 'eventref') continue;
out.push({ rule: 'contextual', name: `Credential by context (${p.profile})`, value, start, end, confidence: 'medium', profile: p.profile });
}
return out;
Expand Down
4 changes: 2 additions & 2 deletions src/forms.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,10 @@ const isMessageId = (w) => /^3EB0[0-9A-F]{16,28}$/.test(w);
// prefix that sessions quote to name a value without showing it. Too short to be a key.
const isShortHash = (w) => /^(?=[a-f]*\d)(?=\d*[a-f])[0-9a-f]{7,12}$/.test(w);

// The reference a monitor event carries after `ref:`: an id of 6 to 12 lowercase letters and
// The reference a monitor event carries after `ref:`: an id of 6 to 16 lowercase letters and
// digits, a hyphen and the 64-hex hash of the event contract (`hn9abcdefg-<64 hex>`). It names
// an event; it opens nothing. A provider prefix (`sk-`, `ghp_`...) is judged before this form.
const isEventRef = (w) => /^[a-z0-9]{6,12}-[0-9a-f]{64}$/.test(w) && /[a-z]/.test(w.split('-')[0]);
const isEventRef = (w) => /^[a-z0-9]{6,16}-[0-9a-f]{64}$/.test(w) && /[a-z]/.test(w.split('-')[0]);

// A reference to a variable, not its value: `$NOME`, `${NOME}`, a grep anchor `^NOME=`,
// an assignment with nothing after the sign `NOME=`. Only when the name is made of words
Expand Down
8 changes: 8 additions & 0 deletions test/travas.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ const cfgWrite = (jev) => fs.writeFileSync(cfgFile, JSON.stringify({ promptMode:
check(`id de evento com hash do contrato não é forma forte (${ref.slice(0, 12)}...)`, strongShape(ref), false);
check(`id de evento não vai ao classificador (${ref.slice(0, 12)}...)`, candidatesOf(`resumo do monitor ref: ${ref} fim`).length, 0);
}
// o ref no fim do evento do monitor não é capturado pelo contexto, em qualquer prefixo
for (const pre of ['hn9u08zc1k', 'hn9abcdefghijkl', 'evt12345ab']) {
const ref = `${pre}-${H64}`;
for (const txt of [`ref: ${ref}`, `[monitor] [resumo]: eventos 101 102\nref: ${ref}`, `resumo de 30 min\nref: ${ref}`]) {
check(`ref do monitor não é achado por contexto (${pre})`, scan(txt, { ambiguous: true, message: true }).findings.length, 0);
}
}
check('ref do monitor com palavra de credencial antes continua achado', scan(`token: hn9u08zc1k-${H64}`, { ambiguous: true, message: true }).findings.length > 0, true);
check('prefixo de provedor com 64 hex continua forte', strongShape(`sk-${H64}`), true);
check('64 hex puro continua forte', strongShape(H64), true);
check('prefixo curto demais com 64 hex continua forte', strongShape(`ab-${H64}`), true);
Expand Down
Loading