seaworthycode 1.1.2 → 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.
Files changed (68) hide show
  1. package/dist/index.js +30 -26
  2. package/dist/index.js.map +1 -1
  3. package/package.json +14 -12
  4. package/rules/external/configuration/insecure-cookie-flags.test.yaml +114 -0
  5. package/rules/external/configuration/insecure-cookie-flags.yaml +77 -0
  6. package/rules/external/configuration/missing-ssl-verification.test.yaml +130 -0
  7. package/rules/external/configuration/missing-ssl-verification.yaml +123 -0
  8. package/rules/external/data-exposure/debug-artifacts.test.yaml +143 -0
  9. package/rules/external/data-exposure/debug-artifacts.yaml +57 -0
  10. package/rules/external/data-exposure/hardcoded-ip.test.yaml +131 -0
  11. package/rules/external/data-exposure/hardcoded-ip.yaml +67 -0
  12. package/rules/external/data-exposure/localstorage-sensitive-data.test.yaml +58 -0
  13. package/rules/external/data-exposure/localstorage-sensitive-data.yaml +60 -0
  14. package/rules/external/dependencies/deprecated-functions.test.yaml +92 -0
  15. package/rules/external/dependencies/deprecated-functions.yaml +66 -0
  16. package/rules/external/ops/hardcoded-port.test.yaml +141 -0
  17. package/rules/external/ops/hardcoded-port.yaml +91 -0
  18. package/rules/external/ops/insecure-file-permissions.test.yaml +111 -0
  19. package/rules/external/ops/insecure-file-permissions.yaml +91 -0
  20. package/rules/external/resilience/missing-memory-limit.test.yaml +54 -0
  21. package/rules/external/resilience/missing-memory-limit.yaml +59 -0
  22. package/rules/external/resilience/missing-timeout-config.test.yaml +179 -0
  23. package/rules/external/resilience/missing-timeout-config.yaml +124 -0
  24. package/rules/external/security/broken-crypto-algorithm.test.yaml +104 -0
  25. package/rules/external/security/broken-crypto-algorithm.yaml +79 -0
  26. package/rules/external/security/http-method-override.test.yaml +40 -0
  27. package/rules/external/security/http-method-override.yaml +35 -0
  28. package/rules/external/security/http-no-tls.test.yaml +115 -0
  29. package/rules/external/security/http-no-tls.yaml +59 -0
  30. package/rules/external/security/path-traversal.test.yaml +188 -0
  31. package/rules/external/security/path-traversal.yaml +210 -0
  32. package/rules/external/security/unsafe-innerhtml.test.yaml +72 -0
  33. package/rules/external/security/unsafe-innerhtml.yaml +46 -0
  34. package/rules/external/security/untrusted-deserialization.test.yaml +79 -0
  35. package/rules/external/security/untrusted-deserialization.yaml +48 -0
  36. package/rules/external/security/weak-encryption-mode.test.yaml +126 -0
  37. package/rules/external/security/weak-encryption-mode.yaml +104 -0
  38. package/rules/external/security/weak-hash-algorithm.test.yaml +121 -0
  39. package/rules/external/security/weak-hash-algorithm.yaml +87 -0
  40. package/rules/external/security/xxe-parsing.test.yaml +76 -0
  41. package/rules/external/security/xxe-parsing.yaml +63 -0
  42. package/rules/internal/security/dangerous-eval.test.yaml +126 -0
  43. package/rules/internal/security/dangerous-eval.yaml +134 -0
  44. package/rules/internal/security/no-document-write.test.yaml +33 -0
  45. package/rules/internal/security/no-document-write.yaml +40 -0
  46. package/rules/internal/taint/MATRIX.md +16 -0
  47. package/rules/internal/taint/bash.test.yaml +84 -0
  48. package/rules/internal/taint/bash.yaml +166 -0
  49. package/rules/internal/taint/dvwa.test.yaml +217 -0
  50. package/rules/internal/taint/go.test.yaml +207 -0
  51. package/rules/internal/taint/go.yaml +325 -0
  52. package/rules/internal/taint/java.test.yaml +158 -0
  53. package/rules/internal/taint/java.yaml +318 -0
  54. package/rules/internal/taint/javascript.test.yaml +374 -0
  55. package/rules/internal/taint/javascript.yaml +439 -0
  56. package/rules/internal/taint/php.test.yaml +134 -0
  57. package/rules/internal/taint/php.yaml +331 -0
  58. package/rules/internal/taint/python.test.yaml +427 -0
  59. package/rules/internal/taint/python.yaml +636 -0
  60. package/rules/internal/taint/ruby.test.yaml +148 -0
  61. package/rules/internal/taint/ruby.yaml +233 -0
  62. package/rules/internal/taint/rust.test.yaml +585 -0
  63. package/rules/internal/taint/rust.yaml +483 -0
  64. package/rules/internal/taint/tsx.test.yaml +140 -0
  65. package/rules/internal/taint/tsx.yaml +51 -0
  66. package/rules/internal/taint/typescript.test.yaml +393 -0
  67. package/rules/internal/taint/typescript.yaml +660 -0
  68. package/wasm/tree-sitter-sql.wasm +0 -0
