Ë
    ãß²j¿!  ã                   óf  — U d Z ddlZddlmZ ddlmZ ddlmZ ddl	m
Z ddl	mZ ded	efd
„Zded	efd„Z ej$                  dej&                  «      Zded	ee   fd„Zded	ee   fd„Z ej$                  dej.                  «      df ej$                  dej.                  «      df ej$                  dej.                  «      df ej$                  dej.                  «      df ej$                  dej.                  «      df ej$                  dej.                  «      df ej$                  dej.                  «      df ej$                  dej.                  ej0                  z  «      d f ej$                  d!ej.                  ej0                  z  «      d ff	Zeeej6                  e   ef   d"f   ed#<    ej$                  d$ej0                  «      Zd%Zeeeef   d"f   ed&<   d'ed	efd(„Zd	efd)„Z d	efd*„Z!d+ed	efd,„Z"ded	e#e   fd-„Z$ded	ee   fd.„Z%ded	ee   fd/„Z&ded	ee   fd0„Z'd1ed2ed	ee   fd3„Z(y)4ué   browser_console(expression=...) policy: SSRF guard gating, private-URL probes,
and the opt-in sensitive-primitive denylist.

Facade-owned state is read through ``_bt`` (``tools.browser_tool``, resolved per call) â€” no import cycle.
é    N)ÚOptional©Úis_truthy_value)Úorigin_module)Úbrowser_tool_cloud)Úbrowser_tool_sessionÚeffective_task_idÚreturnc                 ó–   — t        «       }t        j                  «        xr) |j                  | «       xr t        j                  «        S )aw  Return True when eval-driven private-network access must be guarded.

    Same gating as ``browser_navigate`` / ``browser_snapshot`` / ``browser_vision``: the SSRF guard
    only matters for non-local backends (cloud browser, or a containerized terminal whose
    browser-on-host reaches networks the terminal can't); skipped for local sidecars / ``allow_private_urls``.
    )Ú_originÚ_cloudÚ_is_local_backendÚ_is_local_sidecar_keyÚ_allow_private_urls)r	   Ú_bts     úC/home/ubuntu/.hermes/hermes-agent/tools/browser_tool_eval_policy.pyÚ_eval_ssrf_guard_activer      s\   € ô ‹)€CÜ×'Ñ'Ó)Ð)ò  D°#×2KÑ2KÐL]Ó2^Ð.^ò  DÔgm÷  hBñ  hBó  hDð  dDð  Dó    Úurlc                 óL   — | j                  |«      xs | j                  |«       S )zWTrue when ``url`` hits the always-blocked cloud-metadata floor or fails the SSRF guard.)Ú_is_always_blocked_urlÚ_is_safe_url)r   r   s     r   Ú_url_blockedr      s&   € à×%Ñ% cÓ*ÒG°#×2BÑ2BÀ3Ó2GÐ.GÐGr   zhttps?://[^\s'"`)\]<>]+Ú
expressionc                 óž   ‡— t        «       Št        | t        «      rt        j	                  | «      ng }t        ˆfd„d„ |D «       D «       d«      S )zkReturn the first private/always-blocked ``http(s)://`` literal in a JS expression (best-effort), else None.c              3   ó<   •K  — | ]  }t        ‰|«      sŒ|–— Œ y ­w©N)r   )Ú.0Úcr   s     €r   ú	<genexpr>z2_expression_targets_private_url.<locals>.<genexpr>)   s   øè ø€ ÒX�qÄ<ÐPSÐUVÕCW”ÑXùs   ƒ•c              3   ó>   K  — | ]  }|j                  d «      –— Œ y­w)z.,;N)Úrstrip)r   Úms     r   r    z2_expression_targets_private_url.<locals>.<genexpr>)   s   è ø€ Ò?°˜QŸX™X eŸ_Ñ?ùs   ‚N)r   Ú
isinstanceÚstrÚ_JS_URL_LITERAL_REÚfindallÚnext)r   Úliteralsr   s     @r   Ú_expression_targets_private_urlr*   %   sB   ø€ ä
‹)€CÜ9CÀJÔPSÔ9TÔ!×)Ñ)¨*Ô5ÐZ\€HÜÓXÑ?°hÔ?ÔXÐZ^Ó_Ð_r   c                 ó’  — t        «       }	 t        j                  | ddgdd¬«      }|j                  d«      r^|j                  di «      j                  dd	«      j	                  «       j	                  d
«      j	                  d«      }|rt        ||«      r|S y# t        $ r&}|j                  j                  d|«       Y d}~yd}~ww xY w)zÀReturn the current page URL when it targets a private/internal address (e.g. after a prior
    ``location.href = '...'`` eval). Fail-open on probe failure, matching the snapshot/vision guards.Úevalúwindow.location.hrefé   Úauto)ÚtimeoutÚ_engine_overrideÚsuccessÚdataÚresultÚ ú"ú'z,_current_page_private_url: probe failed (%s)N)	r   Ú_sessionÚ_run_browser_commandÚgetÚstripr   Ú	ExceptionÚloggerÚdebug)r	   r   Ú
