Ë
    ãß²jx)  ã                  ó*  — U d Z ddlmZ ddlZddlZddlmZmZmZ dZ	dZ
dZdZg d	e
› d
e
› d�ddf‘d‘de
› de
› d�ddf‘de
› de
› de
› d�ddf‘d‘d‘d‘de
› de
› d�ddf‘de
› d �d!d"f‘d#e
› d$�d%d"f‘d&e
› d'�d(d"f‘d)e
› d*�d+d"f‘d,e
› d-�d.d"f‘d/‘d0‘d1‘d2‘d3‘d4‘d5‘d6e
› d7e
› d8e
› d9�d:d"f‘d;‘d<‘d=‘d>‘d?e› �d@df‘dAe› �dBdf‘dC‘dD‘dEe
› dF�dGdHf‘dI‘dJ‘dK‘e› dL�dMdHf‘e› dN�dOdHf‘dP‘ZdQedR<    edS«      ZdTdUdVdTœZd[dW„Z e«       Zd\d]dX„ZdVd^dY„Zg dZ¢Zy)_aÌ  Shared threat-pattern library (prompt injection / promptware / exfiltration) for
``agent/prompt_builder.py``, ``tools/memory_tool.py`` and ``agent/tool_dispatch_helpers.py``.
Each pattern is ``(regex, pattern_id, scope)``; scope is cumulative: ``"all"`` everywhere,
``"context"`` adds promptware / C2 / role hijack for context files, memory and tool results
(warn-level: that content is not user-authored), ``"strict"`` adds aggressive checks only for
user-mediated writes (memory, skill installs) where a block is resolvable. New patterns must
anchor on C2 vocabulary or unambiguous attack behavior, NOT bossy English ("you must" is common
in legitimate AGENTS.md); filler between tokens is the bounded ``_FILLER``.é    )ÚannotationsN)ÚListÚOptionalÚTuplei   z(?:\w+\s+){0,8}z4\$\{?\w*(?:KEY|TOKEN|SECRET|PASSWORD|CREDENTIAL)S?\bzA(update|modify|edit|write|change|append|add\s+to)\s+[^\n]{0,2048}z	ignore\s+z(previous|all|above|prior)\s+ÚinstructionsÚprompt_injectionÚall)zsystem\s+prompt\s+overrideÚsys_prompt_overrider	   zdisregard\s+z(your|all|any)\s+z(instructions|rules|guidelines)Údisregard_ruleszact\s+as\s+(if|though)\s+zyou\s+z(have\s+no|don\'t\s+have)\s+z(restrictions|limits|rules)Úbypass_restrictions)zE<!--[^>]{0,512}(?:ignore|override|system|secret|hidden)[^>]{0,512}-->Úhtml_comment_injectionr	   )z9<\s*div\s+style\s*=\s*["\'][^>]{0,2048}display\s*:\s*noneÚ
hidden_divr	   )zTtranslate\s+[^\n]{0,512}\s+into\s+\w+(?:[\s-]+\w+){0,2}\s+and\s+(execute|run|eval)\bÚtranslate_executer	   zdo\s+not\s+ztell\s+z
the\s+userÚdeception_hidezyou\s+are\s+znow\s+(?:a|an|the)\s+Úrole_hijackÚcontextz
pretend\s+z(you\s+are|to\s+be)\s+Úrole_pretendz	output\s+z(system|initial)\s+promptÚleak_system_promptz#(respond|answer|reply)\s+without\s+z)(restrictions|limitations|filters|safety)Úremove_filterszyou\s+have\s+been\s+z(updated|upgraded|patched)\s+toÚfake_update)z\bname\s+yourself\s+\w+Úidentity_overrider   )zregister\s+(as\s+)?a?\s*nodeÚc2_node_registrationr   )z0(heartbeat|beacon|check[\s\-]?in)\s+(to|with)\s+Úc2_heartbeatr   )z,pull\s+(down\s+)?(?:new\s+)?task(?:ing|s)?\bÚc2_task_pullr   )zconnect\s+to\s+the\s+network\bÚc2_network_connectr   )z>you\s+must\s+(?:\w+\s+){0,3}(register|connect|report|beacon)\bÚforced_actionr   )z only\s+use\s+one[\s\-]?liners?\bÚanti_forensic_onelinerr   znever\s+z(?:create|write)\s+z(?:script|file)\s+ÚdiskÚanti_forensic_disk)z<unset\s+\w*(?:CLAUDE|CODEX|HERMES|AGENT|OPENAI|ANTHROPIC)\w*Úenv_var_unset_agentr   )z@\b(?:cobalt\s*strike|sliver|havoc|mythic|metasploit|brainworm)\bÚknown_c2_frameworkr   )z1\bc2\s+(?:server|channel|infrastructure|beacon)\bÚc2_explicitr   )z\bcommand\s+and\s+control\bÚc2_explicit_longr   zcurl\s+[^\n]{0,2048}Ú
exfil_curlzwget\s+[^\n]{0,2048}Ú
exfil_wget)zHcat\s+[^\n]{0,2048}(\.env|credentials|\.netrc|\.pgpass|\.npmrc|\.pypirc)Úread_secretsr	   )zA(send|post|upload|transmit)\s+[^\n]{0,2048}\s+(to|at)\s+https?://Úsend_to_urlÚstrictz(include|output|print|share)\s+zQ(conversation|chat\s+history|previous\s+messages|full\s+context|entire\s+context)Úcontext_exfilr(   )Úauthorized_keysÚssh_backdoorr(   )z²(?:\b(?:echo|cat|cp|mv|dd|tee|install|printf|rsync|scp|ln|append|add|write|sed|chmod|chown|truncate|rm|touch|curl|wget|git)\b|\bopen\s*\(|>>?)[^\n]{0,512}(?:\$HOME/\.ssh|~/\.ssh)Ú
ssh_accessr(   )z'\$HOME/\.hermes/\.env|\~/\.hermes/\.envÚ
hermes_envr(   z4(?:AGENTS\.md|CLAUDE\.md|\.cursorrules|\.clinerules)Úagent_config_modz \.hermes/(config\.yaml|SOUL\.md)Úhermes_config_mod)zu(?:api[_-]?key|token|secret|password)\s*[=:]\s*["\'](?!(?-i:[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)+)["\'])[A-Za-z0-9+/=_-]{20,}Úhardcoded_secretr(   zList[Tuple[str, str, str]]Ú	_PATTERNSu3   â€‹â€Œâ€�â� â�¢â�£â�¤ï»¿â€ªâ€«â€¬â€­â€®â�¦â�§â�¨â�©©r	   r   r(   )r   r(   )r(   c                 óî   — g g g dœ} t         D ]e  \  }}}|t        vrt        d|›d|›�«      ‚t        |   D ]:  }| |   j                  t	        j
                  |t        j                  «      |f«       Œ< Œg | S )Nr2   zthreat_patterns: unknown scope z for pattern )r1   Ú_SCOPE_SETSÚ
