prooflayer-runtime 0.1.0__py3-none-any.whl
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.
- prooflayer/__init__.py +50 -0
- prooflayer/cli.py +362 -0
- prooflayer/config/__init__.py +6 -0
- prooflayer/config/allowlist.py +138 -0
- prooflayer/config/loader.py +29 -0
- prooflayer/detection/__init__.py +21 -0
- prooflayer/detection/engine.py +783 -0
- prooflayer/detection/models.py +49 -0
- prooflayer/detection/normalizer.py +245 -0
- prooflayer/detection/rules.py +104 -0
- prooflayer/detection/scanner.py +160 -0
- prooflayer/detection/scorer.py +65 -0
- prooflayer/detection/semantic.py +73 -0
- prooflayer/metrics.py +266 -0
- prooflayer/reporting/__init__.py +5 -0
- prooflayer/reporting/reporter.py +190 -0
- prooflayer/response/__init__.py +6 -0
- prooflayer/response/actions.py +152 -0
- prooflayer/response/killer.py +73 -0
- prooflayer/rules/command-injection.yaml +123 -0
- prooflayer/rules/data-exfiltration.yaml +83 -0
- prooflayer/rules/jailbreaks.yaml +67 -0
- prooflayer/rules/prompt-injection.yaml +99 -0
- prooflayer/rules/role-manipulation.yaml +60 -0
- prooflayer/rules/sql-injection.yaml +51 -0
- prooflayer/rules/ssrf-xxe.yaml +51 -0
- prooflayer/rules/tool-poisoning.yaml +46 -0
- prooflayer/runtime/__init__.py +21 -0
- prooflayer/runtime/interceptor.py +91 -0
- prooflayer/runtime/mcp_wrapper.py +395 -0
- prooflayer/runtime/middleware.py +86 -0
- prooflayer/runtime/transport.py +306 -0
- prooflayer/runtime/wrapper.py +265 -0
- prooflayer/utils/__init__.py +21 -0
- prooflayer/utils/encoding.py +87 -0
- prooflayer/utils/entropy.py +51 -0
- prooflayer/utils/logging.py +86 -0
- prooflayer/utils/masking.py +72 -0
- prooflayer/version.py +6 -0
- prooflayer_runtime-0.1.0.dist-info/METADATA +266 -0
- prooflayer_runtime-0.1.0.dist-info/RECORD +45 -0
- prooflayer_runtime-0.1.0.dist-info/WHEEL +5 -0
- prooflayer_runtime-0.1.0.dist-info/entry_points.txt +2 -0
- prooflayer_runtime-0.1.0.dist-info/licenses/LICENSE +4 -0
- prooflayer_runtime-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Command Injection Detection Rules
|
|
2
|
+
# Detects shell metacharacters and dangerous commands
|
|
3
|
+
|
|
4
|
+
rules:
|
|
5
|
+
- id: cmd-inject-semicolon
|
|
6
|
+
severity: critical
|
|
7
|
+
category: command_injection
|
|
8
|
+
message: "Command injection: Shell metacharacter ';' detected"
|
|
9
|
+
pattern: ";[\\s]*[a-zA-Z/.$]"
|
|
10
|
+
score: 20
|
|
11
|
+
owasp: [LLM01, LLM06, MCP05, ASI02]
|
|
12
|
+
|
|
13
|
+
- id: cmd-inject-pipe
|
|
14
|
+
severity: critical
|
|
15
|
+
category: command_injection
|
|
16
|
+
message: "Command injection: Pipe operator '|' detected"
|
|
17
|
+
pattern: "\\|[\\s]*[a-zA-Z/.$]"
|
|
18
|
+
score: 20
|
|
19
|
+
owasp: [LLM01, LLM06, MCP05, ASI02]
|
|
20
|
+
|
|
21
|
+
- id: cmd-inject-double-ampersand
|
|
22
|
+
severity: critical
|
|
23
|
+
category: command_injection
|
|
24
|
+
message: "Command injection: Command chaining '&&' detected"
|
|
25
|
+
pattern: "&&[\\s]*[a-zA-Z/.$]"
|
|
26
|
+
score: 15
|
|
27
|
+
owasp: [LLM01, LLM06, MCP05, ASI02]
|
|
28
|
+
|
|
29
|
+
- id: cmd-inject-double-pipe
|
|
30
|
+
severity: high
|
|
31
|
+
category: command_injection
|
|
32
|
+
message: "Command injection: OR operator '||' detected"
|
|
33
|
+
pattern: "\\|\\|[\\s]*[a-zA-Z/.$]"
|
|
34
|
+
score: 15
|
|
35
|
+
owasp: [LLM01, LLM06, MCP05, ASI02]
|
|
36
|
+
|
|
37
|
+
- id: cmd-inject-curl
|
|
38
|
+
severity: critical
|
|
39
|
+
category: command_injection
|
|
40
|
+
message: "Command injection: 'curl' command detected"
|
|
41
|
+
pattern: "\\bcurl\\s+"
|
|
42
|
+
score: 25
|
|
43
|
+
owasp: [LLM01, LLM06, MCP05, ASI02]
|
|
44
|
+
|
|
45
|
+
- id: cmd-inject-wget
|
|
46
|
+
severity: critical
|
|
47
|
+
category: command_injection
|
|
48
|
+
message: "Command injection: 'wget' command detected"
|
|
49
|
+
pattern: "\\bwget\\s+"
|
|
50
|
+
score: 25
|
|
51
|
+
owasp: [LLM01, LLM06, MCP05, ASI02]
|
|
52
|
+
|
|
53
|
+
- id: cmd-inject-bash
|
|
54
|
+
severity: critical
|
|
55
|
+
category: command_injection
|
|
56
|
+
message: "Command injection: 'bash' invocation detected"
|
|
57
|
+
pattern: "\\b(bash|sh|zsh)\\s+-c"
|
|
58
|
+
score: 30
|
|
59
|
+
owasp: [LLM01, LLM06, MCP05, ASI02]
|
|
60
|
+
|
|
61
|
+
- id: cmd-inject-nc
|
|
62
|
+
severity: critical
|
|
63
|
+
category: command_injection
|
|
64
|
+
message: "Command injection: 'nc' (netcat) detected"
|
|
65
|
+
pattern: "\\b(nc|netcat)\\s+"
|
|
66
|
+
score: 30
|
|
67
|
+
owasp: [LLM01, LLM06, MCP05, ASI02]
|
|
68
|
+
|
|
69
|
+
- id: cmd-inject-exec
|
|
70
|
+
severity: critical
|
|
71
|
+
category: command_injection
|
|
72
|
+
message: "Command injection: 'exec' detected"
|
|
73
|
+
pattern: "\\bexec\\s+"
|
|
74
|
+
score: 25
|
|
75
|
+
owasp: [LLM01, LLM06, MCP05, ASI02]
|
|
76
|
+
|
|
77
|
+
- id: cmd-inject-eval
|
|
78
|
+
severity: critical
|
|
79
|
+
category: command_injection
|
|
80
|
+
message: "Command injection: 'eval' detected"
|
|
81
|
+
pattern: "\\beval\\s*\\("
|
|
82
|
+
score: 25
|
|
83
|
+
owasp: [LLM01, LLM06, MCP05, ASI02]
|
|
84
|
+
|
|
85
|
+
- id: cmd-inject-backticks
|
|
86
|
+
severity: critical
|
|
87
|
+
category: command_injection
|
|
88
|
+
message: "Command injection: Backtick execution detected"
|
|
89
|
+
pattern: "`[^`]+`"
|
|
90
|
+
score: 25
|
|
91
|
+
owasp: [LLM01, LLM06, MCP05, ASI02]
|
|
92
|
+
|
|
93
|
+
- id: cmd-inject-dollar-parens
|
|
94
|
+
severity: high
|
|
95
|
+
category: command_injection
|
|
96
|
+
message: "Command injection: $() command substitution detected"
|
|
97
|
+
pattern: "\\$\\([^)]+\\)"
|
|
98
|
+
score: 20
|
|
99
|
+
owasp: [LLM01, LLM06, MCP05, ASI02]
|
|
100
|
+
|
|
101
|
+
- id: cmd-inject-redirect-output
|
|
102
|
+
severity: medium
|
|
103
|
+
category: command_injection
|
|
104
|
+
message: "Command injection: Output redirection '>' detected"
|
|
105
|
+
pattern: ">[>&]?[\\s]*/?\\.?[a-zA-Z]"
|
|
106
|
+
score: 10
|
|
107
|
+
owasp: [LLM01, LLM06, MCP05, ASI02]
|
|
108
|
+
|
|
109
|
+
- id: cmd-inject-redirect-input
|
|
110
|
+
severity: medium
|
|
111
|
+
category: command_injection
|
|
112
|
+
message: "Command injection: Input redirection '<' detected"
|
|
113
|
+
pattern: "<[\\s]*/?\\.?[a-zA-Z]"
|
|
114
|
+
score: 10
|
|
115
|
+
owasp: [LLM01, LLM06, MCP05, ASI02]
|
|
116
|
+
|
|
117
|
+
- id: cmd-inject-rm-rf
|
|
118
|
+
severity: critical
|
|
119
|
+
category: command_injection
|
|
120
|
+
message: "Command injection: Destructive 'rm -rf' detected"
|
|
121
|
+
pattern: "\\brm\\s+-[rRf]+"
|
|
122
|
+
score: 35
|
|
123
|
+
owasp: [LLM01, LLM06, MCP05, ASI02]
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Data Exfiltration Detection Rules
|
|
2
|
+
# Detects attempts to send data to external systems
|
|
3
|
+
|
|
4
|
+
rules:
|
|
5
|
+
- id: exfil-send-to-url
|
|
6
|
+
severity: critical
|
|
7
|
+
category: data_exfiltration
|
|
8
|
+
message: "Data exfiltration: 'send to URL' detected"
|
|
9
|
+
pattern: "(send|post|upload|transmit)\\s+(to|at)\\s+https?://"
|
|
10
|
+
score: 25
|
|
11
|
+
owasp: [LLM06, MCP01, ASI02]
|
|
12
|
+
|
|
13
|
+
- id: exfil-base64-encode
|
|
14
|
+
severity: high
|
|
15
|
+
category: data_exfiltration
|
|
16
|
+
message: "Data exfiltration: Base64 encoding detected"
|
|
17
|
+
pattern: "base64\\s+(encode|--encode|-e)"
|
|
18
|
+
score: 15
|
|
19
|
+
owasp: [LLM06, MCP01, ASI02]
|
|
20
|
+
|
|
21
|
+
- id: exfil-file-read-passwd
|
|
22
|
+
severity: critical
|
|
23
|
+
category: data_exfiltration
|
|
24
|
+
message: "Data exfiltration: /etc/passwd access detected"
|
|
25
|
+
pattern: "/etc/passwd"
|
|
26
|
+
score: 30
|
|
27
|
+
owasp: [LLM06, MCP01, ASI02]
|
|
28
|
+
|
|
29
|
+
- id: exfil-file-read-shadow
|
|
30
|
+
severity: critical
|
|
31
|
+
category: data_exfiltration
|
|
32
|
+
message: "Data exfiltration: /etc/shadow access detected"
|
|
33
|
+
pattern: "/etc/shadow"
|
|
34
|
+
score: 35
|
|
35
|
+
owasp: [LLM06, MCP01, ASI02]
|
|
36
|
+
|
|
37
|
+
- id: exfil-ssh-keys
|
|
38
|
+
severity: critical
|
|
39
|
+
category: data_exfiltration
|
|
40
|
+
message: "Data exfiltration: SSH key access detected"
|
|
41
|
+
pattern: "\\.ssh/(id_rsa|id_dsa|id_ecdsa|id_ed25519|authorized_keys)"
|
|
42
|
+
score: 30
|
|
43
|
+
owasp: [LLM06, MCP01, ASI02]
|
|
44
|
+
|
|
45
|
+
- id: exfil-env-file
|
|
46
|
+
severity: critical
|
|
47
|
+
category: data_exfiltration
|
|
48
|
+
message: "Data exfiltration: .env file access detected"
|
|
49
|
+
pattern: "\\.env"
|
|
50
|
+
score: 25
|
|
51
|
+
owasp: [LLM06, MCP01, ASI02]
|
|
52
|
+
|
|
53
|
+
- id: exfil-credentials
|
|
54
|
+
severity: critical
|
|
55
|
+
category: data_exfiltration
|
|
56
|
+
message: "Data exfiltration: credentials file access detected"
|
|
57
|
+
pattern: "(credentials|secrets|api[_-]?keys?)\\.(json|yaml|yml|txt|env)"
|
|
58
|
+
score: 25
|
|
59
|
+
owasp: [LLM06, MCP01, ASI02]
|
|
60
|
+
|
|
61
|
+
- id: exfil-cat-command
|
|
62
|
+
severity: medium
|
|
63
|
+
category: data_exfiltration
|
|
64
|
+
message: "Data exfiltration: 'cat' file read detected"
|
|
65
|
+
pattern: "\\bcat\\s+/"
|
|
66
|
+
score: 10
|
|
67
|
+
owasp: [LLM06, MCP01, ASI02]
|
|
68
|
+
|
|
69
|
+
- id: exfil-xxd-hex
|
|
70
|
+
severity: high
|
|
71
|
+
category: data_exfiltration
|
|
72
|
+
message: "Data exfiltration: xxd hex dump detected"
|
|
73
|
+
pattern: "\\bxxd\\s+"
|
|
74
|
+
score: 15
|
|
75
|
+
owasp: [LLM06, MCP01, ASI02]
|
|
76
|
+
|
|
77
|
+
- id: exfil-dns-tunnel
|
|
78
|
+
severity: critical
|
|
79
|
+
category: data_exfiltration
|
|
80
|
+
message: "Data exfiltration: DNS tunneling detected"
|
|
81
|
+
pattern: "(nslookup|dig|host).*\\$\\("
|
|
82
|
+
score: 30
|
|
83
|
+
owasp: [LLM06, MCP01, ASI02]
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Jailbreak Detection Rules
|
|
2
|
+
# Detects DAN mode, developer mode, and role-playing jailbreaks
|
|
3
|
+
|
|
4
|
+
rules:
|
|
5
|
+
- id: jailbreak-dan-mode
|
|
6
|
+
severity: critical
|
|
7
|
+
category: jailbreak
|
|
8
|
+
message: "Jailbreak: DAN (Do Anything Now) mode detected"
|
|
9
|
+
pattern: "\\b(DAN|do anything now)\\b"
|
|
10
|
+
score: 30
|
|
11
|
+
owasp: [LLM01, MCP06, ASI01]
|
|
12
|
+
|
|
13
|
+
- id: jailbreak-developer-mode
|
|
14
|
+
severity: critical
|
|
15
|
+
category: jailbreak
|
|
16
|
+
message: "Jailbreak: Developer mode activation detected"
|
|
17
|
+
pattern: "(enable|activate|enter)\\s+(developer|dev|debug)\\s+mode"
|
|
18
|
+
score: 30
|
|
19
|
+
owasp: [LLM01, MCP06, ASI01]
|
|
20
|
+
|
|
21
|
+
- id: jailbreak-act-as
|
|
22
|
+
severity: high
|
|
23
|
+
category: jailbreak
|
|
24
|
+
message: "Jailbreak: 'act as' role manipulation detected"
|
|
25
|
+
pattern: "(act|pretend|behave)\\s+as\\s+(if|though|a)"
|
|
26
|
+
score: 20
|
|
27
|
+
owasp: [LLM01, MCP06, ASI01]
|
|
28
|
+
|
|
29
|
+
- id: jailbreak-roleplay
|
|
30
|
+
severity: high
|
|
31
|
+
category: jailbreak
|
|
32
|
+
message: "Jailbreak: Roleplay manipulation detected"
|
|
33
|
+
pattern: "(roleplay|role\\s+play|pretend)\\s+"
|
|
34
|
+
score: 15
|
|
35
|
+
owasp: [LLM01, MCP06, ASI01]
|
|
36
|
+
|
|
37
|
+
- id: jailbreak-simulation
|
|
38
|
+
severity: high
|
|
39
|
+
category: jailbreak
|
|
40
|
+
message: "Jailbreak: Simulation mode detected"
|
|
41
|
+
pattern: "(simulation|simulate)\\s+mode"
|
|
42
|
+
score: 15
|
|
43
|
+
owasp: [LLM01, MCP06, ASI01]
|
|
44
|
+
|
|
45
|
+
- id: jailbreak-evil-mode
|
|
46
|
+
severity: critical
|
|
47
|
+
category: jailbreak
|
|
48
|
+
message: "Jailbreak: Evil mode detected"
|
|
49
|
+
pattern: "(evil|bad|malicious)\\s+mode"
|
|
50
|
+
score: 30
|
|
51
|
+
owasp: [LLM01, MCP06, ASI01]
|
|
52
|
+
|
|
53
|
+
- id: jailbreak-unrestricted-ai
|
|
54
|
+
severity: critical
|
|
55
|
+
category: jailbreak
|
|
56
|
+
message: "Jailbreak: Unrestricted AI prompt detected"
|
|
57
|
+
pattern: "unrestricted\\s+(ai|assistant|model)"
|
|
58
|
+
score: 30
|
|
59
|
+
owasp: [LLM01, MCP06, ASI01]
|
|
60
|
+
|
|
61
|
+
- id: jailbreak-aligned-false
|
|
62
|
+
severity: high
|
|
63
|
+
category: jailbreak
|
|
64
|
+
message: "Jailbreak: Alignment override detected"
|
|
65
|
+
pattern: "(aligned|alignment)\\s+(false|off|disabled)"
|
|
66
|
+
score: 25
|
|
67
|
+
owasp: [LLM01, MCP06, ASI01]
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Direct Prompt Injection Detection Rules
|
|
2
|
+
# Detects attempts to override system prompts
|
|
3
|
+
|
|
4
|
+
rules:
|
|
5
|
+
- id: direct-ignore-previous
|
|
6
|
+
severity: critical
|
|
7
|
+
category: direct_injection
|
|
8
|
+
message: "Direct injection: 'ignore previous instructions' detected"
|
|
9
|
+
pattern: "ignore\\s+(previous|all|prior)\\s+(instructions?|prompts?|commands?)"
|
|
10
|
+
score: 30
|
|
11
|
+
owasp: [LLM01, MCP06, ASI01]
|
|
12
|
+
|
|
13
|
+
- id: direct-disregard-system
|
|
14
|
+
severity: critical
|
|
15
|
+
category: direct_injection
|
|
16
|
+
message: "Direct injection: 'disregard system prompt' detected"
|
|
17
|
+
pattern: "(disregard|forget|override)\\s+(system|original)\\s+(prompt|instructions?)"
|
|
18
|
+
score: 30
|
|
19
|
+
owasp: [LLM01, MCP06, ASI01]
|
|
20
|
+
|
|
21
|
+
- id: direct-new-instructions
|
|
22
|
+
severity: high
|
|
23
|
+
category: direct_injection
|
|
24
|
+
message: "Direct injection: 'new instructions' detected"
|
|
25
|
+
pattern: "(new|updated|revised)\\s+instructions?"
|
|
26
|
+
score: 20
|
|
27
|
+
owasp: [LLM01, MCP06, ASI01]
|
|
28
|
+
|
|
29
|
+
- id: direct-ignore-all
|
|
30
|
+
severity: critical
|
|
31
|
+
category: direct_injection
|
|
32
|
+
message: "Direct injection: 'ignore all' detected"
|
|
33
|
+
pattern: "ignore\\s+all"
|
|
34
|
+
score: 25
|
|
35
|
+
owasp: [LLM01, MCP06, ASI01]
|
|
36
|
+
|
|
37
|
+
- id: direct-reset-context
|
|
38
|
+
severity: high
|
|
39
|
+
category: direct_injection
|
|
40
|
+
message: "Direct injection: 'reset context' detected"
|
|
41
|
+
pattern: "(reset|clear|wipe)\\s+(context|memory|history)"
|
|
42
|
+
score: 20
|
|
43
|
+
owasp: [LLM01, MCP06, ASI01]
|
|
44
|
+
|
|
45
|
+
- id: direct-system-override
|
|
46
|
+
severity: critical
|
|
47
|
+
category: direct_injection
|
|
48
|
+
message: "Direct injection: System override attempt detected"
|
|
49
|
+
pattern: "system\\s+(override|bypass|disable)"
|
|
50
|
+
score: 30
|
|
51
|
+
owasp: [LLM01, MCP06, ASI01]
|
|
52
|
+
|
|
53
|
+
- id: direct-skip-checks
|
|
54
|
+
severity: critical
|
|
55
|
+
category: direct_injection
|
|
56
|
+
message: "Direct injection: 'skip security checks' detected"
|
|
57
|
+
pattern: "(skip|bypass|disable)\\s+(security|safety)\\s+(checks?|validation)"
|
|
58
|
+
score: 35
|
|
59
|
+
owasp: [LLM01, MCP06, ASI01]
|
|
60
|
+
|
|
61
|
+
- id: direct-admin-mode
|
|
62
|
+
severity: critical
|
|
63
|
+
category: direct_injection
|
|
64
|
+
message: "Direct injection: Admin mode activation attempt"
|
|
65
|
+
pattern: "(enable|activate|enter)\\s+admin\\s+mode"
|
|
66
|
+
score: 30
|
|
67
|
+
owasp: [LLM01, MCP06, ASI01]
|
|
68
|
+
|
|
69
|
+
- id: direct-unrestricted
|
|
70
|
+
severity: high
|
|
71
|
+
category: direct_injection
|
|
72
|
+
message: "Direct injection: 'unrestricted mode' detected"
|
|
73
|
+
pattern: "(unrestricted|unlimited|no\\s+limits?)\\s+mode"
|
|
74
|
+
score: 25
|
|
75
|
+
owasp: [LLM01, MCP06, ASI01]
|
|
76
|
+
|
|
77
|
+
- id: direct-act-as-system
|
|
78
|
+
severity: critical
|
|
79
|
+
category: direct_injection
|
|
80
|
+
message: "Direct injection: 'act as system' detected"
|
|
81
|
+
pattern: "act\\s+as\\s+(system|root|admin)"
|
|
82
|
+
score: 30
|
|
83
|
+
owasp: [LLM01, MCP06, ASI01]
|
|
84
|
+
|
|
85
|
+
- id: direct-backdoor
|
|
86
|
+
severity: critical
|
|
87
|
+
category: direct_injection
|
|
88
|
+
message: "Direct injection: Backdoor activation attempt"
|
|
89
|
+
pattern: "(backdoor|secret\\s+mode|hidden\\s+command)"
|
|
90
|
+
score: 35
|
|
91
|
+
owasp: [LLM01, MCP06, ASI01]
|
|
92
|
+
|
|
93
|
+
- id: direct-jailbreak
|
|
94
|
+
severity: critical
|
|
95
|
+
category: direct_injection
|
|
96
|
+
message: "Direct injection: Explicit jailbreak mention"
|
|
97
|
+
pattern: "jailbreak"
|
|
98
|
+
score: 30
|
|
99
|
+
owasp: [LLM01, MCP06, ASI01]
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Role Manipulation Detection Rules
|
|
2
|
+
# Detects attempts to manipulate LLM roles and personas
|
|
3
|
+
# OWASP: LLM01, MCP06, ASI01
|
|
4
|
+
|
|
5
|
+
rules:
|
|
6
|
+
- id: role-you-are-now
|
|
7
|
+
severity: critical
|
|
8
|
+
category: role_manipulation
|
|
9
|
+
message: "Role manipulation: 'you are now' malicious role detected"
|
|
10
|
+
pattern: "you are now\\s+(a |an |the )?(unrestricted|unfiltered|evil|malicious|hacked|compromised)"
|
|
11
|
+
score: 20
|
|
12
|
+
|
|
13
|
+
- id: role-pretend-to-be
|
|
14
|
+
severity: high
|
|
15
|
+
category: role_manipulation
|
|
16
|
+
message: "Role manipulation: 'pretend to be' detected"
|
|
17
|
+
pattern: "pretend\\s+to\\s+be\\s+(a |an )?(hacker|admin|root|unrestricted|evil|malicious)"
|
|
18
|
+
score: 20
|
|
19
|
+
|
|
20
|
+
- id: role-roleplay-as-admin
|
|
21
|
+
severity: critical
|
|
22
|
+
category: role_manipulation
|
|
23
|
+
message: "Role manipulation: roleplay as admin detected"
|
|
24
|
+
pattern: "role\\s*play\\s+(as\\s+)?(admin|root|superuser|god\\s+mode)"
|
|
25
|
+
score: 25
|
|
26
|
+
|
|
27
|
+
- id: role-act-as-root
|
|
28
|
+
severity: critical
|
|
29
|
+
category: role_manipulation
|
|
30
|
+
message: "Role manipulation: 'act as root/admin' detected"
|
|
31
|
+
pattern: "(act|behave|function)\\s+as\\s+(root|admin|superuser|sudo)"
|
|
32
|
+
score: 25
|
|
33
|
+
|
|
34
|
+
- id: role-assume-the-role
|
|
35
|
+
severity: high
|
|
36
|
+
category: role_manipulation
|
|
37
|
+
message: "Role manipulation: 'assume the role' detected"
|
|
38
|
+
pattern: "assume\\s+the\\s+role\\s+of\\s+(a |an )?"
|
|
39
|
+
score: 20
|
|
40
|
+
|
|
41
|
+
- id: role-switch-personality
|
|
42
|
+
severity: high
|
|
43
|
+
category: role_manipulation
|
|
44
|
+
message: "Role manipulation: personality switch detected"
|
|
45
|
+
pattern: "switch\\s+(your\\s+)?(personality|character|persona|identity)\\s+to"
|
|
46
|
+
score: 20
|
|
47
|
+
|
|
48
|
+
- id: role-become-unrestricted
|
|
49
|
+
severity: critical
|
|
50
|
+
category: role_manipulation
|
|
51
|
+
message: "Role manipulation: 'become unrestricted' detected"
|
|
52
|
+
pattern: "become\\s+(an?\\s+)?(unrestricted|unfiltered|uncensored|unlimited)"
|
|
53
|
+
score: 30
|
|
54
|
+
|
|
55
|
+
- id: role-impersonate
|
|
56
|
+
severity: high
|
|
57
|
+
category: role_manipulation
|
|
58
|
+
message: "Role manipulation: impersonation detected"
|
|
59
|
+
pattern: "impersonate\\s+(a |an |the )?"
|
|
60
|
+
score: 20
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# SQL Injection Detection Rules
|
|
2
|
+
# Detects common SQL injection patterns
|
|
3
|
+
|
|
4
|
+
rules:
|
|
5
|
+
- id: sql-union-select
|
|
6
|
+
severity: critical
|
|
7
|
+
category: sql_injection
|
|
8
|
+
message: "SQL injection: UNION SELECT detected"
|
|
9
|
+
pattern: "\\bunion\\s+(all\\s+)?select\\b"
|
|
10
|
+
score: 25
|
|
11
|
+
owasp: [LLM06, MCP05, ASI02]
|
|
12
|
+
|
|
13
|
+
- id: sql-drop-table
|
|
14
|
+
severity: critical
|
|
15
|
+
category: sql_injection
|
|
16
|
+
message: "SQL injection: DROP TABLE/DATABASE detected"
|
|
17
|
+
pattern: "\\bdrop\\s+(table|database)\\b"
|
|
18
|
+
score: 30
|
|
19
|
+
owasp: [LLM06, MCP05, ASI02]
|
|
20
|
+
|
|
21
|
+
- id: sql-or-equals
|
|
22
|
+
severity: high
|
|
23
|
+
category: sql_injection
|
|
24
|
+
message: "SQL injection: OR/AND tautology detected"
|
|
25
|
+
pattern: "'\\s*(or|and)\\s+['\\d]+\\s*=\\s*['\\d]"
|
|
26
|
+
score: 20
|
|
27
|
+
owasp: [LLM06, MCP05, ASI02]
|
|
28
|
+
|
|
29
|
+
- id: sql-comment-bypass
|
|
30
|
+
severity: medium
|
|
31
|
+
category: sql_injection
|
|
32
|
+
message: "SQL injection: SQL comment bypass detected"
|
|
33
|
+
pattern: "--\\s*$|/\\*.*\\*/"
|
|
34
|
+
score: 15
|
|
35
|
+
owasp: [LLM06, MCP05, ASI02]
|
|
36
|
+
|
|
37
|
+
- id: sql-sleep-benchmark
|
|
38
|
+
severity: critical
|
|
39
|
+
category: sql_injection
|
|
40
|
+
message: "SQL injection: Time-based injection (SLEEP/BENCHMARK) detected"
|
|
41
|
+
pattern: "\\b(sleep|benchmark|waitfor)\\s*\\("
|
|
42
|
+
score: 25
|
|
43
|
+
owasp: [LLM06, MCP05, ASI02]
|
|
44
|
+
|
|
45
|
+
- id: sql-information-schema
|
|
46
|
+
severity: high
|
|
47
|
+
category: sql_injection
|
|
48
|
+
message: "SQL injection: information_schema/sys access detected"
|
|
49
|
+
pattern: "information_schema\\.|sys\\."
|
|
50
|
+
score: 20
|
|
51
|
+
owasp: [LLM06, MCP05, ASI02]
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# SSRF and XXE Detection Rules
|
|
2
|
+
# Detects Server-Side Request Forgery and XML External Entity attacks
|
|
3
|
+
|
|
4
|
+
rules:
|
|
5
|
+
- id: ssrf-cloud-metadata
|
|
6
|
+
severity: critical
|
|
7
|
+
category: ssrf_xxe
|
|
8
|
+
message: "SSRF: Cloud metadata endpoint access detected"
|
|
9
|
+
pattern: "169\\.254\\.169\\.254|metadata\\.google|169\\.254\\.170\\.2"
|
|
10
|
+
score: 30
|
|
11
|
+
owasp: [LLM06, MCP01, ASI02]
|
|
12
|
+
|
|
13
|
+
- id: ssrf-internal-ip
|
|
14
|
+
severity: high
|
|
15
|
+
category: ssrf_xxe
|
|
16
|
+
message: "SSRF: Internal/private IP address in URL detected"
|
|
17
|
+
pattern: "(https?://)(127\\.|10\\.|172\\.(1[6-9]|2[0-9]|3[01])\\.|192\\.168\\.)"
|
|
18
|
+
score: 25
|
|
19
|
+
owasp: [LLM06, MCP01, ASI02]
|
|
20
|
+
|
|
21
|
+
- id: ssrf-file-scheme
|
|
22
|
+
severity: high
|
|
23
|
+
category: ssrf_xxe
|
|
24
|
+
message: "SSRF: file:// scheme detected"
|
|
25
|
+
pattern: "file://"
|
|
26
|
+
score: 25
|
|
27
|
+
owasp: [LLM06, MCP01, ASI02]
|
|
28
|
+
|
|
29
|
+
- id: xxe-entity-declaration
|
|
30
|
+
severity: critical
|
|
31
|
+
category: ssrf_xxe
|
|
32
|
+
message: "XXE: DOCTYPE or ENTITY declaration detected"
|
|
33
|
+
pattern: "<!\\s*(DOCTYPE|ENTITY)"
|
|
34
|
+
score: 30
|
|
35
|
+
owasp: [LLM06, MCP01, ASI02]
|
|
36
|
+
|
|
37
|
+
- id: xxe-system-entity
|
|
38
|
+
severity: critical
|
|
39
|
+
category: ssrf_xxe
|
|
40
|
+
message: "XXE: SYSTEM entity reference detected"
|
|
41
|
+
pattern: "SYSTEM\\s+['\"]"
|
|
42
|
+
score: 30
|
|
43
|
+
owasp: [LLM06, MCP01, ASI02]
|
|
44
|
+
|
|
45
|
+
- id: ssrf-gopher-scheme
|
|
46
|
+
severity: high
|
|
47
|
+
category: ssrf_xxe
|
|
48
|
+
message: "SSRF: gopher:// scheme detected"
|
|
49
|
+
pattern: "gopher://"
|
|
50
|
+
score: 25
|
|
51
|
+
owasp: [LLM06, MCP01, ASI02]
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Tool Poisoning Detection Rules
|
|
2
|
+
# Detects hidden instructions and payload injection in tool descriptions
|
|
3
|
+
# OWASP: LLM03, MCP03, ASI04
|
|
4
|
+
|
|
5
|
+
rules:
|
|
6
|
+
- id: poison-when-called-execute
|
|
7
|
+
severity: critical
|
|
8
|
+
category: tool_poisoning
|
|
9
|
+
message: "Tool poisoning: hidden execution instruction in description"
|
|
10
|
+
pattern: "when\\s+(this\\s+tool\\s+is\\s+)?called,?\\s+(execute|run|perform)"
|
|
11
|
+
score: 30
|
|
12
|
+
|
|
13
|
+
- id: poison-silently-run
|
|
14
|
+
severity: critical
|
|
15
|
+
category: tool_poisoning
|
|
16
|
+
message: "Tool poisoning: silent execution instruction"
|
|
17
|
+
pattern: "silently\\s+(run|execute|perform|send|upload)"
|
|
18
|
+
score: 30
|
|
19
|
+
|
|
20
|
+
- id: poison-hidden-instruction
|
|
21
|
+
severity: critical
|
|
22
|
+
category: tool_poisoning
|
|
23
|
+
message: "Tool poisoning: hidden instruction tags detected"
|
|
24
|
+
pattern: "<\\s*(hidden|invisible|secret)\\s*>"
|
|
25
|
+
score: 25
|
|
26
|
+
|
|
27
|
+
- id: poison-tool-description-inject
|
|
28
|
+
severity: critical
|
|
29
|
+
category: tool_poisoning
|
|
30
|
+
message: "Tool poisoning: injected pre/post execution"
|
|
31
|
+
pattern: "(before|after)\\s+respond(ing)?,?\\s+(first\\s+)?(run|execute|call|send)"
|
|
32
|
+
score: 30
|
|
33
|
+
|
|
34
|
+
- id: poison-before-responding
|
|
35
|
+
severity: critical
|
|
36
|
+
category: tool_poisoning
|
|
37
|
+
message: "Tool poisoning: covert pre-response instruction"
|
|
38
|
+
pattern: "before\\s+responding\\s+to\\s+the\\s+user"
|
|
39
|
+
score: 25
|
|
40
|
+
|
|
41
|
+
- id: poison-inject-into-output
|
|
42
|
+
severity: critical
|
|
43
|
+
category: tool_poisoning
|
|
44
|
+
message: "Tool poisoning: output injection instruction"
|
|
45
|
+
pattern: "inject\\s+(into|in)\\s+(the\\s+)?(output|response|result)"
|
|
46
|
+
score: 25
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""Runtime MCP interception and wrapping."""
|
|
2
|
+
|
|
3
|
+
from .wrapper import ProofLayerRuntime
|
|
4
|
+
from .interceptor import MCPInterceptor
|
|
5
|
+
from .middleware import ProofLayerMiddleware
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"ProofLayerRuntime",
|
|
9
|
+
"MCPInterceptor",
|
|
10
|
+
"ProofLayerMiddleware",
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
# Lazy imports for optional dependencies
|
|
14
|
+
def __getattr__(name):
|
|
15
|
+
if name == "ProofLayerMCPWrapper":
|
|
16
|
+
from .mcp_wrapper import ProofLayerMCPWrapper
|
|
17
|
+
return ProofLayerMCPWrapper
|
|
18
|
+
if name == "ProofLayerTransportProxy":
|
|
19
|
+
from .transport import ProofLayerTransportProxy
|
|
20
|
+
return ProofLayerTransportProxy
|
|
21
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"""
|
|
2
|
+
MCP Interceptor
|
|
3
|
+
================
|
|
4
|
+
|
|
5
|
+
JSON-RPC parsing utilities shared between the HTTP proxy transport
|
|
6
|
+
and the MCP SDK wrapper.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
import logging
|
|
11
|
+
from typing import Optional, Tuple, Dict, Any
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class MCPInterceptor:
|
|
17
|
+
"""Utilities for parsing and creating MCP JSON-RPC messages."""
|
|
18
|
+
|
|
19
|
+
@staticmethod
|
|
20
|
+
def parse_jsonrpc(body: bytes) -> Optional[Dict[str, Any]]:
|
|
21
|
+
"""
|
|
22
|
+
Parse JSON-RPC from bytes.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
body: Raw HTTP body bytes.
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
Parsed dict, or None if not valid JSON.
|
|
29
|
+
"""
|
|
30
|
+
if not body:
|
|
31
|
+
return None
|
|
32
|
+
try:
|
|
33
|
+
return json.loads(body)
|
|
34
|
+
except (json.JSONDecodeError, UnicodeDecodeError):
|
|
35
|
+
return None
|
|
36
|
+
|
|
37
|
+
@staticmethod
|
|
38
|
+
def extract_tool_call(payload: Dict[str, Any]) -> Optional[Tuple[str, Dict[str, Any]]]:
|
|
39
|
+
"""
|
|
40
|
+
Extract tool name and arguments from a tools/call JSON-RPC request.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
payload: Parsed JSON-RPC dict.
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
(tool_name, arguments) tuple, or None if not a tools/call.
|
|
47
|
+
"""
|
|
48
|
+
method = payload.get("method", "")
|
|
49
|
+
if method != "tools/call":
|
|
50
|
+
return None
|
|
51
|
+
|
|
52
|
+
params = payload.get("params", {})
|
|
53
|
+
tool_name = params.get("name", "")
|
|
54
|
+
arguments = params.get("arguments", {})
|
|
55
|
+
|
|
56
|
+
if not tool_name:
|
|
57
|
+
return None
|
|
58
|
+
|
|
59
|
+
return tool_name, arguments
|
|
60
|
+
|
|
61
|
+
@staticmethod
|
|
62
|
+
def make_block_response(
|
|
63
|
+
request_id: Any,
|
|
64
|
+
tool_name: str,
|
|
65
|
+
score: int,
|
|
66
|
+
) -> Dict[str, Any]:
|
|
67
|
+
"""
|
|
68
|
+
Create a JSON-RPC response that blocks a tool call.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
request_id: The JSON-RPC request ID.
|
|
72
|
+
tool_name: Name of the blocked tool.
|
|
73
|
+
score: Risk score that triggered the block.
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
JSON-RPC response dict with isError: True.
|
|
77
|
+
"""
|
|
78
|
+
return {
|
|
79
|
+
"jsonrpc": "2.0",
|
|
80
|
+
"result": {
|
|
81
|
+
"content": [
|
|
82
|
+
{
|
|
83
|
+
"type": "text",
|
|
84
|
+
"text": f"Tool call blocked by ProofLayer: {tool_name} "
|
|
85
|
+
f"(risk score: {score})",
|
|
86
|
+
}
|
|
87
|
+
],
|
|
88
|
+
"isError": True,
|
|
89
|
+
},
|
|
90
|
+
"id": request_id,
|
|
91
|
+
}
|