Buckets:
| <meta charset="utf-8" /><meta name="hf:doc:metadata" content="{"title":"Pickle Scanning","local":"pickle-scanning","sections":[{"title":"What is a pickle?","local":"what-is-a-pickle","sections":[],"depth":2},{"title":"Why is it dangerous?","local":"why-is-it-dangerous","sections":[],"depth":2},{"title":"Mitigation Strategies","local":"mitigation-strategies","sections":[{"title":"Load files from users and organizations you trust","local":"load-files-from-users-and-organizations-you-trust","sections":[],"depth":3},{"title":"Load model weights from TF or Flax","local":"load-model-weights-from-tf-or-flax","sections":[],"depth":3},{"title":"Use your own serialization format","local":"use-your-own-serialization-format","sections":[],"depth":3},{"title":"Improve torch.load/save","local":"improve-torchloadsave","sections":[],"depth":3},{"title":"Hub’s Security Scanner","local":"hubs-security-scanner","sections":[{"title":"What we have now","local":"what-we-have-now","sections":[],"depth":4},{"title":"Potential solutions","local":"potential-solutions","sections":[],"depth":4}],"depth":3}],"depth":2},{"title":"Further Reading","local":"further-reading","sections":[],"depth":2}],"depth":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="{"title":"Pickle Scanning","local":"pickle-scanning","sections":[{"title":"What is a pickle?","local":"what-is-a-pickle","sections":[],"depth":2},{"title":"Why is it dangerous?","local":"why-is-it-dangerous","sections":[],"depth":2},{"title":"Mitigation Strategies","local":"mitigation-strategies","sections":[{"title":"Load files from users and organizations you trust","local":"load-files-from-users-and-organizations-you-trust","sections":[],"depth":3},{"title":"Load model weights from TF or Flax","local":"load-model-weights-from-tf-or-flax","sections":[],"depth":3},{"title":"Use your own serialization format","local":"use-your-own-serialization-format","sections":[],"depth":3},{"title":"Improve torch.load/save","local":"improve-torchloadsave","sections":[],"depth":3},{"title":"Hub’s Security Scanner","local":"hubs-security-scanner","sections":[{"title":"What we have now","local":"what-we-have-now","sections":[],"depth":4},{"title":"Potential solutions","local":"potential-solutions","sections":[],"depth":4}],"depth":3}],"depth":2},{"title":"Further Reading","local":"further-reading","sections":[],"depth":2}],"depth":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">"data I want to share with a friend"</span> | |
| <span class="hljs-comment"># store the pickle data in a file named 'payload.pkl'</span> | |
| <span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">'payload.pkl'</span>, <span class="hljs-string">'wb'</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">'payload.pkl'</span>, <span class="hljs-string">'rb'</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">'data I want to share with a friend'</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">"42"</span>) | |
| <span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">'payload.pkl'</span>, <span class="hljs-string">'wb'</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">"my friend needs to know this"</span> | |
| pickle_bin = pickle.dumps(data) | |
| p = Pickled.load(pickle_bin) | |
| p.insert_python_exec(<span class="hljs-string">'print("you\'ve been pwned !")'</span>) | |
| <span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">'payload.pkl'</span>, <span class="hljs-string">'wb'</span>) <span class="hljs-keyword">as</span> f: | |
| p.dump(f) | |
| <span class="hljs-comment"># innocently unpickle and get your friend's data</span> | |
| <span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">'payload.pkl'</span>, <span class="hljs-string">'rb'</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">'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">"you've been pwned !"</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">"you'v│ | |
| │00000020│ 65 20 62 65 65 6e 20 70 ┊ 77 6e 65 64 20 21 22 29 │e been p┊wned !"</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">"malicious argument"</span>, <span class="hljs-string">"REDUCE"</span>] | |
| opcode = stack.pop() | |
| <span class="hljs-keyword">if</span> opcode == <span class="hljs-string">"REDUCE"</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">"google-bert/bert-base-cased"</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.