cognium-dev 3.30.0 → 3.33.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.
Files changed (2) hide show
  1. package/dist/cli.js +512 -8
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -8990,6 +8990,484 @@ function findChildByTypeGo(node, type) {
8990
8990
  }
8991
8991
  return null;
8992
8992
  }
8993
+ // ../circle-ir/dist/core/extractors/runtime-registrations.js
8994
+ var HTTP_VERB_METHODS = new Set([
8995
+ "get",
8996
+ "post",
8997
+ "put",
8998
+ "patch",
8999
+ "delete",
9000
+ "head",
9001
+ "options",
9002
+ "all"
9003
+ ]);
9004
+ var MIDDLEWARE_METHODS = new Set(["use"]);
9005
+ var EVENT_LISTENER_METHODS = new Set(["on", "once", "ws"]);
9006
+ var EXPRESS_RECEIVER_NAMES = new Set([
9007
+ "app",
9008
+ "router",
9009
+ "server",
9010
+ "apiRouter",
9011
+ "fastify",
9012
+ "koa",
9013
+ "express"
9014
+ ]);
9015
+ var FRAMEWORK_MODULE_PATTERNS = [
9016
+ /^express$/,
9017
+ /^@?fastify(\/.*)?$/,
9018
+ /^koa$/,
9019
+ /^restify$/,
9020
+ /^hapi$/,
9021
+ /^@nestjs\/common$/,
9022
+ /^@nestjs\/core$/
9023
+ ];
9024
+ function extractRuntimeRegistrations(tree, cache, language, imports) {
9025
+ if (language === "javascript" || language === "typescript") {
9026
+ return extractJSRuntimeRegistrations(tree, cache, imports);
9027
+ }
9028
+ if (language === "python") {
9029
+ return extractPythonRuntimeRegistrations(tree, cache, imports);
9030
+ }
9031
+ return [];
9032
+ }
9033
+ function buildHandlerIndex(tree, cache, imports) {
9034
+ const decls = new Map;
9035
+ const recordDeclaration = (name2, node) => {
9036
+ if (!decls.has(name2)) {
9037
+ decls.set(name2, {
9038
+ line: node.startPosition.row + 1,
9039
+ column: node.startPosition.column
9040
+ });
9041
+ }
9042
+ };
9043
+ for (const fn of getNodesFromCache(tree.rootNode, "function_declaration", cache)) {
9044
+ const nameNode = fn.childForFieldName("name");
9045
+ if (nameNode)
9046
+ recordDeclaration(getNodeText(nameNode), fn);
9047
+ }
9048
+ const collectVarDeclarators = (parentType) => {
9049
+ for (const decl of getNodesFromCache(tree.rootNode, parentType, cache)) {
9050
+ for (let i2 = 0;i2 < decl.childCount; i2++) {
9051
+ const child = decl.child(i2);
9052
+ if (!child || child.type !== "variable_declarator")
9053
+ continue;
9054
+ const nameNode = child.childForFieldName("name");
9055
+ const valueNode = child.childForFieldName("value");
9056
+ if (!nameNode || !valueNode)
9057
+ continue;
9058
+ if (valueNode.type === "arrow_function" || valueNode.type === "function_expression" || valueNode.type === "function") {
9059
+ recordDeclaration(getNodeText(nameNode), child);
9060
+ }
9061
+ }
9062
+ }
9063
+ };
9064
+ collectVarDeclarators("lexical_declaration");
9065
+ collectVarDeclarators("variable_declaration");
9066
+ let hasFrameworkImport = false;
9067
+ if (imports) {
9068
+ for (const imp of imports) {
9069
+ const mod = imp.from_package ?? "";
9070
+ if (mod && FRAMEWORK_MODULE_PATTERNS.some((re) => re.test(mod))) {
9071
+ hasFrameworkImport = true;
9072
+ break;
9073
+ }
9074
+ }
9075
+ }
9076
+ return { declarations: decls, hasFrameworkImport };
9077
+ }
9078
+ function extractJSRuntimeRegistrations(tree, cache, imports) {
9079
+ const out2 = [];
9080
+ const index = buildHandlerIndex(tree, cache, imports);
9081
+ const callExpressions = getNodesFromCache(tree.rootNode, "call_expression", cache);
9082
+ for (const call of callExpressions) {
9083
+ const fnNode = call.childForFieldName("function");
9084
+ if (!fnNode || fnNode.type !== "member_expression")
9085
+ continue;
9086
+ const objectNode = fnNode.childForFieldName("object");
9087
+ const propertyNode = fnNode.childForFieldName("property");
9088
+ if (!objectNode || !propertyNode)
9089
+ continue;
9090
+ const method = getNodeText(propertyNode);
9091
+ const receiver = getNodeText(objectNode);
9092
+ const kind = classifyMethod(method);
9093
+ if (!kind)
9094
+ continue;
9095
+ if (!isExpressShapedReceiver(receiver) && !index.hasFrameworkImport) {
9096
+ continue;
9097
+ }
9098
+ const argsNode = call.childForFieldName("arguments");
9099
+ if (!argsNode)
9100
+ continue;
9101
+ const argNodes = getRealArgs(argsNode);
9102
+ if (argNodes.length === 0)
9103
+ continue;
9104
+ let path;
9105
+ let handlerStart = 0;
9106
+ const first = argNodes[0];
9107
+ if (first.type === "string") {
9108
+ path = stripQuotes(getNodeText(first));
9109
+ handlerStart = 1;
9110
+ } else if (first.type === "template_string" && !hasTemplateSubstitution(first)) {
9111
+ path = stripBackticks(getNodeText(first));
9112
+ handlerStart = 1;
9113
+ }
9114
+ for (let i2 = handlerStart;i2 < argNodes.length; i2++) {
9115
+ const handlerNode = argNodes[i2];
9116
+ const handler = resolveHandler(handlerNode, index);
9117
+ if (!handler)
9118
+ continue;
9119
+ out2.push({
9120
+ kind,
9121
+ framework: inferFramework(receiver, index.hasFrameworkImport),
9122
+ registrar: {
9123
+ method,
9124
+ receiver,
9125
+ line: call.startPosition.row + 1,
9126
+ column: call.startPosition.column
9127
+ },
9128
+ ...path !== undefined ? { path } : {},
9129
+ handler
9130
+ });
9131
+ }
9132
+ }
9133
+ return out2;
9134
+ }
9135
+ function classifyMethod(method) {
9136
+ if (HTTP_VERB_METHODS.has(method))
9137
+ return "http_route";
9138
+ if (MIDDLEWARE_METHODS.has(method))
9139
+ return "middleware";
9140
+ if (EVENT_LISTENER_METHODS.has(method))
9141
+ return "event_listener";
9142
+ return null;
9143
+ }
9144
+ function isExpressShapedReceiver(receiver) {
9145
+ if (EXPRESS_RECEIVER_NAMES.has(receiver))
9146
+ return true;
9147
+ if (/(?:Router|App|Server)$/.test(receiver))
9148
+ return true;
9149
+ return false;
9150
+ }
9151
+ function inferFramework(receiver, hasFrameworkImport) {
9152
+ if (receiver === "fastify")
9153
+ return "fastify";
9154
+ if (receiver === "koa")
9155
+ return "koa";
9156
+ if (receiver === "express")
9157
+ return "express";
9158
+ return hasFrameworkImport ? "express" : "unknown";
9159
+ }
9160
+ function getRealArgs(argsNode) {
9161
+ const out2 = [];
9162
+ for (let i2 = 0;i2 < argsNode.childCount; i2++) {
9163
+ const child = argsNode.child(i2);
9164
+ if (!child)
9165
+ continue;
9166
+ if (child.type === "(" || child.type === ")" || child.type === ",")
9167
+ continue;
9168
+ out2.push(child);
9169
+ }
9170
+ return out2;
9171
+ }
9172
+ function stripQuotes(s) {
9173
+ if (s.length >= 2 && (s[0] === '"' || s[0] === "'") && s[s.length - 1] === s[0]) {
9174
+ return s.slice(1, -1);
9175
+ }
9176
+ return s;
9177
+ }
9178
+ function stripBackticks(s) {
9179
+ if (s.length >= 2 && s[0] === "`" && s[s.length - 1] === "`") {
9180
+ return s.slice(1, -1);
9181
+ }
9182
+ return s;
9183
+ }
9184
+ function hasTemplateSubstitution(node) {
9185
+ for (let i2 = 0;i2 < node.childCount; i2++) {
9186
+ const child = node.child(i2);
9187
+ if (child && child.type === "template_substitution")
9188
+ return true;
9189
+ }
9190
+ return false;
9191
+ }
9192
+ function resolveHandler(node, index) {
9193
+ if (node.type === "arrow_function" || node.type === "function_expression" || node.type === "function") {
9194
+ return {
9195
+ name: null,
9196
+ line: node.startPosition.row + 1,
9197
+ column: node.startPosition.column
9198
+ };
9199
+ }
9200
+ if (node.type === "identifier") {
9201
+ const name2 = getNodeText(node);
9202
+ const decl = index.declarations.get(name2);
9203
+ if (decl) {
9204
+ return { name: name2, line: decl.line, column: decl.column };
9205
+ }
9206
+ return {
9207
+ name: name2,
9208
+ line: node.startPosition.row + 1,
9209
+ column: node.startPosition.column
9210
+ };
9211
+ }
9212
+ if (node.type === "member_expression") {
9213
+ return {
9214
+ name: getNodeText(node),
9215
+ line: node.startPosition.row + 1,
9216
+ column: node.startPosition.column
9217
+ };
9218
+ }
9219
+ return null;
9220
+ }
9221
+ var PY_HTTP_ROUTE_METHODS = new Set([
9222
+ "route",
9223
+ "get",
9224
+ "post",
9225
+ "put",
9226
+ "patch",
9227
+ "delete",
9228
+ "head",
9229
+ "options"
9230
+ ]);
9231
+ var PY_MIDDLEWARE_METHODS = new Set([
9232
+ "before_request",
9233
+ "after_request",
9234
+ "teardown_request",
9235
+ "before_first_request",
9236
+ "teardown_appcontext",
9237
+ "middleware"
9238
+ ]);
9239
+ var PY_EVENT_METHODS = new Set([
9240
+ "errorhandler",
9241
+ "on_event",
9242
+ "exception_handler"
9243
+ ]);
9244
+ var PY_STDLIB_DECORATORS = new Set([
9245
+ "property",
9246
+ "staticmethod",
9247
+ "classmethod",
9248
+ "abstractmethod",
9249
+ "cached_property",
9250
+ "dataclass",
9251
+ "cache",
9252
+ "lru_cache",
9253
+ "singledispatch",
9254
+ "singledispatchmethod",
9255
+ "contextmanager",
9256
+ "asynccontextmanager",
9257
+ "final",
9258
+ "override",
9259
+ "wraps"
9260
+ ]);
9261
+ function summarisePythonImports(imports) {
9262
+ const s = {
9263
+ hasFlask: false,
9264
+ hasFastApi: false,
9265
+ hasCelery: false,
9266
+ hasNumba: false,
9267
+ hasClick: false,
9268
+ hasPytest: false
9269
+ };
9270
+ if (!imports)
9271
+ return s;
9272
+ for (const imp of imports) {
9273
+ const mod = imp.from_package ?? "";
9274
+ if (!mod)
9275
+ continue;
9276
+ if (/^flask(\b|\.)/.test(mod))
9277
+ s.hasFlask = true;
9278
+ if (/^fastapi(\b|\.)/.test(mod) || /^starlette(\b|\.)/.test(mod))
9279
+ s.hasFastApi = true;
9280
+ if (/^celery(\b|\.)/.test(mod))
9281
+ s.hasCelery = true;
9282
+ if (/^numba(\b|\.)/.test(mod))
9283
+ s.hasNumba = true;
9284
+ if (/^click(\b|\.)/.test(mod))
9285
+ s.hasClick = true;
9286
+ if (/^pytest(\b|\.)/.test(mod))
9287
+ s.hasPytest = true;
9288
+ }
9289
+ return s;
9290
+ }
9291
+ function extractPythonRuntimeRegistrations(tree, cache, imports) {
9292
+ const out2 = [];
9293
+ const importSummary = summarisePythonImports(imports);
9294
+ const decoratedDefs = getNodesFromCache(tree.rootNode, "decorated_definition", cache);
9295
+ for (const dd of decoratedDefs) {
9296
+ let fnNode = null;
9297
+ const decorators = [];
9298
+ for (let i2 = 0;i2 < dd.childCount; i2++) {
9299
+ const child = dd.child(i2);
9300
+ if (!child)
9301
+ continue;
9302
+ if (child.type === "decorator") {
9303
+ decorators.push(child);
9304
+ } else if (child.type === "function_definition" || child.type === "async_function_definition") {
9305
+ fnNode = child;
9306
+ }
9307
+ }
9308
+ if (!fnNode || decorators.length === 0)
9309
+ continue;
9310
+ const handler = pythonHandlerFromFunctionDef(fnNode);
9311
+ if (!handler)
9312
+ continue;
9313
+ for (const dec of decorators) {
9314
+ const parsed = parsePythonDecorator(dec);
9315
+ if (!parsed)
9316
+ continue;
9317
+ const { receiver, method, path, line, column } = parsed;
9318
+ const { kind, framework } = classifyPythonDecorator(receiver, method, importSummary);
9319
+ out2.push({
9320
+ kind,
9321
+ framework,
9322
+ registrar: { method, receiver, line, column },
9323
+ ...path !== undefined ? { path } : {},
9324
+ handler
9325
+ });
9326
+ }
9327
+ }
9328
+ return out2;
9329
+ }
9330
+ function pythonHandlerFromFunctionDef(fn) {
9331
+ const nameNode = fn.childForFieldName("name");
9332
+ if (!nameNode)
9333
+ return null;
9334
+ return {
9335
+ name: getNodeText(nameNode),
9336
+ line: fn.startPosition.row + 1,
9337
+ column: fn.startPosition.column
9338
+ };
9339
+ }
9340
+ function parsePythonDecorator(dec) {
9341
+ let target = null;
9342
+ for (let i2 = 0;i2 < dec.childCount; i2++) {
9343
+ const child = dec.child(i2);
9344
+ if (!child || child.type === "@")
9345
+ continue;
9346
+ target = child;
9347
+ break;
9348
+ }
9349
+ if (!target)
9350
+ return null;
9351
+ const line = dec.startPosition.row + 1;
9352
+ const column = dec.startPosition.column;
9353
+ if (target.type === "identifier") {
9354
+ return { receiver: "", method: getNodeText(target), line, column };
9355
+ }
9356
+ if (target.type === "attribute") {
9357
+ const { receiver, method } = splitDottedAttribute(target);
9358
+ return { receiver, method, line, column };
9359
+ }
9360
+ if (target.type === "call") {
9361
+ const fnNode = target.childForFieldName("function");
9362
+ if (!fnNode)
9363
+ return null;
9364
+ let receiver = "";
9365
+ let method = "";
9366
+ if (fnNode.type === "identifier") {
9367
+ method = getNodeText(fnNode);
9368
+ } else if (fnNode.type === "attribute") {
9369
+ const split = splitDottedAttribute(fnNode);
9370
+ receiver = split.receiver;
9371
+ method = split.method;
9372
+ } else {
9373
+ method = getNodeText(fnNode);
9374
+ }
9375
+ const path = extractFirstStringArg(target);
9376
+ return { receiver, method, path, line, column };
9377
+ }
9378
+ return null;
9379
+ }
9380
+ function splitDottedAttribute(attr) {
9381
+ const objectNode = attr.childForFieldName("object");
9382
+ const attrNode = attr.childForFieldName("attribute");
9383
+ const method = attrNode ? getNodeText(attrNode) : "";
9384
+ const receiver = objectNode ? getNodeText(objectNode) : "";
9385
+ return { receiver, method };
9386
+ }
9387
+ function extractFirstStringArg(call) {
9388
+ const argsNode = call.childForFieldName("arguments");
9389
+ if (!argsNode)
9390
+ return;
9391
+ for (let i2 = 0;i2 < argsNode.childCount; i2++) {
9392
+ const child = argsNode.child(i2);
9393
+ if (!child)
9394
+ continue;
9395
+ if (child.type === "(" || child.type === ")" || child.type === ",")
9396
+ continue;
9397
+ if (child.type === "string") {
9398
+ return stripPythonStringQuotes(getNodeText(child));
9399
+ }
9400
+ return;
9401
+ }
9402
+ return;
9403
+ }
9404
+ function stripPythonStringQuotes(s) {
9405
+ const m = s.match(/^[bBrRuUfF]{0,2}(['"])(.*)\1$/s);
9406
+ if (m)
9407
+ return m[2];
9408
+ if (s.length >= 2 && (s[0] === '"' || s[0] === "'") && s[s.length - 1] === s[0]) {
9409
+ return s.slice(1, -1);
9410
+ }
9411
+ return s;
9412
+ }
9413
+ function classifyPythonDecorator(receiver, method, imp) {
9414
+ if (!receiver && PY_STDLIB_DECORATORS.has(method)) {
9415
+ return { kind: "decorator", framework: "stdlib" };
9416
+ }
9417
+ if (receiver) {
9418
+ const head = receiver.split(".")[0];
9419
+ if (head === "pytest") {
9420
+ return { kind: "decorator", framework: "pytest" };
9421
+ }
9422
+ if (head === "click") {
9423
+ return { kind: "decorator", framework: "click" };
9424
+ }
9425
+ if (head === "numba" || head === "nb") {
9426
+ return { kind: "decorator", framework: "numba" };
9427
+ }
9428
+ if (head === "celery") {
9429
+ return { kind: "decorator", framework: "celery" };
9430
+ }
9431
+ }
9432
+ if (receiver && PY_HTTP_ROUTE_METHODS.has(method)) {
9433
+ const isRoutey = isPyRouterReceiver(receiver);
9434
+ if (isRoutey) {
9435
+ let framework = "unknown";
9436
+ if (imp.hasFlask)
9437
+ framework = "flask";
9438
+ else if (imp.hasFastApi)
9439
+ framework = "fastapi";
9440
+ else if (method === "route")
9441
+ framework = "flask";
9442
+ else
9443
+ framework = "fastapi";
9444
+ return { kind: "http_route", framework };
9445
+ }
9446
+ }
9447
+ if (receiver && PY_MIDDLEWARE_METHODS.has(method)) {
9448
+ return { kind: "middleware", framework: imp.hasFlask ? "flask" : imp.hasFastApi ? "fastapi" : "unknown" };
9449
+ }
9450
+ if (receiver && PY_EVENT_METHODS.has(method)) {
9451
+ return { kind: "event_listener", framework: imp.hasFlask ? "flask" : imp.hasFastApi ? "fastapi" : "unknown" };
9452
+ }
9453
+ if (method === "task" && imp.hasCelery) {
9454
+ return { kind: "decorator", framework: "celery" };
9455
+ }
9456
+ if (!receiver && (method === "login_required" || method === "require_http_methods" || method === "api_view")) {
9457
+ return { kind: "decorator", framework: "django" };
9458
+ }
9459
+ return { kind: "decorator", framework: "unknown" };
9460
+ }
9461
+ function isPyRouterReceiver(receiver) {
9462
+ const head = receiver.split(".")[0];
9463
+ if (!head)
9464
+ return false;
9465
+ if (["app", "router", "blueprint", "bp", "api", "application"].includes(head))
9466
+ return true;
9467
+ if (/_(router|bp|blueprint|app|api)$/.test(head))
9468
+ return true;
9469
+ return false;
9470
+ }
8993
9471
  // ../circle-ir/dist/analysis/config-loader.js
8994
9472
  var DEFAULT_SOURCES = [
8995
9473
  { method: "getParameter", class: "HttpServletRequest", type: "http_param", severity: "high", return_tainted: true },
@@ -9125,6 +9603,11 @@ var DEFAULT_SOURCES = [
9125
9603
  { method: "getContent", class: "Block", type: "io_input", severity: "high", return_tainted: true },
9126
9604
  { method: "getParameters", class: "Block", type: "io_input", severity: "high", return_tainted: true },
9127
9605
  { method: "getRawContent", type: "io_input", severity: "high", return_tainted: true },
9606
+ { method: "get", class: "XWikiRequest", type: "http_param", severity: "high", return_tainted: true },
9607
+ { method: "getParameter", class: "XWikiRequest", type: "http_param", severity: "high", return_tainted: true },
9608
+ { method: "getParameterValues", class: "XWikiRequest", type: "http_param", severity: "high", return_tainted: true },
9609
+ { method: "getParameterMap", class: "XWikiRequest", type: "http_param", severity: "high", return_tainted: true },
9610
+ { method: "getHeader", class: "XWikiRequest", type: "http_header", severity: "high", return_tainted: true },
9128
9611
  { method: "getAttributes", class: "XMLReader", type: "io_input", severity: "high", return_tainted: true },
9129
9612
  { method: "getValue", class: "Attributes", type: "io_input", severity: "high", return_tainted: true },
9130
9613
  { method: "getLocalName", class: "Attributes", type: "io_input", severity: "high", return_tainted: true },
@@ -9622,6 +10105,8 @@ var DEFAULT_SINKS = [
9622
10105
  { method: "eval", class: "MVEL", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
9623
10106
  { method: "createValueExpression", class: "ExpressionFactory", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [1] },
9624
10107
  { method: "createMethodExpression", class: "ExpressionFactory", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [1] },
10108
+ { method: "evaluateAttributeExpressions", class: "PropertyValue", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [] },
10109
+ { method: "evaluateAttributeExpressions", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [] },
9625
10110
  { method: "evaluate", class: "GroovyShell", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
9626
10111
  { method: "parse", class: "GroovyShell", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
9627
10112
  { method: "parseClass", class: "GroovyClassLoader", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
@@ -9775,6 +10260,21 @@ var DEFAULT_SINKS = [
9775
10260
  { method: "cleanAttributes", class: "XHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
9776
10261
  { method: "printXMLElement", class: "XHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
9777
10262
  { method: "printXMLStartElement", class: "XHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10263
+ { method: "print", class: "WikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10264
+ { method: "println", class: "WikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10265
+ { method: "print", class: "DefaultWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10266
+ { method: "println", class: "DefaultWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10267
+ { method: "print", class: "XHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10268
+ { method: "println", class: "XHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10269
+ { method: "printXML", class: "XHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10270
+ { method: "printXMLComment", class: "XHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10271
+ { method: "print", class: "AnnotatedXHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10272
+ { method: "println", class: "AnnotatedXHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10273
+ { method: "printXMLElement", class: "AnnotatedXHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10274
+ { method: "printXMLStartElement", class: "AnnotatedXHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10275
+ { method: "render", class: "BlockRenderer", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10276
+ { method: "render", class: "AbstractBlockRenderer", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10277
+ { method: "render", class: "DefaultBlockRenderer", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
9778
10278
  { method: "initialize", class: "HTML5Renderer", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
9779
10279
  { method: "initialize", class: "XHTMLRenderer", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
9780
10280
  { method: "beginFormat", class: "HTML5ChainingRenderer", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
@@ -17880,7 +18380,7 @@ function extractEventHandlers(elementNode, eventHandlers) {
17880
18380
  const valueNode = findChildByType2(child, "quoted_attribute_value") ?? findChildByType2(child, "attribute_value");
17881
18381
  if (!valueNode)
17882
18382
  continue;
17883
- const code = stripQuotes(valueNode.text);
18383
+ const code = stripQuotes2(valueNode.text);
17884
18384
  if (code) {
17885
18385
  eventHandlers.push({
17886
18386
  code,
@@ -17913,7 +18413,7 @@ function getAttributeValue(tag, name2) {
17913
18413
  const nameNode = findChildByType2(child, "attribute_name");
17914
18414
  if (nameNode?.text.toLowerCase() === name2) {
17915
18415
  const valueNode = findChildByType2(child, "quoted_attribute_value") ?? findChildByType2(child, "attribute_value");
17916
- return valueNode ? stripQuotes(valueNode.text) : "";
18416
+ return valueNode ? stripQuotes2(valueNode.text) : "";
17917
18417
  }
17918
18418
  }
17919
18419
  return;
@@ -17926,7 +18426,7 @@ function findChildByType2(node, type) {
17926
18426
  }
17927
18427
  return null;
17928
18428
  }
17929
- function stripQuotes(text) {
18429
+ function stripQuotes2(text) {
17930
18430
  if (text.startsWith('"') && text.endsWith('"') || text.startsWith("'") && text.endsWith("'")) {
17931
18431
  return text.slice(1, -1);
17932
18432
  }
@@ -24242,7 +24742,7 @@ class SecurityHeadersPass {
24242
24742
  }
24243
24743
  function literalOf(arg) {
24244
24744
  if (arg.literal !== null && arg.literal !== undefined && arg.literal !== "") {
24245
- return stripQuotes2(arg.literal);
24745
+ return stripQuotes3(arg.literal);
24246
24746
  }
24247
24747
  const expr = arg.expression.trim();
24248
24748
  if (expr.startsWith('"') && expr.endsWith('"') || expr.startsWith("'") && expr.endsWith("'") || expr.startsWith("`") && expr.endsWith("`")) {
@@ -24252,7 +24752,7 @@ function literalOf(arg) {
24252
24752
  }
24253
24753
  return null;
24254
24754
  }
24255
- function stripQuotes2(s) {
24755
+ function stripQuotes3(s) {
24256
24756
  if (s.length < 2)
24257
24757
  return s;
24258
24758
  const first = s[0];
@@ -25716,7 +26216,9 @@ function getNodeTypesForLanguage(language) {
25716
26216
  "import_from_statement",
25717
26217
  "assignment",
25718
26218
  "attribute",
25719
- "subscript"
26219
+ "subscript",
26220
+ "decorated_definition",
26221
+ "decorator"
25720
26222
  ]);
25721
26223
  case "javascript":
25722
26224
  case "typescript":
@@ -25808,6 +26310,7 @@ async function analyze(code, filePath, language, options = {}) {
25808
26310
  const exports = extractExports(types);
25809
26311
  const cfg = buildCFG(tree, language);
25810
26312
  const dfg = buildDFG(tree, nodeCache, language);
26313
+ const runtimeRegistrations = extractRuntimeRegistrations(tree, nodeCache, language, imports);
25811
26314
  const graph = new CodeGraph({
25812
26315
  meta,
25813
26316
  types,
@@ -25934,7 +26437,8 @@ async function analyze(code, filePath, language, options = {}) {
25934
26437
  unresolved,
25935
26438
  enriched,
25936
26439
  findings: findings.length > 0 ? findings : undefined,
25937
- metrics: { file: filePath, metrics: metricValues }
26440
+ metrics: { file: filePath, metrics: metricValues },
26441
+ runtime_registrations: runtimeRegistrations.length > 0 ? runtimeRegistrations : undefined
25938
26442
  };
25939
26443
  } finally {
25940
26444
  disposeTree(tree);
@@ -26083,7 +26587,7 @@ var colors = {
26083
26587
  };
26084
26588
 
26085
26589
  // src/version.ts
26086
- var version = "3.30.0";
26590
+ var version = "3.33.0";
26087
26591
 
26088
26592
  // src/formatters.ts
26089
26593
  var SINK_SEVERITY = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cognium-dev",
3
- "version": "3.30.0",
3
+ "version": "3.33.0",
4
4
  "description": "Static Application Security Testing CLI for detecting security vulnerabilities via taint tracking",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -65,7 +65,7 @@
65
65
  "registry": "https://registry.npmjs.org/"
66
66
  },
67
67
  "dependencies": {
68
- "circle-ir": "^3.30.0"
68
+ "circle-ir": "^3.33.0"
69
69
  },
70
70
  "devDependencies": {
71
71
  "@types/node": "^25.5.0",