package/dist/index.js CHANGED
@@ -515,7 +515,9 @@ function sortFindings(findings) {
515
515
  const fileA = a.file ?? "";
516
516
  const fileB = b.file ?? "";
517
517
  if (fileA !== fileB) return fileA.localeCompare(fileB);
518
- return (a.line ?? 0) - (b.line ?? 0);
518
+ const lineDiff = (a.line ?? 0) - (b.line ?? 0);
519
+ if (lineDiff !== 0) return lineDiff;
520
+ return a.checkId.localeCompare(b.checkId);
519
521
  });
520
522
  }
521
523
  function dedupeDegradedFindings(findings) {
@@ -1559,36 +1561,36 @@ var ScanRunner = class {
1559
1561
  astCache: /* @__PURE__ */ new Map()
1560
1562
  };
1561
1563
  const results = [];
1562
- const mutex = [];
1563
- const inFlight = /* @__PURE__ */ new Map();
1564
- const findingsPerCategory = /* @__PURE__ */ new Map();
1565
- for (const check2 of checks) {
1566
- inFlight.set(check2.category, (inFlight.get(check2.category) ?? 0) + 1);
1567
- }
1564
+ const checkResults = /* @__PURE__ */ new Map();
1568
1565
  await runWithConcurrency(
1569
1566
  checks,
1570
1567
  async (check2) => {
1571
1568
  try {
1572
1569
  const findings2 = await check2.run(ctx);
1573
- mutex.push(...findings2);
1574
- if (options.onCategoryComplete) {
1575
- findingsPerCategory.set(check2.category, (findingsPerCategory.get(check2.category) ?? 0) + findings2.length);
1576
- }
1570
+ checkResults.set(check2.id, findings2);
1577
1571
  } catch (err) {
1578
1572
  console.error(`Check "${check2.id}" failed: ${String(err)}`);
1579
- } finally {
1580
- if (options.onCategoryComplete) {
1581
- const remaining = (inFlight.get(check2.category) ?? 1) - 1;
1582
- inFlight.set(check2.category, remaining);
1583
- if (remaining === 0) {
1584
- options.onCategoryComplete(check2.category, findingsPerCategory.get(check2.category) ?? 0);
1585
- }
1586
- }
1587
1573
  }
1588
1574
  },
1589
1575
  concurrency
1590
1576
  );
1591
- results.push(...mutex);
1577
+ for (const check2 of checks) {
1578
+ results.push(...checkResults.get(check2.id) ?? []);
1579
+ }
1580
+ if (options.onCategoryComplete) {
1581
+ const findingsPerCategory = /* @__PURE__ */ new Map();
1582
+ for (const check2 of checks) {
1583
+ const count = (checkResults.get(check2.id) ?? []).length;
1584
+ findingsPerCategory.set(check2.category, (findingsPerCategory.get(check2.category) ?? 0) + count);
1585
+ }
1586
+ const seen = /* @__PURE__ */ new Set();
1587
+ for (const check2 of checks) {
1588
+ if (!seen.has(check2.category)) {
1589
+ seen.add(check2.category);
1590
+ options.onCategoryComplete(check2.category, findingsPerCategory.get(check2.category) ?? 0);
1591
+ }
1592
+ }
1593
+ }
1592
1594
  if (ctx.astCache) {
1593
1595
  for (const promise of ctx.astCache.values()) {
1594
1596
  try {
@@ -10234,7 +10236,7 @@ registry.register({
10234
10236
  });
10235
10237
  var CHECK_ID40 = "security.weak-email-validation";
10236
10238
  var REMEDIATION34 = getCopy("remediation.security.weak-email-validation");
10237
- var WEAK_EMAIL_REGEX_LINE = /\/\^[^\/]*@[^\/]*\\\.[^\/]{0,4}\$\/[gimsuy]*/g;
10239
+ var WEAK_EMAIL_REGEX_LINE = /\/\^[^/]*@[^/]*\\\.[^/]{0,4}\$\/[gimsuy]*/g;
10238
10240
  var LOOSE_REGEX_CLASS = /\[\^?\\?s@\]\+@\[\^?\\?s@\]\+\\\.\[\^?\\?s@\]\+/g;
10239
10241
  var EMAIL_CONTEXT = /email|e-?mail|validateEmail|isEmail|checkEmail|verifyEmail|deliverable/is;
10240
10242
  function lineAndColumn15(content, index) {
@@ -10290,7 +10292,7 @@ registry.register({
10290
10292
  var CHECK_ID41 = "security.idempotency-key-leak";
10291
10293
  var REMEDIATION35 = getCopy("remediation.security.idempotency-key-leak");
10292
10294
  var IDEMPOTENCY_CONTEXT = /idempotency[_-]?key|idempotency[_-]?token/i;
10293
- var TEMPLATE_LITERAL_INTERPOLATION = /\`[^`]*\$\{[^}]+\}[^`]*\`/g;
10295
+ var TEMPLATE_LITERAL_INTERPOLATION = new RegExp("`[^`]*\\$\\{[^}]+\\}[^`]*`", "g");
10294
10296
  var STRUCTURED_ID_PATTERN = /(?:lic(?:ense|ence)|sub(?:scription)?|order|cust(?:omer)?|user|tx|pay(?:ment)?|inv(?:oice)?)[-/]/i;
10295
10297
  function lineAndColumn16(content, index) {
10296
10298
  const prefix = content.slice(0, index);
@@ -15169,6 +15171,7 @@ var copy3 = {
15169
15171
  "cli.sarif.stdout_conflict": "Flags --sarif-stdout and --json cannot be used together. Use --output to send JSON to a file.",
15170
15172
  "cli.error.llmRequired": "LLM API key required for Pro checks. Set it with seaworthy config or the SEAWORTHY_LLM_API_KEY environment variable.",
15171
15173
  "cli.warn.llmSkipped": "Pro checks skipped: no LLM API key configured. Set it with seaworthy config or the SEAWORTHY_LLM_API_KEY environment variable to enable semantic analysis.",
15174
+ "cli.warn.licenseInvalid": "Your license key is invalid or has been revoked. Running in free tier.\nTo re-enter your key, run: npx seaworthycode setup",
15172
15175
  "cli.error.config.missingKey": "Missing config key. Usage: seaworthy config <set|get> <key>",
15173
15176
  "cli.error.config.missingValue": "Missing config value. Usage: seaworthy config set <key> <value>",
15174
15177
  "cli.error.config.unknownKey": "Unknown config key. Valid keys: licenseKey, llmProvider, llmApiKey, llmModel, llmApiUrl",
@@ -15600,6 +15603,7 @@ async function runCli(options) {
15600
15603
  const message = resolveErrorMessage(authResult.code);
15601
15604
  return { code: resolveExitCode(authResult.code), error: message };
15602
15605
  }
15606
+ console.error(getCopy2("cli.warn.licenseInvalid"));
15603
15607
  }
15604
15608
  const auth = authResult.ok ? authResult.value : { tier: "free", token: "", licensedTo: "free tier" };
15605
15609
  const allowedTiers = {
@@ -15764,6 +15768,10 @@ cli.help(() => {
15764
15768
  $ npx seaworthycode ./my-project --sarif report.sarif
15765
15769
  $ npx seaworthycode --provider kimi ./my-project`
15766
15770
  },
15771
+ {
15772
+ title: "Commands",
15773
+ body: ` npx seaworthycode setup Interactive setup for license key and LLM provider`
15774
+ },
15767
15775
  {
15768
15776
  title: "Options",
15769
15777
  body: ` --json Output JSON to stdout
@@ -15779,10 +15787,6 @@ cli.help(() => {
15779
15787
  --show-ids Show check IDs alongside names
15780
15788
  --debug Enable debug logging`
15781
15789
  },
15782
- {
15783
- title: "Commands",
15784
- body: ` seaworthy setup Interactive first-run setup`
15785
- },
15786
15790
  {
15787
15791
  title: "Configuration",
15788
15792
  body: ` ~/.seaworthy/config # license key, LLM provider, API key, model, url`