circle-ir 4.9.21 → 4.9.22

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.
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Modelled-CWE export (cognium-dev#393).
3
+ *
4
+ * Which weakness classes does the taint engine have a model for? Anything that
5
+ * scores the engine against a CWE-labelled corpus needs the answer, and a
6
+ * hand-kept list drifts and can be tuned. This derives it from the same runtime
7
+ * registries the analyzer matches against, so it is always the truth for the
8
+ * installed version and grows as sinks are added.
9
+ *
10
+ * "Modelled" is deliberately narrow: a CWE some SINK pattern is registered
11
+ * under. Non-taint pattern passes (weak crypto, missing headers, resource
12
+ * leaks …) stamp their CWE on each finding and have no registry to enumerate,
13
+ * so they are out of this export rather than half-listed.
14
+ */
15
+ /**
16
+ * Ids an advisory may carry for a class the engine models under another id —
17
+ * a child or sibling that reaches the same sink family. Keyed advisory-side,
18
+ * valued with the modelled id. Kept short and literal on purpose: each entry
19
+ * widens what counts as in scope, so each is a claim someone can check.
20
+ */
21
+ export declare const RELATED_CWE: Readonly<Record<string, string>>;
22
+ export interface ModelledCwes {
23
+ /** CWEs at least one registered sink pattern carries, sorted numerically. */
24
+ sinkCwes: string[];
25
+ /** Advisory-side ids that map onto a modelled class; see `RELATED_CWE`. */
26
+ related: Readonly<Record<string, string>>;
27
+ }
28
+ /** The engine's modelled taint classes, derived from the live sink registries. */
29
+ export declare function getModelledCwes(): ModelledCwes;
30
+ /**
31
+ * Is `cwe` a class the taint engine models, directly or through `RELATED_CWE`?
32
+ * A related id counts only while the id it maps to is itself still modelled.
33
+ */
34
+ export declare function isModelledCwe(cwe: string, modelled?: ModelledCwes): boolean;
35
+ //# sourceMappingURL=modelled-cwes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modelled-cwes.d.ts","sourceRoot":"","sources":["../../src/analysis/modelled-cwes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH;;;;;GAKG;AACH,eAAO,MAAM,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAcvD,CAAC;AAEH,MAAM,WAAW,YAAY;IAC3B,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,2EAA2E;IAC3E,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC3C;AAKD,kFAAkF;AAClF,wBAAgB,eAAe,IAAI,YAAY,CAO9C;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,GAAE,YAAgC,GAAG,OAAO,CAK9F"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Modelled-CWE export (cognium-dev#393).
3
+ *
4
+ * Which weakness classes does the taint engine have a model for? Anything that
5
+ * scores the engine against a CWE-labelled corpus needs the answer, and a
6
+ * hand-kept list drifts and can be tuned. This derives it from the same runtime
7
+ * registries the analyzer matches against, so it is always the truth for the
8
+ * installed version and grows as sinks are added.
9
+ *
10
+ * "Modelled" is deliberately narrow: a CWE some SINK pattern is registered
11
+ * under. Non-taint pattern passes (weak crypto, missing headers, resource
12
+ * leaks …) stamp their CWE on each finding and have no registry to enumerate,
13
+ * so they are out of this export rather than half-listed.
14
+ */
15
+ import { DEFAULT_SINKS } from './config-loader.js';
16
+ import { createBuiltinPlugins } from '../languages/plugins/index.js';
17
+ /**
18
+ * Ids an advisory may carry for a class the engine models under another id —
19
+ * a child or sibling that reaches the same sink family. Keyed advisory-side,
20
+ * valued with the modelled id. Kept short and literal on purpose: each entry
21
+ * widens what counts as in scope, so each is a claim someone can check.
22
+ */
23
+ export const RELATED_CWE = Object.freeze({
24
+ 'CWE-23': 'CWE-22', // relative path traversal
25
+ 'CWE-36': 'CWE-22', // absolute path traversal
26
+ 'CWE-73': 'CWE-22', // external control of file name or path
27
+ 'CWE-77': 'CWE-78', // command injection (generic) -> OS command injection
28
+ 'CWE-88': 'CWE-78', // argument injection
29
+ 'CWE-80': 'CWE-79', // basic XSS
30
+ 'CWE-564': 'CWE-89', // SQL injection: Hibernate
31
+ 'CWE-95': 'CWE-94', // eval injection
32
+ 'CWE-917': 'CWE-94', // expression language injection
33
+ 'CWE-1336': 'CWE-94', // template engine injection
34
+ 'CWE-93': 'CWE-113', // CRLF injection -> HTTP response splitting
35
+ 'CWE-91': 'CWE-643', // XML injection -> XPath injection
36
+ 'CWE-776': 'CWE-611', // entity expansion -> external entities (same parser config)
37
+ });
38
+ const byNumber = (a, b) => Number(a.slice(4)) - Number(b.slice(4));
39
+ /** The engine's modelled taint classes, derived from the live sink registries. */
40
+ export function getModelledCwes() {
41
+ const cwes = new Set();
42
+ for (const sink of DEFAULT_SINKS)
43
+ if (sink.cwe)
44
+ cwes.add(sink.cwe);
45
+ for (const plugin of createBuiltinPlugins()) {
46
+ for (const sink of plugin.getBuiltinSinks())
47
+ if (sink.cwe)
48
+ cwes.add(sink.cwe);
49
+ }
50
+ return { sinkCwes: [...cwes].sort(byNumber), related: RELATED_CWE };
51
+ }
52
+ /**
53
+ * Is `cwe` a class the taint engine models, directly or through `RELATED_CWE`?
54
+ * A related id counts only while the id it maps to is itself still modelled.
55
+ */
56
+ export function isModelledCwe(cwe, modelled = getModelledCwes()) {
57
+ const direct = new Set(modelled.sinkCwes);
58
+ if (direct.has(cwe))
59
+ return true;
60
+ const parent = modelled.related[cwe];
61
+ return parent !== undefined && direct.has(parent);
62
+ }
63
+ //# sourceMappingURL=modelled-cwes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modelled-cwes.js","sourceRoot":"","sources":["../../src/analysis/modelled-cwes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAErE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAAqC,MAAM,CAAC,MAAM,CAAC;IACzE,QAAQ,EAAE,QAAQ,EAAI,0BAA0B;IAChD,QAAQ,EAAE,QAAQ,EAAI,0BAA0B;IAChD,QAAQ,EAAE,QAAQ,EAAI,wCAAwC;IAC9D,QAAQ,EAAE,QAAQ,EAAI,sDAAsD;IAC5E,QAAQ,EAAE,QAAQ,EAAI,qBAAqB;IAC3C,QAAQ,EAAE,QAAQ,EAAI,YAAY;IAClC,SAAS,EAAE,QAAQ,EAAG,2BAA2B;IACjD,QAAQ,EAAE,QAAQ,EAAI,iBAAiB;IACvC,SAAS,EAAE,QAAQ,EAAG,gCAAgC;IACtD,UAAU,EAAE,QAAQ,EAAE,4BAA4B;IAClD,QAAQ,EAAE,SAAS,EAAG,4CAA4C;IAClE,QAAQ,EAAE,SAAS,EAAG,mCAAmC;IACzD,SAAS,EAAE,SAAS,EAAE,6DAA6D;CACpF,CAAC,CAAC;AASH,MAAM,QAAQ,GAAG,CAAC,CAAS,EAAE,CAAS,EAAU,EAAE,CAChD,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAE1C,kFAAkF;AAClF,MAAM,UAAU,eAAe;IAC7B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,aAAa;QAAE,IAAI,IAAI,CAAC,GAAG;YAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnE,KAAK,MAAM,MAAM,IAAI,oBAAoB,EAAE,EAAE,CAAC;QAC5C,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,eAAe,EAAE;YAAE,IAAI,IAAI,CAAC,GAAG;gBAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;AACtE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW,EAAE,QAAQ,GAAiB,eAAe,EAAE;IACnF,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC1C,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACjC,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACrC,OAAO,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACpD,CAAC"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Pass: xml-entity-expansion (CWE-776 / CWE-611, category: security)
2
+ * Pass: xml-entity-expansion (CWE-611 / CWE-776, category: security)
3
3
  *
4
4
  * Pattern pass — flags XML parser instantiation that does *not* disable
5
5
  * DTD / external-entity processing in the same file. This covers:
@@ -14,8 +14,11 @@
14
14
  * - `XMLInputFactory.newInstance()` (StAX)
15
15
  * - `SchemaFactory.newInstance(...)`
16
16
  * - `TransformerFactory.newInstance()`
17
- * Safe-feature setters (any of these in the same file silences the
18
- * finding for that factory class):
17
+ * Safe-feature setters. Any of these in the file silences a factory
18
+ * UNLESS that factory is a local variable which provably never receives
19
+ * one (no hardening-capable setter on it in its method, never passed to
20
+ * another call, never returned) — so one hardened factory no longer masks
21
+ * an unhardened one beside it:
19
22
  * - `setFeature("http://apache.org/xml/features/disallow-doctype-decl", true)`
20
23
  * - `setFeature("http://xml.org/sax/features/external-general-entities", false)`
21
24
  * - `setFeature("http://xml.org/sax/features/external-parameter-entities", false)`
@@ -35,6 +38,19 @@
35
38
  * because billion-laughs is exploitable via any attacker-supplied entity
36
39
  * file even when the parse() argument itself is trusted.
37
40
  *
41
+ * CWE is assigned PER API, by which weakness the unhardened default actually
42
+ * leaves open (#426) — the same per-API reasoning `language-sources-pass`
43
+ * applies to Python's `xml.sax`:
44
+ * - Java JAXP factories -> CWE-611. External entity resolution is ON by
45
+ * default, while JAXP has shipped a default entity-expansion limit for
46
+ * years, so the live risk on a current JDK is external entities. Every
47
+ * hardening token this pass looks for is an external-entity control.
48
+ * - `lxml.etree` -> CWE-611. `resolve_entities` defaults on.
49
+ * - `xml.etree.ElementTree` -> CWE-776. It never resolves external entities;
50
+ * what remains is entity expansion.
51
+ * The JS variant of this rule (`libxmljs` `noent: true`) already reported
52
+ * CWE-611, so before this the rule disagreed with itself across languages.
53
+ *
38
54
  * Issue: #86, Sprint 6.
39
55
  */
40
56
  import type { AnalysisPass, PassContext } from '../../graph/analysis-pass.js';
@@ -50,6 +66,33 @@ export declare class XmlEntityExpansionPass implements AnalysisPass<XmlEntityExp
50
66
  readonly name = "xml-entity-expansion";
51
67
  readonly category: 'security';
52
68
  run(ctx: PassContext): XmlEntityExpansionResult;
69
+ private methodRanges;
70
+ /**
71
+ * In a file that DOES contain hardening evidence, is the factory created on
72
+ * `line` one that provably never receives it?
73
+ *
74
+ * Deliberately one-sided. It answers true for exactly two shapes:
75
+ *
76
+ * 1. CHAINED — `Factory.newInstance().newDocumentBuilder()`, where the
77
+ * product is not handed on or returned either.
78
+ * 2. LOCAL — `Factory f = Factory.newInstance();` where the enclosing method
79
+ * builds a parser from `f`, never hands `f` to another call, and never
80
+ * returns it.
81
+ *
82
+ * and in both only when the enclosing method contains NO hardening-capable
83
+ * setter on ANY receiver, since hardening may land on the factory's product
84
+ * (`parser.getXMLReader().setFeature(…)`) rather than the factory.
85
+ *
86
+ * Every other shape — a field, a helper that takes the factory, a caller that
87
+ * receives it — may be hardened somewhere this check cannot see, so it keeps
88
+ * the previous file-level silence.
89
+ *
90
+ * A TransformerFactory additionally needs a `StreamSource` in its method: that
91
+ * is the input the transformer parses with its OWN parser. Fed a `DOMSource`
92
+ * it parses nothing, and fed a `SAXSource` it uses the reader it was given —
93
+ * whose hardening is that reader's business, not this factory's.
94
+ */
95
+ private isProvablyUnhardened;
53
96
  private detectJavaCall;
54
97
  private detectPythonCall;
55
98
  private fixForJava;
@@ -1 +1 @@
1
- {"version":3,"file":"xml-entity-expansion-pass.d.ts","sourceRoot":"","sources":["../../../src/analysis/passes/xml-entity-expansion-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AA6C9E,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,KAAK,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,GAAG,EAAE,MAAM,CAAC;KACb,CAAC,CAAC;CACJ;AAED,qBAAa,sBACX,YAAW,YAAY,CAAC,wBAAwB,CAAC;IAEjD,QAAQ,CAAC,IAAI,0BAA0B;IACvC,QAAQ,CAAC,QAAQ,EAAG,UAAU,CAAU;IAExC,GAAG,CAAC,GAAG,EAAE,WAAW,GAAG,wBAAwB,CAsF9C;IAED,OAAO,CAAC,cAAc;IAiBtB,OAAO,CAAC,gBAAgB;IAyBxB,OAAO,CAAC,UAAU;IA6BlB,OAAO,CAAC,YAAY;CAarB"}
1
+ {"version":3,"file":"xml-entity-expansion-pass.d.ts","sourceRoot":"","sources":["../../../src/analysis/passes/xml-entity-expansion-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAwD9E,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,KAAK,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,GAAG,EAAE,MAAM,CAAC;KACb,CAAC,CAAC;CACJ;AAED,qBAAa,sBACX,YAAW,YAAY,CAAC,wBAAwB,CAAC;IAEjD,QAAQ,CAAC,IAAI,0BAA0B;IACvC,QAAQ,CAAC,QAAQ,EAAG,UAAU,CAAU;IAExC,GAAG,CAAC,GAAG,EAAE,WAAW,GAAG,wBAAwB,CAmG9C;IAED,OAAO,CAAC,YAAY;IAWpB;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,OAAO,CAAC,oBAAoB;IA0D5B,OAAO,CAAC,cAAc;IAiBtB,OAAO,CAAC,gBAAgB;IAyBxB,OAAO,CAAC,UAAU;IA6BlB,OAAO,CAAC,YAAY;CAarB"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Pass: xml-entity-expansion (CWE-776 / CWE-611, category: security)
2
+ * Pass: xml-entity-expansion (CWE-611 / CWE-776, category: security)
3
3
  *
4
4
  * Pattern pass — flags XML parser instantiation that does *not* disable
5
5
  * DTD / external-entity processing in the same file. This covers:
@@ -14,8 +14,11 @@
14
14
  * - `XMLInputFactory.newInstance()` (StAX)
15
15
  * - `SchemaFactory.newInstance(...)`
16
16
  * - `TransformerFactory.newInstance()`
17
- * Safe-feature setters (any of these in the same file silences the
18
- * finding for that factory class):
17
+ * Safe-feature setters. Any of these in the file silences a factory
18
+ * UNLESS that factory is a local variable which provably never receives
19
+ * one (no hardening-capable setter on it in its method, never passed to
20
+ * another call, never returned) — so one hardened factory no longer masks
21
+ * an unhardened one beside it:
19
22
  * - `setFeature("http://apache.org/xml/features/disallow-doctype-decl", true)`
20
23
  * - `setFeature("http://xml.org/sax/features/external-general-entities", false)`
21
24
  * - `setFeature("http://xml.org/sax/features/external-parameter-entities", false)`
@@ -35,6 +38,19 @@
35
38
  * because billion-laughs is exploitable via any attacker-supplied entity
36
39
  * file even when the parse() argument itself is trusted.
37
40
  *
41
+ * CWE is assigned PER API, by which weakness the unhardened default actually
42
+ * leaves open (#426) — the same per-API reasoning `language-sources-pass`
43
+ * applies to Python's `xml.sax`:
44
+ * - Java JAXP factories -> CWE-611. External entity resolution is ON by
45
+ * default, while JAXP has shipped a default entity-expansion limit for
46
+ * years, so the live risk on a current JDK is external entities. Every
47
+ * hardening token this pass looks for is an external-entity control.
48
+ * - `lxml.etree` -> CWE-611. `resolve_entities` defaults on.
49
+ * - `xml.etree.ElementTree` -> CWE-776. It never resolves external entities;
50
+ * what remains is entity expansion.
51
+ * The JS variant of this rule (`libxmljs` `noent: true`) already reported
52
+ * CWE-611, so before this the rule disagreed with itself across languages.
53
+ *
38
54
  * Issue: #86, Sprint 6.
39
55
  */
40
56
  const JAVA_FACTORIES = new Set([
@@ -63,6 +79,13 @@ const JAVA_XML_PARSE_INPUT_RE = /\bnew\s+(?:StreamSource|SAXSource|InputSource)\
63
79
  // - file calls NO builder.parse(...) (never reads bytes)
64
80
  const JAVA_DOC_BUILDER_NEW_DOCUMENT_RE = /\.\s*newDocument\s*\(\s*\)/;
65
81
  const JAVA_DOC_BUILDER_PARSE_RE = /(?:DocumentBuilder|builder)\s*\.\s*parse\s*\(/;
82
+ // Any call that CAN carry XML hardening, on any receiver — factory, parser,
83
+ // reader, validator or transformer. Matched by name, not argument, because the
84
+ // feature string is routinely a constant declared elsewhere.
85
+ const JAVA_HARDENING_SETTER_RE = /\.\s*(?:setFeature|setAttribute|setProperty|setXIncludeAware|setExpandEntityReferences)\s*\(/;
86
+ // A factory consumed in the same expression that creates it — never bound to a
87
+ // name, so it can never be configured.
88
+ const JAVA_FACTORY_CHAINED_RE = /\bnewInstance\s*\([^()]*\)\s*\.\s*(?:newDocumentBuilder|newSAXParser|newTransformer|newTemplates|newSchema|createXMLStreamReader|createXMLEventReader)\s*\(/;
66
89
  const PY_LXML_PARSER_INSECURE_DEFAULT_RE = /\bresolve_entities\s*=\s*False\b/;
67
90
  export class XmlEntityExpansionPass {
68
91
  name = 'xml-entity-expansion';
@@ -74,8 +97,15 @@ export class XmlEntityExpansionPass {
74
97
  const code = ctx.code ?? '';
75
98
  if (language === 'java') {
76
99
  const safeInFile = JAVA_SAFE_EVIDENCE_RE.test(code);
77
- if (safeInFile)
78
- return { findings };
100
+ // Hardening evidence used to silence the WHOLE file, so one hardened
101
+ // factory masked every other factory beside it. When evidence exists,
102
+ // keep only the factories that provably never receive it (see
103
+ // `isProvablyUnhardened`); anything ambiguous stays silent, as before.
104
+ // `jdk.xml.*` limits are set process-wide (System.setProperty), so they
105
+ // reach every factory regardless of which variable the file touches.
106
+ const processWide = safeInFile && /jdk\.xml\./.test(code);
107
+ const lines = safeInFile ? code.split('\n') : [];
108
+ const methodRanges = safeInFile ? this.methodRanges(graph.ir.types) : [];
79
109
  // #173 — output-only TransformerFactory + empty DocumentBuilder.
80
110
  // File-level heuristics; conservative-bias (only suppress when the
81
111
  // file shows ONLY the safe shape and NO unsafe shape).
@@ -93,6 +123,8 @@ export class XmlEntityExpansionPass {
93
123
  if (det.api === 'DocumentBuilderFactory' && isDocumentBuilderEmptyOnly)
94
124
  continue;
95
125
  const line = call.location.line;
126
+ if (safeInFile && (processWide || !this.isProvablyUnhardened(lines, line, methodRanges, det.api)))
127
+ continue;
96
128
  findings.push({ line, language, ...det });
97
129
  ctx.addFinding({
98
130
  id: `${this.name}-${file}-${line}-${det.api}`,
@@ -103,15 +135,15 @@ export class XmlEntityExpansionPass {
103
135
  severity: 'high',
104
136
  level: 'error',
105
137
  message: `${det.api} created without disabling DTD / external-entity ` +
106
- 'processing. Vulnerable to billion-laughs / quadratic ' +
107
- 'blow-up DoS (CWE-776) and external-entity disclosure ' +
108
- '(CWE-611). Add `setFeature("http://apache.org/xml/features/' +
138
+ 'processing. Vulnerable to external-entity disclosure ' +
139
+ '(CWE-611) and billion-laughs / quadratic blow-up DoS ' +
140
+ '(CWE-776). Add `setFeature("http://apache.org/xml/features/' +
109
141
  'disallow-doctype-decl", true)` (or the equivalent) before ' +
110
142
  'parsing.',
111
143
  file,
112
144
  line,
113
145
  fix: this.fixForJava(det.api),
114
- evidence: { ...det, language, safeFeatureInFile: false },
146
+ evidence: { ...det, language, safeFeatureInFile: safeInFile },
115
147
  });
116
148
  }
117
149
  return { findings };
@@ -136,8 +168,11 @@ export class XmlEntityExpansionPass {
136
168
  severity: 'high',
137
169
  level: 'error',
138
170
  message: `${det.api} called without an entity-safe parser. Vulnerable ` +
139
- 'to billion-laughs / quadratic blow-up DoS (CWE-776) and ' +
140
- 'external-entity disclosure (CWE-611). Use `defusedxml` or pass ' +
171
+ (det.cwe === 'CWE-611'
172
+ ? 'to external-entity disclosure (CWE-611) and billion-laughs / ' +
173
+ 'quadratic blow-up DoS (CWE-776). '
174
+ : 'to billion-laughs / quadratic blow-up DoS (CWE-776). ') +
175
+ 'Use `defusedxml` or pass ' +
141
176
  'an `XMLParser(resolve_entities=False)` to lxml.',
142
177
  file,
143
178
  line,
@@ -149,6 +184,97 @@ export class XmlEntityExpansionPass {
149
184
  }
150
185
  return { findings };
151
186
  }
187
+ methodRanges(types) {
188
+ const out = [];
189
+ for (const t of types ?? []) {
190
+ for (const m of t.methods ?? []) {
191
+ if (typeof m.start_line === 'number' && typeof m.end_line === 'number')
192
+ out.push([m.start_line, m.end_line]);
193
+ }
194
+ }
195
+ return out;
196
+ }
197
+ /**
198
+ * In a file that DOES contain hardening evidence, is the factory created on
199
+ * `line` one that provably never receives it?
200
+ *
201
+ * Deliberately one-sided. It answers true for exactly two shapes:
202
+ *
203
+ * 1. CHAINED — `Factory.newInstance().newDocumentBuilder()`, where the
204
+ * product is not handed on or returned either.
205
+ * 2. LOCAL — `Factory f = Factory.newInstance();` where the enclosing method
206
+ * builds a parser from `f`, never hands `f` to another call, and never
207
+ * returns it.
208
+ *
209
+ * and in both only when the enclosing method contains NO hardening-capable
210
+ * setter on ANY receiver, since hardening may land on the factory's product
211
+ * (`parser.getXMLReader().setFeature(…)`) rather than the factory.
212
+ *
213
+ * Every other shape — a field, a helper that takes the factory, a caller that
214
+ * receives it — may be hardened somewhere this check cannot see, so it keeps
215
+ * the previous file-level silence.
216
+ *
217
+ * A TransformerFactory additionally needs a `StreamSource` in its method: that
218
+ * is the input the transformer parses with its OWN parser. Fed a `DOMSource`
219
+ * it parses nothing, and fed a `SAXSource` it uses the reader it was given —
220
+ * whose hardening is that reader's business, not this factory's.
221
+ */
222
+ isProvablyUnhardened(lines, line, methodRanges, api) {
223
+ // Innermost enclosing method; without one the factory's reach is unknown.
224
+ let range = null;
225
+ for (const r of methodRanges) {
226
+ if (line < r[0] || line > r[1])
227
+ continue;
228
+ if (!range || r[1] - r[0] < range[1] - range[0])
229
+ range = r;
230
+ }
231
+ if (!range)
232
+ return false;
233
+ // The creating statement, joined to its `;` — `newInstance(` is often broken
234
+ // across lines after the opening parenthesis.
235
+ let decl = '';
236
+ let declEnd = line;
237
+ for (; declEnd <= Math.min(line + 3, range[1]); declEnd++) {
238
+ decl += ' ' + (lines[declEnd - 1] ?? '').trim();
239
+ if (decl.includes(';'))
240
+ break;
241
+ }
242
+ const body = lines.slice(line - 1, range[1]).join('\n');
243
+ if (api === 'TransformerFactory' && !/\bnew\s+StreamSource\s*\(/.test(body))
244
+ return false;
245
+ // Hardening need not land on the factory: `parser.getXMLReader().setFeature(…)`
246
+ // and `parser.setProperty(…)` harden its PRODUCT. So a method containing any
247
+ // hardening-capable setter, on any receiver, is not provable either way.
248
+ if (JAVA_HARDENING_SETTER_RE.test(body))
249
+ return false;
250
+ const chained = JAVA_FACTORY_CHAINED_RE.exec(decl);
251
+ if (chained) {
252
+ // The product may still be handed to a helper that hardens it.
253
+ const prod = /[\w>\]]\s+([A-Za-z_$][\w$]*)\s*=/.exec(decl);
254
+ if (!prod)
255
+ return true;
256
+ const pn = prod[1].replace(/\$/g, '\\$');
257
+ const after = lines.slice(declEnd, range[1]).join('\n');
258
+ return !new RegExp(`[(,]\\s*${pn}\\s*[,)]|\\breturn\\s+${pn}\\s*;`).test(after);
259
+ }
260
+ // `Type name = …newInstance(…);` — a declaration ending the statement, so
261
+ // `name` is a local bound to the factory itself and not to a chained result.
262
+ const m = /[\w>\]]\s+([A-Za-z_$][\w$]*)\s*=\s*[\w.]*\bnewInstance\s*\([^()]*\)\s*;/.exec(decl);
263
+ if (!m)
264
+ return false;
265
+ const name = m[1].replace(/\$/g, '\\$');
266
+ const rest = lines.slice(declEnd, range[1]).join('\n');
267
+ // Only a factory that goes on to build a parser matters; one created to
268
+ // inspect (`factory.getClass()`) and dropped parses nothing.
269
+ const builds = new RegExp(`\\b${name}\\s*\\.\\s*(?:newDocumentBuilder|newSAXParser|newTransformer|newTemplates|newSchema|createXMLStreamReader|createXMLEventReader)\\s*\\(`);
270
+ if (!builds.test(rest))
271
+ return false;
272
+ // Passed to another call (`harden(dbf)`, `x.configure(a, dbf)`) or returned.
273
+ const escapes = new RegExp(`[(,]\\s*${name}\\s*[,)]|\\breturn\\s+${name}\\s*;`);
274
+ if (escapes.test(rest))
275
+ return false;
276
+ return true;
277
+ }
152
278
  detectJavaCall(call) {
153
279
  if (call.method_name !== 'newInstance')
154
280
  return null;
@@ -160,7 +286,7 @@ export class XmlEntityExpansionPass {
160
286
  return {
161
287
  pattern: `${factory}.newInstance()`,
162
288
  api: factory,
163
- cwe: 'CWE-776',
289
+ cwe: 'CWE-611',
164
290
  };
165
291
  }
166
292
  }
@@ -175,7 +301,7 @@ export class XmlEntityExpansionPass {
175
301
  return {
176
302
  pattern: `etree.${method}`,
177
303
  api: `lxml.etree.${method}`,
178
- cwe: 'CWE-776',
304
+ cwe: 'CWE-611',
179
305
  };
180
306
  }
181
307
  // xml.etree.ElementTree.parse / fromstring
@@ -1 +1 @@
1
- {"version":3,"file":"xml-entity-expansion-pass.js","sourceRoot":"","sources":["../../../src/analysis/passes/xml-entity-expansion-pass.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"xml-entity-expansion-pass.js","sourceRoot":"","sources":["../../../src/analysis/passes/xml-entity-expansion-pass.ts"],"names":[],"mappings":"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"}
@@ -26446,16 +26446,21 @@ var CSharpPlugin = class extends BaseLanguagePlugin {
26446
26446
  };
26447
26447
 
26448
26448
  // src/languages/plugins/index.ts
26449
+ function createBuiltinPlugins() {
26450
+ return [
26451
+ new JavaPlugin(),
26452
+ new JavaScriptPlugin(),
26453
+ new PythonPlugin(),
26454
+ new RustPlugin(),
26455
+ new BashPlugin(),
26456
+ new HtmlPlugin(),
26457
+ new VuePlugin(),
26458
+ new GoPlugin(),
26459
+ new CSharpPlugin()
26460
+ ];
26461
+ }
26449
26462
  function registerBuiltinPlugins() {
26450
- registerLanguage(new JavaPlugin());
26451
- registerLanguage(new JavaScriptPlugin());
26452
- registerLanguage(new PythonPlugin());
26453
- registerLanguage(new RustPlugin());
26454
- registerLanguage(new BashPlugin());
26455
- registerLanguage(new HtmlPlugin());
26456
- registerLanguage(new VuePlugin());
26457
- registerLanguage(new GoPlugin());
26458
- registerLanguage(new CSharpPlugin());
26463
+ for (const plugin of createBuiltinPlugins()) registerLanguage(plugin);
26459
26464
  }
26460
26465
 
26461
26466
  // src/analysis/html/html-extractor.ts
@@ -46241,6 +46246,8 @@ var JAVA_XML_OUTPUT_ONLY_RE = /\bnew\s+(?:DOMSource|StreamResult)\s*\(/;
46241
46246
  var JAVA_XML_PARSE_INPUT_RE = /\bnew\s+(?:StreamSource|SAXSource|InputSource)\s*\(/;
46242
46247
  var JAVA_DOC_BUILDER_NEW_DOCUMENT_RE = /\.\s*newDocument\s*\(\s*\)/;
46243
46248
  var JAVA_DOC_BUILDER_PARSE_RE = /(?:DocumentBuilder|builder)\s*\.\s*parse\s*\(/;
46249
+ var JAVA_HARDENING_SETTER_RE = /\.\s*(?:setFeature|setAttribute|setProperty|setXIncludeAware|setExpandEntityReferences)\s*\(/;
46250
+ var JAVA_FACTORY_CHAINED_RE = /\bnewInstance\s*\([^()]*\)\s*\.\s*(?:newDocumentBuilder|newSAXParser|newTransformer|newTemplates|newSchema|createXMLStreamReader|createXMLEventReader)\s*\(/;
46244
46251
  var PY_LXML_PARSER_INSECURE_DEFAULT_RE = /\bresolve_entities\s*=\s*False\b/;
46245
46252
  var XmlEntityExpansionPass = class {
46246
46253
  name = "xml-entity-expansion";
@@ -46252,7 +46259,9 @@ var XmlEntityExpansionPass = class {
46252
46259
  const code = ctx.code ?? "";
46253
46260
  if (language === "java") {
46254
46261
  const safeInFile = JAVA_SAFE_EVIDENCE_RE.test(code);
46255
- if (safeInFile) return { findings };
46262
+ const processWide = safeInFile && /jdk\.xml\./.test(code);
46263
+ const lines = safeInFile ? code.split("\n") : [];
46264
+ const methodRanges = safeInFile ? this.methodRanges(graph.ir.types) : [];
46256
46265
  const isXmlOutputOnly = JAVA_XML_OUTPUT_ONLY_RE.test(code) && !JAVA_XML_PARSE_INPUT_RE.test(code);
46257
46266
  const isDocumentBuilderEmptyOnly = JAVA_DOC_BUILDER_NEW_DOCUMENT_RE.test(code) && !JAVA_DOC_BUILDER_PARSE_RE.test(code);
46258
46267
  for (const call of graph.ir.calls) {
@@ -46262,6 +46271,8 @@ var XmlEntityExpansionPass = class {
46262
46271
  if (det.api === "DocumentBuilderFactory" && isDocumentBuilderEmptyOnly)
46263
46272
  continue;
46264
46273
  const line = call.location.line;
46274
+ if (safeInFile && (processWide || !this.isProvablyUnhardened(lines, line, methodRanges, det.api)))
46275
+ continue;
46265
46276
  findings.push({ line, language, ...det });
46266
46277
  ctx.addFinding({
46267
46278
  id: `${this.name}-${file}-${line}-${det.api}`,
@@ -46271,11 +46282,11 @@ var XmlEntityExpansionPass = class {
46271
46282
  cwe: det.cwe,
46272
46283
  severity: "high",
46273
46284
  level: "error",
46274
- message: `${det.api} created without disabling DTD / external-entity processing. Vulnerable to billion-laughs / quadratic blow-up DoS (CWE-776) and external-entity disclosure (CWE-611). Add \`setFeature("http://apache.org/xml/features/disallow-doctype-decl", true)\` (or the equivalent) before parsing.`,
46285
+ message: `${det.api} created without disabling DTD / external-entity processing. Vulnerable to external-entity disclosure (CWE-611) and billion-laughs / quadratic blow-up DoS (CWE-776). Add \`setFeature("http://apache.org/xml/features/disallow-doctype-decl", true)\` (or the equivalent) before parsing.`,
46275
46286
  file,
46276
46287
  line,
46277
46288
  fix: this.fixForJava(det.api),
46278
- evidence: { ...det, language, safeFeatureInFile: false }
46289
+ evidence: { ...det, language, safeFeatureInFile: safeInFile }
46279
46290
  });
46280
46291
  }
46281
46292
  return { findings };
@@ -46296,7 +46307,7 @@ var XmlEntityExpansionPass = class {
46296
46307
  cwe: det.cwe,
46297
46308
  severity: "high",
46298
46309
  level: "error",
46299
- message: `${det.api} called without an entity-safe parser. Vulnerable to billion-laughs / quadratic blow-up DoS (CWE-776) and external-entity disclosure (CWE-611). Use \`defusedxml\` or pass an \`XMLParser(resolve_entities=False)\` to lxml.`,
46310
+ message: `${det.api} called without an entity-safe parser. Vulnerable ` + (det.cwe === "CWE-611" ? "to external-entity disclosure (CWE-611) and billion-laughs / quadratic blow-up DoS (CWE-776). " : "to billion-laughs / quadratic blow-up DoS (CWE-776). ") + "Use `defusedxml` or pass an `XMLParser(resolve_entities=False)` to lxml.",
46300
46311
  file,
46301
46312
  line,
46302
46313
  fix: this.fixForPython(det.api),
@@ -46307,6 +46318,78 @@ var XmlEntityExpansionPass = class {
46307
46318
  }
46308
46319
  return { findings };
46309
46320
  }
46321
+ methodRanges(types) {
46322
+ const out2 = [];
46323
+ for (const t of types ?? []) {
46324
+ for (const m of t.methods ?? []) {
46325
+ if (typeof m.start_line === "number" && typeof m.end_line === "number")
46326
+ out2.push([m.start_line, m.end_line]);
46327
+ }
46328
+ }
46329
+ return out2;
46330
+ }
46331
+ /**
46332
+ * In a file that DOES contain hardening evidence, is the factory created on
46333
+ * `line` one that provably never receives it?
46334
+ *
46335
+ * Deliberately one-sided. It answers true for exactly two shapes:
46336
+ *
46337
+ * 1. CHAINED — `Factory.newInstance().newDocumentBuilder()`, where the
46338
+ * product is not handed on or returned either.
46339
+ * 2. LOCAL — `Factory f = Factory.newInstance();` where the enclosing method
46340
+ * builds a parser from `f`, never hands `f` to another call, and never
46341
+ * returns it.
46342
+ *
46343
+ * and in both only when the enclosing method contains NO hardening-capable
46344
+ * setter on ANY receiver, since hardening may land on the factory's product
46345
+ * (`parser.getXMLReader().setFeature(…)`) rather than the factory.
46346
+ *
46347
+ * Every other shape — a field, a helper that takes the factory, a caller that
46348
+ * receives it — may be hardened somewhere this check cannot see, so it keeps
46349
+ * the previous file-level silence.
46350
+ *
46351
+ * A TransformerFactory additionally needs a `StreamSource` in its method: that
46352
+ * is the input the transformer parses with its OWN parser. Fed a `DOMSource`
46353
+ * it parses nothing, and fed a `SAXSource` it uses the reader it was given —
46354
+ * whose hardening is that reader's business, not this factory's.
46355
+ */
46356
+ isProvablyUnhardened(lines, line, methodRanges, api) {
46357
+ let range = null;
46358
+ for (const r of methodRanges) {
46359
+ if (line < r[0] || line > r[1]) continue;
46360
+ if (!range || r[1] - r[0] < range[1] - range[0]) range = r;
46361
+ }
46362
+ if (!range) return false;
46363
+ let decl = "";
46364
+ let declEnd = line;
46365
+ for (; declEnd <= Math.min(line + 3, range[1]); declEnd++) {
46366
+ decl += " " + (lines[declEnd - 1] ?? "").trim();
46367
+ if (decl.includes(";")) break;
46368
+ }
46369
+ const body2 = lines.slice(line - 1, range[1]).join("\n");
46370
+ if (api === "TransformerFactory" && !/\bnew\s+StreamSource\s*\(/.test(body2))
46371
+ return false;
46372
+ if (JAVA_HARDENING_SETTER_RE.test(body2)) return false;
46373
+ const chained = JAVA_FACTORY_CHAINED_RE.exec(decl);
46374
+ if (chained) {
46375
+ const prod = /[\w>\]]\s+([A-Za-z_$][\w$]*)\s*=/.exec(decl);
46376
+ if (!prod) return true;
46377
+ const pn = prod[1].replace(/\$/g, "\\$");
46378
+ const after = lines.slice(declEnd, range[1]).join("\n");
46379
+ return !new RegExp(`[(,]\\s*${pn}\\s*[,)]|\\breturn\\s+${pn}\\s*;`).test(after);
46380
+ }
46381
+ const m = /[\w>\]]\s+([A-Za-z_$][\w$]*)\s*=\s*[\w.]*\bnewInstance\s*\([^()]*\)\s*;/.exec(decl);
46382
+ if (!m) return false;
46383
+ const name2 = m[1].replace(/\$/g, "\\$");
46384
+ const rest = lines.slice(declEnd, range[1]).join("\n");
46385
+ const builds = new RegExp(
46386
+ `\\b${name2}\\s*\\.\\s*(?:newDocumentBuilder|newSAXParser|newTransformer|newTemplates|newSchema|createXMLStreamReader|createXMLEventReader)\\s*\\(`
46387
+ );
46388
+ if (!builds.test(rest)) return false;
46389
+ const escapes = new RegExp(`[(,]\\s*${name2}\\s*[,)]|\\breturn\\s+${name2}\\s*;`);
46390
+ if (escapes.test(rest)) return false;
46391
+ return true;
46392
+ }
46310
46393
  detectJavaCall(call) {
46311
46394
  if (call.method_name !== "newInstance") return null;
46312
46395
  const recv = call.receiver ?? "";
@@ -46316,7 +46399,7 @@ var XmlEntityExpansionPass = class {
46316
46399
  return {
46317
46400
  pattern: `${factory}.newInstance()`,
46318
46401
  api: factory,
46319
- cwe: "CWE-776"
46402
+ cwe: "CWE-611"
46320
46403
  };
46321
46404
  }
46322
46405
  }
@@ -46329,7 +46412,7 @@ var XmlEntityExpansionPass = class {
46329
46412
  return {
46330
46413
  pattern: `etree.${method}`,
46331
46414
  api: `lxml.etree.${method}`,
46332
- cwe: "CWE-776"
46415
+ cwe: "CWE-611"
46333
46416
  };
46334
46417
  }
46335
46418
  if ((method === "parse" || method === "fromstring") && (recv === "ET" || recv === "ElementTree" || recv.endsWith(".ElementTree"))) {
package/dist/index.d.ts CHANGED
@@ -12,6 +12,7 @@ export type { UnboundedCollectionOptions } from './analysis/passes/unbounded-col
12
12
  export type { PassOptions } from './analyzer.js';
13
13
  export type { CircleIR, Meta, TypeInfo, MethodInfo, ParameterInfo, FieldInfo, CallInfo, ArgumentInfo, CallResolution, CFG, CFGBlock, CFGEdge, DFG, DFGDef, DFGUse, DFGChain, Taint, TaintSource, TaintSink, TaintSanitizer, ImportInfo, ExportInfo, UnresolvedItem, Enriched, EnrichedFunction, ResolvedCall, Finding, TaintHop, Vulnerability, AnalysisResponse, SourceType, SinkType, Severity, ProjectShape, ProjectEnv, ProjectProfile, ProjectProfileSummary, PassCategory, SarifLevel, SastFinding, MetricCategory, MetricValue, FileMetrics, ProjectAnalysis, ProjectMeta, FileAnalysis, TypeHierarchy, ClassHierarchyInfo, InterfaceHierarchyInfo, CrossFileCall, ArgMapping, TaintPath, } from './types/index.js';
14
14
  export { SOURCE_TYPES, SINK_TYPES } from './types/index.js';
15
+ export { getModelledCwes, isModelledCwe, RELATED_CWE, type ModelledCwes, } from './analysis/modelled-cwes.js';
15
16
  export type { SourceConfig, SinkConfig, TaintConfig, SourcePattern, SinkPattern, SanitizerPattern, } from './types/config.js';
16
17
  export { initParser, parse, walkTree, findNodes, findAncestor, getNodeText, collectAllNodes, type SupportedLanguage, type SyntaxNode, type Node, type NodeCache, type Tree, } from './core/index.js';
17
18
  export { extractMeta, extractTypes, extractCalls, extractImports, extractExports, buildCFG, buildDFG, } from './core/index.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -16,6 +16,9 @@ export { parseNpmDependencies, parseNpmLockDependencies, parsePypiDependencies,
16
16
  // an unmatched value fails a test on their side rather than falling through
17
17
  // to a default branch. Locked by tests/public-entry-exports.test.ts.
18
18
  export { SOURCE_TYPES, SINK_TYPES } from './types/index.js';
19
+ // Modelled-CWE export (#393) — which weakness classes the taint engine covers,
20
+ // derived from the live sink registries.
21
+ export { getModelledCwes, isModelledCwe, RELATED_CWE, } from './analysis/modelled-cwes.js';
19
22
  // Core utilities (for advanced usage)
20
23
  export { initParser, parse, walkTree, findNodes, findAncestor, getNodeText, collectAllNodes, } from './core/index.js';
21
24
  // Core extractors
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,gBAAgB;AAChB,OAAO,EACL,YAAY,EACZ,OAAO,EACP,aAAa,EACb,cAAc,EACd,qBAAqB,EACrB,aAAa,GAEd,MAAM,eAAe,CAAC;AAEvB,4EAA4E;AAC5E,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,0BAA0B,EAC1B,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EACtB,0BAA0B,EAC1B,2BAA2B,EAC3B,mBAAmB,EACnB,mBAAmB,EACnB,WAAW,EACX,MAAM,GACP,MAAM,oBAAoB,CAAC;AA+E5B,sEAAsE;AACtE,6EAA6E;AAC7E,2EAA2E;AAC3E,6EAA6E;AAC7E,8EAA8E;AAC9E,8EAA8E;AAC9E,4EAA4E;AAC5E,qEAAqE;AACrE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAY5D,sCAAsC;AACtC,OAAO,EACL,UAAU,EACV,KAAK,EACL,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,WAAW,EACX,eAAe,GAMhB,MAAM,iBAAiB,CAAC;AAEzB,kBAAkB;AAClB,OAAO,EACL,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,cAAc,EACd,QAAQ,EACR,QAAQ,GACT,MAAM,iBAAiB,CAAC;AAEzB,qBAAqB;AACrB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACZ,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,yBAAyB,EACzB,0BAA0B,EAC1B,gCAAgC,EAChC,0BAA0B,EAC1B,kBAAkB,EAClB,OAAO,EACP,aAAa,EACb,WAAW,EACX,eAAe,EACf,aAAa,EACb,kBAAkB,GAMnB,MAAM,qBAAqB,CAAC;AAE7B,mBAAmB;AACnB,OAAO,EACL,WAAW,EACX,gBAAgB,GAEjB,MAAM,qBAAqB,CAAC;AAE7B,kBAAkB;AAClB,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAqB,MAAM,iCAAiC,CAAC;AAExF,uBAAuB;AACvB,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAE/B,mBAAmB;AACnB,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,mBAAmB,EACnB,sBAAsB,EACtB,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,UAAU,EACV,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAY9B,gCAAgC;AAChC,OAAO,EACL,MAAM,EACN,SAAS,EACT,eAAe,EACf,WAAW,EACX,WAAW,GAIZ,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,gBAAgB;AAChB,OAAO,EACL,YAAY,EACZ,OAAO,EACP,aAAa,EACb,cAAc,EACd,qBAAqB,EACrB,aAAa,GAEd,MAAM,eAAe,CAAC;AAEvB,4EAA4E;AAC5E,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,0BAA0B,EAC1B,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EACtB,0BAA0B,EAC1B,2BAA2B,EAC3B,mBAAmB,EACnB,mBAAmB,EACnB,WAAW,EACX,MAAM,GACP,MAAM,oBAAoB,CAAC;AA+E5B,sEAAsE;AACtE,6EAA6E;AAC7E,2EAA2E;AAC3E,6EAA6E;AAC7E,8EAA8E;AAC9E,8EAA8E;AAC9E,4EAA4E;AAC5E,qEAAqE;AACrE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE5D,+EAA+E;AAC/E,yCAAyC;AACzC,OAAO,EACL,eAAe,EACf,aAAa,EACb,WAAW,GAEZ,MAAM,6BAA6B,CAAC;AAYrC,sCAAsC;AACtC,OAAO,EACL,UAAU,EACV,KAAK,EACL,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,WAAW,EACX,eAAe,GAMhB,MAAM,iBAAiB,CAAC;AAEzB,kBAAkB;AAClB,OAAO,EACL,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,cAAc,EACd,QAAQ,EACR,QAAQ,GACT,MAAM,iBAAiB,CAAC;AAEzB,qBAAqB;AACrB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACZ,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,yBAAyB,EACzB,0BAA0B,EAC1B,gCAAgC,EAChC,0BAA0B,EAC1B,kBAAkB,EAClB,OAAO,EACP,aAAa,EACb,WAAW,EACX,eAAe,EACf,aAAa,EACb,kBAAkB,GAMnB,MAAM,qBAAqB,CAAC;AAE7B,mBAAmB;AACnB,OAAO,EACL,WAAW,EACX,gBAAgB,GAEjB,MAAM,qBAAqB,CAAC;AAE7B,kBAAkB;AAClB,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAqB,MAAM,iCAAiC,CAAC;AAExF,uBAAuB;AACvB,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAE/B,mBAAmB;AACnB,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,mBAAmB,EACnB,sBAAsB,EACtB,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,UAAU,EACV,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAY9B,gCAAgC;AAChC,OAAO,EACL,MAAM,EACN,SAAS,EACT,eAAe,EACf,WAAW,EACX,WAAW,GAIZ,MAAM,mBAAmB,CAAC"}
@@ -12,6 +12,14 @@ export { HtmlPlugin } from './html.js';
12
12
  export { VuePlugin } from './vue.js';
13
13
  export { GoPlugin } from './go.js';
14
14
  export { CSharpPlugin } from './csharp.js';
15
+ import type { LanguagePlugin } from '../types.js';
16
+ /**
17
+ * Fresh instances of every built-in language plugin, unregistered. The single
18
+ * list both `registerBuiltinPlugins` and registry-wide enumerations (e.g. the
19
+ * modelled-CWE export) read, so a new plugin cannot be added to one and missed
20
+ * by the other.
21
+ */
22
+ export declare function createBuiltinPlugins(): LanguagePlugin[];
15
23
  /**
16
24
  * Register all built-in language plugins with the global registry.
17
25
  * Call this during analyzer initialization.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/languages/plugins/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAa3C;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAU7C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/languages/plugins/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAWlD;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,cAAc,EAAE,CAYvD;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C"}
@@ -22,19 +22,31 @@ import { HtmlPlugin } from './html.js';
22
22
  import { VuePlugin } from './vue.js';
23
23
  import { GoPlugin } from './go.js';
24
24
  import { CSharpPlugin } from './csharp.js';
25
+ /**
26
+ * Fresh instances of every built-in language plugin, unregistered. The single
27
+ * list both `registerBuiltinPlugins` and registry-wide enumerations (e.g. the
28
+ * modelled-CWE export) read, so a new plugin cannot be added to one and missed
29
+ * by the other.
30
+ */
31
+ export function createBuiltinPlugins() {
32
+ return [
33
+ new JavaPlugin(),
34
+ new JavaScriptPlugin(),
35
+ new PythonPlugin(),
36
+ new RustPlugin(),
37
+ new BashPlugin(),
38
+ new HtmlPlugin(),
39
+ new VuePlugin(),
40
+ new GoPlugin(),
41
+ new CSharpPlugin(),
42
+ ];
43
+ }
25
44
  /**
26
45
  * Register all built-in language plugins with the global registry.
27
46
  * Call this during analyzer initialization.
28
47
  */
29
48
  export function registerBuiltinPlugins() {
30
- registerLanguage(new JavaPlugin());
31
- registerLanguage(new JavaScriptPlugin());
32
- registerLanguage(new PythonPlugin());
33
- registerLanguage(new RustPlugin());
34
- registerLanguage(new BashPlugin());
35
- registerLanguage(new HtmlPlugin());
36
- registerLanguage(new VuePlugin());
37
- registerLanguage(new GoPlugin());
38
- registerLanguage(new CSharpPlugin());
49
+ for (const plugin of createBuiltinPlugins())
50
+ registerLanguage(plugin);
39
51
  }
40
52
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/languages/plugins/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C;;;GAGG;AACH,MAAM,UAAU,sBAAsB;IACpC,gBAAgB,CAAC,IAAI,UAAU,EAAE,CAAC,CAAC;IACnC,gBAAgB,CAAC,IAAI,gBAAgB,EAAE,CAAC,CAAC;IACzC,gBAAgB,CAAC,IAAI,YAAY,EAAE,CAAC,CAAC;IACrC,gBAAgB,CAAC,IAAI,UAAU,EAAE,CAAC,CAAC;IACnC,gBAAgB,CAAC,IAAI,UAAU,EAAE,CAAC,CAAC;IACnC,gBAAgB,CAAC,IAAI,UAAU,EAAE,CAAC,CAAC;IACnC,gBAAgB,CAAC,IAAI,SAAS,EAAE,CAAC,CAAC;IAClC,gBAAgB,CAAC,IAAI,QAAQ,EAAE,CAAC,CAAC;IACjC,gBAAgB,CAAC,IAAI,YAAY,EAAE,CAAC,CAAC;AACvC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/languages/plugins/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO;QACL,IAAI,UAAU,EAAE;QAChB,IAAI,gBAAgB,EAAE;QACtB,IAAI,YAAY,EAAE;QAClB,IAAI,UAAU,EAAE;QAChB,IAAI,UAAU,EAAE;QAChB,IAAI,UAAU,EAAE;QAChB,IAAI,SAAS,EAAE;QACf,IAAI,QAAQ,EAAE;QACd,IAAI,YAAY,EAAE;KACnB,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB;IACpC,KAAK,MAAM,MAAM,IAAI,oBAAoB,EAAE;QAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;AACxE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "circle-ir",
3
- "version": "4.9.21",
3
+ "version": "4.9.22",
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",