url_resultÚcurrent_urlÚexcs        r   Ú_current_page_private_urlrB   ,   sÇ   € ô ‹)€CðNÜ×2Ñ2Ð3DÀfÐOeÐNfÐpqð  EKô  Lˆ
Ø�>‰>˜)Ô$Ø$Ÿ.™.¨°Ó4×8Ñ8¸À2ÓF×LÑLÓN×TÑTÐUXÓY×_Ñ_Ð`cÓdˆKÙœ|¨C°Ô=Ø"Ð"ð øô ò NØ�
‰
×ÑÐGÈ×MÐMØûðNús   ŒB	B Â	CÂ CÃCz\bdocument\s*\.\s*cookie\búdocument.cookiez#\b(?:localStorage|sessionStorage)\búweb storagez\bindexedDB\bÚ	IndexedDBz%\bcaches\s*\.\s*(?:open|match|keys)\búCache Storagez<\bnavigator\s*\.\s*(?:clipboard|credentials|serviceWorker)\búnavigator sensitive APIz5\b(?:fetch|XMLHttpRequest|WebSocket|EventSource)\s*\(únetwork requestz"\bnavigator\s*\.\s*sendBeacon\s*\(únetwork beaconz$\bdocument\s*\.\s*forms\b.*\bvalue\bzform value extractionzN\bquerySelector(?:All)?\s*\([^)]*(?:input|textarea|password)[^)]*\).*\bvalue\b.Ú_RISKY_BROWSER_EVAL_PATTERNSz8'(?:\\.|[^'\\])*'|\"(?:\\.|[^\"\\])*\"|`(?:\\.|[^`\\])*`))ÚcookierC   )ÚlocalStoragerD   )ÚsessionStoragerD   )Ú	indexedDBrE   )ÚcachesrF   )Ú	clipboardrG   )ÚcredentialsrG   )ÚserviceWorkerrG   )ÚfetchrH   )ÚXMLHttpRequestrH   )Ú	WebSocketrH   )ÚEventSourcerH   )Ú
sendBeaconrI   Ú_SENSITIVE_BROWSER_EVAL_TOKENSÚkeyc                 óH   — t        «       }|j                  | dd„ d| › d�«      S )zRRead boolean ``browser.<key>`` (default False) through the origin's config reader.Fc                 ó   — t        | d¬«      S )NF)Údefaultr   )Úvs    r   ú<lambda>z$_browser_eval_flag.<locals>.<lambda>Y   s   € ´/À!ÈUÔ2S€ r   zbrowser.z from config)r   Ú_browser_cfg)rY   r   s     r   Ú_browser_eval_flagr`   V   s.   € ä
‹)€CØ×Ñ˜C Ñ(SÐW_Ð`cÐ_dÐdpÐUqÓrÐrr   c                  ó   — t        d«      S )z`Whether sensitive browser JS evaluation is explicitly allowed (overrides ``restrict_evaluate``).Úallow_unsafe_evaluate©r`   © r   r   Ú_allow_unsafe_browser_evaluatere   \   s   € äÐ5Ó6Ð6r   c                  ó   — t        d«      S )aÃ  Whether the sensitive-primitive eval denylist is enabled (off by default).

    It blocks the *names* of common primitives (``fetch``, ``cookie``, ``querySelector(...input...)``),
    not actual exfiltration, so it also blocks much legitimate DOM extraction; egress is still gated
    by the SSRF/private-URL guards in ``_browser_eval`` regardless. Opt in via
    ``browser.restrict_evaluate: true`` (e.g. hostile pages with a logged-in profile).
    Úrestrict_evaluaterc   rd   r   r   Ú_restrict_browser_evaluaterh   a   s   € ô Ð1Ó2Ð2r   Úliteralc                 óˆ   — t        | «      dk  r| S 	 t        | dd d«      j                  d«      S # t        $ r | dd cY S w xY w)zbBest-effort decode of a JS string literal (not a parser): normalizes escapes like ``"co\x6fkie"``.é   é   éÿÿÿÿzutf-8Úunicode_escape)ÚlenÚbytesÚdecoder<   )ri   s    r   Ú_decode_js_string_literalrr   l   sR   € ä
ˆ7ƒ|�aÒØˆðÜ�W˜Q˜r�] GÓ,×3Ñ3Ð4DÓEÐEøÜò Ø�q˜ˆ}Òðús   ’0 °AÁ Ac                 ó‚   — t         j                  | «      D �cg c]  }t        |j                  d«      «      ‘Œ c}S c c}w )Nr   )Ú_JS_STRING_LITERAL_REÚfinditerrr   Úgroup)r   Úmatchs     r   Ú_decoded_js_string_literalsrx   v   s0   € ÜCX×CaÑCaÐblÓCmÖn¸%Ô% e§k¡k°!£nÕ5ÒnÐnùÒns   ˜!<c                 óŠ   ‡ ‡— dj                  t        ‰ «      «      j                  «       Št        ˆ ˆfd„t        D «       d«      S )zÿRisk reason for direct or quoted sensitive primitives: direct spellings alone miss
    ``document["cookie"]`` / ``globalThis["fetch"]``, so tokens are also matched inside the decoded,
    concatenated string literals (catches ``document["coo" + "kie"]``).r5   c              3   óÄ   •K  — | ]W  \  }}t        j                  d t        j                  |«      › d �‰t         j                  «      s|j	                  «       ‰v r|–— ŒY y­w)z\bN)ÚreÚsearchÚescapeÚIÚlower)r   ÚtokenÚreasonr   r)   s      €€r   r    z7_sensitive_browser_eval_token_reason.<locals>.<genexpr>   sS   øè ø€ ò j™M˜E 6Ü—I‘I ¤B§I¡I¨eÓ$4Ð#5°RÐ8¸*ÄbÇdÁdÔKÈuÏ{É{Ë}Ð`hÑOhô ñ jùs   ƒAA N)Újoinrx   r   r(   rX   )r   r)   s   `@r   Ú$_sensitive_browser_eval_token_reasonrƒ   z   sC   ù€ ð �w‰wÔ2°:Ó>Ó?×EÑEÓG€HÜô jÔ-Kô jØkoóqð qr   c                 óZ   ‡ — ‰ syt        ˆ fd„t        D «       d«      }|xs t        ‰ «      S )zHReturn a human-readable reason if a JS expression uses risky primitives.Nc              3   óL   •K  — | ]  \  }}|j                  ‰«      sŒ|–— Œ y ­wr   )r|   )r   Úpatternr�   r   s      €r   r    z-_risky_browser_eval_reason.<locals>.<genexpr>‡   s!   øè ø€ Òi™?˜7 FÈgÏnÉnÐ]gÕNh”Ñiùs   ƒ$�$)r(   rJ   rƒ   )r   Úhits   ` r   Ú_risky_browser_eval_reasonrˆ   ƒ   s.   ø€ áØÜ
