xploitscan-shared-rules 1.11.1 → 1.12.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.
package/dist/index.js CHANGED
@@ -1217,6 +1217,41 @@ var sqlInjection = {
1217
1217
  matches.push(m);
1218
1218
  }
1219
1219
  }
1220
+ if (/\.\s*(?:query|execute|raw|queryRawUnsafe|executeRawUnsafe|\$queryRawUnsafe|\$executeRawUnsafe)\s*\(/.test(content)) {
1221
+ const ctx = tryParse(content, filePath);
1222
+ if (ctx) {
1223
+ const { parsed, taint } = ctx;
1224
+ const SQL_SINKS = /* @__PURE__ */ new Set([
1225
+ "query",
1226
+ "execute",
1227
+ "raw",
1228
+ "queryRawUnsafe",
1229
+ "executeRawUnsafe",
1230
+ "$queryRawUnsafe",
1231
+ "$executeRawUnsafe"
1232
+ ]);
1233
+ visitCalls(
1234
+ parsed,
1235
+ (callee) => callee.type === "MemberExpression" && callee.property.type === "Identifier" && SQL_SINKS.has(callee.property.name),
1236
+ (call, line) => {
1237
+ const first = call.arguments[0];
1238
+ if (!first || first.type === "SpreadElement") return;
1239
+ if (first.type === "StringLiteral" || first.type === "TemplateLiteral") return;
1240
+ if (!taint.isTainted(first)) return;
1241
+ if (matches.some((m) => m.line === line)) return;
1242
+ matches.push(
1243
+ astMatch(
1244
+ content,
1245
+ filePath,
1246
+ line,
1247
+ sqlInjection,
1248
+ "Use parameterized queries instead of building SQL from user input in a variable. Example: db.query('SELECT * FROM users WHERE login = ?', [req.body.login])"
1249
+ )
1250
+ );
1251
+ }
1252
+ );
1253
+ }
1254
+ }
1220
1255
  return matches;
1221
1256
  }
1222
1257
  };
@@ -2461,12 +2496,12 @@ var ssrfVulnerability = {
2461
2496
  filePath,
2462
2497
  () => "Validate URLs against an allowlist before fetching. Block internal IPs: 127.0.0.1, 10.x, 172.16-31.x, 192.168.x, 169.254.169.254 (cloud metadata). Use: const url = new URL(input); if (!ALLOWED_HOSTS.includes(url.hostname)) throw new Error('Blocked');"
2463
2498
  ));
2464
- if (!/\b(?:fetch|axios|got|request|http\.get|https\.get)\b/.test(content)) return matches;
2499
+ if (!/\b(?:fetch|axios|got|request|needle|superagent|undici|http\.get|https\.get)\b/.test(content)) return matches;
2465
2500
  const ctx = tryParse(content, filePath);
2466
2501
  if (!ctx) return matches;
2467
2502
  const { parsed, taint } = ctx;
2468
- const FETCH_CALLEES = /* @__PURE__ */ new Set(["fetch", "axios", "got", "request"]);
2469
- const FETCH_METHODS = /* @__PURE__ */ new Set(["get", "post", "put", "patch", "delete", "request"]);
2503
+ const FETCH_CALLEES = /* @__PURE__ */ new Set(["fetch", "axios", "got", "request", "needle", "superagent", "undici"]);
2504
+ const FETCH_METHODS = /* @__PURE__ */ new Set(["get", "post", "put", "patch", "delete", "request", "head"]);
2470
2505
  visitCalls(
2471
2506
  parsed,
2472
2507
  (callee) => {
@@ -2475,7 +2510,7 @@ var ssrfVulnerability = {
2475
2510
  if (!FETCH_METHODS.has(callee.property.name)) return false;
2476
2511
  const obj = callee.object;
2477
2512
  if (obj.type === "Identifier") {
2478
- return obj.name === "axios" || obj.name === "got" || obj.name === "http" || obj.name === "https";
2513
+ return obj.name === "axios" || obj.name === "got" || obj.name === "http" || obj.name === "https" || obj.name === "needle" || obj.name === "superagent" || obj.name === "undici";
2479
2514
  }
2480
2515
  }
2481
2516
  return false;