circle-ir 3.18.7 → 3.19.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.
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Loads YAML configs from configs/sources/ and configs/sinks/
5
5
  */
6
- import type { SourceConfig, SinkConfig, TaintConfig, SourcePattern, SinkPattern, SanitizerPattern } from '../types/config.js';
6
+ import type { SourceConfig, SinkConfig, TaintConfig, SourcePattern, SinkPattern, SanitizerPattern, HeaderRule } from '../types/config.js';
7
7
  /**
8
8
  * Parse YAML/JSON configuration content.
9
9
  * Uses JSON since the config files are actually JSON despite .yaml extension.
@@ -35,3 +35,13 @@ export declare const DEFAULT_SANITIZERS: SanitizerPattern[];
35
35
  * Get the default taint configuration.
36
36
  */
37
37
  export declare function getDefaultConfig(): TaintConfig;
38
+ /**
39
+ * Default rule table for HTTP response security headers. Each rule is
40
+ * evaluated against setHeader/addHeader calls and (for kind='missing')
41
+ * against the absence of any such call on handler files.
42
+ *
43
+ * Covers clickjacking (CWE-1021) and CORS misconfiguration (CWE-346 /
44
+ * CWE-942). Adding a new rule here is enough to surface a finding — no
45
+ * pass code changes required.
46
+ */
47
+ export declare const DEFAULT_HEADER_RULES: HeaderRule[];
@@ -919,6 +919,37 @@ export const DEFAULT_SINKS = [
919
919
  { method: 'processRequest', class: 'Broker', type: 'code_injection', cwe: 'CWE-94', severity: 'critical', arg_positions: [0] },
920
920
  // DolphinScheduler
921
921
  { method: 'execute', class: 'TaskExecuteThread', type: 'code_injection', cwe: 'CWE-94', severity: 'critical', arg_positions: [0] },
922
+ // Apache Commons JEXL (JEXL expression injection)
923
+ { method: 'createExpression', class: 'JexlEngine', type: 'code_injection', cwe: 'CWE-94', severity: 'critical', arg_positions: [0] },
924
+ { method: 'createScript', class: 'JexlEngine', type: 'code_injection', cwe: 'CWE-94', severity: 'critical', arg_positions: [0] },
925
+ { method: 'evaluate', class: 'JexlExpression', type: 'code_injection', cwe: 'CWE-94', severity: 'critical', arg_positions: [] },
926
+ { method: 'execute', class: 'JexlScript', type: 'code_injection', cwe: 'CWE-94', severity: 'critical', arg_positions: [] },
927
+ // Janino expression evaluator (Calcite/Flink/Drill)
928
+ { method: 'createFastEvaluator', class: 'ExpressionEvaluator', type: 'code_injection', cwe: 'CWE-94', severity: 'critical', arg_positions: [0] },
929
+ { method: 'cook', class: 'ExpressionEvaluator', type: 'code_injection', cwe: 'CWE-94', severity: 'critical', arg_positions: [0] },
930
+ { method: 'cook', class: 'ScriptEvaluator', type: 'code_injection', cwe: 'CWE-94', severity: 'critical', arg_positions: [0] },
931
+ { method: 'cook', class: 'ClassBodyEvaluator', type: 'code_injection', cwe: 'CWE-94', severity: 'critical', arg_positions: [0] },
932
+ { method: 'cook', class: 'SimpleCompiler', type: 'code_injection', cwe: 'CWE-94', severity: 'critical', arg_positions: [0] },
933
+ // Apache Camel Simple language (CVE-2018-8041 and similar)
934
+ { method: 'createExpression', class: 'SimpleLanguage', type: 'code_injection', cwe: 'CWE-94', severity: 'critical', arg_positions: [0] },
935
+ { method: 'createPredicate', class: 'SimpleLanguage', type: 'code_injection', cwe: 'CWE-94', severity: 'critical', arg_positions: [0] },
936
+ // Thymeleaf StandardExpression (CVE-2023-38286 and similar)
937
+ { method: 'parseExpression', class: 'StandardExpressionParser', type: 'code_injection', cwe: 'CWE-94', severity: 'critical', arg_positions: [1] },
938
+ { method: 'getValue', class: 'StandardExpression', type: 'code_injection', cwe: 'CWE-94', severity: 'critical', arg_positions: [] },
939
+ // FreeMarker direct template construction (CVE-2022-26336 and similar)
940
+ { method: 'Template', class: 'Template', type: 'code_injection', cwe: 'CWE-94', severity: 'critical', arg_positions: [1] }, // new Template(name, tainted)
941
+ { method: 'getTemplate', class: 'Configuration', type: 'code_injection', cwe: 'CWE-94', severity: 'high', arg_positions: [0] },
942
+ // Jinjava (Java Jinja template engine)
943
+ { method: 'render', class: 'Jinjava', type: 'code_injection', cwe: 'CWE-94', severity: 'high', arg_positions: [0] },
944
+ { method: 'renderForResult', class: 'Jinjava', type: 'code_injection', cwe: 'CWE-94', severity: 'high', arg_positions: [0] },
945
+ // Spring Cloud Function RoutingFunction (CVE-2022-22963)
946
+ { method: 'getRequestedBeanName', class: 'RoutingFunction', type: 'code_injection', cwe: 'CWE-94', severity: 'critical', arg_positions: [] },
947
+ // Kotlin reflection (RCE via reflective construction)
948
+ { method: 'createInstance', class: 'KClass', type: 'code_injection', cwe: 'CWE-94', severity: 'high', arg_positions: [] },
949
+ { method: 'callBy', class: 'KFunction', type: 'code_injection', cwe: 'CWE-94', severity: 'high', arg_positions: [0] },
950
+ // Struts 2 deep injection (CVE-2017-5638 and descendants)
951
+ { method: 'translateVariables', class: 'TextParseUtil', type: 'code_injection', cwe: 'CWE-94', severity: 'critical', arg_positions: [0] },
952
+ { method: 'evaluate', class: 'StrutsResultSupport', type: 'code_injection', cwe: 'CWE-94', severity: 'critical', arg_positions: [0] },
922
953
  // Deserialization (CWE-502)
923
954
  { method: 'readObject', type: 'deserialization', cwe: 'CWE-502', severity: 'critical', arg_positions: [] },
924
955
  { method: 'readUnshared', class: 'ObjectInputStream', type: 'deserialization', cwe: 'CWE-502', severity: 'critical', arg_positions: [] },
@@ -1440,12 +1471,24 @@ export const DEFAULT_SANITIZERS = [
1440
1471
  { method: 'encodeForHTML', removes: ['xss'] },
1441
1472
  { method: 'escapeXml', removes: ['xss'] },
1442
1473
  { method: 'htmlEscape', removes: ['xss'] },
1474
+ { method: 'escapeHtml4', removes: ['xss'] }, // Apache Commons StringEscapeUtils
1475
+ { method: 'escapeHtml3', removes: ['xss'] }, // Apache Commons StringEscapeUtils
1476
+ { method: 'htmlSpecialChars', removes: ['xss'] }, // PHP-style / common wrapper
1477
+ { method: 'forHtml', class: 'Encode', removes: ['xss'] }, // OWASP Java Encoder
1478
+ { method: 'forHtmlContent', class: 'Encode', removes: ['xss'] },
1479
+ { method: 'forHtmlAttribute', class: 'Encode', removes: ['xss'] },
1480
+ { method: 'forJavaScript', class: 'Encode', removes: ['xss'] },
1443
1481
  { method: 'encode_text', removes: ['xss'] }, // Rust html_escape crate
1444
1482
  { method: 'encode_safe', removes: ['xss'] }, // Rust html_escape crate
1445
1483
  { method: 'render', class: 'Template', removes: ['xss'] }, // Rust askama auto-escapes
1446
1484
  { method: 'encodeForJavaScript', removes: ['xss'] },
1447
1485
  { method: 'encodeForCSS', removes: ['xss'] },
1448
1486
  { method: 'encodeForURL', removes: ['xss', 'ssrf'] },
1487
+ // URL encoding wrapper aliases (common patterns in benchmarks and real-world code)
1488
+ { method: 'encodeURL', removes: ['xss', 'ssrf'] },
1489
+ { method: 'urlEncode', removes: ['xss', 'ssrf'] },
1490
+ { method: 'escapeUrl', removes: ['xss', 'ssrf'] },
1491
+ { method: 'escapeURL', removes: ['xss', 'ssrf'] },
1449
1492
  // Path Traversal
1450
1493
  { method: 'normalize', class: 'Path', removes: ['path_traversal'] },
1451
1494
  { method: 'getCanonicalPath', class: 'File', removes: ['path_traversal'] },
@@ -1580,4 +1623,103 @@ export function getDefaultConfig() {
1580
1623
  sanitizers: DEFAULT_SANITIZERS,
1581
1624
  };
1582
1625
  }
1626
+ // ============================================================================
1627
+ // Security Headers Rules (consumed by SecurityHeadersPass)
1628
+ // ============================================================================
1629
+ /**
1630
+ * Default rule table for HTTP response security headers. Each rule is
1631
+ * evaluated against setHeader/addHeader calls and (for kind='missing')
1632
+ * against the absence of any such call on handler files.
1633
+ *
1634
+ * Covers clickjacking (CWE-1021) and CORS misconfiguration (CWE-346 /
1635
+ * CWE-942). Adding a new rule here is enough to surface a finding — no
1636
+ * pass code changes required.
1637
+ */
1638
+ export const DEFAULT_HEADER_RULES = [
1639
+ // -------------------------------------------------------------------------
1640
+ // Clickjacking (CWE-1021)
1641
+ // -------------------------------------------------------------------------
1642
+ {
1643
+ rule_id: 'missing-x-frame-options',
1644
+ cwe: 'CWE-1021',
1645
+ level: 'warning',
1646
+ severity: 'medium',
1647
+ header: 'X-Frame-Options',
1648
+ kind: 'missing',
1649
+ requiresHandler: true,
1650
+ message: 'HTTP handler does not set X-Frame-Options — vulnerable to clickjacking',
1651
+ fix: "Set response.setHeader('X-Frame-Options', 'DENY') or use a CSP frame-ancestors directive",
1652
+ note: 'Defense against UI redress / clickjacking attacks',
1653
+ },
1654
+ {
1655
+ rule_id: 'x-frame-options-allow-from',
1656
+ cwe: 'CWE-1021',
1657
+ level: 'warning',
1658
+ severity: 'medium',
1659
+ header: 'X-Frame-Options',
1660
+ kind: 'weak-value',
1661
+ valuePattern: /^allow-from\b/i,
1662
+ message: 'X-Frame-Options: ALLOW-FROM is deprecated and unsupported by modern browsers',
1663
+ fix: "Use CSP frame-ancestors directive instead: Content-Security-Policy: frame-ancestors 'self'",
1664
+ },
1665
+ {
1666
+ rule_id: 'missing-csp-frame-ancestors',
1667
+ cwe: 'CWE-1021',
1668
+ level: 'note',
1669
+ severity: 'low',
1670
+ header: 'Content-Security-Policy',
1671
+ kind: 'missing',
1672
+ requiresHandler: true,
1673
+ message: 'HTTP handler does not set Content-Security-Policy — frame-ancestors unset',
1674
+ fix: "Set Content-Security-Policy: frame-ancestors 'self' for defense-in-depth clickjacking protection",
1675
+ note: 'Informational; paired with missing-x-frame-options',
1676
+ },
1677
+ // -------------------------------------------------------------------------
1678
+ // CORS Misconfiguration (CWE-346, CWE-942)
1679
+ // -------------------------------------------------------------------------
1680
+ {
1681
+ rule_id: 'cors-wildcard-origin',
1682
+ cwe: 'CWE-942',
1683
+ level: 'error',
1684
+ severity: 'high',
1685
+ header: 'Access-Control-Allow-Origin',
1686
+ kind: 'weak-value',
1687
+ valuePattern: /^\*$/,
1688
+ message: "Access-Control-Allow-Origin: '*' permits cross-origin requests from any site",
1689
+ fix: 'Restrict to a specific trusted origin or use an allowlist',
1690
+ },
1691
+ {
1692
+ rule_id: 'cors-null-origin',
1693
+ cwe: 'CWE-346',
1694
+ level: 'error',
1695
+ severity: 'high',
1696
+ header: 'Access-Control-Allow-Origin',
1697
+ kind: 'weak-value',
1698
+ valuePattern: /^null$/i,
1699
+ message: "Access-Control-Allow-Origin: 'null' is exploitable via sandboxed iframes and data: URIs",
1700
+ fix: 'Restrict to a specific trusted origin',
1701
+ },
1702
+ {
1703
+ rule_id: 'cors-http-origin',
1704
+ cwe: 'CWE-346',
1705
+ level: 'warning',
1706
+ severity: 'medium',
1707
+ header: 'Access-Control-Allow-Origin',
1708
+ kind: 'weak-value',
1709
+ valuePattern: /^http:\/\//i,
1710
+ message: 'Access-Control-Allow-Origin uses insecure http:// scheme',
1711
+ fix: 'Use https:// for the allowed origin',
1712
+ },
1713
+ {
1714
+ rule_id: 'cors-reflected-origin',
1715
+ cwe: 'CWE-346',
1716
+ level: 'error',
1717
+ severity: 'high',
1718
+ header: 'Access-Control-Allow-Origin',
1719
+ kind: 'unsafe-value',
1720
+ message: 'Access-Control-Allow-Origin set to a dynamic value — possible origin reflection',
1721
+ fix: 'Validate the Origin request header against an allowlist before echoing it back',
1722
+ note: 'Fires when the value is not a string literal (likely reflected from request)',
1723
+ },
1724
+ ];
1583
1725
  //# sourceMappingURL=config-loader.js.map