circle-ir 3.179.0 → 3.181.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 +43 -0
- package/dist/analysis/config-loader.js.map +1 -1
- package/dist/analysis/dependency-versions.d.ts +96 -0
- package/dist/analysis/dependency-versions.d.ts.map +1 -1
- package/dist/analysis/dependency-versions.js +219 -0
- package/dist/analysis/dependency-versions.js.map +1 -1
- package/dist/analysis/passes/deserialization-safety-gate-pass.d.ts.map +1 -1
- package/dist/analysis/passes/deserialization-safety-gate-pass.js +6 -2
- package/dist/analysis/passes/deserialization-safety-gate-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 +18 -2
- package/dist/analysis/passes/language-sources-pass.js.map +1 -1
- package/dist/analysis/passes/python-receiver-taint-format-pass.d.ts +64 -0
- package/dist/analysis/passes/python-receiver-taint-format-pass.d.ts.map +1 -0
- package/dist/analysis/passes/python-receiver-taint-format-pass.js +129 -0
- package/dist/analysis/passes/python-receiver-taint-format-pass.js.map +1 -0
- package/dist/analyzer.d.ts +42 -0
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +9 -0
- package/dist/analyzer.js.map +1 -1
- package/dist/browser/circle-ir.js +159 -3
- package/dist/core/circle-ir-core.cjs +43 -0
- package/dist/core/circle-ir-core.js +43 -0
- package/package.json +1 -1
|
@@ -11282,6 +11282,35 @@ var DEFAULT_SOURCES = [
|
|
|
11282
11282
|
{ method: "get", class: "Jedis", type: "db_input", severity: "medium", return_tainted: true, languages: ["java"] },
|
|
11283
11283
|
{ method: "hget", class: "Jedis", type: "db_input", severity: "medium", return_tainted: true, languages: ["java"] },
|
|
11284
11284
|
{ method: "mget", class: "Jedis", type: "db_input", severity: "medium", return_tainted: true, languages: ["java"] },
|
|
11285
|
+
// --- Serverless transport channels (cognium-dev #213 first slice) ---
|
|
11286
|
+
//
|
|
11287
|
+
// AWS Lambda / API Gateway invocation-event properties. The Lambda
|
|
11288
|
+
// handler signature `(event, context) => …` (JS/TS) or
|
|
11289
|
+
// `def handler(event, context)` (Python) receives an `event` object
|
|
11290
|
+
// whose properties carry the untrusted HTTP-request-shaped payload:
|
|
11291
|
+
//
|
|
11292
|
+
// event.body — request body (string)
|
|
11293
|
+
// event.queryStringParameters — `?a=b` params
|
|
11294
|
+
// event.multiValueQueryStringParameters — `?a=1&a=2` params
|
|
11295
|
+
// event.pathParameters — path template captures
|
|
11296
|
+
// event.headers — request headers
|
|
11297
|
+
// event.multiValueHeaders — repeated headers
|
|
11298
|
+
// event.requestContext — API Gateway request context
|
|
11299
|
+
//
|
|
11300
|
+
// Vercel Serverless Functions and Cloudflare Workers both use `req`
|
|
11301
|
+
// / `request` receivers that are already covered by the Express-
|
|
11302
|
+
// style patterns above (line ~398). This block specifically covers
|
|
11303
|
+
// the `event`-shaped API Gateway convention that those don't reach.
|
|
11304
|
+
{ property: "body", object: "event", type: "http_body", severity: "high", property_tainted: true, languages: ["javascript", "typescript"] },
|
|
11305
|
+
{ property: "queryStringParameters", object: "event", type: "http_query", severity: "high", property_tainted: true, languages: ["javascript", "typescript"] },
|
|
11306
|
+
{ property: "multiValueQueryStringParameters", object: "event", type: "http_query", severity: "high", property_tainted: true, languages: ["javascript", "typescript"] },
|
|
11307
|
+
{ property: "pathParameters", object: "event", type: "http_path", severity: "high", property_tainted: true, languages: ["javascript", "typescript"] },
|
|
11308
|
+
{ property: "headers", object: "event", type: "http_header", severity: "high", property_tainted: true, languages: ["javascript", "typescript"] },
|
|
11309
|
+
{ property: "multiValueHeaders", object: "event", type: "http_header", severity: "high", property_tainted: true, languages: ["javascript", "typescript"] },
|
|
11310
|
+
{ property: "body", object: "event", type: "http_body", severity: "high", property_tainted: true, languages: ["python"] },
|
|
11311
|
+
{ property: "queryStringParameters", object: "event", type: "http_query", severity: "high", property_tainted: true, languages: ["python"] },
|
|
11312
|
+
{ property: "pathParameters", object: "event", type: "http_path", severity: "high", property_tainted: true, languages: ["python"] },
|
|
11313
|
+
{ property: "headers", object: "event", type: "http_header", severity: "high", property_tainted: true, languages: ["python"] },
|
|
11285
11314
|
// --- JWT claims (unverified decode — PyJWT / jose / jsonwebtoken / auth0 java-jwt / golang-jwt) ---
|
|
11286
11315
|
// A JWT's payload is *always* attacker-authored. Even after verification
|
|
11287
11316
|
// the *contents* of the claims (username, role, custom fields) are not
|
|
@@ -12277,6 +12306,20 @@ var DEFAULT_SINKS = [
|
|
|
12277
12306
|
// Sandbox/script security
|
|
12278
12307
|
{ method: "onNewInstance", class: "SandboxInterceptor", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
12279
12308
|
// Java Log Injection (slf4j / logback / java.util.logging) — CWE-117
|
|
12309
|
+
//
|
|
12310
|
+
// Classification decision — cognium-dev #264: Logger receivers stay
|
|
12311
|
+
// as log_injection (CWE-117), NOT format_string (CWE-134). The real
|
|
12312
|
+
// vulnerability with tainted data flowing into Logger.log(fmt, ...)
|
|
12313
|
+
// is log-forgery via CRLF injection, not format-string exploitation.
|
|
12314
|
+
// A genuine format_string vulnerability requires the FORMAT STRING
|
|
12315
|
+
// itself to be attacker-controlled, which is virtually never the
|
|
12316
|
+
// case in Logger APIs (the format string is a literal at the call
|
|
12317
|
+
// site). Adding format_string sinks for these same receivers would
|
|
12318
|
+
// duplicate the existing log_injection findings on every call site
|
|
12319
|
+
// without adding real signal. The rare edge case where a caller
|
|
12320
|
+
// passes `taintedFmt` at arg[0] is still caught by these entries
|
|
12321
|
+
// (via arg_positions[0] on the SLF4J-family methods), classified as
|
|
12322
|
+
// log_injection.
|
|
12280
12323
|
// Issue #44: log.info/warn/error/debug emit the message argument and any
|
|
12281
12324
|
// {} format arguments to the log stream. Untrusted input forwarded into
|
|
12282
12325
|
// these calls allows log forging (newline injection) and downstream log
|
|
@@ -25490,7 +25533,19 @@ var JS_TAINTED_PATTERNS = [
|
|
|
25490
25533
|
{ pattern: /\bdocument\.title\b/, type: "dom_input" },
|
|
25491
25534
|
{ pattern: /\bhistory\.state\b/, type: "dom_input" },
|
|
25492
25535
|
{ pattern: /\blocalStorage\.getItem\b/, type: "dom_input" },
|
|
25493
|
-
{ pattern: /\bsessionStorage\.getItem\b/, type: "dom_input" }
|
|
25536
|
+
{ pattern: /\bsessionStorage\.getItem\b/, type: "dom_input" },
|
|
25537
|
+
// AWS Lambda / API Gateway event-shape sources (cognium-dev #213
|
|
25538
|
+
// transport-channel first slice). The `event` parameter of a
|
|
25539
|
+
// Lambda handler carries the untrusted HTTP payload; forward-taint
|
|
25540
|
+
// tracking through `const q = event.body; sink(q)` needs the
|
|
25541
|
+
// regex here in addition to the property patterns in
|
|
25542
|
+
// config-loader.ts:DEFAULT_SOURCES.
|
|
25543
|
+
{ pattern: /\bevent\.body\b/, type: "http_body" },
|
|
25544
|
+
{ pattern: /\bevent\.queryStringParameters\b/, type: "http_param" },
|
|
25545
|
+
{ pattern: /\bevent\.multiValueQueryStringParameters\b/, type: "http_param" },
|
|
25546
|
+
{ pattern: /\bevent\.pathParameters\b/, type: "http_path" },
|
|
25547
|
+
{ pattern: /\bevent\.headers\b/, type: "http_header" },
|
|
25548
|
+
{ pattern: /\bevent\.multiValueHeaders\b/, type: "http_header" }
|
|
25494
25549
|
];
|
|
25495
25550
|
var PYTHON_TAINTED_PATTERNS2 = [
|
|
25496
25551
|
{ pattern: /\brequest\.args\b/, type: "http_param" },
|
|
@@ -30008,7 +30063,7 @@ function findPythonTaintedFormatStringFindings(code, file) {
|
|
|
30008
30063
|
}
|
|
30009
30064
|
if (taintedVars.size === 0) return findings;
|
|
30010
30065
|
const percentRe = /\b(\w+)\s*%\s*[\(\[\{"'\w]/;
|
|
30011
|
-
const dotFormatRe = /\b(\w+)\s*\.\s*format\s*\(/;
|
|
30066
|
+
const dotFormatRe = /\b(\w+)\s*\.\s*(?:format|format_map)\s*\(/;
|
|
30012
30067
|
const seen = /* @__PURE__ */ new Set();
|
|
30013
30068
|
for (let i2 = 0; i2 < lines.length; i2++) {
|
|
30014
30069
|
const line = lines[i2];
|
|
@@ -32892,6 +32947,12 @@ function resolveFastjsonFromGradle(buildGradle) {
|
|
|
32892
32947
|
const version2 = direct[1];
|
|
32893
32948
|
return { version: version2, noneAutotype: /_noneautotype/i.test(version2) };
|
|
32894
32949
|
}
|
|
32950
|
+
const constraintsBlockRe = /['"(]\s*com\.alibaba:fastjson\s*['")]\s*\)?\s*\{[\s\S]*?\bversion\s*\{[\s\S]*?\b(?:strictly|require|prefer)\s+['"]([^'"\s]+)['"]/;
|
|
32951
|
+
const constraintsBlock = buildGradle.match(constraintsBlockRe);
|
|
32952
|
+
if (constraintsBlock) {
|
|
32953
|
+
const version2 = constraintsBlock[1];
|
|
32954
|
+
return { version: version2, noneAutotype: /_noneautotype/i.test(version2) };
|
|
32955
|
+
}
|
|
32895
32956
|
const propRefRe = /['"(]\s*com\.alibaba:fastjson:\$\{?([A-Za-z_][A-Za-z0-9_]*)\}?\s*['")]/;
|
|
32896
32957
|
const propRef = buildGradle.match(propRefRe);
|
|
32897
32958
|
if (!propRef) return null;
|
|
@@ -32904,6 +32965,51 @@ function resolveFastjsonFromGradle(buildGradle) {
|
|
|
32904
32965
|
const version = def[1];
|
|
32905
32966
|
return { version, noneAutotype: /_noneautotype/i.test(version) };
|
|
32906
32967
|
}
|
|
32968
|
+
function resolveFastjsonFromGradleCatalog(buildGradle, libsVersionsToml) {
|
|
32969
|
+
if (!buildGradle || !libsVersionsToml) return null;
|
|
32970
|
+
const librariesMatch = libsVersionsToml.match(
|
|
32971
|
+
/\[libraries\]([\s\S]*?)(?=\n\[|$)/
|
|
32972
|
+
);
|
|
32973
|
+
if (!librariesMatch) return null;
|
|
32974
|
+
const librariesBlock = librariesMatch[1];
|
|
32975
|
+
const moduleForm = librariesBlock.match(
|
|
32976
|
+
/^\s*([\w.-]+)\s*=\s*\{[^}]*\bmodule\s*=\s*"com\.alibaba:fastjson"[^}]*\}/m
|
|
32977
|
+
);
|
|
32978
|
+
const groupNameForm = librariesBlock.match(
|
|
32979
|
+
/^\s*([\w.-]+)\s*=\s*\{[^}]*\bgroup\s*=\s*"com\.alibaba"[^}]*\bname\s*=\s*"fastjson"[^}]*\}/m
|
|
32980
|
+
);
|
|
32981
|
+
const entry = moduleForm ?? groupNameForm;
|
|
32982
|
+
if (!entry) return null;
|
|
32983
|
+
const alias = entry[1];
|
|
32984
|
+
const entryBody = entry[0];
|
|
32985
|
+
const aliasEsc = alias.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
32986
|
+
const aliasRefRe = new RegExp(`\\blibs\\s*\\.\\s*${aliasEsc}\\b`);
|
|
32987
|
+
if (!aliasRefRe.test(buildGradle)) return null;
|
|
32988
|
+
const inlineVersionM = entryBody.match(
|
|
32989
|
+
/\bversion\s*=\s*"([^"$][^"]*)"/
|
|
32990
|
+
);
|
|
32991
|
+
if (inlineVersionM) {
|
|
32992
|
+
const version2 = inlineVersionM[1];
|
|
32993
|
+
return { version: version2, noneAutotype: /_noneautotype/i.test(version2) };
|
|
32994
|
+
}
|
|
32995
|
+
const versionRefM = entryBody.match(/\bversion\.ref\s*=\s*"([^"]+)"/);
|
|
32996
|
+
if (!versionRefM) return null;
|
|
32997
|
+
const versionAlias = versionRefM[1];
|
|
32998
|
+
const versionsMatch = libsVersionsToml.match(
|
|
32999
|
+
/\[versions\]([\s\S]*?)(?=\n\[|$)/
|
|
33000
|
+
);
|
|
33001
|
+
if (!versionsMatch) return null;
|
|
33002
|
+
const versionsBlock = versionsMatch[1];
|
|
33003
|
+
const versionAliasEsc = versionAlias.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
33004
|
+
const versionLineRe = new RegExp(
|
|
33005
|
+
`^\\s*${versionAliasEsc}\\s*=\\s*"([^"]+)"`,
|
|
33006
|
+
"m"
|
|
33007
|
+
);
|
|
33008
|
+
const versionLine = versionsBlock.match(versionLineRe);
|
|
33009
|
+
if (!versionLine) return null;
|
|
33010
|
+
const version = versionLine[1];
|
|
33011
|
+
return { version, noneAutotype: /_noneautotype/i.test(version) };
|
|
33012
|
+
}
|
|
32907
33013
|
function resolvePyYamlFromRequirements(requirementsTxt) {
|
|
32908
33014
|
if (!requirementsTxt) return null;
|
|
32909
33015
|
for (const rawLine of requirementsTxt.split(/\r?\n/)) {
|
|
@@ -33005,7 +33111,8 @@ var DeserializationSafetyGatePass = class {
|
|
|
33005
33111
|
const sinks = ctx.hasResult("sink-filter") ? ctx.getResult("sink-filter").sinks : graph.ir.taint.sinks;
|
|
33006
33112
|
const pomXml = this.dependencyContext?.java?.pomXml;
|
|
33007
33113
|
const buildGradle = this.dependencyContext?.java?.buildGradle;
|
|
33008
|
-
const
|
|
33114
|
+
const libsVersionsToml = this.dependencyContext?.java?.libsVersionsToml;
|
|
33115
|
+
const fastjson = (pomXml ? resolveFastjsonFromPom(pomXml) : null) ?? (buildGradle ? resolveFastjsonFromGradle(buildGradle) : null) ?? (buildGradle && libsVersionsToml ? resolveFastjsonFromGradleCatalog(buildGradle, libsVersionsToml) : null);
|
|
33009
33116
|
const fastjsonHardened = fastjson?.noneAutotype === true && !fileReenablesFastjsonAutotype(code);
|
|
33010
33117
|
const jacksonSafe = !fileEnablesJacksonPolymorphism(code);
|
|
33011
33118
|
const snakeYamlSafe = fileConfiguresSnakeYamlSafely(code);
|
|
@@ -38822,6 +38929,53 @@ var ScanSecretsPass = class {
|
|
|
38822
38929
|
}
|
|
38823
38930
|
};
|
|
38824
38931
|
|
|
38932
|
+
// src/analysis/passes/python-receiver-taint-format-pass.ts
|
|
38933
|
+
var PythonReceiverTaintFormatPass = class {
|
|
38934
|
+
name = "python-receiver-taint-format";
|
|
38935
|
+
category = "security";
|
|
38936
|
+
run(ctx) {
|
|
38937
|
+
if (ctx.language !== "python") {
|
|
38938
|
+
return { findingsEmitted: 0 };
|
|
38939
|
+
}
|
|
38940
|
+
const { calls, meta, taint } = ctx.graph.ir;
|
|
38941
|
+
const taintedVarNames = /* @__PURE__ */ new Set();
|
|
38942
|
+
for (const s of taint.sources) {
|
|
38943
|
+
if (typeof s.variable === "string" && s.variable.length > 0) {
|
|
38944
|
+
taintedVarNames.add(s.variable);
|
|
38945
|
+
}
|
|
38946
|
+
}
|
|
38947
|
+
if (taintedVarNames.size === 0) {
|
|
38948
|
+
return { findingsEmitted: 0 };
|
|
38949
|
+
}
|
|
38950
|
+
const seen = /* @__PURE__ */ new Set();
|
|
38951
|
+
let count = 0;
|
|
38952
|
+
for (const call of calls) {
|
|
38953
|
+
if (call.method_name !== "format" && call.method_name !== "format_map") continue;
|
|
38954
|
+
const receiver = call.receiver;
|
|
38955
|
+
if (!receiver) continue;
|
|
38956
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(receiver)) continue;
|
|
38957
|
+
if (!taintedVarNames.has(receiver)) continue;
|
|
38958
|
+
const seenKey = `${call.location.line}:${receiver}`;
|
|
38959
|
+
if (seen.has(seenKey)) continue;
|
|
38960
|
+
seen.add(seenKey);
|
|
38961
|
+
ctx.addFinding({
|
|
38962
|
+
id: `format_string-${meta.file}-${call.location.line}-${receiver}-${call.method_name}`,
|
|
38963
|
+
pass: this.name,
|
|
38964
|
+
category: "security",
|
|
38965
|
+
rule_id: "format_string",
|
|
38966
|
+
cwe: "CWE-134",
|
|
38967
|
+
severity: "medium",
|
|
38968
|
+
level: "warning",
|
|
38969
|
+
message: `Format-string vulnerability: the format template \`${receiver}\` is tainted (traces back to a taint source) and used as the receiver of \`${call.method_name}(...)\`. Attacker can leak object attributes via \`{obj.__class__.__mro__[\u2026]}\` chains or crash the process via unbounded specifiers. Use a literal format string and pass user input as an argument instead.`,
|
|
38970
|
+
file: meta.file,
|
|
38971
|
+
line: call.location.line
|
|
38972
|
+
});
|
|
38973
|
+
count++;
|
|
38974
|
+
}
|
|
38975
|
+
return { findingsEmitted: count };
|
|
38976
|
+
}
|
|
38977
|
+
};
|
|
38978
|
+
|
|
38825
38979
|
// src/analysis/passes/spring4shell-pass.ts
|
|
38826
38980
|
var CONTROLLER_ANNOTATIONS = /* @__PURE__ */ new Set([
|
|
38827
38981
|
"Controller",
|
|
@@ -43162,6 +43316,8 @@ async function analyze(code, filePath, language, options = {}) {
|
|
|
43162
43316
|
if (!disabledPasses.has("library-profile-cwe22-path-gate"))
|
|
43163
43317
|
pipeline.add(new LibraryProfileCwe22PathGatePass());
|
|
43164
43318
|
if (!disabledPasses.has("scan-secrets")) pipeline.add(new ScanSecretsPass());
|
|
43319
|
+
if (!disabledPasses.has("python-receiver-taint-format"))
|
|
43320
|
+
pipeline.add(new PythonReceiverTaintFormatPass());
|
|
43165
43321
|
if (!disabledPasses.has("dead-code")) pipeline.add(new DeadCodePass());
|
|
43166
43322
|
if (!disabledPasses.has("missing-await")) pipeline.add(new MissingAwaitPass());
|
|
43167
43323
|
if (!disabledPasses.has("n-plus-one")) pipeline.add(new NPlusOnePass());
|
|
@@ -10677,6 +10677,35 @@ var DEFAULT_SOURCES = [
|
|
|
10677
10677
|
{ method: "get", class: "Jedis", type: "db_input", severity: "medium", return_tainted: true, languages: ["java"] },
|
|
10678
10678
|
{ method: "hget", class: "Jedis", type: "db_input", severity: "medium", return_tainted: true, languages: ["java"] },
|
|
10679
10679
|
{ method: "mget", class: "Jedis", type: "db_input", severity: "medium", return_tainted: true, languages: ["java"] },
|
|
10680
|
+
// --- Serverless transport channels (cognium-dev #213 first slice) ---
|
|
10681
|
+
//
|
|
10682
|
+
// AWS Lambda / API Gateway invocation-event properties. The Lambda
|
|
10683
|
+
// handler signature `(event, context) => …` (JS/TS) or
|
|
10684
|
+
// `def handler(event, context)` (Python) receives an `event` object
|
|
10685
|
+
// whose properties carry the untrusted HTTP-request-shaped payload:
|
|
10686
|
+
//
|
|
10687
|
+
// event.body — request body (string)
|
|
10688
|
+
// event.queryStringParameters — `?a=b` params
|
|
10689
|
+
// event.multiValueQueryStringParameters — `?a=1&a=2` params
|
|
10690
|
+
// event.pathParameters — path template captures
|
|
10691
|
+
// event.headers — request headers
|
|
10692
|
+
// event.multiValueHeaders — repeated headers
|
|
10693
|
+
// event.requestContext — API Gateway request context
|
|
10694
|
+
//
|
|
10695
|
+
// Vercel Serverless Functions and Cloudflare Workers both use `req`
|
|
10696
|
+
// / `request` receivers that are already covered by the Express-
|
|
10697
|
+
// style patterns above (line ~398). This block specifically covers
|
|
10698
|
+
// the `event`-shaped API Gateway convention that those don't reach.
|
|
10699
|
+
{ property: "body", object: "event", type: "http_body", severity: "high", property_tainted: true, languages: ["javascript", "typescript"] },
|
|
10700
|
+
{ property: "queryStringParameters", object: "event", type: "http_query", severity: "high", property_tainted: true, languages: ["javascript", "typescript"] },
|
|
10701
|
+
{ property: "multiValueQueryStringParameters", object: "event", type: "http_query", severity: "high", property_tainted: true, languages: ["javascript", "typescript"] },
|
|
10702
|
+
{ property: "pathParameters", object: "event", type: "http_path", severity: "high", property_tainted: true, languages: ["javascript", "typescript"] },
|
|
10703
|
+
{ property: "headers", object: "event", type: "http_header", severity: "high", property_tainted: true, languages: ["javascript", "typescript"] },
|
|
10704
|
+
{ property: "multiValueHeaders", object: "event", type: "http_header", severity: "high", property_tainted: true, languages: ["javascript", "typescript"] },
|
|
10705
|
+
{ property: "body", object: "event", type: "http_body", severity: "high", property_tainted: true, languages: ["python"] },
|
|
10706
|
+
{ property: "queryStringParameters", object: "event", type: "http_query", severity: "high", property_tainted: true, languages: ["python"] },
|
|
10707
|
+
{ property: "pathParameters", object: "event", type: "http_path", severity: "high", property_tainted: true, languages: ["python"] },
|
|
10708
|
+
{ property: "headers", object: "event", type: "http_header", severity: "high", property_tainted: true, languages: ["python"] },
|
|
10680
10709
|
// --- JWT claims (unverified decode — PyJWT / jose / jsonwebtoken / auth0 java-jwt / golang-jwt) ---
|
|
10681
10710
|
// A JWT's payload is *always* attacker-authored. Even after verification
|
|
10682
10711
|
// the *contents* of the claims (username, role, custom fields) are not
|
|
@@ -11672,6 +11701,20 @@ var DEFAULT_SINKS = [
|
|
|
11672
11701
|
// Sandbox/script security
|
|
11673
11702
|
{ method: "onNewInstance", class: "SandboxInterceptor", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
11674
11703
|
// Java Log Injection (slf4j / logback / java.util.logging) — CWE-117
|
|
11704
|
+
//
|
|
11705
|
+
// Classification decision — cognium-dev #264: Logger receivers stay
|
|
11706
|
+
// as log_injection (CWE-117), NOT format_string (CWE-134). The real
|
|
11707
|
+
// vulnerability with tainted data flowing into Logger.log(fmt, ...)
|
|
11708
|
+
// is log-forgery via CRLF injection, not format-string exploitation.
|
|
11709
|
+
// A genuine format_string vulnerability requires the FORMAT STRING
|
|
11710
|
+
// itself to be attacker-controlled, which is virtually never the
|
|
11711
|
+
// case in Logger APIs (the format string is a literal at the call
|
|
11712
|
+
// site). Adding format_string sinks for these same receivers would
|
|
11713
|
+
// duplicate the existing log_injection findings on every call site
|
|
11714
|
+
// without adding real signal. The rare edge case where a caller
|
|
11715
|
+
// passes `taintedFmt` at arg[0] is still caught by these entries
|
|
11716
|
+
// (via arg_positions[0] on the SLF4J-family methods), classified as
|
|
11717
|
+
// log_injection.
|
|
11675
11718
|
// Issue #44: log.info/warn/error/debug emit the message argument and any
|
|
11676
11719
|
// {} format arguments to the log stream. Untrusted input forwarded into
|
|
11677
11720
|
// these calls allows log forging (newline injection) and downstream log
|
|
@@ -10611,6 +10611,35 @@ var DEFAULT_SOURCES = [
|
|
|
10611
10611
|
{ method: "get", class: "Jedis", type: "db_input", severity: "medium", return_tainted: true, languages: ["java"] },
|
|
10612
10612
|
{ method: "hget", class: "Jedis", type: "db_input", severity: "medium", return_tainted: true, languages: ["java"] },
|
|
10613
10613
|
{ method: "mget", class: "Jedis", type: "db_input", severity: "medium", return_tainted: true, languages: ["java"] },
|
|
10614
|
+
// --- Serverless transport channels (cognium-dev #213 first slice) ---
|
|
10615
|
+
//
|
|
10616
|
+
// AWS Lambda / API Gateway invocation-event properties. The Lambda
|
|
10617
|
+
// handler signature `(event, context) => …` (JS/TS) or
|
|
10618
|
+
// `def handler(event, context)` (Python) receives an `event` object
|
|
10619
|
+
// whose properties carry the untrusted HTTP-request-shaped payload:
|
|
10620
|
+
//
|
|
10621
|
+
// event.body — request body (string)
|
|
10622
|
+
// event.queryStringParameters — `?a=b` params
|
|
10623
|
+
// event.multiValueQueryStringParameters — `?a=1&a=2` params
|
|
10624
|
+
// event.pathParameters — path template captures
|
|
10625
|
+
// event.headers — request headers
|
|
10626
|
+
// event.multiValueHeaders — repeated headers
|
|
10627
|
+
// event.requestContext — API Gateway request context
|
|
10628
|
+
//
|
|
10629
|
+
// Vercel Serverless Functions and Cloudflare Workers both use `req`
|
|
10630
|
+
// / `request` receivers that are already covered by the Express-
|
|
10631
|
+
// style patterns above (line ~398). This block specifically covers
|
|
10632
|
+
// the `event`-shaped API Gateway convention that those don't reach.
|
|
10633
|
+
{ property: "body", object: "event", type: "http_body", severity: "high", property_tainted: true, languages: ["javascript", "typescript"] },
|
|
10634
|
+
{ property: "queryStringParameters", object: "event", type: "http_query", severity: "high", property_tainted: true, languages: ["javascript", "typescript"] },
|
|
10635
|
+
{ property: "multiValueQueryStringParameters", object: "event", type: "http_query", severity: "high", property_tainted: true, languages: ["javascript", "typescript"] },
|
|
10636
|
+
{ property: "pathParameters", object: "event", type: "http_path", severity: "high", property_tainted: true, languages: ["javascript", "typescript"] },
|
|
10637
|
+
{ property: "headers", object: "event", type: "http_header", severity: "high", property_tainted: true, languages: ["javascript", "typescript"] },
|
|
10638
|
+
{ property: "multiValueHeaders", object: "event", type: "http_header", severity: "high", property_tainted: true, languages: ["javascript", "typescript"] },
|
|
10639
|
+
{ property: "body", object: "event", type: "http_body", severity: "high", property_tainted: true, languages: ["python"] },
|
|
10640
|
+
{ property: "queryStringParameters", object: "event", type: "http_query", severity: "high", property_tainted: true, languages: ["python"] },
|
|
10641
|
+
{ property: "pathParameters", object: "event", type: "http_path", severity: "high", property_tainted: true, languages: ["python"] },
|
|
10642
|
+
{ property: "headers", object: "event", type: "http_header", severity: "high", property_tainted: true, languages: ["python"] },
|
|
10614
10643
|
// --- JWT claims (unverified decode — PyJWT / jose / jsonwebtoken / auth0 java-jwt / golang-jwt) ---
|
|
10615
10644
|
// A JWT's payload is *always* attacker-authored. Even after verification
|
|
10616
10645
|
// the *contents* of the claims (username, role, custom fields) are not
|
|
@@ -11606,6 +11635,20 @@ var DEFAULT_SINKS = [
|
|
|
11606
11635
|
// Sandbox/script security
|
|
11607
11636
|
{ method: "onNewInstance", class: "SandboxInterceptor", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
11608
11637
|
// Java Log Injection (slf4j / logback / java.util.logging) — CWE-117
|
|
11638
|
+
//
|
|
11639
|
+
// Classification decision — cognium-dev #264: Logger receivers stay
|
|
11640
|
+
// as log_injection (CWE-117), NOT format_string (CWE-134). The real
|
|
11641
|
+
// vulnerability with tainted data flowing into Logger.log(fmt, ...)
|
|
11642
|
+
// is log-forgery via CRLF injection, not format-string exploitation.
|
|
11643
|
+
// A genuine format_string vulnerability requires the FORMAT STRING
|
|
11644
|
+
// itself to be attacker-controlled, which is virtually never the
|
|
11645
|
+
// case in Logger APIs (the format string is a literal at the call
|
|
11646
|
+
// site). Adding format_string sinks for these same receivers would
|
|
11647
|
+
// duplicate the existing log_injection findings on every call site
|
|
11648
|
+
// without adding real signal. The rare edge case where a caller
|
|
11649
|
+
// passes `taintedFmt` at arg[0] is still caught by these entries
|
|
11650
|
+
// (via arg_positions[0] on the SLF4J-family methods), classified as
|
|
11651
|
+
// log_injection.
|
|
11609
11652
|
// Issue #44: log.info/warn/error/debug emit the message argument and any
|
|
11610
11653
|
// {} format arguments to the log stream. Untrusted input forwarded into
|
|
11611
11654
|
// these calls allows log forging (newline injection) and downstream log
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "circle-ir",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.181.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",
|