xploitscan 1.1.3 → 1.1.4

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/index.js CHANGED
@@ -43512,7 +43512,25 @@ var ALWAYS_IGNORE = [
43512
43512
  "*.map",
43513
43513
  "package-lock.json",
43514
43514
  "pnpm-lock.yaml",
43515
- "yarn.lock"
43515
+ "yarn.lock",
43516
+ // Intentionally-vulnerable test corpora. Security tools (XploitScan,
43517
+ // Semgrep, Bearer, Gitleaks, Snyk Code) all maintain directories of
43518
+ // known-bad code samples used to verify that rules fire. Scanning
43519
+ // them produces a flood of "critical" findings on the scanner's own
43520
+ // dogfood, drowning the signal from real product code. Skip by
43521
+ // default. Users who genuinely want to scan a fixture directory can
43522
+ // override via .xploitscanignore (the negation syntax `!test-
43523
+ // fixtures/` un-ignores it).
43524
+ //
43525
+ // We only match these as directory names anywhere in the tree, so a
43526
+ // project whose actual source happens to live under a path called
43527
+ // `fixtures-prod/` is unaffected.
43528
+ "test-fixtures",
43529
+ "test-fixtures/**",
43530
+ "__fixtures__",
43531
+ "__fixtures__/**",
43532
+ "vulnerable-samples",
43533
+ "vulnerable-samples/**"
43516
43534
  ];
43517
43535
  async function collectFiles(directory) {
43518
43536
  const ig = ignore.default();
@@ -45531,7 +45549,21 @@ For each finding, respond ONLY with a JSON array. No other text.
45531
45549
  Each element: {"index": <number>, "verdict": "real" or "fp", "reason": "<1 sentence>"}`;
45532
45550
  var MAX_FINDINGS_PER_BATCH = 15;
45533
45551
  var MAX_CONTEXT_LINES = 10;
45534
- var MAX_TOTAL_FINDINGS = 50;
45552
+ var DEFAULT_MAX_TOTAL_FINDINGS = 200;
45553
+ var MAX_TOTAL_FINDINGS = (() => {
45554
+ const raw = process.env.XPLOITSCAN_AI_FILTER_MAX;
45555
+ if (!raw) return DEFAULT_MAX_TOTAL_FINDINGS;
45556
+ const n = parseInt(raw, 10);
45557
+ if (!Number.isFinite(n) || n < 1) return DEFAULT_MAX_TOTAL_FINDINGS;
45558
+ return Math.min(n, 1e3);
45559
+ })();
45560
+ var SEVERITY_PRIORITY = {
45561
+ critical: 0,
45562
+ high: 1,
45563
+ medium: 2,
45564
+ low: 3,
45565
+ info: 4
45566
+ };
45535
45567
  function getExpandedContext(content, line, contextLines = MAX_CONTEXT_LINES) {
45536
45568
  const lines = content.split("\n");
45537
45569
  const start = Math.max(0, line - 1 - contextLines);
@@ -45579,8 +45611,13 @@ async function filterFalsePositives(findings, fileContents) {
45579
45611
  const empty = { findings, filteredFindings: [], aiReviewed: false, removedCount: 0, totalBefore: findings.length };
45580
45612
  if (!process.env.ANTHROPIC_API_KEY) return empty;
45581
45613
  if (findings.length === 0) return empty;
45582
- const toReview = findings.slice(0, MAX_TOTAL_FINDINGS);
45583
- const overflow = findings.slice(MAX_TOTAL_FINDINGS);
45614
+ const prioritized = [...findings].sort((a, b) => {
45615
+ const pa = SEVERITY_PRIORITY[(a.severity || "").toLowerCase()] ?? 5;
45616
+ const pb = SEVERITY_PRIORITY[(b.severity || "").toLowerCase()] ?? 5;
45617
+ return pa - pb;
45618
+ });
45619
+ const toReview = prioritized.slice(0, MAX_TOTAL_FINDINGS);
45620
+ const overflow = prioritized.slice(MAX_TOTAL_FINDINGS);
45584
45621
  const totalBefore = findings.length;
45585
45622
  const byFile = /* @__PURE__ */ new Map();
45586
45623
  for (const f of toReview) {
@@ -48182,7 +48219,7 @@ async function cursorInstallCommand(opts = {}) {
48182
48219
  var program = new Command();
48183
48220
  program.name("xploitscan").description(
48184
48221
  "AI security scanner for vibe-coded apps. Find vulnerabilities before attackers do."
48185
- ).version("1.1.3");
48222
+ ).version("1.1.4");
48186
48223
  program.command("scan").description("Scan a directory for security vulnerabilities").argument("[directory]", "Directory to scan", ".").option("--no-ai", "Skip AI-powered analysis").option(
48187
48224
  "-f, --format <format>",
48188
48225
  "Output format: terminal, json, sarif, splunk-hec, elastic-ecs, datadog-logs",