@sikkuumiii/defuse 0.0.0-stage → 0.5.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/LICENSE +235 -0
- package/README.md +561 -2
- package/dist/src/cli.d.ts +20 -0
- package/dist/src/cli.js +619 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/core/analyze.d.ts +178 -0
- package/dist/src/core/analyze.js +834 -0
- package/dist/src/core/analyze.js.map +1 -0
- package/dist/src/core/coverage.d.ts +87 -0
- package/dist/src/core/coverage.js +181 -0
- package/dist/src/core/coverage.js.map +1 -0
- package/dist/src/core/finding.d.ts +196 -0
- package/dist/src/core/finding.js +178 -0
- package/dist/src/core/finding.js.map +1 -0
- package/dist/src/core/licence.d.ts +50 -0
- package/dist/src/core/licence.js +56 -0
- package/dist/src/core/licence.js.map +1 -0
- package/dist/src/core/paths.d.ts +21 -0
- package/dist/src/core/paths.js +58 -0
- package/dist/src/core/paths.js.map +1 -0
- package/dist/src/core/score.d.ts +137 -0
- package/dist/src/core/score.js +232 -0
- package/dist/src/core/score.js.map +1 -0
- package/dist/src/dast/targets.d.ts +30 -0
- package/dist/src/dast/targets.js +79 -0
- package/dist/src/dast/targets.js.map +1 -0
- package/dist/src/dast/zap.d.ts +42 -0
- package/dist/src/dast/zap.js +184 -0
- package/dist/src/dast/zap.js.map +1 -0
- package/dist/src/engine/scan.d.ts +80 -0
- package/dist/src/engine/scan.js +129 -0
- package/dist/src/engine/scan.js.map +1 -0
- package/dist/src/engine/shapes.d.ts +47 -0
- package/dist/src/engine/shapes.js +328 -0
- package/dist/src/engine/shapes.js.map +1 -0
- package/dist/src/engine/walk.d.ts +60 -0
- package/dist/src/engine/walk.js +156 -0
- package/dist/src/engine/walk.js.map +1 -0
- package/dist/src/parse/astDump.d.ts +31 -0
- package/dist/src/parse/astDump.js +66 -0
- package/dist/src/parse/astDump.js.map +1 -0
- package/dist/src/parse/languages.d.ts +70 -0
- package/dist/src/parse/languages.js +174 -0
- package/dist/src/parse/languages.js.map +1 -0
- package/dist/src/parse/location.d.ts +17 -0
- package/dist/src/parse/location.js +38 -0
- package/dist/src/parse/location.js.map +1 -0
- package/dist/src/parse/node-grammars.d.ts +12 -0
- package/dist/src/parse/node-grammars.js +35 -0
- package/dist/src/parse/node-grammars.js.map +1 -0
- package/dist/src/parse/parser.d.ts +126 -0
- package/dist/src/parse/parser.js +202 -0
- package/dist/src/parse/parser.js.map +1 -0
- package/dist/src/parse/tree-store.d.ts +139 -0
- package/dist/src/parse/tree-store.js +236 -0
- package/dist/src/parse/tree-store.js.map +1 -0
- package/dist/src/platform/dependency-rule.d.ts +27 -0
- package/dist/src/platform/dependency-rule.js +21 -0
- package/dist/src/platform/dependency-rule.js.map +1 -0
- package/dist/src/platform/deps.d.ts +86 -0
- package/dist/src/platform/deps.js +304 -0
- package/dist/src/platform/deps.js.map +1 -0
- package/dist/src/platform/php-facts.d.ts +49 -0
- package/dist/src/platform/php-facts.js +67 -0
- package/dist/src/platform/php-facts.js.map +1 -0
- package/dist/src/platform/runtime-version.d.ts +78 -0
- package/dist/src/platform/runtime-version.js +573 -0
- package/dist/src/platform/runtime-version.js.map +1 -0
- package/dist/src/report/colors.d.ts +50 -0
- package/dist/src/report/colors.js +97 -0
- package/dist/src/report/colors.js.map +1 -0
- package/dist/src/report/coverage-table.d.ts +90 -0
- package/dist/src/report/coverage-table.js +291 -0
- package/dist/src/report/coverage-table.js.map +1 -0
- package/dist/src/report/html-report.d.ts +66 -0
- package/dist/src/report/html-report.js +489 -0
- package/dist/src/report/html-report.js.map +1 -0
- package/dist/src/report/human.d.ts +44 -0
- package/dist/src/report/human.js +575 -0
- package/dist/src/report/human.js.map +1 -0
- package/dist/src/report/json.d.ts +24 -0
- package/dist/src/report/json.js +178 -0
- package/dist/src/report/json.js.map +1 -0
- package/dist/src/report/mark.d.ts +17 -0
- package/dist/src/report/mark.js +39 -0
- package/dist/src/report/mark.js.map +1 -0
- package/dist/src/report/pricing.d.ts +33 -0
- package/dist/src/report/pricing.js +343 -0
- package/dist/src/report/pricing.js.map +1 -0
- package/dist/src/report/sarif.d.ts +39 -0
- package/dist/src/report/sarif.js +219 -0
- package/dist/src/report/sarif.js.map +1 -0
- package/dist/src/report/site.d.ts +87 -0
- package/dist/src/report/site.js +742 -0
- package/dist/src/report/site.js.map +1 -0
- package/dist/src/rules/code-injection.d.ts +47 -0
- package/dist/src/rules/code-injection.js +326 -0
- package/dist/src/rules/code-injection.js.map +1 -0
- package/dist/src/rules/command-injection.d.ts +30 -0
- package/dist/src/rules/command-injection.js +286 -0
- package/dist/src/rules/command-injection.js.map +1 -0
- package/dist/src/rules/contract.d.ts +198 -0
- package/dist/src/rules/contract.js +39 -0
- package/dist/src/rules/contract.js.map +1 -0
- package/dist/src/rules/format-string.d.ts +46 -0
- package/dist/src/rules/format-string.js +146 -0
- package/dist/src/rules/format-string.js.map +1 -0
- package/dist/src/rules/hardcoded-secret.d.ts +38 -0
- package/dist/src/rules/hardcoded-secret.js +440 -0
- package/dist/src/rules/hardcoded-secret.js.map +1 -0
- package/dist/src/rules/lib/guards.d.ts +168 -0
- package/dist/src/rules/lib/guards.js +1179 -0
- package/dist/src/rules/lib/guards.js.map +1 -0
- package/dist/src/rules/lib/html-safety.d.ts +75 -0
- package/dist/src/rules/lib/html-safety.js +755 -0
- package/dist/src/rules/lib/html-safety.js.map +1 -0
- package/dist/src/rules/lib/local-build.d.ts +59 -0
- package/dist/src/rules/lib/local-build.js +320 -0
- package/dist/src/rules/lib/local-build.js.map +1 -0
- package/dist/src/rules/lib/strings.d.ts +208 -0
- package/dist/src/rules/lib/strings.js +1970 -0
- package/dist/src/rules/lib/strings.js.map +1 -0
- package/dist/src/rules/path-traversal.d.ts +33 -0
- package/dist/src/rules/path-traversal.js +96 -0
- package/dist/src/rules/path-traversal.js.map +1 -0
- package/dist/src/rules/registry.d.ts +19 -0
- package/dist/src/rules/registry.js +77 -0
- package/dist/src/rules/registry.js.map +1 -0
- package/dist/src/rules/sql-injection.d.ts +36 -0
- package/dist/src/rules/sql-injection.js +299 -0
- package/dist/src/rules/sql-injection.js.map +1 -0
- package/dist/src/rules/ssrf.d.ts +39 -0
- package/dist/src/rules/ssrf.js +111 -0
- package/dist/src/rules/ssrf.js.map +1 -0
- package/dist/src/rules/unbounded-copy.d.ts +37 -0
- package/dist/src/rules/unbounded-copy.js +147 -0
- package/dist/src/rules/unbounded-copy.js.map +1 -0
- package/dist/src/rules/unsafe-deserialization.d.ts +43 -0
- package/dist/src/rules/unsafe-deserialization.js +276 -0
- package/dist/src/rules/unsafe-deserialization.js.map +1 -0
- package/dist/src/rules/weak-hash.d.ts +37 -0
- package/dist/src/rules/weak-hash.js +197 -0
- package/dist/src/rules/weak-hash.js.map +1 -0
- package/dist/src/rules/xss.d.ts +38 -0
- package/dist/src/rules/xss.js +527 -0
- package/dist/src/rules/xss.js.map +1 -0
- package/dist/src/taint/content-type.d.ts +19 -0
- package/dist/src/taint/content-type.js +20 -0
- package/dist/src/taint/content-type.js.map +1 -0
- package/dist/src/taint/dictionaries.d.ts +23 -0
- package/dist/src/taint/dictionaries.js +1778 -0
- package/dist/src/taint/dictionaries.js.map +1 -0
- package/dist/src/taint/fold.d.ts +59 -0
- package/dist/src/taint/fold.js +1177 -0
- package/dist/src/taint/fold.js.map +1 -0
- package/dist/src/taint/java-scope.d.ts +61 -0
- package/dist/src/taint/java-scope.js +212 -0
- package/dist/src/taint/java-scope.js.map +1 -0
- package/dist/src/taint/local-map.d.ts +79 -0
- package/dist/src/taint/local-map.js +603 -0
- package/dist/src/taint/local-map.js.map +1 -0
- package/dist/src/taint/project.d.ts +172 -0
- package/dist/src/taint/project.js +617 -0
- package/dist/src/taint/project.js.map +1 -0
- package/dist/src/taint/tracer.d.ts +265 -0
- package/dist/src/taint/tracer.js +3817 -0
- package/dist/src/taint/tracer.js.map +1 -0
- package/dist/src/taint/types.d.ts +484 -0
- package/dist/src/taint/types.js +47 -0
- package/dist/src/taint/types.js.map +1 -0
- package/dist/src/taint/visibility.d.ts +25 -0
- package/dist/src/taint/visibility.js +96 -0
- package/dist/src/taint/visibility.js.map +1 -0
- package/docs/examples/defuse.json +20 -0
- package/docs/examples/dvwa-urls.json +14 -0
- package/docs/examples/github-code-scanning.yml +54 -0
- package/docs/examples/tiny.js +4 -0
- package/package.json +73 -4
- package/src/cli.ts +747 -0
- package/src/core/analyze.ts +1072 -0
- package/src/core/coverage.ts +269 -0
- package/src/core/finding.ts +311 -0
- package/src/core/licence.ts +61 -0
- package/src/core/paths.ts +59 -0
- package/src/core/score.ts +353 -0
- package/src/dast/targets.ts +121 -0
- package/src/dast/zap.ts +246 -0
- package/src/engine/scan.ts +200 -0
- package/src/engine/shapes.ts +348 -0
- package/src/engine/walk.ts +196 -0
- package/src/parse/astDump.ts +85 -0
- package/src/parse/languages.ts +232 -0
- package/src/parse/location.ts +44 -0
- package/src/parse/node-grammars.ts +41 -0
- package/src/parse/parser.ts +262 -0
- package/src/parse/tree-store.ts +301 -0
- package/src/platform/dependency-rule.ts +33 -0
- package/src/platform/deps.ts +374 -0
- package/src/platform/php-facts.ts +85 -0
- package/src/platform/runtime-version.ts +710 -0
- package/src/report/colors.ts +107 -0
- package/src/report/coverage-table.ts +359 -0
- package/src/report/html-report.ts +601 -0
- package/src/report/human.ts +811 -0
- package/src/report/json.ts +189 -0
- package/src/report/mark.ts +47 -0
- package/src/report/pricing.ts +374 -0
- package/src/report/sarif.ts +235 -0
- package/src/report/site.ts +760 -0
- package/src/rules/code-injection.ts +346 -0
- package/src/rules/command-injection.ts +296 -0
- package/src/rules/contract.ts +220 -0
- package/src/rules/format-string.ts +158 -0
- package/src/rules/hardcoded-secret.ts +485 -0
- package/src/rules/lib/guards.ts +1235 -0
- package/src/rules/lib/html-safety.ts +793 -0
- package/src/rules/lib/local-build.ts +329 -0
- package/src/rules/lib/strings.ts +2034 -0
- package/src/rules/path-traversal.ts +101 -0
- package/src/rules/registry.ts +90 -0
- package/src/rules/sql-injection.ts +311 -0
- package/src/rules/ssrf.ts +118 -0
- package/src/rules/unbounded-copy.ts +162 -0
- package/src/rules/unsafe-deserialization.ts +291 -0
- package/src/rules/weak-hash.ts +226 -0
- package/src/rules/xss.ts +572 -0
- package/src/taint/content-type.ts +20 -0
- package/src/taint/dictionaries.ts +1855 -0
- package/src/taint/fold.ts +1206 -0
- package/src/taint/java-scope.ts +200 -0
- package/src/taint/local-map.ts +594 -0
- package/src/taint/project.ts +774 -0
- package/src/taint/tracer.ts +4298 -0
- package/src/taint/types.ts +511 -0
- package/src/taint/visibility.ts +100 -0
- package/tsconfig.json +61 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-safety.js","sourceRoot":"","sources":["../../../../src/rules/lib/html-safety.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WHERE WAS THIS VARIABLE BUILT?
|
|
3
|
+
* ==============================
|
|
4
|
+
*
|
|
5
|
+
* A signature rule reads the argument of a dangerous call and asks how its text
|
|
6
|
+
* was assembled. That question has an obvious blind spot, and until this file
|
|
7
|
+
* existed the command-injection rule sat squarely in it:
|
|
8
|
+
*
|
|
9
|
+
* os.system("ls " + name) <- the argument IS the build. Reported.
|
|
10
|
+
*
|
|
11
|
+
* cmd = "ls " + name
|
|
12
|
+
* os.system(cmd) <- the argument is a NAME. Silent.
|
|
13
|
+
*
|
|
14
|
+
* Same code, same risk, one line break apart - in every language. In C it was
|
|
15
|
+
* worse than a blind spot: C has no `+` for strings, so a command is ALWAYS
|
|
16
|
+
* formatted into a buffer first and run afterwards, and the signature pass saw
|
|
17
|
+
* `system(buf)` every single time.
|
|
18
|
+
*
|
|
19
|
+
* WHAT THIS DOES, AND ON PURPOSE WHAT IT DOES NOT.
|
|
20
|
+
*
|
|
21
|
+
* Given a bare name at a call site, it looks back through the SAME function for
|
|
22
|
+
* the writes that reach the call, in straight-line code:
|
|
23
|
+
*
|
|
24
|
+
* a RESET replaces the value cmd = ... char cmd[] = ... sprintf(cmd, ...)
|
|
25
|
+
* an EXTEND appends to it cmd += ... strcat(cmd, ...) cmd.append(...)
|
|
26
|
+
*
|
|
27
|
+
* The value at the call is the LAST reset plus every extend after it. That is
|
|
28
|
+
* what makes `cmd = "ls " + name; cmd = "ls -l"; system(cmd)` quiet: the build
|
|
29
|
+
* that spliced `name` in was overwritten before the call ran.
|
|
30
|
+
*
|
|
31
|
+
* It gives up - returns null, which leaves the rule exactly as quiet as it was
|
|
32
|
+
* before - whenever the answer would depend on which way the program went:
|
|
33
|
+
*
|
|
34
|
+
* - any write to the name sits under an if, a loop, a switch or a try;
|
|
35
|
+
* - there is no reset in this function at all (a parameter, a global);
|
|
36
|
+
* - the write is a shape this file has not been taught.
|
|
37
|
+
*
|
|
38
|
+
* Giving up is the safe direction for a SIGNATURE rule in the narrow sense that
|
|
39
|
+
* it cannot add a false finding. It is not free: every one of those is a guess
|
|
40
|
+
* the rule could have made and did not. The coverage notes say so, rather than
|
|
41
|
+
* letting "implemented" imply the conditional case is covered too.
|
|
42
|
+
*
|
|
43
|
+
* It never evaluates anything. It describes how the text was put together,
|
|
44
|
+
* which is all a signature rule is entitled to know.
|
|
45
|
+
*/
|
|
46
|
+
import type { Node } from 'web-tree-sitter';
|
|
47
|
+
import type { LanguageId } from '../../parse/languages.js';
|
|
48
|
+
import { type StringExpression } from './strings.js';
|
|
49
|
+
export interface LocalBuild {
|
|
50
|
+
readonly expression: StringExpression;
|
|
51
|
+
/** 1-based line of the write the value at the call starts from. */
|
|
52
|
+
readonly line: number;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Follow the argument of a dangerous call back to how its text was built.
|
|
56
|
+
* Returns null when there is nothing to follow, or when following it would
|
|
57
|
+
* need to know which way the program went.
|
|
58
|
+
*/
|
|
59
|
+
export declare function followLocalBuild(arg: Node, language: LanguageId): LocalBuild | null;
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WHERE WAS THIS VARIABLE BUILT?
|
|
3
|
+
* ==============================
|
|
4
|
+
*
|
|
5
|
+
* A signature rule reads the argument of a dangerous call and asks how its text
|
|
6
|
+
* was assembled. That question has an obvious blind spot, and until this file
|
|
7
|
+
* existed the command-injection rule sat squarely in it:
|
|
8
|
+
*
|
|
9
|
+
* os.system("ls " + name) <- the argument IS the build. Reported.
|
|
10
|
+
*
|
|
11
|
+
* cmd = "ls " + name
|
|
12
|
+
* os.system(cmd) <- the argument is a NAME. Silent.
|
|
13
|
+
*
|
|
14
|
+
* Same code, same risk, one line break apart - in every language. In C it was
|
|
15
|
+
* worse than a blind spot: C has no `+` for strings, so a command is ALWAYS
|
|
16
|
+
* formatted into a buffer first and run afterwards, and the signature pass saw
|
|
17
|
+
* `system(buf)` every single time.
|
|
18
|
+
*
|
|
19
|
+
* WHAT THIS DOES, AND ON PURPOSE WHAT IT DOES NOT.
|
|
20
|
+
*
|
|
21
|
+
* Given a bare name at a call site, it looks back through the SAME function for
|
|
22
|
+
* the writes that reach the call, in straight-line code:
|
|
23
|
+
*
|
|
24
|
+
* a RESET replaces the value cmd = ... char cmd[] = ... sprintf(cmd, ...)
|
|
25
|
+
* an EXTEND appends to it cmd += ... strcat(cmd, ...) cmd.append(...)
|
|
26
|
+
*
|
|
27
|
+
* The value at the call is the LAST reset plus every extend after it. That is
|
|
28
|
+
* what makes `cmd = "ls " + name; cmd = "ls -l"; system(cmd)` quiet: the build
|
|
29
|
+
* that spliced `name` in was overwritten before the call ran.
|
|
30
|
+
*
|
|
31
|
+
* It gives up - returns null, which leaves the rule exactly as quiet as it was
|
|
32
|
+
* before - whenever the answer would depend on which way the program went:
|
|
33
|
+
*
|
|
34
|
+
* - any write to the name sits under an if, a loop, a switch or a try;
|
|
35
|
+
* - there is no reset in this function at all (a parameter, a global);
|
|
36
|
+
* - the write is a shape this file has not been taught.
|
|
37
|
+
*
|
|
38
|
+
* Giving up is the safe direction for a SIGNATURE rule in the narrow sense that
|
|
39
|
+
* it cannot add a false finding. It is not free: every one of those is a guess
|
|
40
|
+
* the rule could have made and did not. The coverage notes say so, rather than
|
|
41
|
+
* letting "implemented" imply the conditional case is covered too.
|
|
42
|
+
*
|
|
43
|
+
* It never evaluates anything. It describes how the text was put together,
|
|
44
|
+
* which is all a signature rule is entitled to know.
|
|
45
|
+
*/
|
|
46
|
+
import { analyzeStringExpression } from './strings.js';
|
|
47
|
+
/** Where a function's own writes stop. A nested function is a different scope. */
|
|
48
|
+
const FUNCTION_NODES = new Set([
|
|
49
|
+
'function_declaration', 'function_expression', 'arrow_function', 'method_definition',
|
|
50
|
+
'function_definition', 'lambda', 'lambda_expression',
|
|
51
|
+
'method_declaration', 'constructor_declaration',
|
|
52
|
+
'func_literal', 'anonymous_function_creation_expression',
|
|
53
|
+
]);
|
|
54
|
+
/*
|
|
55
|
+
* Control flow, matched on the node-type NAME across all eight grammars, because
|
|
56
|
+
* eight grammars spell it eight ways (if_statement, elif_clause,
|
|
57
|
+
* expression_switch_statement, enhanced_for_statement, for_range_loop,
|
|
58
|
+
* switch_block_statement_group, catch_clause, except_clause...). A type this
|
|
59
|
+
* pattern wrongly calls conditional only makes the helper give up - it cannot
|
|
60
|
+
* make it report something it would not otherwise have reported.
|
|
61
|
+
*/
|
|
62
|
+
const CONTROL_FLOW = /(^|_)(if|else|elif|switch|case|for|foreach|while|do|try|catch|except|finally|match|conditional|ternary)(_|$)/;
|
|
63
|
+
/* C's output-parameter writers. The destination is always argument 0. */
|
|
64
|
+
const C_FORMAT_WRITERS = {
|
|
65
|
+
sprintf: 1, vsprintf: 1, snprintf: 2, vsnprintf: 2, // value: index of the format string
|
|
66
|
+
};
|
|
67
|
+
const C_COPY_RESETS = new Set(['strcpy', 'strncpy', 'strlcpy']);
|
|
68
|
+
const C_APPENDS = new Set(['strcat', 'strncat', 'strlcat']);
|
|
69
|
+
/* C++ std::string members that replace or extend the receiver. */
|
|
70
|
+
const CPP_MEMBER_RESETS = new Set(['assign']);
|
|
71
|
+
const CPP_MEMBER_APPENDS = new Set(['append']);
|
|
72
|
+
/*
|
|
73
|
+
* `.c_str()` and `.data()` do nothing to the text; they hand a std::string over
|
|
74
|
+
* in the shape a C API wants. std::system() takes a `const char*`, so EVERY C++
|
|
75
|
+
* shell call ends in one of these, and to the signature pass a method call was
|
|
76
|
+
* an opaque value - which is why even the one-line form was silent:
|
|
77
|
+
*
|
|
78
|
+
* std::system(("ls " + name).c_str());
|
|
79
|
+
*/
|
|
80
|
+
const TRANSPARENT_METHODS = new Set(['c_str', 'data']);
|
|
81
|
+
const lineOf = (node) => node.startPosition.row + 1;
|
|
82
|
+
const same = (a, b) => a !== null && b !== null && a.startIndex === b.startIndex && a.endIndex === b.endIndex;
|
|
83
|
+
/** The bare name a declarator or assignment target binds: `cmd`, `buf[256]`, `*p`, `$cmd`. */
|
|
84
|
+
function boundName(target) {
|
|
85
|
+
let current = target;
|
|
86
|
+
for (let depth = 0; current && depth < 6; depth++) {
|
|
87
|
+
if (current.type === 'identifier' || current.type === 'variable_name') {
|
|
88
|
+
return (current.text ?? '').replace(/^\$/, '');
|
|
89
|
+
}
|
|
90
|
+
// array_declarator, pointer_declarator, reference_declarator, expression_list
|
|
91
|
+
current = current.childForFieldName('declarator') ?? current.namedChildren[0] ?? null;
|
|
92
|
+
}
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
/** Strip parentheses and `.c_str()` / `.data()` - wrappers that do not change the text. */
|
|
96
|
+
function unwrap(node) {
|
|
97
|
+
let current = node;
|
|
98
|
+
for (let depth = 0; depth < 6; depth++) {
|
|
99
|
+
if (current.type === 'parenthesized_expression' && current.namedChildren.length === 1) {
|
|
100
|
+
current = current.namedChildren[0] ?? current;
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
if (current.type === 'call_expression') {
|
|
104
|
+
const fn = current.childForFieldName('function');
|
|
105
|
+
const args = current.childForFieldName('arguments');
|
|
106
|
+
const field = fn?.childForFieldName('field')?.text ?? '';
|
|
107
|
+
const receiver = fn?.childForFieldName('argument') ?? null;
|
|
108
|
+
if (fn?.type === 'field_expression' && TRANSPARENT_METHODS.has(field) && receiver &&
|
|
109
|
+
(args?.namedChildren.length ?? 0) === 0) {
|
|
110
|
+
current = receiver;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
return current;
|
|
117
|
+
}
|
|
118
|
+
/*
|
|
119
|
+
* THE FORMAT STRING IS A TYPE DECLARATION.
|
|
120
|
+
*
|
|
121
|
+
* `%d` can only ever emit digits and a sign, so it cannot carry a semicolon, a
|
|
122
|
+
* pipe or a backtick however hostile the integer is. `%s` and `%c` splice text.
|
|
123
|
+
* So `snprintf(buf, n, "kill -9 %d", pid)` is not a built command in any sense
|
|
124
|
+
* that matters to a shell, and `snprintf(buf, n, "ls %s", name)` is.
|
|
125
|
+
*
|
|
126
|
+
* A format string that is not itself a literal is the worst case of all - the
|
|
127
|
+
* caller controls the shape of the command - and is reported as dynamic.
|
|
128
|
+
*/
|
|
129
|
+
const SPECIFIER = /%[-+ #0]*(\*|\d+)?(?:\.(\*|\d+))?(?:hh|h|ll|l|j|z|t|L)?([diouxXeEfFgGaAcspn%])/g;
|
|
130
|
+
function formatPiece(call, language, formatIndex, isVa) {
|
|
131
|
+
const args = (call.childForFieldName('arguments')?.namedChildren ?? []).filter((c) => c !== null);
|
|
132
|
+
const format = args[formatIndex];
|
|
133
|
+
if (!format)
|
|
134
|
+
return { isDynamic: false, mechanism: 'literal', literalText: '', dynamicParts: [] };
|
|
135
|
+
const fmt = analyzeStringExpression(format, language);
|
|
136
|
+
if (fmt.isDynamic) {
|
|
137
|
+
return { isDynamic: true, mechanism: 'format-call', literalText: '', dynamicParts: [format.text ?? ''] };
|
|
138
|
+
}
|
|
139
|
+
const dynamicParts = [];
|
|
140
|
+
let argCursor = formatIndex + 1;
|
|
141
|
+
for (const match of fmt.literalText.matchAll(SPECIFIER)) {
|
|
142
|
+
const [, width, precision, conversion] = match;
|
|
143
|
+
if (conversion === '%')
|
|
144
|
+
continue;
|
|
145
|
+
if (width === '*')
|
|
146
|
+
argCursor++;
|
|
147
|
+
if (precision === '*')
|
|
148
|
+
argCursor++;
|
|
149
|
+
const value = args[argCursor++];
|
|
150
|
+
if (conversion !== 's' && conversion !== 'c')
|
|
151
|
+
continue; // numeric: cannot splice text
|
|
152
|
+
if (isVa) {
|
|
153
|
+
dynamicParts.push('va_list');
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
if (!value)
|
|
157
|
+
continue;
|
|
158
|
+
const piece = analyzeStringExpression(value, language);
|
|
159
|
+
if (piece.isDynamic)
|
|
160
|
+
dynamicParts.push((value.text ?? '').trim().slice(0, 60));
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
isDynamic: dynamicParts.length > 0,
|
|
164
|
+
mechanism: dynamicParts.length > 0 ? 'format-call' : 'literal',
|
|
165
|
+
literalText: fmt.literalText.replace(SPECIFIER, ''),
|
|
166
|
+
dynamicParts,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
/** Classify one node as a write to `name`, or null if it is not one. */
|
|
170
|
+
function writeTo(node, name, language) {
|
|
171
|
+
const piece = (value) => value ? analyzeStringExpression(unwrap(value), language) : null;
|
|
172
|
+
// Declarations with an initialiser: JS/TS/Java variable_declarator, C/C++ init_declarator, Go var_spec.
|
|
173
|
+
if (node.type === 'variable_declarator' || node.type === 'init_declarator' || node.type === 'var_spec') {
|
|
174
|
+
const target = node.childForFieldName('name') ?? node.childForFieldName('declarator');
|
|
175
|
+
const value = node.childForFieldName('value');
|
|
176
|
+
if (boundName(target) !== name || !value)
|
|
177
|
+
return null;
|
|
178
|
+
const p = piece(value);
|
|
179
|
+
return p ? { kind: 'reset', node, piece: p } : null;
|
|
180
|
+
}
|
|
181
|
+
// Assignment, plain or compound. The operator decides reset versus extend.
|
|
182
|
+
if (node.type === 'assignment' || node.type === 'assignment_expression' ||
|
|
183
|
+
node.type === 'augmented_assignment' || node.type === 'augmented_assignment_expression' ||
|
|
184
|
+
node.type === 'assignment_statement' || node.type === 'short_var_declaration') {
|
|
185
|
+
const target = node.childForFieldName('left');
|
|
186
|
+
const value = node.childForFieldName('right');
|
|
187
|
+
if (!target || !value)
|
|
188
|
+
return null;
|
|
189
|
+
if ((target.text ?? '').trim().replace(/^\$/, '') !== name)
|
|
190
|
+
return null;
|
|
191
|
+
const operator = (node.childForFieldName('operator')?.text ?? '=').trim();
|
|
192
|
+
const p = piece(value);
|
|
193
|
+
if (!p)
|
|
194
|
+
return null;
|
|
195
|
+
if (operator === '=' || operator === ':=')
|
|
196
|
+
return { kind: 'reset', node, piece: p };
|
|
197
|
+
if (operator === '+=' || operator === '.=')
|
|
198
|
+
return { kind: 'extend', node, piece: p };
|
|
199
|
+
return null; // some other compound operator: not a string build this knows
|
|
200
|
+
}
|
|
201
|
+
if (node.type !== 'call_expression')
|
|
202
|
+
return null;
|
|
203
|
+
const fn = node.childForFieldName('function');
|
|
204
|
+
const args = (node.childForFieldName('arguments')?.namedChildren ?? []).filter((c) => c !== null);
|
|
205
|
+
// C++ members on the string itself: cmd.append(x), cmd.assign(x).
|
|
206
|
+
if (fn?.type === 'field_expression') {
|
|
207
|
+
const receiver = fn.childForFieldName('argument');
|
|
208
|
+
const member = fn.childForFieldName('field')?.text ?? '';
|
|
209
|
+
if ((receiver?.text ?? '').trim() !== name)
|
|
210
|
+
return null;
|
|
211
|
+
const p = piece(args[0] ?? null);
|
|
212
|
+
if (!p)
|
|
213
|
+
return null;
|
|
214
|
+
if (CPP_MEMBER_APPENDS.has(member))
|
|
215
|
+
return { kind: 'extend', node, piece: p };
|
|
216
|
+
if (CPP_MEMBER_RESETS.has(member))
|
|
217
|
+
return { kind: 'reset', node, piece: p };
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
// C's output-parameter idiom: the buffer is argument 0.
|
|
221
|
+
if (language !== 'c' && language !== 'cpp')
|
|
222
|
+
return null;
|
|
223
|
+
const callee = (fn?.text ?? '').split('::').pop() ?? '';
|
|
224
|
+
if ((args[0]?.text ?? '').trim() !== name)
|
|
225
|
+
return null;
|
|
226
|
+
if (callee in C_FORMAT_WRITERS) {
|
|
227
|
+
return {
|
|
228
|
+
kind: 'reset',
|
|
229
|
+
node,
|
|
230
|
+
piece: formatPiece(node, language, C_FORMAT_WRITERS[callee] ?? 1, callee.startsWith('v')),
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
const p = piece(args[1] ?? null);
|
|
234
|
+
if (!p)
|
|
235
|
+
return null;
|
|
236
|
+
if (C_COPY_RESETS.has(callee))
|
|
237
|
+
return { kind: 'reset', node, piece: p };
|
|
238
|
+
if (C_APPENDS.has(callee))
|
|
239
|
+
return { kind: 'extend', node, piece: p };
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
/** Is `node` inside a branch, loop or try between itself and the function body? */
|
|
243
|
+
function underControlFlow(node, body) {
|
|
244
|
+
let current = node.parent;
|
|
245
|
+
while (current && !same(current, body)) {
|
|
246
|
+
if (CONTROL_FLOW.test(current.type))
|
|
247
|
+
return true;
|
|
248
|
+
current = current.parent;
|
|
249
|
+
}
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Follow the argument of a dangerous call back to how its text was built.
|
|
254
|
+
* Returns null when there is nothing to follow, or when following it would
|
|
255
|
+
* need to know which way the program went.
|
|
256
|
+
*/
|
|
257
|
+
export function followLocalBuild(arg, language) {
|
|
258
|
+
const target = unwrap(arg);
|
|
259
|
+
// Unwrapping alone can expose an inline build: std::system(("ls " + x).c_str()).
|
|
260
|
+
if (!same(target, arg) && target.type !== 'identifier') {
|
|
261
|
+
return { expression: analyzeStringExpression(target, language), line: lineOf(target) };
|
|
262
|
+
}
|
|
263
|
+
if (target.type !== 'identifier' && target.type !== 'variable_name')
|
|
264
|
+
return null;
|
|
265
|
+
const name = (target.text ?? '').replace(/^\$/, '');
|
|
266
|
+
let body = arg.parent;
|
|
267
|
+
while (body && !FUNCTION_NODES.has(body.type))
|
|
268
|
+
body = body.parent;
|
|
269
|
+
if (!body)
|
|
270
|
+
return null;
|
|
271
|
+
const writes = [];
|
|
272
|
+
let unsafe = false;
|
|
273
|
+
const visit = (node) => {
|
|
274
|
+
if (unsafe || node.startIndex >= arg.startIndex)
|
|
275
|
+
return;
|
|
276
|
+
if (!same(node, body) && FUNCTION_NODES.has(node.type))
|
|
277
|
+
return; // a nested function
|
|
278
|
+
const write = writeTo(node, name, language);
|
|
279
|
+
if (write) {
|
|
280
|
+
if (underControlFlow(node, body))
|
|
281
|
+
unsafe = true;
|
|
282
|
+
else
|
|
283
|
+
writes.push(write);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
for (const child of node.namedChildren)
|
|
287
|
+
if (child)
|
|
288
|
+
visit(child);
|
|
289
|
+
};
|
|
290
|
+
visit(body);
|
|
291
|
+
if (unsafe)
|
|
292
|
+
return null;
|
|
293
|
+
let start = -1;
|
|
294
|
+
for (let i = writes.length - 1; i >= 0; i--) {
|
|
295
|
+
if (writes[i]?.kind === 'reset') {
|
|
296
|
+
start = i;
|
|
297
|
+
break;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (start < 0)
|
|
301
|
+
return null; // a parameter or a global: nothing here says how it was built
|
|
302
|
+
const pieces = writes.slice(start).map((w) => w.piece);
|
|
303
|
+
const first = writes[start];
|
|
304
|
+
if (pieces.length === 1)
|
|
305
|
+
return { expression: pieces[0], line: lineOf(first.node) };
|
|
306
|
+
const dynamicParts = pieces.flatMap((p) => [...p.dynamicParts]);
|
|
307
|
+
const literalText = pieces.map((p) => p.literalText).join('');
|
|
308
|
+
const mechanism = pieces.some((p) => p.mechanism === 'interpolation')
|
|
309
|
+
? 'interpolation'
|
|
310
|
+
: pieces.some((p) => p.mechanism === 'format-call')
|
|
311
|
+
? 'format-call'
|
|
312
|
+
: dynamicParts.length > 0
|
|
313
|
+
? 'concatenation'
|
|
314
|
+
: 'literal';
|
|
315
|
+
return {
|
|
316
|
+
expression: { isDynamic: mechanism !== 'literal', mechanism, literalText, dynamicParts },
|
|
317
|
+
line: lineOf(first.node),
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
//# sourceMappingURL=local-build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-build.js","sourceRoot":"","sources":["../../../../src/rules/lib/local-build.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* STRING BUILDING ANALYSIS
|
|
3
|
+
* ========================
|
|
4
|
+
*
|
|
5
|
+
* Almost every injection bug in this tool's catalogue has the same skeleton:
|
|
6
|
+
* a string was ASSEMBLED at runtime and then handed to something that treats
|
|
7
|
+
* strings as instructions (a database, a shell, a browser).
|
|
8
|
+
*
|
|
9
|
+
* So the one question we ask over and over is: "was this expression a fixed
|
|
10
|
+
* piece of text, or was it stitched together from parts?" This file answers it
|
|
11
|
+
* for all five languages, and it is the piece of shared machinery that lets one
|
|
12
|
+
* rule cover JavaScript, Python, Java and Go at once.
|
|
13
|
+
*
|
|
14
|
+
* VOCABULARY YOU'LL NEED:
|
|
15
|
+
*
|
|
16
|
+
* Sanitisation - cleaning or neutralising untrusted input before use. For SQL
|
|
17
|
+
* the real fix is not cleaning at all but PARAMETERISATION: you hand the
|
|
18
|
+
* database the query and the values separately, so the values can never be
|
|
19
|
+
* read as commands. For HTML it means escaping < > & " so text is displayed
|
|
20
|
+
* rather than executed.
|
|
21
|
+
*
|
|
22
|
+
* Interpolation - languages' built-in "put this value inside this string"
|
|
23
|
+
* syntax: `${x}` in JS, f"{x}" in Python, fmt.Sprintf("%s", x) in Go.
|
|
24
|
+
* To a database or a shell it is identical to concatenation. Feeling
|
|
25
|
+
* modern does not make it safe.
|
|
26
|
+
*
|
|
27
|
+
* PHASE 1 HONESTY NOTE: knowing a string was built dynamically does NOT mean
|
|
28
|
+
* the parts came from an attacker. `"SELECT * FROM " + TABLE_NAME` with a
|
|
29
|
+
* hard-coded constant is fine. We cannot tell the difference without data-flow
|
|
30
|
+
* analysis, which is Phase 3. That is exactly why these findings are labelled
|
|
31
|
+
* signature-based, and why every one of them says so in its `limitations`.
|
|
32
|
+
*/
|
|
33
|
+
import type { Node } from 'web-tree-sitter';
|
|
34
|
+
import type { LanguageId } from '../../parse/languages.js';
|
|
35
|
+
import type { StaticMethodLookup } from '../contract.js';
|
|
36
|
+
export type BuildMechanism = 'literal' | 'concatenation' | 'interpolation' | 'format-call' | 'opaque';
|
|
37
|
+
export interface StringExpression {
|
|
38
|
+
/** True when the text is not fully known at write time. */
|
|
39
|
+
readonly isDynamic: boolean;
|
|
40
|
+
readonly mechanism: BuildMechanism;
|
|
41
|
+
/** The fixed parts we could read, joined. Empty when the whole thing is opaque. */
|
|
42
|
+
readonly literalText: string;
|
|
43
|
+
/** The expressions spliced in. Reported so a human can judge them. */
|
|
44
|
+
readonly dynamicParts: readonly string[];
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* True when this node could plausibly evaluate to a string that was assembled.
|
|
48
|
+
* Object literals, arrays, functions and class bodies return false - they are
|
|
49
|
+
* containers, not strings, even though they contain strings.
|
|
50
|
+
*/
|
|
51
|
+
export declare function isStringBuildingExpression(node: Node, language: LanguageId): boolean;
|
|
52
|
+
export declare function isStringLiteral(node: Node, language: LanguageId): boolean;
|
|
53
|
+
/** Remove surrounding quotes, backticks and prefixes (f"", b'', @"", `` ). */
|
|
54
|
+
export declare function unquote(raw: string): string;
|
|
55
|
+
/**
|
|
56
|
+
* Read an expression and describe how its text was assembled.
|
|
57
|
+
*
|
|
58
|
+
* The walk is deliberately shallow (depth-limited) and deliberately simple: it
|
|
59
|
+
* collects three things - fixed text chunks, evidence of splicing, and the
|
|
60
|
+
* spliced expressions - and infers the mechanism from what it found. It does
|
|
61
|
+
* NOT try to evaluate the expression. A scanner that guesses at runtime values
|
|
62
|
+
* is a scanner that lies.
|
|
63
|
+
*/
|
|
64
|
+
export declare function analyzeStringExpression(node: Node, language: LanguageId, maxDepth?: number): StringExpression;
|
|
65
|
+
/**
|
|
66
|
+
* SQL needs the SHAPE of a statement, not a scattering of keywords.
|
|
67
|
+
* Conservative on purpose: a fragment we cannot recognise is reported as
|
|
68
|
+
* "not SQL", which loses a finding rather than inventing one.
|
|
69
|
+
*/
|
|
70
|
+
export declare function looksLikeSql(text: string): boolean;
|
|
71
|
+
export declare function looksLikeHtml(text: string): boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Shannon entropy: a number for "how random does this look?".
|
|
74
|
+
* Roughly - English prose scores ~2.5-3.5 bits/char, a base64 API key ~4.5-6.
|
|
75
|
+
* It is a hint, never a verdict, and we say so in the finding.
|
|
76
|
+
*/
|
|
77
|
+
export declare function shannonEntropy(text: string): number;
|
|
78
|
+
/**
|
|
79
|
+
* Is this value STRUCTURALLY incapable of being a credential, whatever the
|
|
80
|
+
* variable holding it is called?
|
|
81
|
+
*
|
|
82
|
+
* The name-based signal ("the variable is called `token`") never asked this,
|
|
83
|
+
* and VS Code's editor package showed why: 151 of its 163 high-severity secret
|
|
84
|
+
* findings were Monaco's syntax-highlighting tokens.
|
|
85
|
+
*
|
|
86
|
+
* token: 'delimiter.curly'
|
|
87
|
+
* token: 'variable.predefined'
|
|
88
|
+
* token: 'comment'
|
|
89
|
+
*
|
|
90
|
+
* The variable really is called `token`. The value is a theme scope name. No
|
|
91
|
+
* amount of suspicion about the NAME should survive looking at the VALUE.
|
|
92
|
+
*
|
|
93
|
+
* Two shapes, both decidable:
|
|
94
|
+
* - a dotted namespace (`delimiter.curly`, `com.example.thing`) - no key
|
|
95
|
+
* format contains dots, except a JWT, which starts `eyJ`;
|
|
96
|
+
* - a single lowercase dictionary-shaped word (`comment`, `invalid`) - real
|
|
97
|
+
* credentials mix character classes, because they are generated.
|
|
98
|
+
*/
|
|
99
|
+
export declare function isStructuralIdentifier(value: string): boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Does this spliced-in expression produce nothing but SQL PLACEHOLDERS?
|
|
102
|
+
*
|
|
103
|
+
* VS Code builds a bulk insert the correct way:
|
|
104
|
+
*
|
|
105
|
+
* `INSERT INTO ItemTable VALUES ${new Array(n).fill('(?,?)').join(',')} ...`
|
|
106
|
+
* stmt.run(keysValuesChunk)
|
|
107
|
+
*
|
|
108
|
+
* The interpolation expands to `(?,?),(?,?),(?,?)`. Not one byte of data is in
|
|
109
|
+
* that string - the values go to the driver separately, which is exactly what
|
|
110
|
+
* parameterisation means. And the rule reported it as SQL injection.
|
|
111
|
+
*
|
|
112
|
+
* That is the worst mistake an injection rule can make. Flagging the CORRECT
|
|
113
|
+
* form teaches people that doing it properly does not help, and this is the
|
|
114
|
+
* third time today the same failure has turned up in a different rule -
|
|
115
|
+
* unserialize with allowed_classes, yaml with a SafeLoader, and now this.
|
|
116
|
+
*
|
|
117
|
+
* The test is narrow on purpose. Every string literal inside the expression
|
|
118
|
+
* must be placeholder punctuation, AND at least one must contain an actual
|
|
119
|
+
* placeholder marker (`?`, `$1`, `%s`). That second half is what stops
|
|
120
|
+
* `rows.map(r => `'${r}'`).join(',')` - which builds real quoted DATA and is a
|
|
121
|
+
* genuine injection - from slipping through on its commas.
|
|
122
|
+
*/
|
|
123
|
+
export declare function expandsOnlyPlaceholders(expressionText: string): boolean;
|
|
124
|
+
export declare function isLikelyPlaceholder(text: string): boolean;
|
|
125
|
+
/**
|
|
126
|
+
* "Could this string plausibly BE a credential?" - a structural gate we apply
|
|
127
|
+
* before the entropy heuristic.
|
|
128
|
+
*
|
|
129
|
+
* This function exists because of measurement, not theory. Running the entropy
|
|
130
|
+
* check alone against five real open-source repositories produced 80 findings,
|
|
131
|
+
* and the top offenders were things like:
|
|
132
|
+
*
|
|
133
|
+
* 'application/x-www-form-urlencoded' a MIME type
|
|
134
|
+
* 'abcdefghijklmnopqrstuvwxyz' a literal alphabet
|
|
135
|
+
* 'https://images.opencollective.com/…' a URL
|
|
136
|
+
*
|
|
137
|
+
* All three score high on randomness and none of them is a secret. Real tokens
|
|
138
|
+
* share a shape: no spaces, no slashes, and a MIX of character classes. Testing
|
|
139
|
+
* for that shape first removes the whole category of noise above without
|
|
140
|
+
* weakening detection of anything that actually looks like a key.
|
|
141
|
+
*/
|
|
142
|
+
export declare function looksLikeToken(value: string): boolean;
|
|
143
|
+
/**
|
|
144
|
+
* Paths that mean "this is a fixture, not production configuration".
|
|
145
|
+
* A credential in a test file is still a credential in git history, so we do
|
|
146
|
+
* not drop these findings - we lower their severity and say why.
|
|
147
|
+
*/
|
|
148
|
+
export declare function isTestPath(filePath: string): boolean;
|
|
149
|
+
/**
|
|
150
|
+
* Is this value just a restatement of the NAME it is stored under?
|
|
151
|
+
*
|
|
152
|
+
* PRIVATE_KEY_KEY = "privateKey" Keycloak, 4,000 Java files
|
|
153
|
+
* KEYSTORE_PASSWORD_KEY = "keystorePassword"
|
|
154
|
+
* MANAGE_OAUTH = "manage_oauth" Mattermost, TypeScript
|
|
155
|
+
* TOKEN_CREATING = "creating"
|
|
156
|
+
* SECTION_TOKENS = "tokens"
|
|
157
|
+
*
|
|
158
|
+
* These are the strings a program uses to LOOK UP a secret in a config map, and
|
|
159
|
+
* they are dense in exactly the codebases that handle credentials for a living
|
|
160
|
+
* - which is why an identity server produced 152 findings and most were this.
|
|
161
|
+
*
|
|
162
|
+
* The test is a subset check on words, which is what makes it safe: a real
|
|
163
|
+
* credential shares no vocabulary with its own variable name. `password =
|
|
164
|
+
* "Tr0ub4dor3xK"`, `SECRET_KEY = "config"` and `password = "configpass"` all
|
|
165
|
+
* survive it, and all three are asserted elsewhere in the suite.
|
|
166
|
+
*
|
|
167
|
+
* Requires at least one word on each side, so an empty or punctuation-only
|
|
168
|
+
* value cannot vacuously qualify.
|
|
169
|
+
*/
|
|
170
|
+
export declare function echoesItsOwnName(name: string, value: string): boolean;
|
|
171
|
+
export declare function looksLikeProse(name: string, value: string): boolean;
|
|
172
|
+
/** Well-known credential formats. A hit here is far stronger than entropy alone. */
|
|
173
|
+
export interface KnownSecretFormat {
|
|
174
|
+
readonly label: string;
|
|
175
|
+
readonly pattern: RegExp;
|
|
176
|
+
}
|
|
177
|
+
export declare const KNOWN_SECRET_FORMATS: readonly KnownSecretFormat[];
|
|
178
|
+
/**
|
|
179
|
+
* True when a value matches a vendor key format but is a published,
|
|
180
|
+
* deliberately non-functional documentation example rather than a credential.
|
|
181
|
+
*
|
|
182
|
+
* Pass the MATCHED KEY, not the string it was found in. The first version of
|
|
183
|
+
* this tested the whole enclosing string, so a demo code sample containing
|
|
184
|
+
* `AKIAIOSFODNN7EXAMPLE` in the middle of two hundred other characters never
|
|
185
|
+
* matched the `...EXAMPLE$` anchor and was still reported as a live key. The
|
|
186
|
+
* question is about the credential, so it has to be asked of the credential.
|
|
187
|
+
*/
|
|
188
|
+
export declare function isVendorDocExample(matchedKey: string): boolean;
|
|
189
|
+
export declare function matchKnownSecret(text: string): KnownSecretFormat | null;
|
|
190
|
+
/** Why a string built from pieces is still provably fixed - or null when it is not. */
|
|
191
|
+
export interface ConstantProof {
|
|
192
|
+
/**
|
|
193
|
+
* True when the proof needed control-flow reasoning - a branch that cannot
|
|
194
|
+
* run, a condition decided at compile time, a ternary whose every arm is a
|
|
195
|
+
* literal - rather than "every binding is a plain literal". Only reasoned
|
|
196
|
+
* proofs leave a receipt, because only reasoning can be wrong.
|
|
197
|
+
*/
|
|
198
|
+
readonly reasoned: boolean;
|
|
199
|
+
/** One sentence per name, written so a reader can check it against the code. */
|
|
200
|
+
readonly reason: string;
|
|
201
|
+
}
|
|
202
|
+
export interface ConstantProofOptions {
|
|
203
|
+
/** RuleContext.staticMethod. Absent: no helper in another file is read. */
|
|
204
|
+
readonly staticMethod?: StaticMethodLookup | undefined;
|
|
205
|
+
/** RuleContext.javaTypeInScan. Absent: every supertype is assumed to be in the scan. */
|
|
206
|
+
readonly javaTypeInScan?: ((simpleName: string) => boolean) | undefined;
|
|
207
|
+
}
|
|
208
|
+
export declare function constantProof(node: Node, dynamicParts: readonly string[], language: LanguageId, options?: ConstantProofOptions): ConstantProof | null;
|