circle-ir 3.178.0 → 3.179.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/config-loader.d.ts.map +1 -1
- package/dist/analysis/config-loader.js +16 -0
- package/dist/analysis/config-loader.js.map +1 -1
- package/dist/analysis/dependency-versions.d.ts +112 -0
- package/dist/analysis/dependency-versions.d.ts.map +1 -1
- package/dist/analysis/dependency-versions.js +199 -0
- package/dist/analysis/dependency-versions.js.map +1 -1
- package/dist/analysis/passes/deserialization-safety-gate-pass.d.ts +2 -0
- package/dist/analysis/passes/deserialization-safety-gate-pass.d.ts.map +1 -1
- package/dist/analysis/passes/deserialization-safety-gate-pass.js +52 -9
- package/dist/analysis/passes/deserialization-safety-gate-pass.js.map +1 -1
- package/dist/analysis/taint-matcher.d.ts.map +1 -1
- package/dist/analysis/taint-matcher.js +18 -0
- package/dist/analysis/taint-matcher.js.map +1 -1
- package/dist/analyzer.d.ts +22 -0
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js.map +1 -1
- package/dist/browser/circle-ir.js +122 -5
- package/dist/core/circle-ir-core.cjs +21 -0
- package/dist/core/circle-ir-core.js +21 -0
- package/package.json +1 -1
|
@@ -12874,6 +12874,16 @@ var DEFAULT_SINKS = [
|
|
|
12874
12874
|
{ method: "format", class: "String", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
12875
12875
|
{ method: "format", class: "Formatter", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
12876
12876
|
{ method: "printf", class: "System.out", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
12877
|
+
// cognium-dev #264 — extend the Java format-string surface.
|
|
12878
|
+
// MessageFormat.format(pattern, args) — same receiver-family as String.format
|
|
12879
|
+
// but on the java.text side. PrintStream/PrintWriter.{printf,format} —
|
|
12880
|
+
// arbitrary streams (not just System.out) also honour format-string
|
|
12881
|
+
// specifiers, so a tainted first arg is a genuine CWE-134 sink.
|
|
12882
|
+
{ method: "format", class: "MessageFormat", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
12883
|
+
{ method: "printf", class: "PrintStream", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
12884
|
+
{ method: "format", class: "PrintStream", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
12885
|
+
{ method: "printf", class: "PrintWriter", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
12886
|
+
{ method: "format", class: "PrintWriter", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
12877
12887
|
// NOTE: Python `userFmt.format(...)` and `userFmt % args` require
|
|
12878
12888
|
// receiver-taint or operator-LHS-taint tracking — the format string is the
|
|
12879
12889
|
// receiver, not an argument. Deferred to Sprint 6 (#86 follow-up).
|
|
@@ -12885,6 +12895,12 @@ var DEFAULT_SINKS = [
|
|
|
12885
12895
|
{ method: "Printf", class: "fmt", type: "format_string", cwe: "CWE-134", severity: "medium", arg_positions: [0], languages: ["go"] },
|
|
12886
12896
|
{ method: "Errorf", class: "fmt", type: "format_string", cwe: "CWE-134", severity: "medium", arg_positions: [0], languages: ["go"] },
|
|
12887
12897
|
{ method: "Fprintf", class: "fmt", type: "format_string", cwe: "CWE-134", severity: "medium", arg_positions: [1], languages: ["go"] },
|
|
12898
|
+
// cognium-dev #264 — Go stdlib `log` package format-string entry points.
|
|
12899
|
+
// log.Printf / Fatalf / Panicf take the format string at arg[0]; tainted
|
|
12900
|
+
// format string reaches the same fmt.Sprintf machinery internally.
|
|
12901
|
+
{ method: "Printf", class: "log", type: "format_string", cwe: "CWE-134", severity: "medium", arg_positions: [0], languages: ["go"] },
|
|
12902
|
+
{ method: "Fatalf", class: "log", type: "format_string", cwe: "CWE-134", severity: "medium", arg_positions: [0], languages: ["go"] },
|
|
12903
|
+
{ method: "Panicf", class: "log", type: "format_string", cwe: "CWE-134", severity: "medium", arg_positions: [0], languages: ["go"] },
|
|
12888
12904
|
// CRLF / HTTP response splitting (CWE-113) — Sprint 6, #86.
|
|
12889
12905
|
// Node.js / Express response header / cookie sinks. The header *name* (arg 0)
|
|
12890
12906
|
// is also CRLF-sensitive but is almost always a string literal; we model
|
|
@@ -15072,6 +15088,11 @@ function calculateSinkConfidence(call, pattern) {
|
|
|
15072
15088
|
if (pattern.class && call.receiver) {
|
|
15073
15089
|
if (receiverMightBeClass(call.receiver, pattern.class)) {
|
|
15074
15090
|
confidence += 0.1;
|
|
15091
|
+
const receiverLc = call.receiver.toLowerCase();
|
|
15092
|
+
const classLc = pattern.class.toLowerCase();
|
|
15093
|
+
if (call.receiver === pattern.class || receiverLc === classLc) {
|
|
15094
|
+
confidence += 0.05;
|
|
15095
|
+
}
|
|
15075
15096
|
}
|
|
15076
15097
|
}
|
|
15077
15098
|
if (pattern.severity === "critical") {
|
|
@@ -32863,6 +32884,85 @@ function resolveFastjsonFromPom(pomXml) {
|
|
|
32863
32884
|
}
|
|
32864
32885
|
return null;
|
|
32865
32886
|
}
|
|
32887
|
+
function resolveFastjsonFromGradle(buildGradle) {
|
|
32888
|
+
if (!buildGradle) return null;
|
|
32889
|
+
const directRe = /['"(]\s*com\.alibaba:fastjson:([^'"$\s)]+)\s*['")]/;
|
|
32890
|
+
const direct = buildGradle.match(directRe);
|
|
32891
|
+
if (direct) {
|
|
32892
|
+
const version2 = direct[1];
|
|
32893
|
+
return { version: version2, noneAutotype: /_noneautotype/i.test(version2) };
|
|
32894
|
+
}
|
|
32895
|
+
const propRefRe = /['"(]\s*com\.alibaba:fastjson:\$\{?([A-Za-z_][A-Za-z0-9_]*)\}?\s*['")]/;
|
|
32896
|
+
const propRef = buildGradle.match(propRefRe);
|
|
32897
|
+
if (!propRef) return null;
|
|
32898
|
+
const propName = propRef[1];
|
|
32899
|
+
const defRe = new RegExp(
|
|
32900
|
+
`\\b${propName}\\s*[=:]\\s*['"]([^'"\\s]+)['"]`
|
|
32901
|
+
);
|
|
32902
|
+
const def = buildGradle.match(defRe);
|
|
32903
|
+
if (!def) return null;
|
|
32904
|
+
const version = def[1];
|
|
32905
|
+
return { version, noneAutotype: /_noneautotype/i.test(version) };
|
|
32906
|
+
}
|
|
32907
|
+
function resolvePyYamlFromRequirements(requirementsTxt) {
|
|
32908
|
+
if (!requirementsTxt) return null;
|
|
32909
|
+
for (const rawLine of requirementsTxt.split(/\r?\n/)) {
|
|
32910
|
+
const line = rawLine.replace(/#.*$/, "").trim();
|
|
32911
|
+
if (!line) continue;
|
|
32912
|
+
if (line.startsWith("-")) continue;
|
|
32913
|
+
const m = line.match(
|
|
32914
|
+
/^(pyyaml)\s*(==|>=|~=|>|===)\s*(\d+(?:\.\d+)*)/i
|
|
32915
|
+
);
|
|
32916
|
+
if (!m) continue;
|
|
32917
|
+
const version = m[3];
|
|
32918
|
+
return { version, safeByDefault: isPyYamlVersionSafeByDefault(version) };
|
|
32919
|
+
}
|
|
32920
|
+
return null;
|
|
32921
|
+
}
|
|
32922
|
+
function resolvePyYamlFromPyproject(pyprojectToml) {
|
|
32923
|
+
if (!pyprojectToml) return null;
|
|
32924
|
+
const poetryLine = pyprojectToml.match(
|
|
32925
|
+
/^\s*(pyyaml)\s*=\s*"([\^~=<>]*)(\d+(?:\.\d+)*)"/im
|
|
32926
|
+
);
|
|
32927
|
+
if (poetryLine) {
|
|
32928
|
+
const version = poetryLine[3];
|
|
32929
|
+
return { version, safeByDefault: isPyYamlVersionSafeByDefault(version) };
|
|
32930
|
+
}
|
|
32931
|
+
const poetryTable = pyprojectToml.match(
|
|
32932
|
+
/^\s*(pyyaml)\s*=\s*\{[^}]*\bversion\s*=\s*"([\^~=<>]*)(\d+(?:\.\d+)*)"/im
|
|
32933
|
+
);
|
|
32934
|
+
if (poetryTable) {
|
|
32935
|
+
const version = poetryTable[3];
|
|
32936
|
+
return { version, safeByDefault: isPyYamlVersionSafeByDefault(version) };
|
|
32937
|
+
}
|
|
32938
|
+
const pep621 = pyprojectToml.match(
|
|
32939
|
+
/"(pyyaml)\s*(==|>=|~=|>|===)\s*(\d+(?:\.\d+)*)/i
|
|
32940
|
+
);
|
|
32941
|
+
if (pep621) {
|
|
32942
|
+
const version = pep621[3];
|
|
32943
|
+
return { version, safeByDefault: isPyYamlVersionSafeByDefault(version) };
|
|
32944
|
+
}
|
|
32945
|
+
return null;
|
|
32946
|
+
}
|
|
32947
|
+
function isPyYamlVersionSafeByDefault(version) {
|
|
32948
|
+
const parts2 = version.split(".").map((s) => Number.parseInt(s, 10));
|
|
32949
|
+
if (parts2.length === 0 || !Number.isFinite(parts2[0])) return false;
|
|
32950
|
+
return parts2[0] >= 6;
|
|
32951
|
+
}
|
|
32952
|
+
function fileHasUnsafePyYamlLoader(sourceLines, sinkLine) {
|
|
32953
|
+
const start2 = Math.max(0, sinkLine - 1);
|
|
32954
|
+
const end = Math.min(sourceLines.length, start2 + 10);
|
|
32955
|
+
const unsafeRe = /\bLoader\s*=\s*(?:yaml\s*\.\s*)?(?:Loader|UnsafeLoader|FullLoader)\b/;
|
|
32956
|
+
for (let i2 = start2; i2 < end; i2++) {
|
|
32957
|
+
const ln = sourceLines[i2] ?? "";
|
|
32958
|
+
if (unsafeRe.test(ln)) return true;
|
|
32959
|
+
const stripped = ln.trim();
|
|
32960
|
+
if (i2 > start2 && (stripped === ")" || stripped.endsWith(")"))) {
|
|
32961
|
+
return false;
|
|
32962
|
+
}
|
|
32963
|
+
}
|
|
32964
|
+
return false;
|
|
32965
|
+
}
|
|
32866
32966
|
function fileReenablesFastjsonAutotype(source) {
|
|
32867
32967
|
if (!source) return false;
|
|
32868
32968
|
return /\bsetAutoTypeSupport\s*\(\s*true\b/.test(source);
|
|
@@ -32888,6 +32988,8 @@ var JACKSON_METHODS = /* @__PURE__ */ new Set(["readValue", "convertValue", "tre
|
|
|
32888
32988
|
var JACKSON_CLASSES = /* @__PURE__ */ new Set(["ObjectMapper", "ObjectReader"]);
|
|
32889
32989
|
var SNAKEYAML_METHODS = /* @__PURE__ */ new Set(["load", "loadAs", "loadAll"]);
|
|
32890
32990
|
var SNAKEYAML_CLASSES = /* @__PURE__ */ new Set(["Yaml"]);
|
|
32991
|
+
var PYYAML_METHODS = /* @__PURE__ */ new Set(["load"]);
|
|
32992
|
+
var PYYAML_CLASSES = /* @__PURE__ */ new Set(["yaml"]);
|
|
32891
32993
|
var DeserializationSafetyGatePass = class {
|
|
32892
32994
|
constructor(dependencyContext) {
|
|
32893
32995
|
this.dependencyContext = dependencyContext;
|
|
@@ -32897,18 +32999,29 @@ var DeserializationSafetyGatePass = class {
|
|
|
32897
32999
|
category = "security";
|
|
32898
33000
|
run(ctx) {
|
|
32899
33001
|
const { graph, language, code } = ctx;
|
|
32900
|
-
if (language !== "java") {
|
|
32901
|
-
return { droppedFastjson: 0, droppedJackson: 0, droppedSnakeYaml: 0 };
|
|
33002
|
+
if (language !== "java" && language !== "python") {
|
|
33003
|
+
return { droppedFastjson: 0, droppedJackson: 0, droppedSnakeYaml: 0, droppedPyYaml: 0 };
|
|
32902
33004
|
}
|
|
32903
33005
|
const sinks = ctx.hasResult("sink-filter") ? ctx.getResult("sink-filter").sinks : graph.ir.taint.sinks;
|
|
32904
33006
|
const pomXml = this.dependencyContext?.java?.pomXml;
|
|
32905
|
-
const
|
|
33007
|
+
const buildGradle = this.dependencyContext?.java?.buildGradle;
|
|
33008
|
+
const fastjson = (pomXml ? resolveFastjsonFromPom(pomXml) : null) ?? (buildGradle ? resolveFastjsonFromGradle(buildGradle) : null);
|
|
32906
33009
|
const fastjsonHardened = fastjson?.noneAutotype === true && !fileReenablesFastjsonAutotype(code);
|
|
32907
33010
|
const jacksonSafe = !fileEnablesJacksonPolymorphism(code);
|
|
32908
33011
|
const snakeYamlSafe = fileConfiguresSnakeYamlSafely(code);
|
|
33012
|
+
const requirementsTxt = this.dependencyContext?.python?.requirementsTxt;
|
|
33013
|
+
const pyprojectToml = this.dependencyContext?.python?.pyprojectToml;
|
|
33014
|
+
const pyYaml = (requirementsTxt ? resolvePyYamlFromRequirements(requirementsTxt) : null) ?? (pyprojectToml ? resolvePyYamlFromPyproject(pyprojectToml) : null);
|
|
33015
|
+
const pyYamlSafeByDefault = pyYaml?.safeByDefault === true;
|
|
33016
|
+
let sourceLines = null;
|
|
33017
|
+
const getSourceLines = () => {
|
|
33018
|
+
if (sourceLines === null) sourceLines = code.split("\n");
|
|
33019
|
+
return sourceLines;
|
|
33020
|
+
};
|
|
32909
33021
|
let droppedFastjson = 0;
|
|
32910
33022
|
let droppedJackson = 0;
|
|
32911
33023
|
let droppedSnakeYaml = 0;
|
|
33024
|
+
let droppedPyYaml = 0;
|
|
32912
33025
|
const kept = sinks.filter((sink) => {
|
|
32913
33026
|
if (sink.type !== "deserialization") return true;
|
|
32914
33027
|
if (!sink.method) return true;
|
|
@@ -32924,14 +33037,18 @@ var DeserializationSafetyGatePass = class {
|
|
|
32924
33037
|
droppedSnakeYaml++;
|
|
32925
33038
|
return false;
|
|
32926
33039
|
}
|
|
33040
|
+
if (language === "python" && pyYamlSafeByDefault && PYYAML_METHODS.has(sink.method) && (sink.class === void 0 || PYYAML_CLASSES.has(sink.class)) && !fileHasUnsafePyYamlLoader(getSourceLines(), sink.line)) {
|
|
33041
|
+
droppedPyYaml++;
|
|
33042
|
+
return false;
|
|
33043
|
+
}
|
|
32927
33044
|
return true;
|
|
32928
33045
|
});
|
|
32929
|
-
const totalDropped = droppedFastjson + droppedJackson + droppedSnakeYaml;
|
|
33046
|
+
const totalDropped = droppedFastjson + droppedJackson + droppedSnakeYaml + droppedPyYaml;
|
|
32930
33047
|
if (totalDropped > 0) {
|
|
32931
33048
|
sinks.length = 0;
|
|
32932
33049
|
sinks.push(...kept);
|
|
32933
33050
|
}
|
|
32934
|
-
return { droppedFastjson, droppedJackson, droppedSnakeYaml };
|
|
33051
|
+
return { droppedFastjson, droppedJackson, droppedSnakeYaml, droppedPyYaml };
|
|
32935
33052
|
}
|
|
32936
33053
|
};
|
|
32937
33054
|
|
|
@@ -12269,6 +12269,16 @@ var DEFAULT_SINKS = [
|
|
|
12269
12269
|
{ method: "format", class: "String", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
12270
12270
|
{ method: "format", class: "Formatter", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
12271
12271
|
{ method: "printf", class: "System.out", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
12272
|
+
// cognium-dev #264 — extend the Java format-string surface.
|
|
12273
|
+
// MessageFormat.format(pattern, args) — same receiver-family as String.format
|
|
12274
|
+
// but on the java.text side. PrintStream/PrintWriter.{printf,format} —
|
|
12275
|
+
// arbitrary streams (not just System.out) also honour format-string
|
|
12276
|
+
// specifiers, so a tainted first arg is a genuine CWE-134 sink.
|
|
12277
|
+
{ method: "format", class: "MessageFormat", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
12278
|
+
{ method: "printf", class: "PrintStream", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
12279
|
+
{ method: "format", class: "PrintStream", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
12280
|
+
{ method: "printf", class: "PrintWriter", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
12281
|
+
{ method: "format", class: "PrintWriter", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
12272
12282
|
// NOTE: Python `userFmt.format(...)` and `userFmt % args` require
|
|
12273
12283
|
// receiver-taint or operator-LHS-taint tracking — the format string is the
|
|
12274
12284
|
// receiver, not an argument. Deferred to Sprint 6 (#86 follow-up).
|
|
@@ -12280,6 +12290,12 @@ var DEFAULT_SINKS = [
|
|
|
12280
12290
|
{ method: "Printf", class: "fmt", type: "format_string", cwe: "CWE-134", severity: "medium", arg_positions: [0], languages: ["go"] },
|
|
12281
12291
|
{ method: "Errorf", class: "fmt", type: "format_string", cwe: "CWE-134", severity: "medium", arg_positions: [0], languages: ["go"] },
|
|
12282
12292
|
{ method: "Fprintf", class: "fmt", type: "format_string", cwe: "CWE-134", severity: "medium", arg_positions: [1], languages: ["go"] },
|
|
12293
|
+
// cognium-dev #264 — Go stdlib `log` package format-string entry points.
|
|
12294
|
+
// log.Printf / Fatalf / Panicf take the format string at arg[0]; tainted
|
|
12295
|
+
// format string reaches the same fmt.Sprintf machinery internally.
|
|
12296
|
+
{ method: "Printf", class: "log", type: "format_string", cwe: "CWE-134", severity: "medium", arg_positions: [0], languages: ["go"] },
|
|
12297
|
+
{ method: "Fatalf", class: "log", type: "format_string", cwe: "CWE-134", severity: "medium", arg_positions: [0], languages: ["go"] },
|
|
12298
|
+
{ method: "Panicf", class: "log", type: "format_string", cwe: "CWE-134", severity: "medium", arg_positions: [0], languages: ["go"] },
|
|
12283
12299
|
// CRLF / HTTP response splitting (CWE-113) — Sprint 6, #86.
|
|
12284
12300
|
// Node.js / Express response header / cookie sinks. The header *name* (arg 0)
|
|
12285
12301
|
// is also CRLF-sensitive but is almost always a string literal; we model
|
|
@@ -14372,6 +14388,11 @@ function calculateSinkConfidence(call, pattern) {
|
|
|
14372
14388
|
if (pattern.class && call.receiver) {
|
|
14373
14389
|
if (receiverMightBeClass(call.receiver, pattern.class)) {
|
|
14374
14390
|
confidence += 0.1;
|
|
14391
|
+
const receiverLc = call.receiver.toLowerCase();
|
|
14392
|
+
const classLc = pattern.class.toLowerCase();
|
|
14393
|
+
if (call.receiver === pattern.class || receiverLc === classLc) {
|
|
14394
|
+
confidence += 0.05;
|
|
14395
|
+
}
|
|
14375
14396
|
}
|
|
14376
14397
|
}
|
|
14377
14398
|
if (pattern.severity === "critical") {
|
|
@@ -12203,6 +12203,16 @@ var DEFAULT_SINKS = [
|
|
|
12203
12203
|
{ method: "format", class: "String", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
12204
12204
|
{ method: "format", class: "Formatter", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
12205
12205
|
{ method: "printf", class: "System.out", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
12206
|
+
// cognium-dev #264 — extend the Java format-string surface.
|
|
12207
|
+
// MessageFormat.format(pattern, args) — same receiver-family as String.format
|
|
12208
|
+
// but on the java.text side. PrintStream/PrintWriter.{printf,format} —
|
|
12209
|
+
// arbitrary streams (not just System.out) also honour format-string
|
|
12210
|
+
// specifiers, so a tainted first arg is a genuine CWE-134 sink.
|
|
12211
|
+
{ method: "format", class: "MessageFormat", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
12212
|
+
{ method: "printf", class: "PrintStream", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
12213
|
+
{ method: "format", class: "PrintStream", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
12214
|
+
{ method: "printf", class: "PrintWriter", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
12215
|
+
{ method: "format", class: "PrintWriter", type: "format_string", cwe: "CWE-134", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
12206
12216
|
// NOTE: Python `userFmt.format(...)` and `userFmt % args` require
|
|
12207
12217
|
// receiver-taint or operator-LHS-taint tracking — the format string is the
|
|
12208
12218
|
// receiver, not an argument. Deferred to Sprint 6 (#86 follow-up).
|
|
@@ -12214,6 +12224,12 @@ var DEFAULT_SINKS = [
|
|
|
12214
12224
|
{ method: "Printf", class: "fmt", type: "format_string", cwe: "CWE-134", severity: "medium", arg_positions: [0], languages: ["go"] },
|
|
12215
12225
|
{ method: "Errorf", class: "fmt", type: "format_string", cwe: "CWE-134", severity: "medium", arg_positions: [0], languages: ["go"] },
|
|
12216
12226
|
{ method: "Fprintf", class: "fmt", type: "format_string", cwe: "CWE-134", severity: "medium", arg_positions: [1], languages: ["go"] },
|
|
12227
|
+
// cognium-dev #264 — Go stdlib `log` package format-string entry points.
|
|
12228
|
+
// log.Printf / Fatalf / Panicf take the format string at arg[0]; tainted
|
|
12229
|
+
// format string reaches the same fmt.Sprintf machinery internally.
|
|
12230
|
+
{ method: "Printf", class: "log", type: "format_string", cwe: "CWE-134", severity: "medium", arg_positions: [0], languages: ["go"] },
|
|
12231
|
+
{ method: "Fatalf", class: "log", type: "format_string", cwe: "CWE-134", severity: "medium", arg_positions: [0], languages: ["go"] },
|
|
12232
|
+
{ method: "Panicf", class: "log", type: "format_string", cwe: "CWE-134", severity: "medium", arg_positions: [0], languages: ["go"] },
|
|
12217
12233
|
// CRLF / HTTP response splitting (CWE-113) — Sprint 6, #86.
|
|
12218
12234
|
// Node.js / Express response header / cookie sinks. The header *name* (arg 0)
|
|
12219
12235
|
// is also CRLF-sensitive but is almost always a string literal; we model
|
|
@@ -14306,6 +14322,11 @@ function calculateSinkConfidence(call, pattern) {
|
|
|
14306
14322
|
if (pattern.class && call.receiver) {
|
|
14307
14323
|
if (receiverMightBeClass(call.receiver, pattern.class)) {
|
|
14308
14324
|
confidence += 0.1;
|
|
14325
|
+
const receiverLc = call.receiver.toLowerCase();
|
|
14326
|
+
const classLc = pattern.class.toLowerCase();
|
|
14327
|
+
if (call.receiver === pattern.class || receiverLc === classLc) {
|
|
14328
|
+
confidence += 0.05;
|
|
14329
|
+
}
|
|
14309
14330
|
}
|
|
14310
14331
|
}
|
|
14311
14332
|
if (pattern.severity === "critical") {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "circle-ir",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.179.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",
|