Buckets:

hf-doc-build/doc-dev / hub /pr_2521 /en /security-pickle.html
HuggingFaceDocBuilder's picture
download
raw
51.3 kB
<meta charset="utf-8" /><meta name="hf:doc:metadata" content="{&quot;title&quot;:&quot;Pickle Scanning&quot;,&quot;local&quot;:&quot;pickle-scanning&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;What is a pickle?&quot;,&quot;local&quot;:&quot;what-is-a-pickle&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Why is it dangerous?&quot;,&quot;local&quot;:&quot;why-is-it-dangerous&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Mitigation Strategies&quot;,&quot;local&quot;:&quot;mitigation-strategies&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;Load files from users and organizations you trust&quot;,&quot;local&quot;:&quot;load-files-from-users-and-organizations-you-trust&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;Load model weights from TF or Flax&quot;,&quot;local&quot;:&quot;load-model-weights-from-tf-or-flax&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;Use your own serialization format&quot;,&quot;local&quot;:&quot;use-your-own-serialization-format&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;Improve torch.load/save&quot;,&quot;local&quot;:&quot;improve-torchloadsave&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;Hub’s Security Scanner&quot;,&quot;local&quot;:&quot;hubs-security-scanner&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;What we have now&quot;,&quot;local&quot;:&quot;what-we-have-now&quot;,&quot;sections&quot;:[],&quot;depth&quot;:4},{&quot;title&quot;:&quot;Potential solutions&quot;,&quot;local&quot;:&quot;potential-solutions&quot;,&quot;sections&quot;:[],&quot;depth&quot;:4}],&quot;depth&quot;:3}],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Further Reading&quot;,&quot;local&quot;:&quot;further-reading&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2}],&quot;depth&quot;:1}">
<link href="/docs/hub/pr_2521/en/_app/immutable/assets/0.e3b0c442.css" rel="modulepreload">
<link rel="modulepreload" href="/docs/hub/pr_2521/en/_app/immutable/entry/start.d19e5ca7.js">
<link rel="modulepreload" href="/docs/hub/pr_2521/en/_app/immutable/chunks/scheduler.409792a1.js">
<link rel="modulepreload" href="/docs/hub/pr_2521/en/_app/immutable/chunks/singletons.1ece723a.js">
<link rel="modulepreload" href="/docs/hub/pr_2521/en/_app/immutable/chunks/index.0f0d9f26.js">
<link rel="modulepreload" href="/docs/hub/pr_2521/en/_app/immutable/chunks/paths.a67d9216.js">
<link rel="modulepreload" href="/docs/hub/pr_2521/en/_app/immutable/entry/app.98ab229a.js">
<link rel="modulepreload" href="/docs/hub/pr_2521/en/_app/immutable/chunks/preload-helper.78e52d9f.js">
<link rel="modulepreload" href="/docs/hub/pr_2521/en/_app/immutable/chunks/index.92d389ff.js">
<link rel="modulepreload" href="/docs/hub/pr_2521/en/_app/immutable/nodes/0.7799902b.js">
<link rel="modulepreload" href="/docs/hub/pr_2521/en/_app/immutable/chunks/each.e59479a4.js">
<link rel="modulepreload" href="/docs/hub/pr_2521/en/_app/immutable/nodes/168.5c3229ab.js">
<link rel="modulepreload" href="/docs/hub/pr_2521/en/_app/immutable/chunks/CopyLLMTxtMenu.dcf7fb47.js">
<link rel="modulepreload" href="/docs/hub/pr_2521/en/_app/immutable/chunks/MermaidChart.svelte_svelte_type_style_lang.0c189c7e.js">
<link rel="modulepreload" href="/docs/hub/pr_2521/en/_app/immutable/chunks/CodeBlock.5ed269c1.js"><!-- HEAD_svelte-u9bgzb_START --><meta name="hf:doc:metadata" content="{&quot;title&quot;:&quot;Pickle Scanning&quot;,&quot;local&quot;:&quot;pickle-scanning&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;What is a pickle?&quot;,&quot;local&quot;:&quot;what-is-a-pickle&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Why is it dangerous?&quot;,&quot;local&quot;:&quot;why-is-it-dangerous&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Mitigation Strategies&quot;,&quot;local&quot;:&quot;mitigation-strategies&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;Load files from users and organizations you trust&quot;,&quot;local&quot;:&quot;load-files-from-users-and-organizations-you-trust&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;Load model weights from TF or Flax&quot;,&quot;local&quot;:&quot;load-model-weights-from-tf-or-flax&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;Use your own serialization format&quot;,&quot;local&quot;:&quot;use-your-own-serialization-format&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;Improve torch.load/save&quot;,&quot;local&quot;:&quot;improve-torchloadsave&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;Hub’s Security Scanner&quot;,&quot;local&quot;:&quot;hubs-security-scanner&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;What we have now&quot;,&quot;local&quot;:&quot;what-we-have-now&quot;,&quot;sections&quot;:[],&quot;depth&quot;:4},{&quot;title&quot;:&quot;Potential solutions&quot;,&quot;local&quot;:&quot;potential-solutions&quot;,&quot;sections&quot;:[],&quot;depth&quot;:4}],&quot;depth&quot;:3}],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Further Reading&quot;,&quot;local&quot;:&quot;further-reading&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2}],&quot;depth&quot;:1}"><!-- HEAD_svelte-u9bgzb_END --> <p></p> <div class="items-center shrink-0 min-w-[100px] max-sm:min-w-[50px] justify-end ml-auto flex" style="float: right; margin-left: 10px; display: inline-flex; position: relative; z-index: 10;"><div class="inline-flex rounded-md max-sm:rounded-sm"><button class="inline-flex items-center gap-1 h-7 max-sm:h-7 px-2 max-sm:px-1.5 text-sm font-medium text-gray-800 border border-r-0 rounded-l-md max-sm:rounded-l-sm border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-live="polite"><span class="inline-flex items-center justify-center rounded-md p-0.5 max-sm:p-0 hover:text-gray-800 dark:hover:text-gray-200"><svg class="sm:size-3.5 size-3" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg></span> <span>Copy page</span></button> <button class="inline-flex items-center justify-center w-6 max-sm:w-5 h-7 max-sm:h-7 disabled:pointer-events-none text-sm text-gray-500 hover:text-gray-700 dark:hover:text-white rounded-r-md max-sm:rounded-r-sm border border-l transition border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-haspopup="menu" aria-expanded="false" aria-label="Open copy menu"><svg class="transition-transform text-gray-400 overflow-visible sm:size-3.5 size-3 rotate-0" width="1em" height="1em" viewBox="0 0 12 7" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1 1L6 6L11 1" stroke="currentColor"></path></svg></button></div> </div> <h1 class="relative group"><a id="pickle-scanning" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#pickle-scanning"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Pickle Scanning</span></h1> <p data-svelte-h="svelte-fqsq33">Pickle is a widely used serialization format in ML. Most notably, it is the default format for PyTorch model weights.</p> <p data-svelte-h="svelte-a29lns">There are dangerous arbitrary code execution attacks that can be perpetrated when you load a pickle file. We suggest loading models from users and organizations you trust, relying on signed commits, and/or loading models from TF or Jax formats with the <code>from_tf=True</code> auto-conversion mechanism. We also alleviate this issue by displaying/“vetting” the list of imports in any pickled file, directly on the Hub. Finally, we are experimenting with a new, simple serialization format for weights called <a href="https://github.com/huggingface/safetensors" rel="nofollow"><code>safetensors</code></a>.</p> <h2 class="relative group"><a id="what-is-a-pickle" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#what-is-a-pickle"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>What is a pickle?</span></h2> <p data-svelte-h="svelte-t990cu">From the <a href="https://docs.python.org/3/library/pickle.html" rel="nofollow">official docs</a> :</p> <blockquote data-svelte-h="svelte-mvgji8"><p>The <code>pickle</code> module implements binary protocols for serializing and de-serializing a Python object structure.</p></blockquote> <p data-svelte-h="svelte-xlsbn2">What this means is that pickle is a serializing protocol, something you use to efficiently share data amongst parties.</p> <p data-svelte-h="svelte-crw8fq">We call a pickle the binary file that was generated while pickling.</p> <p data-svelte-h="svelte-903ikp">At its core, the pickle is basically a stack of instructions or opcodes. As you probably have guessed, it’s not human readable. The opcodes are generated when pickling and read sequentially at unpickling. Based on the opcode, a given action is executed.</p> <p data-svelte-h="svelte-ybkvbq">Here’s a small example:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-python "><!-- HTML_TAG_START --><span class="hljs-keyword">import</span> pickle
<span class="hljs-keyword">import</span> pickletools
var = <span class="hljs-string">&quot;data I want to share with a friend&quot;</span>
<span class="hljs-comment"># store the pickle data in a file named &#x27;payload.pkl&#x27;</span>
<span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">&#x27;payload.pkl&#x27;</span>, <span class="hljs-string">&#x27;wb&#x27;</span>) <span class="hljs-keyword">as</span> f:
pickle.dump(var, f)
<span class="hljs-comment"># disassemble the pickle</span>
<span class="hljs-comment"># and print the instructions to the command line</span>
<span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">&#x27;payload.pkl&#x27;</span>, <span class="hljs-string">&#x27;rb&#x27;</span>) <span class="hljs-keyword">as</span> f:
pickletools.dis(f)<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-dc6jzh">When you run this, it will create a pickle file and print the following instructions in your terminal:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-python "><!-- HTML_TAG_START --> <span class="hljs-number">0</span>: \x80 PROTO <span class="hljs-number">4</span>
<span class="hljs-number">2</span>: \x95 FRAME <span class="hljs-number">48</span>
<span class="hljs-number">11</span>: \x8c SHORT_BINUNICODE <span class="hljs-string">&#x27;data I want to share with a friend&#x27;</span>
<span class="hljs-number">57</span>: \x94 MEMOIZE (<span class="hljs-keyword">as</span> <span class="hljs-number">0</span>)
<span class="hljs-number">58</span>: . STOP
highest protocol among opcodes = <span class="hljs-number">4</span><!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-2o2p4t">Don’t worry too much about the instructions for now, just know that the <a href="https://docs.python.org/3/library/pickletools.html" rel="nofollow">pickletools</a> module is very useful for analyzing pickles. It allows you to read the instructions in the file <strong><em>without</em></strong> executing any code.</p> <p data-svelte-h="svelte-1lc08qc">Pickle is not simply a serialization protocol, it allows more flexibility by giving the ability to users to run python code at de-serialization time. Doesn’t sound good, does it?</p> <h2 class="relative group"><a id="why-is-it-dangerous" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#why-is-it-dangerous"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Why is it dangerous?</span></h2> <p data-svelte-h="svelte-18mv2f5">As we’ve stated above, de-serializing pickle means that code can be executed. But this comes with certain limitations: you can only reference functions and classes from the top level module; you cannot embed them in the pickle file itself.</p> <p data-svelte-h="svelte-qlmkz7">Back to the drawing board:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-python "><!-- HTML_TAG_START --><span class="hljs-keyword">import</span> pickle
<span class="hljs-keyword">import</span> pickletools
<span class="hljs-keyword">class</span> <span class="hljs-title class_">Data</span>:
<span class="hljs-keyword">def</span> <span class="hljs-title function_">__init__</span>(<span class="hljs-params">self, important_stuff: <span class="hljs-built_in">str</span></span>):
self.important_stuff = important_stuff
d = Data(<span class="hljs-string">&quot;42&quot;</span>)
<span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">&#x27;payload.pkl&#x27;</span>, <span class="hljs-string">&#x27;wb&#x27;</span>) <span class="hljs-keyword">as</span> f:
pickle.dump(d, f)<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-45qs4">When we run this script we get the <code>payload.pkl</code> again. When we check the file’s contents:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-bash "><!-- HTML_TAG_START -->
<span class="hljs-comment"># cat payload.pkl</span>
__main__Data)}important_stuff42sb.%
<span class="hljs-comment"># hexyl payload.pkl</span>
┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐
│00000000│ 80 04 95 33 00 00 00 00 ┊ 00 00 00 8c 08 5f 5f 6d │ו×30000┊000ו__m│
│00000010│ 61 69 6e 5f 5f 94 8c 04 ┊ 44 61 74 61 94 93 94 29 │ain__×ו┊Data×××)│
│00000020│ 81 94 7d 94 8c 0f 69 6d ┊ 70 6f 72 74 61 6e 74 5f │××}×וim┊portant_│
│00000030│ 73 74 75 66 66 94 8c 02 ┊ 34 32 94 73 62 2e │stuff×ו┊42×sb. │
└────────┴─────────────────────────┴─────────────────────────┴────────┴────────┘<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-162o2y5">We can see that there isn’t much in there, a few opcodes and the associated data. You might be thinking, so what’s the problem with pickle?</p> <p data-svelte-h="svelte-1cipmup">Let’s try something else:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-python "><!-- HTML_TAG_START --><span class="hljs-keyword">from</span> fickling.pickle <span class="hljs-keyword">import</span> Pickled
<span class="hljs-keyword">import</span> pickle
<span class="hljs-comment"># Create a malicious pickle</span>
data = <span class="hljs-string">&quot;my friend needs to know this&quot;</span>
pickle_bin = pickle.dumps(data)
p = Pickled.load(pickle_bin)
p.insert_python_exec(<span class="hljs-string">&#x27;print(&quot;you\&#x27;ve been pwned !&quot;)&#x27;</span>)
<span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">&#x27;payload.pkl&#x27;</span>, <span class="hljs-string">&#x27;wb&#x27;</span>) <span class="hljs-keyword">as</span> f:
p.dump(f)
<span class="hljs-comment"># innocently unpickle and get your friend&#x27;s data</span>
<span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">&#x27;payload.pkl&#x27;</span>, <span class="hljs-string">&#x27;rb&#x27;</span>) <span class="hljs-keyword">as</span> f:
data = pickle.load(f)
<span class="hljs-built_in">print</span>(data)<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-tiwo6o">Here we’re using the <a href="https://github.com/trailofbits/fickling" rel="nofollow">fickling</a> library for simplicity. It allows us to add pickle instructions to execute code contained in a string via the <code>exec</code> function. This is how you circumvent the fact that you cannot define functions or classes in your pickles: you run exec on python code saved as a string.</p> <p data-svelte-h="svelte-exjbyy">When you run this, it creates a <code>payload.pkl</code> and prints the following:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=" "><!-- HTML_TAG_START -->you<span class="hljs-comment">&#x27;ve been pwned !</span>
my <span class="hljs-keyword">friend</span> needs <span class="hljs-keyword">to</span> know this<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-f6hcto">If we check the contents of the pickle file, we get:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-bash "><!-- HTML_TAG_START --><span class="hljs-comment"># cat payload.pkl</span>
c__builtin__
<span class="hljs-built_in">exec</span>
(Vprint(<span class="hljs-string">&quot;you&#x27;ve been pwned !&quot;</span>)
tR my friend needs to know this.%
<span class="hljs-comment"># hexyl payload.pkl</span>
┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐
│00000000│ 63 5f 5f 62 75 69 6c 74 ┊ 69 6e 5f 5f 0a 65 78 65 │c__built┊in___exe│
│00000010│ 63 0a 28 56 70 72 69 6e ┊ 74 28 22 79 6f 75 27 76 │c_(Vprin┊t(<span class="hljs-string">&quot;you&#x27;v│
│00000020│ 65 20 62 65 65 6e 20 70 ┊ 77 6e 65 64 20 21 22 29 │e been p┊wned !&quot;</span>)│
│00000030│ 0a 74 52 80 04 95 20 00 ┊ 00 00 00 00 00 00 8c 1c │_tR×•× 0┊000000ו│
│00000040│ 6d 79 20 66 72 69 65 6e ┊ 64 20 6e 65 65 64 73 20 │my frien┊d needs │
│00000050│ 74 6f 20 6b 6e 6f 77 20 ┊ 74 68 69 73 94 2e │to know ┊this×. │
└────────┴─────────────────────────┴─────────────────────────┴────────┴────────┘<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-17mv8nc">Basically, this is what’s happening when you unpickle:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-python "><!-- HTML_TAG_START --><span class="hljs-comment"># ...</span>
opcodes_stack = [exec_func, <span class="hljs-string">&quot;malicious argument&quot;</span>, <span class="hljs-string">&quot;REDUCE&quot;</span>]
opcode = stack.pop()
<span class="hljs-keyword">if</span> opcode == <span class="hljs-string">&quot;REDUCE&quot;</span>:
arg = opcodes_stack.pop()
<span class="hljs-built_in">callable</span> = opcodes_stack.pop()
opcodes_stack.append(<span class="hljs-built_in">callable</span>(arg))
<span class="hljs-comment"># ...</span><!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1ywjbrq">The instructions that pose a threat are <code>STACK_GLOBAL</code>, <code>GLOBAL</code> and <code>REDUCE</code>.</p> <p data-svelte-h="svelte-2a921e"><code>REDUCE</code> is what tells the unpickler to execute the function with the provided arguments and <code>*GLOBAL</code> instructions are telling the unpickler to <code>import</code> stuff.</p> <p data-svelte-h="svelte-1anxjjv">To sum up, pickle is dangerous because:</p> <ul data-svelte-h="svelte-tgdm9a"><li>when importing a python module, arbitrary code can be executed</li> <li>you can import builtin functions like <code>eval</code> or <code>exec</code>, which can be used to execute arbitrary code</li> <li>when instantiating an object, the constructor may be called</li></ul> <p data-svelte-h="svelte-nlb4po">This is why it is stated in most docs using pickle, do not unpickle data from untrusted sources.</p> <h2 class="relative group"><a id="mitigation-strategies" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#mitigation-strategies"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Mitigation Strategies</span></h2> <p data-svelte-h="svelte-1gahowb"><strong><em>Don’t use pickle</em></strong></p> <p data-svelte-h="svelte-1i4ndwq">Sound advice Luc, but pickle is used profusely and isn’t going anywhere soon: finding a new format everyone is happy with and initiating the change will take some time.</p> <p data-svelte-h="svelte-1akd8xr">So what can we do for now?</p> <h3 class="relative group"><a id="load-files-from-users-and-organizations-you-trust" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#load-files-from-users-and-organizations-you-trust"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Load files from users and organizations you trust</span></h3> <p data-svelte-h="svelte-18verv9">On the Hub, you have the ability to <a href="./security-gpg">sign your commits with a GPG key</a>. This does <strong>not</strong> guarantee that your file is safe, but it does guarantee the origin of the file.</p> <p data-svelte-h="svelte-xz3ko3">If you know and trust user A and the commit that includes the file on the Hub is signed by user A’s GPG key, it’s pretty safe to assume that you can trust the file.</p> <h3 class="relative group"><a id="load-model-weights-from-tf-or-flax" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#load-model-weights-from-tf-or-flax"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Load model weights from TF or Flax</span></h3> <p data-svelte-h="svelte-gbqaor">TensorFlow and Flax checkpoints are not affected, and can be loaded within PyTorch architectures using the <code>from_tf</code> and <code>from_flax</code> kwargs for the <code>from_pretrained</code> method to circumvent this issue.</p> <p data-svelte-h="svelte-oz78gk">E.g.:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class="language-python "><!-- HTML_TAG_START --><span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> AutoModel
model = AutoModel.from_pretrained(<span class="hljs-string">&quot;google-bert/bert-base-cased&quot;</span>, from_flax=<span class="hljs-literal">True</span>)<!-- HTML_TAG_END --></pre></div> <h3 class="relative group"><a id="use-your-own-serialization-format" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#use-your-own-serialization-format"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Use your own serialization format</span></h3> <ul data-svelte-h="svelte-iyr210"><li><a href="https://msgpack.org/index.html" rel="nofollow">MsgPack</a></li> <li><a href="https://developers.google.com/protocol-buffers" rel="nofollow">Protobuf</a></li> <li><a href="https://capnproto.org/" rel="nofollow">Cap’n’proto</a></li> <li><a href="https://avro.apache.org/" rel="nofollow">Avro</a></li> <li><a href="https://github.com/huggingface/safetensors" rel="nofollow">safetensors</a></li></ul> <p data-svelte-h="svelte-ztaxgy">This last format, <code>safetensors</code>, is a simple serialization format that we are working on and experimenting with currently! Please help or contribute if you can 🔥.</p> <h3 class="relative group"><a id="improve-torchloadsave" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#improve-torchloadsave"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Improve torch.load/save</span></h3> <p data-svelte-h="svelte-15ucwe">There’s an open discussion in progress at PyTorch on having a <a href="https://github.com/pytorch/pytorch/issues/52181" rel="nofollow">Safe way of loading only weights from *.pt file by default</a> – please chime in there!</p> <h3 class="relative group"><a id="hubs-security-scanner" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#hubs-security-scanner"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Hub’s Security Scanner</span></h3> <h4 class="relative group"><a id="what-we-have-now" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#what-we-have-now"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>What we have now</span></h4> <p data-svelte-h="svelte-65c4de">We have created a security scanner that scans every file pushed to the Hub and runs security checks. At the time of writing, it runs two types of scans:</p> <ul data-svelte-h="svelte-1zxf3f"><li>ClamAV scans</li> <li>Pickle Import scans</li></ul> <p data-svelte-h="svelte-g06wit">For ClamAV scans, files are run through the open-source antivirus <a href="https://www.clamav.net" rel="nofollow">ClamAV</a>. While this covers a good amount of dangerous files, it doesn’t cover pickle exploits.</p> <p data-svelte-h="svelte-1hmoht6">We have implemented a Pickle Import scan, which extracts the list of imports referenced in a pickle file. Every time you upload a <code>pytorch_model.bin</code> or any other pickled file, this scan is run.</p> <p data-svelte-h="svelte-3ixeiy">On the hub the list of imports will be displayed next to each file containing imports. If any import looks suspicious, it will be highlighted.</p> <div class="flex justify-center" data-svelte-h="svelte-1skhc0f"><img class="block dark:hidden" src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/hub/security-pickle-imports.png"> <img class="hidden dark:block" src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/hub/security-pickle-imports-dark.png"></div> <p data-svelte-h="svelte-wdhs2f">We get this data thanks to <a href="https://docs.python.org/3/library/pickletools.html#pickletools.genops" rel="nofollow"><code>pickletools.genops</code></a> which allows us to read the file without executing potentially dangerous code.</p> <p data-svelte-h="svelte-1bjlcuv">Note that this is what allows to know if, when unpickling a file, it will <code>REDUCE</code> on a potentially dangerous function that was imported by <code>*GLOBAL</code>.</p> <p data-svelte-h="svelte-t5sie"><strong><em>Disclaimer</em></strong>: this is not 100% foolproof. It is your responsibility as a user to check if something is safe or not. We are not actively auditing python packages for safety, the safe/unsafe imports lists we have are maintained in a best-effort manner.
Please contact us if you think something is not safe, and we flag it as such, by sending us an email to website at huggingface.co</p> <h4 class="relative group"><a id="potential-solutions" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#potential-solutions"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Potential solutions</span></h4> <p data-svelte-h="svelte-17489ml">One could think of creating a custom <a href="https://docs.python.org/3/library/pickle.html#pickle.Unpickler" rel="nofollow">Unpickler</a> in the likes of <a href="https://github.com/facebookresearch/CrypTen/blob/main/crypten/common/serial.py" rel="nofollow">this one</a>. But as we can see in this <a href="https://ctftime.org/writeup/16723" rel="nofollow">sophisticated exploit</a>, this won’t work.</p> <p data-svelte-h="svelte-4971ge">Thankfully, there is always a trace of the <code>eval</code> import, so reading the opcodes directly should allow to catch malicious usage.</p> <p data-svelte-h="svelte-bttwre">The current solution I propose is creating a file resembling a <code>.gitignore</code> but for imports.</p> <p data-svelte-h="svelte-1her4zo">This file would be a whitelist of imports that would make a <code>pytorch_model.bin</code> file flagged as dangerous if there are imports not included in the whitelist.</p> <p data-svelte-h="svelte-19plnsx">One could imagine having a regex-ish format where you could allow all numpy submodules for instance via a simple line like: <code>numpy.*</code>.</p> <h2 class="relative group"><a id="further-reading" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#further-reading"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Further Reading</span></h2> <p data-svelte-h="svelte-dshrcb"><a href="https://docs.python.org/3/library/pickle.html#what-can-be-pickled-and-unpickled" rel="nofollow">pickle - Python object serialization - Python 3.10.6 documentation</a></p> <p data-svelte-h="svelte-1nbw5zj"><a href="https://intoli.com/blog/dangerous-pickles/" rel="nofollow">Dangerous Pickles - Malicious Python Serialization</a></p> <p data-svelte-h="svelte-1pxtenc"><a href="https://github.com/trailofbits/fickling" rel="nofollow">GitHub - trailofbits/fickling: A Python pickling decompiler and static analyzer</a></p> <p data-svelte-h="svelte-dgsssn"><a href="https://davidhamann.de/2020/04/05/exploiting-python-pickle/" rel="nofollow">Exploiting Python pickles</a></p> <p data-svelte-h="svelte-9sknvp"><a href="https://github.com/python/cpython/blob/3.10/Lib/pickletools.py" rel="nofollow">cpython/pickletools.py at 3.10 · python/cpython</a></p> <p data-svelte-h="svelte-yi9gp3"><a href="https://github.com/python/cpython/blob/3.10/Lib/pickle.py" rel="nofollow">cpython/pickle.py at 3.10 · python/cpython</a></p> <p data-svelte-h="svelte-162i3ur"><a href="https://github.com/facebookresearch/CrypTen/blob/main/crypten/common/serial.py" rel="nofollow">CrypTen/serial.py at main · facebookresearch/CrypTen</a></p> <p data-svelte-h="svelte-1uviqpm"><a href="https://ctftime.org/writeup/16723" rel="nofollow">CTFtime.org / Balsn CTF 2019 / pyshv1 / Writeup</a></p> <p data-svelte-h="svelte-1bxqg0w"><a href="https://github.com/moreati/pickle-fuzz" rel="nofollow">Rehabilitating Python’s pickle module</a></p> <a class="!text-gray-400 !no-underline text-sm flex items-center not-prose mt-4" href="https://github.com/huggingface/hub-docs/blob/main/docs/hub/security-pickle.md" target="_blank"><svg class="mr-1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M31,16l-7,7l-1.41-1.41L28.17,16l-5.58-5.59L24,9l7,7z"></path><path d="M1,16l7-7l1.41,1.41L3.83,16l5.58,5.59L8,23l-7-7z"></path><path d="M12.419,25.484L17.639,6.552l1.932,0.518L14.351,26.002z"></path></svg> <span data-svelte-h="svelte-zjs2n5"><span class="underline">Update</span> on GitHub</span></a> <p></p>
<script>
{
__sveltekit_1bollga = {
assets: "/docs/hub/pr_2521/en",
base: "/docs/hub/pr_2521/en",
env: {}
};
const element = document.currentScript.parentElement;
const data = [null,null];
Promise.all([
import("/docs/hub/pr_2521/en/_app/immutable/entry/start.d19e5ca7.js"),
import("/docs/hub/pr_2521/en/_app/immutable/entry/app.98ab229a.js")
]).then(([kit, app]) => {
kit.start(app, element, {
node_ids: [0, 168],
data,
form: null,
error: null
});
});
}
</script>

Xet Storage Details

Size:
51.3 kB
·
Xet hash:
8d53f55d69f71df54fbadea365afc7471ec7ed97a4a448eb861d02ff0a2e9acd

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.