tweek 0.1.0__py3-none-any.whl → 0.2.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.
Files changed (85) hide show
  1. tweek/__init__.py +2 -2
  2. tweek/_keygen.py +53 -0
  3. tweek/audit.py +288 -0
  4. tweek/cli.py +5303 -2396
  5. tweek/cli_model.py +380 -0
  6. tweek/config/families.yaml +609 -0
  7. tweek/config/manager.py +42 -5
  8. tweek/config/patterns.yaml +1510 -8
  9. tweek/config/tiers.yaml +161 -11
  10. tweek/diagnostics.py +71 -2
  11. tweek/hooks/break_glass.py +163 -0
  12. tweek/hooks/feedback.py +223 -0
  13. tweek/hooks/overrides.py +531 -0
  14. tweek/hooks/post_tool_use.py +472 -0
  15. tweek/hooks/pre_tool_use.py +1024 -62
  16. tweek/integrations/openclaw.py +443 -0
  17. tweek/integrations/openclaw_server.py +385 -0
  18. tweek/licensing.py +14 -54
  19. tweek/logging/bundle.py +2 -2
  20. tweek/logging/security_log.py +56 -13
  21. tweek/mcp/approval.py +57 -16
  22. tweek/mcp/proxy.py +18 -0
  23. tweek/mcp/screening.py +5 -5
  24. tweek/mcp/server.py +4 -1
  25. tweek/memory/__init__.py +24 -0
  26. tweek/memory/queries.py +223 -0
  27. tweek/memory/safety.py +140 -0
  28. tweek/memory/schemas.py +80 -0
  29. tweek/memory/store.py +989 -0
  30. tweek/platform/__init__.py +4 -4
  31. tweek/plugins/__init__.py +40 -24
  32. tweek/plugins/base.py +1 -1
  33. tweek/plugins/detectors/__init__.py +3 -3
  34. tweek/plugins/detectors/{moltbot.py → openclaw.py} +30 -27
  35. tweek/plugins/git_discovery.py +16 -4
  36. tweek/plugins/git_registry.py +8 -2
  37. tweek/plugins/git_security.py +21 -9
  38. tweek/plugins/screening/__init__.py +10 -1
  39. tweek/plugins/screening/heuristic_scorer.py +477 -0
  40. tweek/plugins/screening/llm_reviewer.py +14 -6
  41. tweek/plugins/screening/local_model_reviewer.py +161 -0
  42. tweek/proxy/__init__.py +38 -37
  43. tweek/proxy/addon.py +22 -3
  44. tweek/proxy/interceptor.py +1 -0
  45. tweek/proxy/server.py +4 -2
  46. tweek/sandbox/__init__.py +11 -0
  47. tweek/sandbox/docker_bridge.py +143 -0
  48. tweek/sandbox/executor.py +9 -6
  49. tweek/sandbox/layers.py +97 -0
  50. tweek/sandbox/linux.py +1 -0
  51. tweek/sandbox/project.py +548 -0
  52. tweek/sandbox/registry.py +149 -0
  53. tweek/security/__init__.py +9 -0
  54. tweek/security/language.py +250 -0
  55. tweek/security/llm_reviewer.py +1146 -60
  56. tweek/security/local_model.py +331 -0
  57. tweek/security/local_reviewer.py +146 -0
  58. tweek/security/model_registry.py +371 -0
  59. tweek/security/rate_limiter.py +11 -6
  60. tweek/security/secret_scanner.py +70 -4
  61. tweek/security/session_analyzer.py +26 -2
  62. tweek/skill_template/SKILL.md +200 -0
  63. tweek/skill_template/__init__.py +0 -0
  64. tweek/skill_template/cli-reference.md +331 -0
  65. tweek/skill_template/overrides-reference.md +184 -0
  66. tweek/skill_template/scripts/__init__.py +0 -0
  67. tweek/skill_template/scripts/check_installed.py +170 -0
  68. tweek/skills/__init__.py +38 -0
  69. tweek/skills/config.py +150 -0
  70. tweek/skills/fingerprints.py +198 -0
  71. tweek/skills/guard.py +293 -0
  72. tweek/skills/isolation.py +469 -0
  73. tweek/skills/scanner.py +715 -0
  74. tweek/vault/__init__.py +0 -1
  75. tweek/vault/cross_platform.py +12 -1
  76. tweek/vault/keychain.py +87 -29
  77. tweek-0.2.0.dist-info/METADATA +281 -0
  78. tweek-0.2.0.dist-info/RECORD +121 -0
  79. {tweek-0.1.0.dist-info → tweek-0.2.0.dist-info}/entry_points.txt +8 -1
  80. {tweek-0.1.0.dist-info → tweek-0.2.0.dist-info}/licenses/LICENSE +80 -0
  81. tweek/integrations/moltbot.py +0 -243
  82. tweek-0.1.0.dist-info/METADATA +0 -335
  83. tweek-0.1.0.dist-info/RECORD +0 -85
  84. {tweek-0.1.0.dist-info → tweek-0.2.0.dist-info}/WHEEL +0 -0
  85. {tweek-0.1.0.dist-info → tweek-0.2.0.dist-info}/top_level.txt +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": ("safe", "Find files by pattern"),
107
- "Grep": ("safe", "Search file contents"),
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 = {"moltbot", "cursor", "continue", "copilot", "windsurf"}
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]: