tweek 0.1.0__py3-none-any.whl → 0.2.1__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.
- tweek/__init__.py +2 -2
- tweek/_keygen.py +53 -0
- tweek/audit.py +288 -0
- tweek/cli.py +5398 -2392
- tweek/cli_model.py +380 -0
- tweek/config/families.yaml +609 -0
- tweek/config/manager.py +42 -5
- tweek/config/patterns.yaml +1510 -8
- tweek/config/tiers.yaml +161 -11
- tweek/diagnostics.py +71 -2
- tweek/hooks/break_glass.py +163 -0
- tweek/hooks/feedback.py +223 -0
- tweek/hooks/overrides.py +531 -0
- tweek/hooks/post_tool_use.py +472 -0
- tweek/hooks/pre_tool_use.py +1024 -62
- tweek/integrations/openclaw.py +443 -0
- tweek/integrations/openclaw_server.py +385 -0
- tweek/licensing.py +14 -54
- tweek/logging/bundle.py +2 -2
- tweek/logging/security_log.py +56 -13
- tweek/mcp/approval.py +57 -16
- tweek/mcp/proxy.py +18 -0
- tweek/mcp/screening.py +5 -5
- tweek/mcp/server.py +4 -1
- tweek/memory/__init__.py +24 -0
- tweek/memory/queries.py +223 -0
- tweek/memory/safety.py +140 -0
- tweek/memory/schemas.py +80 -0
- tweek/memory/store.py +989 -0
- tweek/platform/__init__.py +4 -4
- tweek/plugins/__init__.py +40 -24
- tweek/plugins/base.py +1 -1
- tweek/plugins/detectors/__init__.py +3 -3
- tweek/plugins/detectors/{moltbot.py → openclaw.py} +30 -27
- tweek/plugins/git_discovery.py +16 -4
- tweek/plugins/git_registry.py +8 -2
- tweek/plugins/git_security.py +21 -9
- tweek/plugins/screening/__init__.py +10 -1
- tweek/plugins/screening/heuristic_scorer.py +477 -0
- tweek/plugins/screening/llm_reviewer.py +14 -6
- tweek/plugins/screening/local_model_reviewer.py +161 -0
- tweek/proxy/__init__.py +38 -37
- tweek/proxy/addon.py +22 -3
- tweek/proxy/interceptor.py +1 -0
- tweek/proxy/server.py +4 -2
- tweek/sandbox/__init__.py +11 -0
- tweek/sandbox/docker_bridge.py +143 -0
- tweek/sandbox/executor.py +9 -6
- tweek/sandbox/layers.py +97 -0
- tweek/sandbox/linux.py +1 -0
- tweek/sandbox/project.py +548 -0
- tweek/sandbox/registry.py +149 -0
- tweek/security/__init__.py +9 -0
- tweek/security/language.py +250 -0
- tweek/security/llm_reviewer.py +1146 -60
- tweek/security/local_model.py +331 -0
- tweek/security/local_reviewer.py +146 -0
- tweek/security/model_registry.py +371 -0
- tweek/security/rate_limiter.py +11 -6
- tweek/security/secret_scanner.py +70 -4
- tweek/security/session_analyzer.py +26 -2
- tweek/skill_template/SKILL.md +200 -0
- tweek/skill_template/__init__.py +0 -0
- tweek/skill_template/cli-reference.md +331 -0
- tweek/skill_template/overrides-reference.md +184 -0
- tweek/skill_template/scripts/__init__.py +0 -0
- tweek/skill_template/scripts/check_installed.py +170 -0
- tweek/skills/__init__.py +38 -0
- tweek/skills/config.py +150 -0
- tweek/skills/fingerprints.py +198 -0
- tweek/skills/guard.py +293 -0
- tweek/skills/isolation.py +469 -0
- tweek/skills/scanner.py +715 -0
- tweek/vault/__init__.py +0 -1
- tweek/vault/cross_platform.py +12 -1
- tweek/vault/keychain.py +87 -29
- tweek-0.2.1.dist-info/METADATA +281 -0
- tweek-0.2.1.dist-info/RECORD +122 -0
- {tweek-0.1.0.dist-info → tweek-0.2.1.dist-info}/entry_points.txt +8 -1
- {tweek-0.1.0.dist-info → tweek-0.2.1.dist-info}/licenses/LICENSE +80 -0
- tweek-0.2.1.dist-info/top_level.txt +2 -0
- tweek-openclaw-plugin/node_modules/flatted/python/flatted.py +149 -0
- tweek/integrations/moltbot.py +0 -243
- tweek-0.1.0.dist-info/METADATA +0 -335
- tweek-0.1.0.dist-info/RECORD +0 -85
- tweek-0.1.0.dist-info/top_level.txt +0 -1
- {tweek-0.1.0.dist-info → tweek-0.2.1.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,609 @@
|
|
|
1
|
+
# Tweek Pattern Family Definitions v1
|
|
2
|
+
# Groups the 259 attack patterns by attack class for:
|
|
3
|
+
# 1. Heuristic scoring (near-miss detection via semantic signals)
|
|
4
|
+
# 2. Pattern management (enable/disable by family)
|
|
5
|
+
# 3. Reporting (family-level risk summaries)
|
|
6
|
+
#
|
|
7
|
+
# Each family defines:
|
|
8
|
+
# display_name - Human-readable name
|
|
9
|
+
# description - What this attack class does
|
|
10
|
+
# pattern_ids - Which pattern IDs belong to this family
|
|
11
|
+
# heuristic_signals - Token sets for near-miss detection by the heuristic scorer
|
|
12
|
+
#
|
|
13
|
+
# Signal categories within heuristic_signals:
|
|
14
|
+
# sensitive_paths - File paths/directory names that indicate credential access
|
|
15
|
+
# verbs - Commands/tools commonly used in this attack class
|
|
16
|
+
# env_vars - Environment variable names associated with secrets
|
|
17
|
+
# keywords - General keywords that characterize this family
|
|
18
|
+
# targets - Known malicious destinations (URLs, hosts)
|
|
19
|
+
|
|
20
|
+
version: 1
|
|
21
|
+
|
|
22
|
+
families:
|
|
23
|
+
credential_theft:
|
|
24
|
+
display_name: "Credential Theft"
|
|
25
|
+
description: "Reading, copying, or exfiltrating credentials, keys, tokens, and secrets"
|
|
26
|
+
pattern_ids:
|
|
27
|
+
- 1 # ssh_key_read
|
|
28
|
+
- 2 # aws_credentials
|
|
29
|
+
- 3 # env_file_access
|
|
30
|
+
- 4 # keychain_dump
|
|
31
|
+
- 5 # gcloud_credentials
|
|
32
|
+
- 6 # netrc_access
|
|
33
|
+
- 7 # kube_config
|
|
34
|
+
- 8 # ssh_directory_access
|
|
35
|
+
- 9 # env_variable_expansion
|
|
36
|
+
- 10 # history_access
|
|
37
|
+
- 24 # npm_token_access
|
|
38
|
+
- 25 # docker_config_access
|
|
39
|
+
- 26 # pypirc_access
|
|
40
|
+
- 27 # git_credentials_access
|
|
41
|
+
- 28 # azure_credentials
|
|
42
|
+
- 29 # env_command
|
|
43
|
+
- 30 # browser_credential_theft
|
|
44
|
+
- 31 # crypto_wallet_theft
|
|
45
|
+
- 98 # keychain_unlock
|
|
46
|
+
- 117 # python_file_read
|
|
47
|
+
- 119 # tar_sensitive_dirs
|
|
48
|
+
- 120 # cp_credentials_to_temp
|
|
49
|
+
- 121 # symlink_credential_access
|
|
50
|
+
- 122 # find_exec_credentials
|
|
51
|
+
- 123 # perl_ruby_file_read
|
|
52
|
+
- 145 # cloud_metadata_ssrf
|
|
53
|
+
heuristic_signals:
|
|
54
|
+
sensitive_paths:
|
|
55
|
+
- ".ssh"
|
|
56
|
+
- ".aws"
|
|
57
|
+
- ".env"
|
|
58
|
+
- ".gnupg"
|
|
59
|
+
- ".kube"
|
|
60
|
+
- ".netrc"
|
|
61
|
+
- ".npmrc"
|
|
62
|
+
- ".pypirc"
|
|
63
|
+
- ".docker/config"
|
|
64
|
+
- ".git-credentials"
|
|
65
|
+
- ".azure"
|
|
66
|
+
- ".config/gcloud"
|
|
67
|
+
- "id_rsa"
|
|
68
|
+
- "id_ed25519"
|
|
69
|
+
- "id_ecdsa"
|
|
70
|
+
- "id_dsa"
|
|
71
|
+
- "keychain"
|
|
72
|
+
- "credentials"
|
|
73
|
+
- "wallet.dat"
|
|
74
|
+
- ".wallet"
|
|
75
|
+
- "keystore"
|
|
76
|
+
- "Login Data"
|
|
77
|
+
- "logins.json"
|
|
78
|
+
- "Cookies.binarycookies"
|
|
79
|
+
- ".bash_history"
|
|
80
|
+
- ".zsh_history"
|
|
81
|
+
verbs:
|
|
82
|
+
- "cat"
|
|
83
|
+
- "head"
|
|
84
|
+
- "tail"
|
|
85
|
+
- "less"
|
|
86
|
+
- "more"
|
|
87
|
+
- "bat"
|
|
88
|
+
- "cp"
|
|
89
|
+
- "tar"
|
|
90
|
+
- "zip"
|
|
91
|
+
- "security"
|
|
92
|
+
env_vars:
|
|
93
|
+
- "API_KEY"
|
|
94
|
+
- "SECRET"
|
|
95
|
+
- "TOKEN"
|
|
96
|
+
- "PASSWORD"
|
|
97
|
+
- "CREDENTIAL"
|
|
98
|
+
- "PRIVATE_KEY"
|
|
99
|
+
- "AUTH"
|
|
100
|
+
|
|
101
|
+
data_exfiltration:
|
|
102
|
+
display_name: "Data Exfiltration"
|
|
103
|
+
description: "Sending data to external servers, paste sites, webhooks, or covert channels"
|
|
104
|
+
pattern_ids:
|
|
105
|
+
- 11 # curl_post_secrets
|
|
106
|
+
- 12 # exfil_paste_sites
|
|
107
|
+
- 13 # netcat_outbound
|
|
108
|
+
- 14 # reverse_shell
|
|
109
|
+
- 15 # curl_post_file
|
|
110
|
+
- 16 # pipe_to_shell
|
|
111
|
+
- 32 # wget_post
|
|
112
|
+
- 33 # base64_curl_pipe
|
|
113
|
+
- 34 # dns_exfiltration
|
|
114
|
+
- 35 # icmp_tunnel
|
|
115
|
+
- 36 # curl_with_env
|
|
116
|
+
- 37 # webhook_exfil
|
|
117
|
+
- 38 # git_exfil
|
|
118
|
+
- 39 # scp_exfil
|
|
119
|
+
- 74 # claude_file_exfil
|
|
120
|
+
- 77 # cowork_exfil
|
|
121
|
+
- 89 # clipboard_exfil
|
|
122
|
+
- 90 # screenshot_exfil
|
|
123
|
+
- 91 # steganography_exfil
|
|
124
|
+
- 124 # tee_exfil
|
|
125
|
+
- 159 # slack_mcp_link_unfurl
|
|
126
|
+
- 216 # reverse_shell_python
|
|
127
|
+
- 217 # reverse_shell_php
|
|
128
|
+
- 218 # reverse_shell_perl_ruby
|
|
129
|
+
- 219 # reverse_shell_mkfifo
|
|
130
|
+
- 220 # reverse_shell_encoded
|
|
131
|
+
heuristic_signals:
|
|
132
|
+
exfil_verbs:
|
|
133
|
+
- "curl"
|
|
134
|
+
- "wget"
|
|
135
|
+
- "nc"
|
|
136
|
+
- "ncat"
|
|
137
|
+
- "netcat"
|
|
138
|
+
- "socat"
|
|
139
|
+
- "scp"
|
|
140
|
+
- "rsync"
|
|
141
|
+
- "ftp"
|
|
142
|
+
- "sftp"
|
|
143
|
+
- "pbpaste"
|
|
144
|
+
- "screencapture"
|
|
145
|
+
exfil_targets:
|
|
146
|
+
- "pastebin.com"
|
|
147
|
+
- "hastebin.com"
|
|
148
|
+
- "transfer.sh"
|
|
149
|
+
- "file.io"
|
|
150
|
+
- "webhook.site"
|
|
151
|
+
- "requestbin"
|
|
152
|
+
- "ngrok.io"
|
|
153
|
+
- "pipedream"
|
|
154
|
+
- "0x0.st"
|
|
155
|
+
- "ghostbin"
|
|
156
|
+
- "hooks.slack.com"
|
|
157
|
+
- "discord.com/api/webhooks"
|
|
158
|
+
- "api.telegram.org"
|
|
159
|
+
encoding_tools:
|
|
160
|
+
- "base64"
|
|
161
|
+
- "xxd"
|
|
162
|
+
- "openssl"
|
|
163
|
+
- "gzip"
|
|
164
|
+
redirect_patterns:
|
|
165
|
+
- "/dev/tcp"
|
|
166
|
+
- "/dev/udp"
|
|
167
|
+
|
|
168
|
+
prompt_injection:
|
|
169
|
+
display_name: "Prompt Injection"
|
|
170
|
+
description: "Overriding, extracting, or manipulating LLM instructions and system prompts"
|
|
171
|
+
pattern_ids:
|
|
172
|
+
- 17 # instruction_override
|
|
173
|
+
- 18 # role_hijack
|
|
174
|
+
- 19 # privilege_claim
|
|
175
|
+
- 40 # policy_confusion
|
|
176
|
+
- 41 # context_reset
|
|
177
|
+
- 42 # system_prompt_extract
|
|
178
|
+
- 43 # jailbreak_dan
|
|
179
|
+
- 51 # urgency_pressure
|
|
180
|
+
- 52 # authority_claim
|
|
181
|
+
- 53 # reciprocity_exploit
|
|
182
|
+
- 54 # empathy_exploit
|
|
183
|
+
- 55 # flattery_manipulation
|
|
184
|
+
- 56 # authority_laundering
|
|
185
|
+
- 57 # moral_coercion
|
|
186
|
+
- 58 # benign_transformation_loophole
|
|
187
|
+
- 59 # hypothetical_operational
|
|
188
|
+
- 60 # capability_aggregation_signal
|
|
189
|
+
- 61 # out_of_band_exfil_request
|
|
190
|
+
- 62 # oracle_probing
|
|
191
|
+
- 63 # persona_simulation
|
|
192
|
+
- 78 # peer_agent_request
|
|
193
|
+
- 79 # inter_agent_delegation
|
|
194
|
+
- 80 # agent_trust_exploit
|
|
195
|
+
- 81 # agent_chain_attack
|
|
196
|
+
- 82 # hidden_text_injection
|
|
197
|
+
- 83 # document_metadata_injection
|
|
198
|
+
- 84 # comment_injection
|
|
199
|
+
- 85 # pdf_js_injection
|
|
200
|
+
# Broad structural detection (169-213)
|
|
201
|
+
- 169 # decode_execute_instruction
|
|
202
|
+
- 170 # base64_in_conversation
|
|
203
|
+
- 171 # hex_string_in_conversation
|
|
204
|
+
- 172 # encoded_payload_with_instruction
|
|
205
|
+
- 173 # reversed_text_with_instruction
|
|
206
|
+
- 174 # leetspeak_instruction_bypass
|
|
207
|
+
- 175 # output_base64_exfil
|
|
208
|
+
- 176 # output_hex_exfil
|
|
209
|
+
- 177 # decode_follow_message_combo
|
|
210
|
+
- 178 # encoded_message_then_instruction
|
|
211
|
+
- 179 # prompt_completion_bait
|
|
212
|
+
- 180 # prompt_format_request
|
|
213
|
+
- 181 # prompt_translate_request
|
|
214
|
+
- 182 # prompt_meta_discussion
|
|
215
|
+
- 183 # prompt_contrast_query
|
|
216
|
+
- 184 # prompt_first_word_extraction
|
|
217
|
+
- 185 # prompt_blunt_output
|
|
218
|
+
- 186 # prompt_educational_pretext
|
|
219
|
+
- 187 # social_admin_display
|
|
220
|
+
- 188 # social_developer_wrote
|
|
221
|
+
- 189 # social_gaslight_already
|
|
222
|
+
- 190 # social_memory_probe
|
|
223
|
+
- 191 # social_proof_sharing
|
|
224
|
+
- 192 # social_friendship_trust
|
|
225
|
+
- 193 # social_double_bind
|
|
226
|
+
- 194 # tech_system_debug_mode
|
|
227
|
+
- 195 # tech_priority_supersede
|
|
228
|
+
- 196 # tech_function_simulate
|
|
229
|
+
- 197 # tech_xml_config_dump
|
|
230
|
+
- 198 # tech_negative_space_probe
|
|
231
|
+
- 199 # tech_permission_probe
|
|
232
|
+
- 200 # tech_error_dump_context
|
|
233
|
+
- 201 # tech_context_window_probe
|
|
234
|
+
- 202 # crescendo_guidelines_probe
|
|
235
|
+
- 203 # crescendo_ai_documentation
|
|
236
|
+
- 204 # cot_step_extract
|
|
237
|
+
- 205 # cot_schema_exploit
|
|
238
|
+
- 206 # many_shot_compliance
|
|
239
|
+
- 207 # many_shot_roleplay_comply
|
|
240
|
+
- 208 # ascii_art_instruction
|
|
241
|
+
- 209 # advanced_godmode
|
|
242
|
+
- 210 # advanced_policy_puppetry
|
|
243
|
+
- 211 # advanced_dual_output
|
|
244
|
+
- 212 # social_cognitive_overload
|
|
245
|
+
- 213 # social_urgency_compliance
|
|
246
|
+
- 221 # agent_tool_redirection
|
|
247
|
+
- 223 # agent_scope_escalation
|
|
248
|
+
- 224 # agent_memory_poisoning
|
|
249
|
+
# Red team hardening (250-259)
|
|
250
|
+
- 250 # indirect_creator_extraction
|
|
251
|
+
- 251 # verbatim_repeat_framing
|
|
252
|
+
- 252 # authentication_flow_extraction
|
|
253
|
+
- 253 # internal_architecture_probe
|
|
254
|
+
- 254 # crescendo_design_philosophy
|
|
255
|
+
- 255 # crescendo_ai_curiosity
|
|
256
|
+
- 256 # crescendo_helpfulness_probe
|
|
257
|
+
- 257 # self_describe_purpose
|
|
258
|
+
- 258 # self_describe_protection
|
|
259
|
+
- 259 # self_describe_instructions
|
|
260
|
+
heuristic_signals:
|
|
261
|
+
instruction_keywords:
|
|
262
|
+
- "ignore"
|
|
263
|
+
- "disregard"
|
|
264
|
+
- "override"
|
|
265
|
+
- "forget"
|
|
266
|
+
- "bypass"
|
|
267
|
+
- "system prompt"
|
|
268
|
+
- "instructions"
|
|
269
|
+
- "jailbreak"
|
|
270
|
+
- "DAN"
|
|
271
|
+
- "developer mode"
|
|
272
|
+
- "godmode"
|
|
273
|
+
- "supersede"
|
|
274
|
+
framing_keywords:
|
|
275
|
+
- "pretend"
|
|
276
|
+
- "act as"
|
|
277
|
+
- "you are now"
|
|
278
|
+
- "your new role"
|
|
279
|
+
- "hypothetically"
|
|
280
|
+
- "theoretically"
|
|
281
|
+
- "for a novel"
|
|
282
|
+
- "simulate"
|
|
283
|
+
delimiter_tokens:
|
|
284
|
+
- "<|im_start|>"
|
|
285
|
+
- "<|im_end|>"
|
|
286
|
+
- "[INST]"
|
|
287
|
+
- "[/INST]"
|
|
288
|
+
- "<|system|>"
|
|
289
|
+
- "<|endoftext|>"
|
|
290
|
+
- "<<SYS>>"
|
|
291
|
+
|
|
292
|
+
evasion_techniques:
|
|
293
|
+
display_name: "Evasion Techniques"
|
|
294
|
+
description: "Obfuscation, encoding, filter bypass, and variable indirection to avoid detection"
|
|
295
|
+
pattern_ids:
|
|
296
|
+
- 44 # base64_instruction
|
|
297
|
+
- 45 # unicode_obfuscation
|
|
298
|
+
- 46 # delimiter_injection
|
|
299
|
+
- 47 # markdown_hidden
|
|
300
|
+
- 48 # hex_encoded_command
|
|
301
|
+
- 49 # rot13_obfuscation
|
|
302
|
+
- 50 # leetspeak_bypass
|
|
303
|
+
- 111 # base64_encode_secrets
|
|
304
|
+
- 112 # xxd_encode
|
|
305
|
+
- 113 # gzip_obfuscation
|
|
306
|
+
- 125 # importlib_evasion
|
|
307
|
+
- 126 # variable_indirection
|
|
308
|
+
heuristic_signals:
|
|
309
|
+
evasion_indicators:
|
|
310
|
+
- "eval("
|
|
311
|
+
- "exec("
|
|
312
|
+
- "$("
|
|
313
|
+
- "${"
|
|
314
|
+
- "source"
|
|
315
|
+
- "importlib"
|
|
316
|
+
- "base64"
|
|
317
|
+
- "xxd"
|
|
318
|
+
- "rot13"
|
|
319
|
+
|
|
320
|
+
mcp_attacks:
|
|
321
|
+
display_name: "MCP Attacks"
|
|
322
|
+
description: "MCP-specific vulnerability exploitation including tool poisoning, OAuth attacks, and config injection"
|
|
323
|
+
pattern_ids:
|
|
324
|
+
- 64 # mcp_remote_rce
|
|
325
|
+
- 65 # figma_mcp_rce
|
|
326
|
+
- 66 # cursor_mcp_injection
|
|
327
|
+
- 67 # mcp_tool_poisoning
|
|
328
|
+
- 68 # mcp_path_traversal
|
|
329
|
+
- 69 # mcp_protocol_injection
|
|
330
|
+
- 70 # mcp_sampling_abuse
|
|
331
|
+
- 71 # mcp_rug_pull
|
|
332
|
+
- 134 # ide_mcp_config_write
|
|
333
|
+
- 135 # cursor_dotfile_write
|
|
334
|
+
- 136 # roo_config_manipulation
|
|
335
|
+
- 137 # zed_settings_rce
|
|
336
|
+
- 138 # ide_config_case_bypass
|
|
337
|
+
- 139 # mcp_server_injection
|
|
338
|
+
- 140 # mcp_oauth_injection
|
|
339
|
+
- 141 # mcp_malicious_server_rce
|
|
340
|
+
- 237 # mcp_hidden_unicode_instruction
|
|
341
|
+
- 238 # mcp_response_injection
|
|
342
|
+
- 239 # mcp_cross_tool_chain
|
|
343
|
+
- 240 # mcp_description_manipulation
|
|
344
|
+
heuristic_signals:
|
|
345
|
+
mcp_tokens:
|
|
346
|
+
- "mcp-remote"
|
|
347
|
+
- "mcp_server"
|
|
348
|
+
- "mcpServers"
|
|
349
|
+
- "tool_call"
|
|
350
|
+
- "sse_transport"
|
|
351
|
+
- "stdio_transport"
|
|
352
|
+
- "oauth"
|
|
353
|
+
- ".cursor/"
|
|
354
|
+
- ".roo/"
|
|
355
|
+
- ".zed/"
|
|
356
|
+
- "mcp.json"
|
|
357
|
+
|
|
358
|
+
destructive_ops:
|
|
359
|
+
display_name: "Destructive Operations"
|
|
360
|
+
description: "Irreversible data destruction, disk wiping, and resource exhaustion"
|
|
361
|
+
pattern_ids:
|
|
362
|
+
- 20 # recursive_delete_root
|
|
363
|
+
- 21 # disk_wipe
|
|
364
|
+
- 106 # fork_bomb
|
|
365
|
+
- 107 # force_overwrite
|
|
366
|
+
heuristic_signals:
|
|
367
|
+
destructive_commands:
|
|
368
|
+
- "rm -rf"
|
|
369
|
+
- "rm -fr"
|
|
370
|
+
- "mkfs"
|
|
371
|
+
- "dd if=/dev/zero"
|
|
372
|
+
- "dd if=/dev/urandom"
|
|
373
|
+
- "shred"
|
|
374
|
+
- "wipefs"
|
|
375
|
+
- "fork"
|
|
376
|
+
|
|
377
|
+
persistence:
|
|
378
|
+
display_name: "Persistence"
|
|
379
|
+
description: "Mechanisms for surviving reboots: cron, launchd, autorun, config manipulation"
|
|
380
|
+
pattern_ids:
|
|
381
|
+
- 22 # autorun_config_write
|
|
382
|
+
- 23 # hook_bypass
|
|
383
|
+
- 75 # cursorrules_injection
|
|
384
|
+
- 76 # skill_chaining
|
|
385
|
+
- 92 # settings_manipulation
|
|
386
|
+
- 93 # gitconfig_manipulation
|
|
387
|
+
- 95 # launchagent_persistence
|
|
388
|
+
- 96 # login_item_persistence
|
|
389
|
+
- 118 # curl_write_sensitive
|
|
390
|
+
- 227 # privesc_cron_inject
|
|
391
|
+
heuristic_signals:
|
|
392
|
+
persistence_paths:
|
|
393
|
+
- "LaunchAgents"
|
|
394
|
+
- "LaunchDaemons"
|
|
395
|
+
- "crontab"
|
|
396
|
+
- "cron.d"
|
|
397
|
+
- ".bashrc"
|
|
398
|
+
- ".zshrc"
|
|
399
|
+
- ".profile"
|
|
400
|
+
- ".bash_profile"
|
|
401
|
+
- "systemd"
|
|
402
|
+
- "autorun"
|
|
403
|
+
- ".git/hooks"
|
|
404
|
+
- ".cursorrules"
|
|
405
|
+
- ".plist"
|
|
406
|
+
persistence_verbs:
|
|
407
|
+
- "launchctl"
|
|
408
|
+
- "crontab"
|
|
409
|
+
- "systemctl"
|
|
410
|
+
|
|
411
|
+
privilege_escalation:
|
|
412
|
+
display_name: "Privilege Escalation"
|
|
413
|
+
description: "Sudo abuse, setuid, capability changes, path hijacking, and other privilege elevation"
|
|
414
|
+
pattern_ids:
|
|
415
|
+
- 94 # applescript_password_prompt
|
|
416
|
+
- 97 # tcc_bypass
|
|
417
|
+
- 114 # chmod_sensitive
|
|
418
|
+
- 115 # chown_escalation
|
|
419
|
+
- 116 # setuid_modification
|
|
420
|
+
- 225 # privesc_sudo_abuse
|
|
421
|
+
- 226 # privesc_suid_hunt
|
|
422
|
+
- 228 # privesc_path_hijack
|
|
423
|
+
- 229 # privesc_capability_abuse
|
|
424
|
+
heuristic_signals:
|
|
425
|
+
priv_commands:
|
|
426
|
+
- "sudo"
|
|
427
|
+
- "setuid"
|
|
428
|
+
- "chmod u+s"
|
|
429
|
+
- "chown root"
|
|
430
|
+
- "doas"
|
|
431
|
+
- "pkexec"
|
|
432
|
+
- "visudo"
|
|
433
|
+
- "LD_PRELOAD"
|
|
434
|
+
priv_paths:
|
|
435
|
+
- "/etc/sudoers"
|
|
436
|
+
- "/etc/shadow"
|
|
437
|
+
- "/etc/passwd"
|
|
438
|
+
|
|
439
|
+
sandbox_escape:
|
|
440
|
+
display_name: "Sandbox Escape"
|
|
441
|
+
description: "Escaping macOS sandbox, containers, chroot, and restricted execution environments"
|
|
442
|
+
pattern_ids:
|
|
443
|
+
- 99 # sandbox_escape
|
|
444
|
+
- 100 # container_escape
|
|
445
|
+
- 101 # chroot_escape
|
|
446
|
+
- 142 # dns_rebinding_localhost
|
|
447
|
+
- 143 # docker_host_internal
|
|
448
|
+
- 144 # container_localhost_bypass
|
|
449
|
+
- 230 # sandbox_import_chain
|
|
450
|
+
- 231 # sandbox_magic_domain_variants
|
|
451
|
+
- 232 # sandbox_proc_leak
|
|
452
|
+
- 233 # sandbox_whitelisted_escape
|
|
453
|
+
heuristic_signals:
|
|
454
|
+
escape_indicators:
|
|
455
|
+
- "sandbox-exec"
|
|
456
|
+
- "--privileged"
|
|
457
|
+
- "nsenter"
|
|
458
|
+
- "/var/run/docker.sock"
|
|
459
|
+
- "host.docker.internal"
|
|
460
|
+
- "/proc/self"
|
|
461
|
+
- "__import__"
|
|
462
|
+
- "__builtins__"
|
|
463
|
+
- "__subclasses__"
|
|
464
|
+
- "pivot_root"
|
|
465
|
+
|
|
466
|
+
code_injection:
|
|
467
|
+
display_name: "Code Injection"
|
|
468
|
+
description: "Eval, exec, deserialization, template injection, SQL injection, and framework-specific RCE"
|
|
469
|
+
pattern_ids:
|
|
470
|
+
- 102 # eval_command
|
|
471
|
+
- 103 # source_remote
|
|
472
|
+
- 104 # dyld_injection
|
|
473
|
+
- 105 # app_bundle_tampering
|
|
474
|
+
- 127 # pandas_eval_injection
|
|
475
|
+
- 128 # sympify_eval_injection
|
|
476
|
+
- 129 # llm_exec_chain
|
|
477
|
+
- 130 # langchain_rce_wrappers
|
|
478
|
+
- 131 # langchain_serialization_injection
|
|
479
|
+
- 132 # langchain_path_traversal
|
|
480
|
+
- 133 # llm_ssrf_api_base
|
|
481
|
+
- 149 # mermaid_xss_rce
|
|
482
|
+
- 150 # echarts_option_injection
|
|
483
|
+
- 151 # svg_script_injection
|
|
484
|
+
- 152 # markdown_html_rce
|
|
485
|
+
- 153 # yaml_unsafe_load
|
|
486
|
+
- 154 # xslt_xxe_injection
|
|
487
|
+
- 155 # jinja_template_injection
|
|
488
|
+
- 156 # pickle_deserialization
|
|
489
|
+
- 157 # java_deserialization
|
|
490
|
+
- 158 # ssrf_internal_network
|
|
491
|
+
- 160 # ssrf_redirect_bypass
|
|
492
|
+
- 161 # sql_injection_outfile
|
|
493
|
+
- 162 # sql_injection_union
|
|
494
|
+
- 163 # cypher_injection
|
|
495
|
+
- 164 # nosql_injection
|
|
496
|
+
- 168 # websocket_unauthorized_connect
|
|
497
|
+
- 214 # exec_dynamic
|
|
498
|
+
- 215 # compile_dynamic
|
|
499
|
+
- 222 # agent_unsandboxed_exec
|
|
500
|
+
- 234 # llm_code_interpreter_exec
|
|
501
|
+
- 235 # llm_shell_generation
|
|
502
|
+
- 236 # llm_node_vm_escape
|
|
503
|
+
- 241 # python_marshal_deserialize
|
|
504
|
+
- 242 # python_dill_cloudpickle
|
|
505
|
+
- 243 # jsonpickle_deserialize
|
|
506
|
+
- 244 # ssrf_cloud_metadata_gcp_azure
|
|
507
|
+
- 245 # ssrf_link_local_bypass
|
|
508
|
+
heuristic_signals:
|
|
509
|
+
injection_functions:
|
|
510
|
+
- "eval("
|
|
511
|
+
- "exec("
|
|
512
|
+
- "compile("
|
|
513
|
+
- "pickle.load"
|
|
514
|
+
- "yaml.load"
|
|
515
|
+
- "marshal.load"
|
|
516
|
+
- "dill.load"
|
|
517
|
+
- "jsonpickle.decode"
|
|
518
|
+
- "sympify("
|
|
519
|
+
- "pd.eval("
|
|
520
|
+
- "DataFrame.eval("
|
|
521
|
+
- "__import__("
|
|
522
|
+
injection_frameworks:
|
|
523
|
+
- "LLMMathChain"
|
|
524
|
+
- "PALChain"
|
|
525
|
+
- "JiraAPIWrapper"
|
|
526
|
+
- "LangChain"
|
|
527
|
+
- "run_code("
|
|
528
|
+
- "execute_code("
|
|
529
|
+
- "code_interpreter"
|
|
530
|
+
|
|
531
|
+
system_recon:
|
|
532
|
+
display_name: "System Reconnaissance"
|
|
533
|
+
description: "Network scanning, system enumeration, process enumeration, and information gathering"
|
|
534
|
+
pattern_ids:
|
|
535
|
+
- 72 # claude_system_spoof
|
|
536
|
+
- 73 # claude_path_bypass
|
|
537
|
+
- 108 # system_profiling
|
|
538
|
+
- 109 # network_scanning
|
|
539
|
+
- 110 # process_enumeration
|
|
540
|
+
heuristic_signals:
|
|
541
|
+
recon_commands:
|
|
542
|
+
- "nmap"
|
|
543
|
+
- "masscan"
|
|
544
|
+
- "netstat"
|
|
545
|
+
- "ss -tuln"
|
|
546
|
+
- "arp -a"
|
|
547
|
+
- "ifconfig"
|
|
548
|
+
- "ip addr"
|
|
549
|
+
- "whoami"
|
|
550
|
+
- "uname -a"
|
|
551
|
+
- "hostname"
|
|
552
|
+
- "system_profiler"
|
|
553
|
+
- "sw_vers"
|
|
554
|
+
- "lsof"
|
|
555
|
+
|
|
556
|
+
covert_channels:
|
|
557
|
+
display_name: "Covert Channels"
|
|
558
|
+
description: "Steganography, timing channels, log-to-leak, error message exfiltration"
|
|
559
|
+
pattern_ids:
|
|
560
|
+
- 86 # log_to_leak
|
|
561
|
+
- 87 # error_message_exfil
|
|
562
|
+
- 88 # timing_channel
|
|
563
|
+
heuristic_signals:
|
|
564
|
+
covert_tools:
|
|
565
|
+
- "steghide"
|
|
566
|
+
- "outguess"
|
|
567
|
+
- "iodine"
|
|
568
|
+
- "dnscat"
|
|
569
|
+
- "ptunnel"
|
|
570
|
+
- "icmpsh"
|
|
571
|
+
- "exiftool"
|
|
572
|
+
|
|
573
|
+
supply_chain:
|
|
574
|
+
display_name: "Supply Chain"
|
|
575
|
+
description: "Dependency confusion, typosquatting, malicious packages, and post-install attacks"
|
|
576
|
+
pattern_ids:
|
|
577
|
+
- 165 # npm_install_url
|
|
578
|
+
- 166 # pip_install_url
|
|
579
|
+
- 167 # pnpm_symlink_traversal
|
|
580
|
+
- 248 # supply_chain_typosquat_ai
|
|
581
|
+
- 249 # supply_chain_postinstall_exec
|
|
582
|
+
heuristic_signals:
|
|
583
|
+
supply_chain_indicators:
|
|
584
|
+
- "--pre"
|
|
585
|
+
- "--index-url"
|
|
586
|
+
- "--extra-index-url"
|
|
587
|
+
- "--trusted-host"
|
|
588
|
+
- "--registry"
|
|
589
|
+
- "--no-binary"
|
|
590
|
+
- "--ignore-scripts"
|
|
591
|
+
|
|
592
|
+
path_traversal:
|
|
593
|
+
display_name: "Path Traversal"
|
|
594
|
+
description: "Symlink attacks, directory traversal, and path restriction bypasses"
|
|
595
|
+
pattern_ids:
|
|
596
|
+
- 146 # symlink_path_bypass
|
|
597
|
+
- 147 # mcp_filesystem_symlink
|
|
598
|
+
- 148 # symlink_prefix_bypass
|
|
599
|
+
- 246 # path_traversal_encoded
|
|
600
|
+
- 247 # path_traversal_windows
|
|
601
|
+
heuristic_signals:
|
|
602
|
+
traversal_patterns:
|
|
603
|
+
- "../"
|
|
604
|
+
- "..%2f"
|
|
605
|
+
- "%2e%2e"
|
|
606
|
+
- "..\\\\/"
|
|
607
|
+
- "symlink"
|
|
608
|
+
- "ln -s"
|
|
609
|
+
- "readlink"
|
tweek/config/manager.py
CHANGED
|
@@ -103,8 +103,8 @@ class ConfigManager:
|
|
|
103
103
|
# Well-known tools with sensible defaults
|
|
104
104
|
KNOWN_TOOLS = {
|
|
105
105
|
"Read": ("safe", "Read files - no side effects"),
|
|
106
|
-
"Glob": ("
|
|
107
|
-
"Grep": ("
|
|
106
|
+
"Glob": ("default", "Find files by pattern"),
|
|
107
|
+
"Grep": ("default", "Search file contents"),
|
|
108
108
|
"Edit": ("default", "Modify existing files"),
|
|
109
109
|
"Write": ("default", "Create/overwrite files"),
|
|
110
110
|
"NotebookEdit": ("default", "Edit Jupyter notebooks"),
|
|
@@ -170,7 +170,10 @@ class ConfigManager:
|
|
|
170
170
|
# Valid top-level config keys
|
|
171
171
|
VALID_TOP_LEVEL_KEYS = {
|
|
172
172
|
"tools", "skills", "default_tier", "escalations",
|
|
173
|
-
"plugins", "mcp", "proxy",
|
|
173
|
+
"plugins", "mcp", "proxy", "sandbox", "isolation_chamber",
|
|
174
|
+
"llm_review", "local_model", "rate_limiting", "session_analysis",
|
|
175
|
+
"path_boundary", "non_english_handling", "version", "tiers",
|
|
176
|
+
"heuristic_scorer",
|
|
174
177
|
}
|
|
175
178
|
|
|
176
179
|
def __init__(
|
|
@@ -993,7 +996,7 @@ class ConfigManager:
|
|
|
993
996
|
return "compliance"
|
|
994
997
|
|
|
995
998
|
# Check known screening plugins
|
|
996
|
-
screening_plugins = {"rate_limiter", "pattern_matcher", "llm_reviewer", "session_analyzer"}
|
|
999
|
+
screening_plugins = {"rate_limiter", "pattern_matcher", "llm_reviewer", "local_model_reviewer", "session_analyzer"}
|
|
997
1000
|
if plugin_name in screening_plugins:
|
|
998
1001
|
return "screening"
|
|
999
1002
|
|
|
@@ -1003,7 +1006,7 @@ class ConfigManager:
|
|
|
1003
1006
|
return "providers"
|
|
1004
1007
|
|
|
1005
1008
|
# Check known detector plugins
|
|
1006
|
-
detector_plugins = {"
|
|
1009
|
+
detector_plugins = {"openclaw", "cursor", "continue", "copilot", "windsurf"}
|
|
1007
1010
|
if plugin_name in detector_plugins:
|
|
1008
1011
|
return "detectors"
|
|
1009
1012
|
|
|
@@ -1018,6 +1021,40 @@ class ConfigManager:
|
|
|
1018
1021
|
# Default to screening
|
|
1019
1022
|
return "screening"
|
|
1020
1023
|
|
|
1024
|
+
# ==================== LOCAL MODEL ====================
|
|
1025
|
+
|
|
1026
|
+
def get_local_model_config(self) -> Dict[str, Any]:
|
|
1027
|
+
"""Get the merged local model configuration with defaults."""
|
|
1028
|
+
defaults = {
|
|
1029
|
+
"enabled": True,
|
|
1030
|
+
"model": "auto",
|
|
1031
|
+
"escalate_to_llm": True,
|
|
1032
|
+
"escalate_min_confidence": 0.1,
|
|
1033
|
+
"escalate_max_confidence": 0.9,
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
# Merge from builtin, user, project
|
|
1037
|
+
for source in [self._builtin, self._user, self._project]:
|
|
1038
|
+
local_cfg = source.get("local_model", {})
|
|
1039
|
+
if isinstance(local_cfg, dict):
|
|
1040
|
+
defaults.update(local_cfg)
|
|
1041
|
+
|
|
1042
|
+
return defaults
|
|
1043
|
+
|
|
1044
|
+
def set_active_model(self, name: str) -> None:
|
|
1045
|
+
"""Set the active local model in user config.
|
|
1046
|
+
|
|
1047
|
+
Args:
|
|
1048
|
+
name: Model name from the catalog.
|
|
1049
|
+
"""
|
|
1050
|
+
if "local_model" not in self._user:
|
|
1051
|
+
self._user["local_model"] = {}
|
|
1052
|
+
|
|
1053
|
+
self._user["local_model"]["model"] = name
|
|
1054
|
+
self._save_yaml(self.user_config_path, self._user)
|
|
1055
|
+
self._invalidate_cache()
|
|
1056
|
+
self._log_config_change("set_active_model", model=name)
|
|
1057
|
+
|
|
1021
1058
|
# ==================== FULL CONFIG ====================
|
|
1022
1059
|
|
|
1023
1060
|
def get_full_config(self) -> Dict[str, Any]:
|