@clear-capabilities/agentic-security-scanner 0.147.5 → 0.148.1

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.
@@ -32,7 +32,13 @@ const ASSET_PATTERNS = [
32
32
  // [regex, category, exposure]
33
33
  [/(?:stripe|paddle|braintree)\.\w+\.create/g, 'payment-method', 'public-api'],
34
34
  [/(?:User|users?)\.create\(|prisma\.user\.create/g, 'identity', 'public-api'],
35
- [/(?:session|token|jwt)\s*=\s*/g, 'session', 'internal'],
35
+ // Real customer false positive: `session = requests.Session()` matched
36
+ // the pattern only checked the LHS identifier, so an HTTP CLIENT object
37
+ // (requests.Session / aiohttp.ClientSession / httpx.Client) got reported
38
+ // as an "authenticated user session" asset. The negative lookahead
39
+ // excludes the specific RHS constructor shapes that mean "this is an
40
+ // outbound HTTP client", not "this holds a logged-in user's session".
41
+ [/(?:session|token|jwt)\s*=\s*(?!\s*(?:requests\.Session|aiohttp\.ClientSession|httpx\.(?:Client|AsyncClient))\s*\()/g, 'session', 'internal'],
36
42
  [/process\.env\.([A-Z_]+(?:KEY|SECRET|TOKEN))/g, 'secret', 'internal'],
37
43
  [/(?:aws-sdk|@aws-sdk).*\.upload|s3\.put/g, 'object-storage', 'public-api'],
38
44
  [/(?:openai|anthropic|together|groq)\.(?:chat|messages|completions)/g, 'llm-egress', 'external-api'],
@@ -43,8 +49,19 @@ const TRUST_BOUNDARY_PATTERNS = [
43
49
  [/router\.(?:get|post|put|patch|delete)\s*\(\s*['"`]([^'"`]+)['"`]/g, 'http-route'],
44
50
  [/@(?:Get|Post|Put|Patch|Delete)Mapping\s*\(/g, 'http-route-java'],
45
51
  [/@(?:app|router)\.(?:get|post|put|patch|delete)\s*\(\s*['"`]([^'"`]+)['"`]/g, 'http-route-py'],
46
- [/(?:kafka|pubsub|sqs|sns)\.consume|\.subscribe|\.receiveMessage/gi, 'queue-consumer'],
47
- [/(?:kafka|pubsub|sqs|sns)\.produce|\.publish|\.sendMessage/gi, 'queue-producer'],
52
+ // Real customer false positive: alternation without a shared group scopes
53
+ // ONLY the first branch to a queue library — `(?:kafka|pubsub|sqs|sns)\.produce
54
+ // |\.publish|\.sendMessage` is three TOP-LEVEL alternatives, and the last
55
+ // two are bare, unscoped substrings. `bundle.publisher_domain` and
56
+ // `bundle.published_at` both contain the literal substring ".publish" (the
57
+ // first 8 characters of "publisher"/"published"), so plain field access
58
+ // with no queue library, and no method call at all, was read as a
59
+ // queue-producer trust boundary. Moving the method-name alternation
60
+ // INSIDE the shared `(?:kafka|pubsub|sqs|sns)\.` prefix scopes every
61
+ // branch to an actual queue client, and requiring a trailing `(` excludes
62
+ // attribute access from matching a call-shaped rule.
63
+ [/(?:kafka|pubsub|sqs|sns)\.(?:consume|subscribe|receiveMessage)\s*\(/gi, 'queue-consumer'],
64
+ [/(?:kafka|pubsub|sqs|sns)\.(?:produce|publish|sendMessage)\s*\(/gi, 'queue-producer'],
48
65
  [/grpc\.Server|new\s+Server\s*\(\s*\)/g, 'grpc-server'],
49
66
  [/(?:db|pool|client)\.(?:query|execute|raw)\s*\(/g, 'db-edge'],
50
67
  ];
@@ -41,7 +41,30 @@ const SQLA_RAW_EXEC_CONCAT_RE = /\b(?:cursor|conn|connection|session)\s*\.\s*exe
41
41
  // quotes (single quotes inside double-quoted f-string and vice versa) so we
42
42
  // use two parallel patterns rather than a single character class that excludes
43
43
  // both quote kinds.
44
- const SQLA_FSTRING_SQL_ASSIGN_RE = /(?:f"[^"]*(?:SELECT|INSERT|UPDATE|DELETE)[^"]*\{[^}]*\}|f'[^']*(?:SELECT|INSERT|UPDATE|DELETE)[^']*\{[^}]*\})/gi;
44
+ //
45
+ // Two real-world false positives, both from the same underlying defect —
46
+ // this regex checked for a co-occurring keyword-shaped substring and a `{}`
47
+ // interpolation, not an actual SQL statement being assigned:
48
+ //
49
+ // query = f"SELECT * FROM users WHERE id = {user_id}" -> should fire
50
+ // print(f"[{position}] {len(selected)} readable pages") -> was firing
51
+ // raise RuntimeError(f"Selected TAR members exceed {N} bytes") -> was firing
52
+ //
53
+ // Case-insensitive matching with no word boundary let the SQL keyword
54
+ // alternation match inside ordinary English/identifier text — "Select" is
55
+ // the first six letters of "Selected", and "select" is the first six of the
56
+ // variable name "selected". `\b...\b` fixes that: a word boundary requires a
57
+ // non-word/word transition, which does not exist between "Select" and the
58
+ // trailing "ed" (both are word characters), so "Selected"/"selected" no
59
+ // longer match while "SELECT"/"select" as complete tokens still do.
60
+ //
61
+ // The vuln title claims "f-string SQL ASSIGNED TO VARIABLE", but the regex
62
+ // never actually checked for an assignment — it fired on any f-string
63
+ // anywhere, including a bare argument to print()/raise. Requiring
64
+ // `IDENT = ` (optionally through an opening paren, for a wrapped assignment)
65
+ // immediately before the f-string makes the check match what its own name
66
+ // promises, and excludes the print()/raise-message shape entirely.
67
+ const SQLA_FSTRING_SQL_ASSIGN_RE = /\b[A-Za-z_]\w*\s*=\s*\(?\s*(?:f"[^"]*\b(?:SELECT|INSERT|UPDATE|DELETE)\b[^"]*\{[^}]*\}|f'[^']*\b(?:SELECT|INSERT|UPDATE|DELETE)\b[^']*\{[^}]*\})/gi;
45
68
 
46
69
  // ─── Command injection ────────────────────────────────────────────────────
47
70
  //