File size: 7,223 Bytes
4b371b6
127023d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64e3179
127023d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4b371b6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>modelvet — vet a Hugging Face model before you trust it</title>
<style>
  :root {
    color-scheme: light dark;
    --bg: #0f1115;
    --panel: #171a21;
    --border: #2a2f3a;
    --text: #e7e9ee;
    --muted: #9aa3b2;
    --accent: #ffb020;
    --ok: #4fd18b;
    --bad: #ff6b6b;
  }
  @media (prefers-color-scheme: light) {
    :root {
      --bg: #f7f7f9;
      --panel: #ffffff;
      --border: #e2e5ea;
      --text: #14161a;
      --muted: #5b6270;
      --accent: #b5720a;
      --ok: #1a8a53;
      --bad: #c8321f;
    }
  }
  * { box-sizing: border-box; }
  body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    line-height: 1.55;
  }
  .wrap {
    max-width: 820px;
    margin: 0 auto;
    padding: 48px 20px 80px;
  }
  header h1 {
    font-size: 2rem;
    margin: 0 0 4px;
    letter-spacing: -0.02em;
  }
  header p.tagline {
    color: var(--muted);
    font-size: 1.1rem;
    margin: 0 0 28px;
  }
  .badges { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 32px; }
  .badge {
    font-size: 0.78rem;
    padding: 3px 10px;
    border-radius: 999px;
    border: 1px solid var(--border);
    color: var(--muted);
  }
  section { margin-bottom: 36px; }
  h2 {
    font-size: 1.05rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
    margin: 0 0 14px;
  }
  p { margin: 0 0 12px; }
  a { color: var(--accent); }
  ul { margin: 0 0 12px; padding-left: 22px; }
  li { margin-bottom: 6px; }
  code {
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 4px;
    padding: 1px 6px;
    font-size: 0.92em;
  }
  pre {
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 16px;
    overflow-x: auto;
    font-size: 0.85rem;
  }
  pre code { background: none; border: none; padding: 0; }
  .panel {
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 20px 22px;
  }
  .note {
    font-size: 0.88rem;
    color: var(--muted);
    border-left: 3px solid var(--accent);
    padding: 4px 0 4px 14px;
    margin: 16px 0;
  }
  .example-row {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 5px 0;
    border-bottom: 1px solid var(--border);
    font-size: 0.85rem;
  }
  .example-row:last-child { border-bottom: none; }
  .ok { color: var(--ok); }
  .tool { color: var(--muted); }
  footer {
    margin-top: 48px;
    padding-top: 20px;
    border-top: 1px solid var(--border);
    color: var(--muted);
    font-size: 0.85rem;
  }
</style>
</head>
<body>
<div class="wrap">

  <header>
    <h1>modelvet</h1>
    <p class="tagline">Vet a Hugging Face model before you trust it.</p>
    <div class="badges">
      <span class="badge">MIT licensed</span>
      <span class="badge">CLI, stdlib + picklescan + model-signing</span>
      <span class="badge">v1</span>
    </div>
  </header>

  <section>
    <h2>Why</h2>
    <p>
      Malicious PyTorch checkpoints have repeatedly bypassed <code>picklescan</code>
      (Hugging Face's own scanning dependency) via documented, CVE-tracked techniques —
      CVE-2025-1889, CVE-2025-10155, CVE-2026-53875, and more.
    </p>
    <p>
      Hugging Face's website shows scan-result badges, but <code>huggingface_hub</code>'s
      <code>hf_hub_download()</code> / <code>snapshot_download()</code> have no API to check
      "was this scanned, and did it pass" from a script. A developer or agent downloading a
      model programmatically never sees that signal at all. <code>modelvet</code> closes that
      gap: it re-scans what you actually downloaded, and checks for a
      Sigstore / OpenSSF Model Signing signature (real, working, but essentially unadopted
      on Hugging Face today).
    </p>
  </section>

  <section>
    <h2>Install &amp; use</h2>
    <div class="panel">
      <p>Not on PyPI yet — install straight from the source repo:</p>
      <pre><code>pip install git+https://github.com/sangmorg1-debug/modelvet.git

modelvet scan bert-base-uncased
modelvet scan bert-base-uncased --format json
modelvet scan local-check --local-dir ./downloaded-model</code></pre>
    </div>
  </section>

  <section>
    <h2>Example scan (captured output, not a live demo)</h2>
    <div class="note">
      This Space is static — Hugging Face's free tier no longer includes compute for
      Gradio or Docker Spaces, only static pages. So this isn't an interactive scanner;
      it's a real, captured run of <code>modelvet scan hf-internal-testing/tiny-random-gpt2</code>
      against an actual public model, shown as-is. Install the CLI locally to scan a real repo
      of your own.
    </div>
    <div class="panel">
      <div class="example-row"><span>.gitattributes</span><span class="tool ok">picklescan · clean</span></div>
      <div class="example-row"><span>config.json</span><span class="tool ok">picklescan · clean</span></div>
      <div class="example-row"><span>merges.txt</span><span class="tool ok">picklescan · clean</span></div>
      <div class="example-row"><span>model.safetensors</span><span class="tool ok">picklescan · clean</span></div>
      <div class="example-row"><span>pytorch_model.bin</span><span class="tool ok">picklescan · clean</span></div>
      <div class="example-row"><span>special_tokens_map.json</span><span class="tool ok">picklescan · clean</span></div>
      <div class="example-row"><span>tf_model.h5</span><span class="tool ok">picklescan · clean</span></div>
      <div class="example-row"><span>tokenizer.json</span><span class="tool ok">picklescan · clean</span></div>
      <div class="example-row"><span>tokenizer_config.json</span><span class="tool ok">picklescan · clean</span></div>
      <div class="example-row"><span>vocab.json</span><span class="tool ok">picklescan · clean</span></div>
      <p style="margin-top:14px;"><strong>signature:</strong> <code>no_signature</code> — expected; this repo, like almost every repo on Hugging Face today, has never published one.</p>
      <p><strong>exit code:</strong> <code>0</code></p>
    </div>
  </section>

  <section>
    <h2>What it does not do (yet)</h2>
    <ul>
      <li>No <code>transformers.from_pretrained()</code> wrapper — CLI only in v1.</li>
      <li>No custom pickle-opcode engine — detection is built on <code>picklescan</code> (an actively maintained, if imperfect, tool), with two narrowly-scoped checks added for its documented bypasses (archive-format mismatch, hidden pickles under non-pickle extensions).</li>
      <li>Signature verification only works against <code>--local-dir</code> today, not a bare Hub repo id — Hugging Face's cache layout gives no place to put a signature file for a model you didn't download and sign yourself.</li>
    </ul>
  </section>

  <footer>
    <p>
      <a href="https://github.com/sangmorg1-debug/modelvet">Source on GitHub</a> ·
      MIT License
    </p>
  </footer>

</div>
</body>
</html>