tewip-ai 0.18.2 → 0.18.3
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.
|
@@ -54,18 +54,26 @@ export function entropyOf(value) {
|
|
|
54
54
|
const PLACEHOLDER_WORDS = /example|placeholder|dummy|sample|changeme|your[-_ ]?(?:key|token|secret|api)|xxxx|redacted|fake|notreal|test[-_]?key|<[^>]+>|\$\{|\{\{/i;
|
|
55
55
|
/** Files whose whole purpose is to show the shape of a secret, not to hold one. */
|
|
56
56
|
const DOC_FILE = /(?:^|[\\/])(?:\.env\.example|\.env\.sample|\.env\.template|[^\\/]*\.(?:md|rst|txt|adoc)|[^\\/]*example[^\\/]*|[^\\/]*sample[^\\/]*)$/i;
|
|
57
|
-
/**
|
|
57
|
+
/**
|
|
58
|
+
* Why this match is probably not a live credential, or null when nothing says so.
|
|
59
|
+
*
|
|
60
|
+
* The file's name is deliberately not enough on its own any more. A realistic AWS key placed in
|
|
61
|
+
* `src/config-sample.js` was dismissed as noise - "nothing: this is not a credential" - while the
|
|
62
|
+
* identical key in `src/settings.js` was reported as critical. A filename is the weakest evidence
|
|
63
|
+
* there is, and a key pasted into an example file by accident is one of the commonest ways
|
|
64
|
+
* credentials leak. That case is now shown as a template finding instead of being dismissed.
|
|
65
|
+
*/
|
|
58
66
|
export function looksPlanted(value, line, file) {
|
|
59
67
|
if (PLACEHOLDER_WORDS.test(value))
|
|
60
68
|
return 'the value itself says it is an example';
|
|
61
69
|
if (PLACEHOLDER_WORDS.test(line))
|
|
62
70
|
return 'the line around it says it is an example';
|
|
63
|
-
if (DOC_FILE.test(file))
|
|
64
|
-
return 'it is in a documentation or example file';
|
|
65
71
|
if (/(.)\1{5,}/.test(value))
|
|
66
72
|
return 'the value repeats one character, so it is a stand-in';
|
|
67
73
|
return null;
|
|
68
74
|
}
|
|
75
|
+
/** True when only the file's name suggests a template, whatever the value itself looks like. */
|
|
76
|
+
export const inATemplate = (file) => DOC_FILE.test(file);
|
|
69
77
|
const SKIP_DIR = new Set(['node_modules', '.git', 'dist', 'build', 'out', 'coverage', 'target', 'vendor', '__pycache__', '.venv', 'venv', '.tewip', '.next', '.cache']);
|
|
70
78
|
const BINARY = /\.(?:png|jpe?g|gif|webp|ico|svg|pdf|zip|gz|tar|exe|dll|so|dylib|woff2?|ttf|eot|mp4|mp3|wav|class|jar|pyc|lock)$/i;
|
|
71
79
|
const MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
@@ -150,6 +158,7 @@ export function scanSecrets(root, files = sourceFiles(root)) {
|
|
|
150
158
|
evidence: redact(lines[line - 1] ?? '', value),
|
|
151
159
|
entropy: Number(entropy.toFixed(2)),
|
|
152
160
|
placeholder: looksPlanted(value, lines[line - 1] ?? '', rel),
|
|
161
|
+
template: inATemplate(rel),
|
|
153
162
|
});
|
|
154
163
|
}
|
|
155
164
|
}
|
|
@@ -60,6 +60,18 @@ export function triageSecret(finding, root, accepted) {
|
|
|
60
60
|
if (finding.placeholder) {
|
|
61
61
|
return { ...base, verdict: 'noise', severity: 'low', why: `${finding.placeholder}: ${finding.evidence}`, next: 'nothing: this is not a credential' };
|
|
62
62
|
}
|
|
63
|
+
if (finding.template) {
|
|
64
|
+
// Only the file's name says this is a template; the value itself looks like a real credential.
|
|
65
|
+
// Dismissing it would hide the commonest accident there is - a working key pasted into an
|
|
66
|
+
// example file - so it is shown, below the ones that need acting on now.
|
|
67
|
+
return {
|
|
68
|
+
...base,
|
|
69
|
+
verdict: 'not-reachable',
|
|
70
|
+
severity: 'medium',
|
|
71
|
+
why: `${finding.evidence} - the file is a template or documentation, but the value itself does not say it is an example`,
|
|
72
|
+
next: 'check whether this was ever a working credential; if it was, rotate it and replace it here with an obvious placeholder',
|
|
73
|
+
};
|
|
74
|
+
}
|
|
63
75
|
const tracked = isTracked(root, finding.file);
|
|
64
76
|
if (!tracked) {
|
|
65
77
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tewip-ai",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.3",
|
|
4
4
|
"description": "Tewip finds why each failing test failed - real bug, flaky test, environment, test data or changed selector - for any stack, from the command line, CI, or your editor.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"test-failures",
|