circle-ir 3.168.0 → 3.174.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/configs/sinks/prompt_injection.yaml +50 -0
- package/dist/analysis/config-loader.d.ts.map +1 -1
- package/dist/analysis/config-loader.js +157 -0
- package/dist/analysis/config-loader.js.map +1 -1
- package/dist/analysis/passes/cross-file-pass.d.ts.map +1 -1
- package/dist/analysis/passes/cross-file-pass.js +3 -2
- package/dist/analysis/passes/cross-file-pass.js.map +1 -1
- package/dist/analysis/passes/interprocedural-pass.d.ts.map +1 -1
- package/dist/analysis/passes/interprocedural-pass.js +3 -2
- package/dist/analysis/passes/interprocedural-pass.js.map +1 -1
- package/dist/analysis/passes/sink-filter-pass.d.ts.map +1 -1
- package/dist/analysis/passes/sink-filter-pass.js +2 -1
- package/dist/analysis/passes/sink-filter-pass.js.map +1 -1
- package/dist/analysis/passes/taint-propagation-pass.d.ts.map +1 -1
- package/dist/analysis/passes/taint-propagation-pass.js +29 -15
- package/dist/analysis/passes/taint-propagation-pass.js.map +1 -1
- package/dist/analysis/rules.d.ts.map +1 -1
- package/dist/analysis/rules.js +9 -0
- package/dist/analysis/rules.js.map +1 -1
- package/dist/analysis/sanitizer-index.d.ts +34 -0
- package/dist/analysis/sanitizer-index.d.ts.map +1 -0
- package/dist/analysis/sanitizer-index.js +48 -0
- package/dist/analysis/sanitizer-index.js.map +1 -0
- package/dist/analysis/taint-matcher.d.ts.map +1 -1
- package/dist/analysis/taint-matcher.js +93 -45
- package/dist/analysis/taint-matcher.js.map +1 -1
- package/dist/analysis/taint-propagation.d.ts.map +1 -1
- package/dist/analysis/taint-propagation.js +5 -2
- package/dist/analysis/taint-propagation.js.map +1 -1
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +51 -2
- package/dist/analyzer.js.map +1 -1
- package/dist/browser/circle-ir.js +336 -95
- package/dist/core/circle-ir-core.cjs +272 -73
- package/dist/core/circle-ir-core.js +272 -73
- package/dist/core/extractors/cfg.d.ts +11 -1
- package/dist/core/extractors/cfg.d.ts.map +1 -1
- package/dist/core/extractors/cfg.js +18 -9
- package/dist/core/extractors/cfg.js.map +1 -1
- package/dist/core/extractors/imports.d.ts +9 -1
- package/dist/core/extractors/imports.d.ts.map +1 -1
- package/dist/core/extractors/imports.js +29 -22
- package/dist/core/extractors/imports.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "Reference-only. Runtime uses DEFAULT_SINKS in src/analysis/config-loader.ts. See cognium-dev#248.",
|
|
3
|
+
"sinks": [
|
|
4
|
+
{ "method": "create", "class": "Completions", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["python"] },
|
|
5
|
+
{ "method": "create", "class": "Responses", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["python"] },
|
|
6
|
+
{ "method": "create", "class": "ChatCompletion", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["python"] },
|
|
7
|
+
{ "method": "create", "class": "Completion", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["python"] },
|
|
8
|
+
{ "method": "create", "class": "Messages", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["python"] },
|
|
9
|
+
{ "method": "stream", "class": "Messages", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["python"] },
|
|
10
|
+
{ "method": "completion", "class": "litellm", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["python"] },
|
|
11
|
+
{ "method": "acompletion", "class": "litellm", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["python"] },
|
|
12
|
+
{ "method": "invoke", "class": "ChatOpenAI", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["python"] },
|
|
13
|
+
{ "method": "predict", "class": "ChatOpenAI", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["python"] },
|
|
14
|
+
{ "method": "stream", "class": "ChatOpenAI", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["python"] },
|
|
15
|
+
{ "method": "generate", "class": "ChatOpenAI", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["python"] },
|
|
16
|
+
{ "method": "invoke", "class": "ChatAnthropic", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["python"] },
|
|
17
|
+
{ "method": "invoke", "class": "ChatGoogleGenerativeAI", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["python"] },
|
|
18
|
+
{ "method": "run", "class": "LLMChain", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["python"] },
|
|
19
|
+
{ "method": "invoke", "class": "LLMChain", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["python"] },
|
|
20
|
+
|
|
21
|
+
{ "method": "create", "class": "Completions", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["javascript", "typescript"] },
|
|
22
|
+
{ "method": "create", "class": "Responses", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["javascript", "typescript"] },
|
|
23
|
+
{ "method": "create", "class": "Messages", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["javascript", "typescript"] },
|
|
24
|
+
{ "method": "stream", "class": "Messages", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["javascript", "typescript"] },
|
|
25
|
+
{ "method": "generateText", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0], "languages": ["javascript", "typescript"] },
|
|
26
|
+
{ "method": "streamText", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0], "languages": ["javascript", "typescript"] },
|
|
27
|
+
{ "method": "generateObject", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0], "languages": ["javascript", "typescript"] },
|
|
28
|
+
{ "method": "streamObject", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0], "languages": ["javascript", "typescript"] },
|
|
29
|
+
{ "method": "invoke", "class": "ChatOpenAI", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["javascript", "typescript"] },
|
|
30
|
+
{ "method": "invoke", "class": "ChatAnthropic", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["javascript", "typescript"] },
|
|
31
|
+
{ "method": "stream", "class": "ChatOpenAI", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["javascript", "typescript"] },
|
|
32
|
+
|
|
33
|
+
{ "method": "generate", "class": "ChatLanguageModel", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["java"] },
|
|
34
|
+
{ "method": "chat", "class": "ChatLanguageModel", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["java"] },
|
|
35
|
+
{ "method": "generate", "class": "StreamingChatLanguageModel", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["java"] },
|
|
36
|
+
{ "method": "chat", "class": "StreamingChatLanguageModel", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["java"] },
|
|
37
|
+
{ "method": "prompt", "class": "ChatClient", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["java"] },
|
|
38
|
+
{ "method": "call", "class": "ChatClient", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["java"] },
|
|
39
|
+
{ "method": "call", "class": "ChatModel", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["java"] },
|
|
40
|
+
{ "method": "createChatCompletion", "class": "OpenAiService", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["java"] },
|
|
41
|
+
{ "method": "createCompletion", "class": "OpenAiService", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["java"] },
|
|
42
|
+
|
|
43
|
+
{ "method": "CreateChatCompletion", "class": "Client", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["go"] },
|
|
44
|
+
{ "method": "CreateCompletion", "class": "Client", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["go"] },
|
|
45
|
+
{ "method": "CreateChatCompletionStream", "class": "Client", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["go"] },
|
|
46
|
+
{ "method": "Call", "class": "LLM", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["go"] },
|
|
47
|
+
{ "method": "Generate", "class": "LLM", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["go"] },
|
|
48
|
+
{ "method": "GenerateContent", "class": "Model", "type": "prompt_injection", "cwe": "CWE-1427", "severity": "high", "arg_positions": [0, 1, 2, 3], "languages": ["go"] }
|
|
49
|
+
]
|
|
50
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../src/analysis/config-loader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,UAAU,EACV,mBAAmB,EACnB,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,UAAU,EACX,MAAM,oBAAoB,CAAC;AAE5B;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC,CAEjD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,aAAa,EAAE,CAiB1E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG;IACtD,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,UAAU,EAAE,gBAAgB,EAAE,CAAC;CAChC,CAcA;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,mBAAmB,EAAE,GAC7B,kBAAkB,EAAE,CAQtB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,cAAc,EAAE,MAAM,EAAE,EACxB,YAAY,EAAE,MAAM,EAAE,EACtB,qBAAqB,GAAE,MAAM,EAAO,GACnC,WAAW,CAYb;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../src/analysis/config-loader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,UAAU,EACV,mBAAmB,EACnB,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,UAAU,EACX,MAAM,oBAAoB,CAAC;AAE5B;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC,CAEjD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,aAAa,EAAE,CAiB1E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG;IACtD,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,UAAU,EAAE,gBAAgB,EAAE,CAAC;CAChC,CAcA;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,mBAAmB,EAAE,GAC7B,kBAAkB,EAAE,CAQtB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,cAAc,EAAE,MAAM,EAAE,EACxB,YAAY,EAAE,MAAM,EAAE,EACtB,qBAAqB,GAAE,MAAM,EAAO,GACnC,WAAW,CAYb;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,aAAa,EA6hB1C,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,WAAW,EA6tDtC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,gBAAgB,EAwThD,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,EAAE,kBAAkB,EAiDtD,CAAC;AAEF;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,WAAW,CAO9C;AAMD;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,EAAE,UAAU,EA8F5C,CAAC"}
|
|
@@ -475,6 +475,85 @@ export const DEFAULT_SOURCES = [
|
|
|
475
475
|
{ method: 'read', class: 'TcpStream', type: 'network_input', severity: 'high', return_tainted: true },
|
|
476
476
|
{ method: 'read_to_end', class: 'TcpStream', type: 'network_input', severity: 'high', return_tainted: true },
|
|
477
477
|
{ method: 'read_to_string', class: 'TcpStream', type: 'network_input', severity: 'high', return_tainted: true },
|
|
478
|
+
// =========================================================================
|
|
479
|
+
// Modern taint sources (cognium-dev #242 — 3.170.0)
|
|
480
|
+
// GraphQL resolver args, gRPC request metadata, cache reads (second-order
|
|
481
|
+
// taint), and JWT claims (unverified decode). These attacker-influenced
|
|
482
|
+
// surfaces were previously silent — a resolver that concatenated an
|
|
483
|
+
// `Args`-annotated field into a SQL string produced zero flows.
|
|
484
|
+
// =========================================================================
|
|
485
|
+
// --- GraphQL resolver argument sources (JS / TS — Apollo, TypeGraphQL, NestJS) ---
|
|
486
|
+
// TypeGraphQL / NestJS annotate query/mutation/subscription methods; every
|
|
487
|
+
// parameter on the annotated method carries attacker input from the GraphQL
|
|
488
|
+
// POST body's `variables` field.
|
|
489
|
+
{ method_annotation: 'Query', type: 'http_body', severity: 'high', languages: ['javascript', 'typescript'] },
|
|
490
|
+
{ method_annotation: 'Mutation', type: 'http_body', severity: 'high', languages: ['javascript', 'typescript'] },
|
|
491
|
+
{ method_annotation: 'Subscription', type: 'http_body', severity: 'high', languages: ['javascript', 'typescript'] },
|
|
492
|
+
{ method_annotation: 'FieldResolver', type: 'http_body', severity: 'high', languages: ['javascript', 'typescript'] },
|
|
493
|
+
{ method_annotation: 'ResolveField', type: 'http_body', severity: 'high', languages: ['javascript', 'typescript'] },
|
|
494
|
+
// Parameter-level: `@Arg('id') id: string`, `@Args('input') input: FooDto`.
|
|
495
|
+
{ annotation: 'Arg', type: 'http_param', severity: 'high', param_tainted: true, languages: ['javascript', 'typescript'] },
|
|
496
|
+
{ annotation: 'Args', type: 'http_param', severity: 'high', param_tainted: true, languages: ['javascript', 'typescript'] },
|
|
497
|
+
// --- GraphQL resolver argument sources (Python — Strawberry, Graphene, Ariadne) ---
|
|
498
|
+
{ method_annotation: 'strawberry.field', type: 'http_body', severity: 'high', languages: ['python'] },
|
|
499
|
+
{ method_annotation: 'strawberry.mutation', type: 'http_body', severity: 'high', languages: ['python'] },
|
|
500
|
+
{ method_annotation: 'strawberry.subscription', type: 'http_body', severity: 'high', languages: ['python'] },
|
|
501
|
+
// --- GraphQL resolver argument sources (Java — Netflix DGS, SPQR, graphql-java-annotations) ---
|
|
502
|
+
{ method_annotation: 'DgsQuery', type: 'http_body', severity: 'high', languages: ['java'] },
|
|
503
|
+
{ method_annotation: 'DgsMutation', type: 'http_body', severity: 'high', languages: ['java'] },
|
|
504
|
+
{ method_annotation: 'DgsSubscription', type: 'http_body', severity: 'high', languages: ['java'] },
|
|
505
|
+
{ method_annotation: 'DgsData', type: 'http_body', severity: 'high', languages: ['java'] },
|
|
506
|
+
{ method_annotation: 'GraphQLQuery', type: 'http_body', severity: 'high', languages: ['java'] },
|
|
507
|
+
{ method_annotation: 'GraphQLMutation', type: 'http_body', severity: 'high', languages: ['java'] },
|
|
508
|
+
{ annotation: 'InputArgument', type: 'http_param', severity: 'high', param_tainted: true, languages: ['java'] },
|
|
509
|
+
{ annotation: 'GraphQLArgument', type: 'http_param', severity: 'high', param_tainted: true, languages: ['java'] },
|
|
510
|
+
// --- gRPC request metadata (Python — grpcio) ---
|
|
511
|
+
// `context.invocation_metadata()` returns the caller-supplied metadata tuple.
|
|
512
|
+
// No `class` filter — receiver names vary (`context`, `ctx`, `servicer_context`).
|
|
513
|
+
{ method: 'invocation_metadata', type: 'http_header', severity: 'high', return_tainted: true, languages: ['python'] },
|
|
514
|
+
// --- gRPC request metadata (JS / TS — @grpc/grpc-js) ---
|
|
515
|
+
// `call.metadata.get(key)` / `call.metadata.getMap()` inside a service handler.
|
|
516
|
+
{ method: 'get', class: 'Metadata', type: 'http_header', severity: 'high', return_tainted: true, languages: ['javascript', 'typescript'] },
|
|
517
|
+
{ method: 'getMap', class: 'Metadata', type: 'http_header', severity: 'high', return_tainted: true, languages: ['javascript', 'typescript'] },
|
|
518
|
+
// --- gRPC request metadata (Go — google.golang.org/grpc/metadata) ---
|
|
519
|
+
// `md, _ := metadata.FromIncomingContext(ctx)` pulls the caller's headers.
|
|
520
|
+
{ method: 'FromIncomingContext', class: 'metadata', type: 'http_header', severity: 'high', return_tainted: true, languages: ['go'] },
|
|
521
|
+
// --- gRPC request metadata (Java — io.grpc.Metadata) ---
|
|
522
|
+
// Server-side interceptor receives `Metadata headers`; `headers.get(KEY)`
|
|
523
|
+
// returns caller-supplied header values.
|
|
524
|
+
{ method: 'get', class: 'Metadata', type: 'http_header', severity: 'high', return_tainted: true, languages: ['java'] },
|
|
525
|
+
// --- Cache reads (second-order taint — Redis / Memcached / Django cache) ---
|
|
526
|
+
// The cache round-trip is a canonical second-order sink: whatever was
|
|
527
|
+
// written previously (potentially attacker-controlled) resurfaces on read.
|
|
528
|
+
// Severity 'medium' — cache contents are usually filtered by the writer but
|
|
529
|
+
// the read side often forgets that guarantee. Class-scoped to `Redis`,
|
|
530
|
+
// `Jedis`, `cache` to avoid colliding with generic `Map.get()`.
|
|
531
|
+
{ method: 'get', class: 'Redis', type: 'db_input', severity: 'medium', return_tainted: true, languages: ['python'] },
|
|
532
|
+
{ method: 'hget', class: 'Redis', type: 'db_input', severity: 'medium', return_tainted: true, languages: ['python'] },
|
|
533
|
+
{ method: 'mget', class: 'Redis', type: 'db_input', severity: 'medium', return_tainted: true, languages: ['python'] },
|
|
534
|
+
{ method: 'lrange', class: 'Redis', type: 'db_input', severity: 'medium', return_tainted: true, languages: ['python'] },
|
|
535
|
+
{ method: 'get', class: 'cache', type: 'db_input', severity: 'medium', return_tainted: true, languages: ['python'] },
|
|
536
|
+
{ method: 'get_many', class: 'cache', type: 'db_input', severity: 'medium', return_tainted: true, languages: ['python'] },
|
|
537
|
+
{ method: 'get', class: 'Redis', type: 'db_input', severity: 'medium', return_tainted: true, languages: ['javascript', 'typescript'] },
|
|
538
|
+
{ method: 'hget', class: 'Redis', type: 'db_input', severity: 'medium', return_tainted: true, languages: ['javascript', 'typescript'] },
|
|
539
|
+
{ method: 'mget', class: 'Redis', type: 'db_input', severity: 'medium', return_tainted: true, languages: ['javascript', 'typescript'] },
|
|
540
|
+
{ method: 'get', class: 'Jedis', type: 'db_input', severity: 'medium', return_tainted: true, languages: ['java'] },
|
|
541
|
+
{ method: 'hget', class: 'Jedis', type: 'db_input', severity: 'medium', return_tainted: true, languages: ['java'] },
|
|
542
|
+
{ method: 'mget', class: 'Jedis', type: 'db_input', severity: 'medium', return_tainted: true, languages: ['java'] },
|
|
543
|
+
// --- JWT claims (unverified decode — PyJWT / jose / jsonwebtoken / auth0 java-jwt / golang-jwt) ---
|
|
544
|
+
// A JWT's payload is *always* attacker-authored. Even after verification
|
|
545
|
+
// the *contents* of the claims (username, role, custom fields) are not
|
|
546
|
+
// trusted for downstream flows into SQL, HTML, shell, etc. The `decode`
|
|
547
|
+
// variants here return the parsed claims dictionary/object.
|
|
548
|
+
{ method: 'decode', class: 'jwt', type: 'http_header', severity: 'high', return_tainted: true, languages: ['python'] },
|
|
549
|
+
{ method: 'get_unverified_claims', class: 'jwt', type: 'http_header', severity: 'high', return_tainted: true, languages: ['python'] },
|
|
550
|
+
{ method: 'get_unverified_header', class: 'jwt', type: 'http_header', severity: 'high', return_tainted: true, languages: ['python'] },
|
|
551
|
+
{ method: 'decode', class: 'jwt', type: 'http_header', severity: 'high', return_tainted: true, languages: ['javascript', 'typescript'] },
|
|
552
|
+
{ method: 'decode', class: 'jsonwebtoken', type: 'http_header', severity: 'high', return_tainted: true, languages: ['javascript', 'typescript'] },
|
|
553
|
+
{ method: 'decodeJwt', class: 'jose', type: 'http_header', severity: 'high', return_tainted: true, languages: ['javascript', 'typescript'] },
|
|
554
|
+
{ method: 'decodeProtectedHeader', class: 'jose', type: 'http_header', severity: 'high', return_tainted: true, languages: ['javascript', 'typescript'] },
|
|
555
|
+
{ method: 'decode', class: 'JWT', type: 'http_header', severity: 'high', return_tainted: true, languages: ['java'] },
|
|
556
|
+
{ method: 'ParseUnverified', class: 'jwt', type: 'http_header', severity: 'high', return_tainted: true, languages: ['go'] },
|
|
478
557
|
];
|
|
479
558
|
export const DEFAULT_SINKS = [
|
|
480
559
|
// SQL Injection (CWE-89)
|
|
@@ -2041,6 +2120,84 @@ export const DEFAULT_SINKS = [
|
|
|
2041
2120
|
// they iterate after net/http entries and don't hijack `http.Get`.
|
|
2042
2121
|
{ method: 'Do', class: 'Client', type: 'ssrf', cwe: 'CWE-918', severity: 'high', arg_positions: [0], languages: ['go'] }, // *fasthttp.Client.Do(req)
|
|
2043
2122
|
{ method: 'DoTimeout', class: 'Client', type: 'ssrf', cwe: 'CWE-918', severity: 'high', arg_positions: [0], languages: ['go'] },
|
|
2123
|
+
// =========================================================================
|
|
2124
|
+
// cognium-dev #248 — prompt-injection sinks (CWE-1427)
|
|
2125
|
+
//
|
|
2126
|
+
// Tainted data reaching a generative-model prompt-construction API is
|
|
2127
|
+
// classified as `prompt_injection`. v1 uses broad positional matching
|
|
2128
|
+
// (arg_positions [0..3]) because these APIs are kwarg-heavy: Python
|
|
2129
|
+
// `openai.chat.completions.create(model=..., messages=...)` may pass the
|
|
2130
|
+
// messages arg at position 0 or 1 depending on caller order, and JS/TS
|
|
2131
|
+
// object-literal `{ messages: [...], model: '...' }` is a single
|
|
2132
|
+
// positional arg whose taint is inherited from any tainted property.
|
|
2133
|
+
// Argname-precise matching (messages=/prompt=/content=) and
|
|
2134
|
+
// sanitizer credit for prompt-template libraries (PromptTemplate,
|
|
2135
|
+
// ChatPromptTemplate) are follow-ups.
|
|
2136
|
+
//
|
|
2137
|
+
// Class-qualified entries prevent bare `create()` / `generate()` calls
|
|
2138
|
+
// with no receiver from matching (per taint-matcher.ts:1696 guard).
|
|
2139
|
+
// =========================================================================
|
|
2140
|
+
// --- Python: openai (v1 SDK) --------------------------------------------
|
|
2141
|
+
{ method: 'create', class: 'Completions', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['python'] },
|
|
2142
|
+
{ method: 'create', class: 'Responses', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['python'] },
|
|
2143
|
+
// openai <1.0 legacy top-level API — `openai.ChatCompletion.create(...)` / `openai.Completion.create(...)`
|
|
2144
|
+
{ method: 'create', class: 'ChatCompletion', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['python'] },
|
|
2145
|
+
{ method: 'create', class: 'Completion', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['python'] },
|
|
2146
|
+
// --- Python: anthropic ---------------------------------------------------
|
|
2147
|
+
{ method: 'create', class: 'Messages', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['python'] },
|
|
2148
|
+
{ method: 'stream', class: 'Messages', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['python'] },
|
|
2149
|
+
// --- Python: litellm (bare functions from the litellm module) -----------
|
|
2150
|
+
{ method: 'completion', class: 'litellm', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['python'] },
|
|
2151
|
+
{ method: 'acompletion', class: 'litellm', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['python'] },
|
|
2152
|
+
// --- Python: langchain chat/llm models ----------------------------------
|
|
2153
|
+
// Common concrete classes; matching the class name catches typical usage
|
|
2154
|
+
// `ChatOpenAI().invoke(prompt)` where the receiver-type resolver identifies
|
|
2155
|
+
// the class from the constructor.
|
|
2156
|
+
{ method: 'invoke', class: 'ChatOpenAI', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['python'] },
|
|
2157
|
+
{ method: 'predict', class: 'ChatOpenAI', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['python'] },
|
|
2158
|
+
{ method: 'stream', class: 'ChatOpenAI', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['python'] },
|
|
2159
|
+
{ method: 'generate', class: 'ChatOpenAI', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['python'] },
|
|
2160
|
+
{ method: 'invoke', class: 'ChatAnthropic', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['python'] },
|
|
2161
|
+
{ method: 'invoke', class: 'ChatGoogleGenerativeAI', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['python'] },
|
|
2162
|
+
{ method: 'run', class: 'LLMChain', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['python'] },
|
|
2163
|
+
{ method: 'invoke', class: 'LLMChain', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['python'] },
|
|
2164
|
+
// --- JS/TS: openai node SDK ---------------------------------------------
|
|
2165
|
+
{ method: 'create', class: 'Completions', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['javascript', 'typescript'] },
|
|
2166
|
+
{ method: 'create', class: 'Responses', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['javascript', 'typescript'] },
|
|
2167
|
+
// --- JS/TS: @anthropic-ai/sdk -------------------------------------------
|
|
2168
|
+
{ method: 'create', class: 'Messages', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['javascript', 'typescript'] },
|
|
2169
|
+
{ method: 'stream', class: 'Messages', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['javascript', 'typescript'] },
|
|
2170
|
+
// --- JS/TS: Vercel AI SDK (bare functions from the `ai` package) --------
|
|
2171
|
+
// generateText/streamText/generateObject take a single options object;
|
|
2172
|
+
// taint reaches the sink when a tainted variable flows into any property.
|
|
2173
|
+
{ method: 'generateText', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0], languages: ['javascript', 'typescript'] },
|
|
2174
|
+
{ method: 'streamText', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0], languages: ['javascript', 'typescript'] },
|
|
2175
|
+
{ method: 'generateObject', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0], languages: ['javascript', 'typescript'] },
|
|
2176
|
+
{ method: 'streamObject', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0], languages: ['javascript', 'typescript'] },
|
|
2177
|
+
// --- JS/TS: langchain.js ------------------------------------------------
|
|
2178
|
+
{ method: 'invoke', class: 'ChatOpenAI', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['javascript', 'typescript'] },
|
|
2179
|
+
{ method: 'invoke', class: 'ChatAnthropic', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['javascript', 'typescript'] },
|
|
2180
|
+
{ method: 'stream', class: 'ChatOpenAI', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['javascript', 'typescript'] },
|
|
2181
|
+
// --- Java: LangChain4j --------------------------------------------------
|
|
2182
|
+
{ method: 'generate', class: 'ChatLanguageModel', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['java'] },
|
|
2183
|
+
{ method: 'chat', class: 'ChatLanguageModel', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['java'] },
|
|
2184
|
+
{ method: 'generate', class: 'StreamingChatLanguageModel', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['java'] },
|
|
2185
|
+
{ method: 'chat', class: 'StreamingChatLanguageModel', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['java'] },
|
|
2186
|
+
// --- Java: Spring AI ----------------------------------------------------
|
|
2187
|
+
{ method: 'prompt', class: 'ChatClient', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['java'] },
|
|
2188
|
+
{ method: 'call', class: 'ChatClient', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['java'] },
|
|
2189
|
+
{ method: 'call', class: 'ChatModel', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['java'] },
|
|
2190
|
+
// --- Java: OpenAI Java SDK (theokanning) --------------------------------
|
|
2191
|
+
{ method: 'createChatCompletion', class: 'OpenAiService', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['java'] },
|
|
2192
|
+
{ method: 'createCompletion', class: 'OpenAiService', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['java'] },
|
|
2193
|
+
// --- Go: go-openai (sashabaranov/go-openai) -----------------------------
|
|
2194
|
+
{ method: 'CreateChatCompletion', class: 'Client', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['go'] },
|
|
2195
|
+
{ method: 'CreateCompletion', class: 'Client', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['go'] },
|
|
2196
|
+
{ method: 'CreateChatCompletionStream', class: 'Client', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['go'] },
|
|
2197
|
+
// --- Go: langchaingo ----------------------------------------------------
|
|
2198
|
+
{ method: 'Call', class: 'LLM', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['go'] },
|
|
2199
|
+
{ method: 'Generate', class: 'LLM', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['go'] },
|
|
2200
|
+
{ method: 'GenerateContent', class: 'Model', type: 'prompt_injection', cwe: 'CWE-1427', severity: 'high', arg_positions: [0, 1, 2, 3], languages: ['go'] },
|
|
2044
2201
|
];
|
|
2045
2202
|
export const DEFAULT_SANITIZERS = [
|
|
2046
2203
|
// SQL Injection - proper parameter binding sanitizes input
|