circle-ir 3.157.0 → 3.159.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/dist/analysis/passes/cross-file-pass.d.ts.map +1 -1
- package/dist/analysis/passes/cross-file-pass.js +44 -2
- package/dist/analysis/passes/cross-file-pass.js.map +1 -1
- package/dist/analysis/passes/language-sources-pass.d.ts.map +1 -1
- package/dist/analysis/passes/language-sources-pass.js +79 -0
- package/dist/analysis/passes/language-sources-pass.js.map +1 -1
- package/dist/analysis/passes/sink-filter-pass.d.ts.map +1 -1
- package/dist/analysis/passes/sink-filter-pass.js +47 -0
- package/dist/analysis/passes/sink-filter-pass.js.map +1 -1
- package/dist/analysis/path-classification.d.ts +7 -0
- package/dist/analysis/path-classification.d.ts.map +1 -1
- package/dist/analysis/path-classification.js +39 -0
- package/dist/analysis/path-classification.js.map +1 -1
- package/dist/analysis/require-entry-path.d.ts.map +1 -1
- package/dist/analysis/require-entry-path.js +76 -0
- package/dist/analysis/require-entry-path.js.map +1 -1
- package/dist/browser/circle-ir.js +72 -0
- package/package.json +1 -1
|
@@ -24592,6 +24592,7 @@ var LanguageSourcesPass = class {
|
|
|
24592
24592
|
additionalSanitizers.push(
|
|
24593
24593
|
...findJavaPathNormalizeStartsWithGuardSanitizers(code)
|
|
24594
24594
|
);
|
|
24595
|
+
additionalSanitizers.push(...findJavaPathGetFileNameSanitizers(code));
|
|
24595
24596
|
additionalSanitizers.push(...findJavaInlineCrlfStripLogSanitizers(code));
|
|
24596
24597
|
additionalSanitizers.push(...findJavaArgvFormExecSanitizers(code));
|
|
24597
24598
|
for (const finding of findJavaPatternFindings(code, graph.ir.meta.file)) {
|
|
@@ -26634,6 +26635,42 @@ function findJavaPathNormalizeStartsWithGuardSanitizers(code) {
|
|
|
26634
26635
|
}
|
|
26635
26636
|
return sanitizers;
|
|
26636
26637
|
}
|
|
26638
|
+
function findJavaPathGetFileNameSanitizers(code) {
|
|
26639
|
+
const sanitizers = [];
|
|
26640
|
+
const lines = code.split("\n");
|
|
26641
|
+
const assignmentRe = /^\s*(?:(?:final\s+)?[A-Za-z_][\w.<>?,\s\[\]]*?\s+)?([A-Za-z_]\w*)\s*=\s*(.+?);\s*$/;
|
|
26642
|
+
const rhsHasGetFileNameRe = /\.\s*getFileName\s*\(\s*\)/;
|
|
26643
|
+
const rhsHasPathsChainRe = /\b(?:Paths\s*\.\s*get|Path\s*\.\s*of)\s*\(/;
|
|
26644
|
+
const candidates = [];
|
|
26645
|
+
for (let i2 = 0; i2 < lines.length; i2++) {
|
|
26646
|
+
const m = assignmentRe.exec(lines[i2]);
|
|
26647
|
+
if (!m) continue;
|
|
26648
|
+
const rhs = m[2];
|
|
26649
|
+
if (!rhsHasGetFileNameRe.test(rhs)) continue;
|
|
26650
|
+
if (!rhsHasPathsChainRe.test(rhs)) continue;
|
|
26651
|
+
candidates.push({ line: i2 + 1, boundVar: m[1] });
|
|
26652
|
+
}
|
|
26653
|
+
if (candidates.length === 0) return sanitizers;
|
|
26654
|
+
for (const c of candidates) {
|
|
26655
|
+
sanitizers.push({
|
|
26656
|
+
type: "java_path_get_filename",
|
|
26657
|
+
method: "getFileName",
|
|
26658
|
+
line: c.line,
|
|
26659
|
+
sanitizes: ["path_traversal", "external_taint_escape"]
|
|
26660
|
+
});
|
|
26661
|
+
const varRefRe = new RegExp(`\\b${c.boundVar}\\b`);
|
|
26662
|
+
for (let l = c.line; l < lines.length; l++) {
|
|
26663
|
+
if (!varRefRe.test(lines[l])) continue;
|
|
26664
|
+
sanitizers.push({
|
|
26665
|
+
type: "java_path_get_filename",
|
|
26666
|
+
method: "getFileName",
|
|
26667
|
+
line: l + 1,
|
|
26668
|
+
sanitizes: ["path_traversal", "external_taint_escape"]
|
|
26669
|
+
});
|
|
26670
|
+
}
|
|
26671
|
+
}
|
|
26672
|
+
return sanitizers;
|
|
26673
|
+
}
|
|
26637
26674
|
function findJavaInlineCrlfStripLogSanitizers(code) {
|
|
26638
26675
|
const sanitizers = [];
|
|
26639
26676
|
const lines = code.split("\n");
|
|
@@ -30699,6 +30736,27 @@ var SinkFilterPass = class {
|
|
|
30699
30736
|
return true;
|
|
30700
30737
|
});
|
|
30701
30738
|
}
|
|
30739
|
+
if (language === "java") {
|
|
30740
|
+
const sourceLines = ctx.code.split("\n");
|
|
30741
|
+
filtered = filtered.filter((sink) => {
|
|
30742
|
+
if (sink.type !== "xss") return true;
|
|
30743
|
+
const sinkLineText = sourceLines[sink.line - 1] ?? "";
|
|
30744
|
+
const receiverMatch = sinkLineText.match(/\b(\w+)\s*\.\s*(\w+)\s*\(/);
|
|
30745
|
+
const receiver = receiverMatch?.[1];
|
|
30746
|
+
const method = sink.method ?? receiverMatch?.[2];
|
|
30747
|
+
if ((method === "render" || method === "process" || method === "merge" || method === "renderTo" || method === "apply") && receiver) {
|
|
30748
|
+
const recvType = resolveJavaReceiverType(receiver, sink.line, sourceLines);
|
|
30749
|
+
if (recvType && COMPILED_TEMPLATE_TYPES.has(recvType)) return false;
|
|
30750
|
+
if (recvType && TEMPLATE_ENGINE_LITERAL_TARGETS.has(recvType)) {
|
|
30751
|
+
const args2 = extractJavaCallArgs(method, sinkLineText);
|
|
30752
|
+
if (args2 !== null && args2.length >= 1 && isJavaLiteralOrAnnotationAccessor(args2[0])) {
|
|
30753
|
+
return false;
|
|
30754
|
+
}
|
|
30755
|
+
}
|
|
30756
|
+
}
|
|
30757
|
+
return true;
|
|
30758
|
+
});
|
|
30759
|
+
}
|
|
30702
30760
|
if (language === "java") {
|
|
30703
30761
|
const sourceLines = ctx.code.split("\n");
|
|
30704
30762
|
filtered = filtered.filter((sink) => {
|
|
@@ -37749,9 +37807,23 @@ var TEST_PATH_PATTERNS = [
|
|
|
37749
37807
|
// JVM alt naming
|
|
37750
37808
|
/\.test\.(?:java|kt)$/i
|
|
37751
37809
|
];
|
|
37810
|
+
var JVM_TEST_FILE_PATTERNS = [
|
|
37811
|
+
// JUnit/Spock/Spring convention: FooTest.java, FooTests.java,
|
|
37812
|
+
// FooSpec.java, FooIT.java, FooITCase.java, FooTestCase.java.
|
|
37813
|
+
/(?:^|\/)[A-Za-z_]\w*(?:Test|Tests|Spec|IT|ITCase|TestCase)\.(?:java|kt|scala|groovy)$/,
|
|
37814
|
+
// Alt naming: Foo.test.java, Foo.spec.java.
|
|
37815
|
+
/(?:^|\/)[A-Za-z_]\w*\.(?:test|spec)\.(?:java|kt|scala|groovy)$/i
|
|
37816
|
+
];
|
|
37817
|
+
var JVM_SOURCE_FILE_RE = /\.(?:java|kt|scala|groovy)$/i;
|
|
37752
37818
|
function isTestPath(filepath) {
|
|
37753
37819
|
if (!filepath) return false;
|
|
37754
37820
|
const normalized = filepath.replace(/\\/g, "/");
|
|
37821
|
+
if (JVM_SOURCE_FILE_RE.test(normalized)) {
|
|
37822
|
+
for (const pattern of JVM_TEST_FILE_PATTERNS) {
|
|
37823
|
+
if (pattern.test(normalized)) return true;
|
|
37824
|
+
}
|
|
37825
|
+
return false;
|
|
37826
|
+
}
|
|
37755
37827
|
for (const pattern of TEST_PATH_PATTERNS) {
|
|
37756
37828
|
if (pattern.test(normalized)) return true;
|
|
37757
37829
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "circle-ir",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.159.0",
|
|
4
4
|
"description": "High-performance Static Application Security Testing (SAST) library for detecting security vulnerabilities through taint analysis",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|