blitzstrike 2.4.87 → 2.4.88

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/CHANGELOG.md CHANGED
@@ -5,6 +5,16 @@ All notable changes to Blitz Strike are documented here.
5
5
  The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/).
7
7
 
8
+ ## [2.4.88] — 2026-09-17
9
+
10
+ ### Changed — XSS detector precision (local taint flow)
11
+
12
+ - `xss` no longer flags a DOM sink merely because a source exists somewhere in the
13
+ same file. It now builds a tainted-variable set via assignment flow (transitive,
14
+ ≤3 hops) and flags a sink only when its argument references a tainted variable or
15
+ is a direct source expression. Removes the "source + sink co-occurrence" false
16
+ positives (4 FPs on the 30-lab benchmark) with zero recall loss.
17
+
8
18
  ## [2.4.87] — 2026-09-17
9
19
 
10
20
  ### Fixed — web3 class naming consistency + jwt grounding
package/dist/index.js CHANGED
@@ -16937,11 +16937,34 @@ function detectCorsMisconfig(code, file, out) {
16937
16937
  function detectXss(code, file, out) {
16938
16938
  const clean = stripCommentsOnly(code);
16939
16939
  const ls = lines2(code);
16940
- const hasSource = /\b(?:req\.(?:query|params|body|cookies|headers)|request\.(?:get|args|form|json|values|headers|params)|location\.(?:hash|search|href)|window\.location|document\.(?:URL|referrer)|URLSearchParams|searchParams\.get|getElementById\([^)]*\)\.value|routeParams|queryParams|this\.props|params\s*[:=])/i.test(clean) || /\b(?:req\.(?:query|params|body)|request\.(?:get|args|json|values)|location\.(?:hash|search))\b/i.test(clean);
16941
- if (!hasSource)
16940
+ const isSourceExpr = (expr) => /\b(?:req\.(?:query|params|body|cookies|headers)|request\.(?:get|args|form|json|values|headers|params)|location\.(?:hash|search|href)|window\.location|document\.(?:URL|referrer)|URLSearchParams|searchParams\.get|getElementById\([^)]*\)\.value|routeParams|queryParams|this\.props)\b/i.test(expr);
16941
+ const tainted = new Set;
16942
+ const assignments = [];
16943
+ const assignRe = /\b(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*([^;\n]+)|(?<![\w$.])([A-Za-z_$][\w$]*)\s*=\s*([^;\n]+)/g;
16944
+ let m;
16945
+ while ((m = assignRe.exec(clean)) !== null) {
16946
+ const lhs = m[1] ?? m[3];
16947
+ const rhs = (m[2] ?? m[4] ?? "").trim();
16948
+ if (lhs)
16949
+ assignments.push({ lhs, rhs });
16950
+ }
16951
+ for (let hop = 0;hop < 3; hop++) {
16952
+ let changed = false;
16953
+ for (const a of assignments) {
16954
+ if (tainted.has(a.lhs))
16955
+ continue;
16956
+ const refsTainted = [...tainted].some((t) => new RegExp(`\\b${t}\\b`).test(a.rhs));
16957
+ if (isSourceExpr(a.rhs) || refsTainted) {
16958
+ tainted.add(a.lhs);
16959
+ changed = true;
16960
+ }
16961
+ }
16962
+ if (!changed)
16963
+ break;
16964
+ }
16965
+ if (tainted.size === 0)
16942
16966
  return;
16943
16967
  const sinkRe = /dangerouslySetInnerHTML|\.innerHTML\s*=|\.outerHTML\s*=|document\.write\s*\(|insertAdjacentHTML\s*\(|\.html\s*\(|eval\s*\(/g;
16944
- let m;
16945
16968
  const seen = new Set;
16946
16969
  while ((m = sinkRe.exec(clean)) !== null) {
16947
16970
  const ln = lineNo2(code, m.index);
@@ -16951,9 +16974,8 @@ function detectXss(code, file, out) {
16951
16974
  const rest = line.slice(line.indexOf(m[0]) + m[0].length);
16952
16975
  if (/^\s*["'`]/.test(rest))
16953
16976
  continue;
16954
- if (m[0] === "eval(" && /^\s*["'`]/.test(rest))
16955
- continue;
16956
- if (m[0] === "dangerouslySetInnerHTML" && !/__html\s*:\s*[^'"`]/.test(line))
16977
+ const refsTainted = [...tainted].some((t) => new RegExp(`\\b${t}\\b`).test(rest));
16978
+ if (!refsTainted && !isSourceExpr(rest))
16957
16979
  continue;
16958
16980
  seen.add(ln);
16959
16981
  out.push({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blitzstrike",
3
- "version": "2.4.87",
3
+ "version": "2.4.88",
4
4
  "description": "Blitz Strike — a universal MCP security-audit toolbelt. BLITZ sweeps the attack surface, EAGLE-EYE traces source-to-sink, STRIKE verifies live. 57 attack chains, 130-tool catalog, intelligence data layer. One server, every agent.",
5
5
  "type": "module",
6
6
  "bin": {