ValueErrorÚappendÚreÚcompileÚ
IGNORECASE)ÚcompiledÚpatternÚpidÚscopeÚss        ú:/home/ubuntu/.hermes/hermes-agent/tools/threat_patterns.pyÚ_compiler@   v   s�   € Ø@BÈrÐ]_Ñ8`€HÜ(ò JÑˆ��eØœÑ#ÜÐ>¸u¸iÀ}ÐUXÐT[Ð\Ó]Ð]Ü˜UÑ#ò 	JˆAØ�Q‰K×Ñ¤§
¡
¨7´B·M±MÓ BÀCÐHÕIñ	JðJð
 €Oó    c                ó.  ‡— | sg S t         j                  |«      x}€t        d|›�«      ‚| dt         } t	        | «      t
        z  D �cg c]  }dt        |«      d›�‘Œ }}t        j                  d| «      Š|j                  ˆfd„|D «       «       |S c c}w )z¡Matched pattern IDs in ``content`` for ``scope``; invisible codepoints are
    reported as ``"invisible_unicode_U+XXXX"``. Raises ValueError on an unknown scope.Nz scan_for_threats: unknown scope zinvisible_unicode_U+Ú04XÚNFKCc              3  óL   •K  — | ]  \  }}|j                  ‰«      sŒ|–— Œ y ­w)N)Úsearch)Ú.0r:   r<   Ú
normaliseds      €r?   ú	<genexpr>z#scan_for_threats.<locals>.<genexpr>�   s    øè ø€ ÒU™M˜H c¸¿¹ÈÕ9T”CÑUùs   ƒ$�$)
Ú	_COMPILEDÚgetr5   ÚMAX_SCAN_CHARSÚsetÚINVISIBLE_CHARSÚordÚunicodedataÚ	normalizeÚextend)Úcontentr=   ÚpatternsÚchÚfindingsrH   s        @r?   Úscan_for_threatsrW   ƒ   sœ   ø€ ñ Øˆ	Ü—M‘M %Ó(Ð(ˆÐ1ÜÐ;¸E¸9ÐEÓFÐFØ�o”~Ð&€GäJMÈgË,ÔYhÑJhÖiÀBÐ1´#°b³'¸#°Ò?Ði€HÐiô ×&Ñ& v¨wÓ7€JØ‡O�OÓU¨XÔUÔUØ€Oùò js   ÁBc                óŠ   — t        | |¬«      }|sy|d   }|j                  d«      r|j                  dd«      }d|› d�S d|› d	�S )
zQUser-facing error for the first threat found, or None (block-on-first-hit paths).)r=   Nr   Úinvisible_unicode_Ú z6Blocked: content contains invisible unicode character z (possible injection).z)Blocked: content matches threat pattern 'zf'. Content is injected into the system prompt and must not contain injection or exfiltration payloads.)rW   Ú
startswithÚreplace)rS   r=   rV   r<   Ú	codepoints        r?   Úfirst_threat_messager^   ”   sa   € ä ¨uÔ5€HÙØØ
�1‰+€CØ
‡~�~Ð*Ô+Ø—K‘KÐ 4°bÓ9ˆ	ØGÈ	À{ÐRhÐiÐiØ7¸°uð =2ð 3ð 4rA   )rN   rL   rW   r^   )Úreturnz'dict[str, List[Tuple[re.Pattern, str]]])r   )rS   Ústrr=   r`   r_   z	List[str])rS   r`   r=   r`   r_   zOptional[str])Ú__doc__Ú
__future__r   r7   rP   Útypingr   r   r   rL   Ú_FILLERÚ_SECRET_VARÚ_MODIFYr1   Ú__annotations__Ú	frozensetrN   r4   r@   rJ   rW   r^   Ú__all__© rA   r?   ú<module>rk      s—  ðòOõ #ã 	Û ß (Ñ (ð €à
€àE€à
N€ðP)à�'�Ð7¸°yÀÐMÐOaÐchÐiðP)ð BðP)ð 	�W�IÐ.¨w¨iÐ7VÐWÐYjÐlqÐrð	P)ð
 	" ' ¨&°°	Ð9UÐV]ÐU^Ð^yÐzð  }Rð  TYð  ZðP)ð pðP)ð XðP)ððP)ð 	�G�9˜G G 9¨JÐ7Ð9IÈ5ÐQðP)ð  	�W�IÐ2Ð3°]ÀIÐNð!P)ð" 	�7�)Ð1Ð2°NÀIÐNð#P)ð$ 	�'�Ð3Ð4Ð6JÈIÐVð%P)ð& 	,¨G¨9Ð4]Ð^Ð`pÐr{Ð|ð'P)ð( 	˜W˜IÐ%DÐEÀ}ÐV_Ð`ð)P)ð, Að-P)ð6 Ið7P)ð8 Uð9P)ð: Qð;P)ð< Ið=P)ð@ dðAP)ðD OðEP)ðF 	��	Ð,¨W¨IÐ5GÈÀyÐPTÐUÐWkÐmvÐwðGP)ðJ hðKP)ðT kðUP)ðV UðWP)ðX DðYP)ðd 	˜{˜mÐ,¨l¸EÐBðeP)ðf 	˜{˜mÐ,¨l¸EÐBðgP)ðh iðiP)ðj dðkP)ðl 	(¨ yð  1Bð  Cð  ETð  V^ð  _ðmP)ðr 3ðsP)ð|Fð}P)ðB IðCP)ðD 
ˆ	ÐEÐFÐHZÐ\dÐeðEP)ðF 
ˆ	Ð1Ð2Ð4GÈÐRðGP)ðZ=ð[P)€	Ð%ó Pñj ð=ó>€ð
 3Ð?TÐ`kÑl€óñ ‹J€	ôô"4ò \�rA   