
    >/i                         S r SSKrSSKrSSKJr  SSKJr  \R                  " S5      \R                  " S5      S 5       5       r	g)a  
================================================
B615: Test for unsafe Hugging Face Hub downloads
================================================

This plugin checks for unsafe downloads from Hugging Face Hub without proper
integrity verification. Downloading models, datasets, or files without
specifying a revision based on an immmutable revision (commit) can
lead to supply chain attacks where malicious actors could
replace model files and use an existing tag or branch name
to serve malicious content.

The secure approach is to:

1. Pin to specific revisions/commits when downloading models, files or datasets

Common unsafe patterns:
- ``AutoModel.from_pretrained("org/model-name")``
- ``AutoModel.from_pretrained("org/model-name", revision="main")``
- ``AutoModel.from_pretrained("org/model-name", revision="v1.0.0")``
- ``load_dataset("org/dataset-name")`` without revision
- ``load_dataset("org/dataset-name", revision="main")``
- ``load_dataset("org/dataset-name", revision="v1.0")``
- ``AutoTokenizer.from_pretrained("org/model-name")``
- ``AutoTokenizer.from_pretrained("org/model-name", revision="main")``
- ``AutoTokenizer.from_pretrained("org/model-name", revision="v3.3.0")``
- ``hf_hub_download(repo_id="org/model_name", filename="file_name")``
- ``hf_hub_download(repo_id="org/model_name",
        filename="file_name",
        revision="main"
        )``
- ``hf_hub_download(repo_id="org/model_name",
        filename="file_name",
        revision="v2.0.0"
    )``
- ``snapshot_download(repo_id="org/model_name")``
- ``snapshot_download(repo_id="org/model_name", revision="main")``
- ``snapshot_download(repo_id="org/model_name", revision="refs/pr/1")``


:Example:

.. code-block:: none

        >> Issue: Unsafe Hugging Face Hub download without revision pinning
        Severity: Medium   Confidence: High
        CWE: CWE-494 (https://cwe.mitre.org/data/definitions/494.html)
        Location: examples/huggingface_unsafe_download.py:8
        7    # Unsafe: no revision specified
        8    model = AutoModel.from_pretrained("org/model_name")
        9

.. seealso::

     - https://cwe.mitre.org/data/definitions/494.html
     - https://huggingface.co/docs/huggingface_hub/en/guides/download

.. versionadded:: 1.8.6

    N)issue)test_propertiesCallB615c           	      r  ^ ^ / SQn[        U 4S jU 5       5      nU(       d  gT R                  n[        U[        5      (       d  gS/S/S/S/S/S.nUR	                  S5      mTS	   nXT;  a  gXE   n[        U4S
 jU 5       5      (       d  gT R                  S5      nT R                  S5      nU=(       d    Un	U	bX  [        U	[        5      (       aC  [        U	5      R                  S5      n
[        S U
 5       5      n[        U
5      S:  a  U(       a  gT R                  S5      nU(       a,  [        U[        5      (       a  UR                  S5      (       a  g[        R                  " [        R                  [        R                  SU S3[        R                   R"                  T R%                  U5      S9$ )zx
This plugin checks for unsafe artifact download from Hugging Face Hub
without immutable/reproducible revision pinning.
)transformersdatasetshuggingface_hubc              3   F   >#    U  H  nTR                  U5      v   M     g 7fN)is_module_imported_like).0modulecontexts     d/home/james-whalen/.local/lib/python3.13/site-packages/bandit/plugins/huggingface_unsafe_download.py	<genexpr>.huggingface_unsafe_download.<locals>.<genexpr>T   s"      >HF''//js   !Nr   r	   r
   )from_pretrainedload_datasethf_hub_downloadsnapshot_downloadrepository_id.c              3   ,   >#    U  H	  oT;   v   M     g 7fr    )r   r   qualname_partss     r   r   r   q   s     G6FF'6Fs   revision	commit_idz"'c              3   F   #    U  H  o[         R                  ;   v   M     g 7fr   )string	hexdigits)r   cs     r   r   r      s     E1f...s   !   r   )z.//z../z=Unsafe Hugging Face Hub download without revision pinning in z())severity
confidencetextcwelineno)anycall_function_name_qual
isinstancestrsplitget_call_arg_valuestripalllenget_call_arg_at_position
startswithbanditIssueMEDIUMHIGHr   Cwe(DOWNLOAD_OF_CODE_WITHOUT_INTEGRITY_CHECKget_lineno_for_call_arg)r   
hf_moduleshf_importedqualnameunsafe_patterns	func_namerequired_modulesrevision_valuecommit_id_valuerevision_to_checkrevision_stris_hex	first_argr   s   `            @r   huggingface_unsafe_downloadrI   E   s   J  >H K ..Hh$$ ++#-./0+,	O ^^C(Nr"I'&1G6FGGG //
;N00=O '9/$ '--0177>L EEEF< A%& 003IZ	3// 233<<;;B  II>>..y9	 	    )
__doc__r!   r6   bandit.corer   r   testcheckstest_idrI   r   rJ   r   <module>rP      sI   ;x    / VfR  RrJ   