ÓiÔ.JÔiÐkoÓ
p€CØÒBÔ6°zÓBÐBr   c                 óT   — t        «       r
t        «       ryt        | «      }|syd|› d�S )z¼Block sensitive browser JS evaluation when the opt-in denylist is on (opt-in because it gates on
    primitive *names*; private-address egress is enforced separately in ``_browser_eval``).Nz^Blocked: browser_console(expression=...) tried to use sensitive browser JavaScript primitive (zè) while browser.restrict_evaluate is enabled. Use browser_snapshot/browser_get_images/browser_console without expression for normal inspection, or set browser.restrict_evaluate: false in config.yaml to allow programmatic evaluation.)rh   re   rˆ   )r   r�   s     r   Ú_enforce_browser_eval_policyrŠ   ‹   s?   € ô &Ô'Ô+IÔ+KØÜ'¨
Ó3€FÙØð%Ø%+ Hð -`ð`ð ar   Útab_idÚuser_idc                 óˆ  — t        «       }	 ddlm}  |d| › d�d|dœ¬«      }t        t	        |t
        «      r|j                  d«      n|xs d	«      }|j                  «       j                  d
«      j                  d«      }|rt        ||«      r|S y# t        $ r&}|j                  j                  d|«       Y d}~yd}~ww xY w)uÎ   Camofox analogue of ``_current_page_private_url`` (evaluate endpoint instead of the CLI). Fail-open
    on probe failure, matching the snapshot/vision guards â€” do not make fail-closed without the sibling.r   )Ú_postz/tabs/z	/evaluater-   )r   ÚuserId)Úbodyr4   r5   r6   r7   z4_camofox_current_page_private_url: probe failed (%s)N)r   Útools.browser_camofoxrŽ   r%   r$   Údictr:   r;   r   r<   r=   r>   )r‹   rŒ   r   rŽ   r3   r@   rA   s          r   Ú!_camofox_current_page_private_urlr“   š   s¾   € ô ‹)€CðVÝ/Ù�v˜f˜X YÐ/ÐE[ÐgnÑ6oÔpˆÜ´
¸4ÄÔ0F˜$Ÿ(™( 8Ô,ÈDÊJÐTVÓWˆØ!×'Ñ'Ó)×/Ñ/°Ó4×:Ñ:¸3Ó?ˆÙœ<¨¨[Ô9ØÐð øô ò VØ�
‰
×ÑÐOÐQT×UÐUØûðVús   ŒBB Â	CÂB<Â<C))Ú__doc__r{   Útypingr   Úutilsr   Útools.browser_tool_originr   r   Útoolsr   r   r   r8   r%   Úboolr   r   ÚcompileÚ
IGNORECASEr&   r*   rB   r~   ÚSrJ   ÚtupleÚPatternÚ__annotations__rt   rX   r`   re   rh   rr   Úlistrx   rƒ   rˆ   rŠ   r“   rd   r   r   ú<module>r¡      sÙ  ðòó 
Ý Ý !Ý >Ý .Ý 2ðD¨sð D°tó DðH˜3ð H 4ó Hð  �R—Z‘ZÐ >ÀÇÁÓNÐ ð`°ð `¸À¹ó `ð°ð ¸À#¹ó ð  €R‡Z�ZÐ-¨r¯t©tÓ4Ð6GÐHØ€R‡Z�ZÐ6¸¿¹Ó=¸}ÐMØ€R‡Z�ZÐ  "§$¡$Ó'¨Ð5Ø€R‡Z�ZÐ8¸"¿$¹$Ó?ÀÐQØ€R‡Z�ZÐOÐQS×QUÑQUÓVÐXqÐrØ€R‡Z�ZÐHÈ"Ï$É$ÓOÐQbÐcØ€R‡Z�ZÐ5°r·t±tÓ<Ð>NÐOØ€R‡Z�ZÐ7¸¿¹ÀÇÁ¹ÓEÐG^Ð_Ø€R‡Z�ZÐaÐce×cgÑcgÐjl×jnÑjnÑcnÓoð  rIð  Jð
IÐ ˜e E¨"¯*©*°S©/¸3Ð*>Ñ$?ÀÐ$DÑEó 
ð #˜Ÿ
™
Ð#bÐdf×dhÑdhÓiÐ ð	?Ð   e¨C°¨H¡o°sÐ&:Ñ ;ó 	ðs˜Cð s Dó sð7¨ó 7ð
3 Dó 3ð sð ¨só ðo¨Cð o°D¸±Ió oðq°Sð q¸XÀc¹]ó qðC¨3ð C°8¸C±=ó Cða¨Sð a°X¸c±]ó að¨cð ¸Cð ÀHÈSÁMô r   