pompelmi 0.34.2 → 0.34.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +132 -58
- package/package.json +17 -35
package/README.md
CHANGED
|
@@ -1,22 +1,80 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<picture>
|
|
4
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/pompelmi/pompelmi/main/assets/logo.svg">
|
|
5
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/pompelmi/pompelmi/main/assets/logo.svg">
|
|
6
|
+
<img src="https://raw.githubusercontent.com/pompelmi/pompelmi/main/assets/logo.svg" alt="Pompelmi logo" width="220" />
|
|
7
|
+
</picture>
|
|
4
8
|
|
|
5
|
-
|
|
6
|
-
[](https://www.npmjs.com/package/pompelmi)
|
|
7
|
-
[](https://github.com/pompelmi/pompelmi/actions/workflows/ci.yml)
|
|
9
|
+
<h1>Pompelmi</h1>
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
<p><strong>Stop malicious uploads before they hit storage.</strong></p>
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
<p>Secure file upload scanning for Node.js with MIME sniffing, ZIP bomb protection, polyglot detection, risky document checks, and optional YARA.</p>
|
|
14
|
+
|
|
15
|
+
<p>
|
|
16
|
+
<a href="https://github.com/pompelmi/pompelmi/stargazers"><img alt="Star on GitHub" src="https://img.shields.io/badge/Star%20on%20GitHub-181717?style=for-the-badge&logo=github&logoColor=white"></a>
|
|
17
|
+
<a href="#quick-start"><img alt="Start in 60 seconds" src="https://img.shields.io/badge/Start%20in-60%20seconds-059669?style=for-the-badge"></a>
|
|
18
|
+
<a href="https://pompelmi.github.io/pompelmi/"><img alt="Read the docs" src="https://img.shields.io/badge/Read%20the-Docs-2563eb?style=for-the-badge"></a>
|
|
19
|
+
</p>
|
|
20
|
+
|
|
21
|
+
<p><strong>Private by design</strong> • <strong>No cloud API</strong> • <strong>No daemon</strong> • <strong>Express / Next.js / Koa / NestJS / Fastify</strong></p>
|
|
22
|
+
|
|
23
|
+
<p>
|
|
24
|
+
<a href="https://github.com/pompelmi/pompelmi/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/pompelmi/pompelmi?style=for-the-badge&logo=github&label=stars"></a>
|
|
25
|
+
<a href="https://www.npmjs.com/package/pompelmi"><img alt="npm downloads per month" src="https://img.shields.io/npm/dm/pompelmi?style=for-the-badge&logo=npm&label=downloads%2Fmonth"></a>
|
|
26
|
+
<a href="https://www.npmjs.com/package/pompelmi"><img alt="npm version" src="https://img.shields.io/npm/v/pompelmi?style=for-the-badge&logo=npm&label=npm"></a>
|
|
27
|
+
<a href="https://github.com/pompelmi/pompelmi/actions/workflows/ci.yml"><img alt="CI" src="https://img.shields.io/github/actions/workflow/status/pompelmi/pompelmi/ci.yml?style=for-the-badge&branch=main&label=CI"></a>
|
|
28
|
+
</p>
|
|
29
|
+
|
|
30
|
+
<p>
|
|
31
|
+
<img alt="Node 18+" src="https://img.shields.io/badge/node-%3E%3D18-339933?style=for-the-badge&logo=node.js&logoColor=white">
|
|
32
|
+
<img alt="TypeScript" src="https://img.shields.io/badge/types-TypeScript-3178C6?style=for-the-badge&logo=typescript&logoColor=white">
|
|
33
|
+
<img alt="MIT license" src="https://img.shields.io/badge/license-MIT-0f172a?style=for-the-badge">
|
|
34
|
+
<img alt="Zero cloud dependency" src="https://img.shields.io/badge/cloud-none-059669?style=for-the-badge">
|
|
35
|
+
</p>
|
|
36
|
+
|
|
37
|
+
<p>
|
|
38
|
+
<strong>
|
|
39
|
+
<a href="https://pompelmi.github.io/pompelmi/">Docs</a> •
|
|
40
|
+
<a href="#quick-start">Quick start</a> •
|
|
41
|
+
<a href="./examples">Examples</a> •
|
|
42
|
+
<a href="#frameworks">Frameworks</a> •
|
|
43
|
+
<a href="#star-history">Star history</a>
|
|
44
|
+
</strong>
|
|
45
|
+
</p>
|
|
46
|
+
|
|
47
|
+
<p>If Pompelmi saves you from building upload security plumbing from scratch, give it a star. It helps the project grow and helps more Node.js teams find it.</p>
|
|
48
|
+
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
<p align="center">
|
|
52
|
+
<img src="https://raw.githubusercontent.com/pompelmi/pompelmi/main/assets/readme-banner.png" alt="Pompelmi banner" width="100%">
|
|
53
|
+
</p>
|
|
54
|
+
|
|
55
|
+
## Featured In
|
|
12
56
|
|
|
13
|
-
|
|
57
|
+
Picked up by developer newsletters, security media, and curated awesome lists.
|
|
14
58
|
|
|
15
|
-
|
|
59
|
+
<p align="center">
|
|
60
|
+
<a href="https://www.producthunt.com/products/pompelmi"><img alt="Featured on Product Hunt" src="https://img.shields.io/badge/featured-Product%20Hunt-da552f?style=for-the-badge&logo=producthunt&logoColor=white"></a>
|
|
61
|
+
<a href="https://www.helpnetsecurity.com/2026/02/02/pompelmi-open-source-secure-file-upload-scanning-node-js/"><img alt="Featured on Help Net Security" src="https://img.shields.io/badge/featured-Help%20Net%20Security-ff6b35?style=for-the-badge"></a>
|
|
62
|
+
<a href="https://stackoverflow.blog/2026/02/23/defense-against-uploads-oss-file-scanner-pompelmi/"><img alt="Featured on Stack Overflow Blog" src="https://img.shields.io/badge/featured-Stack%20Overflow%20Blog-f58025?style=for-the-badge&logo=stackoverflow&logoColor=white"></a>
|
|
63
|
+
<a href="https://nodeweekly.com/issues/594"><img alt="Featured in Node Weekly issue 594" src="https://img.shields.io/badge/featured-Node%20Weekly%20%23594-43853d?style=for-the-badge&logo=node.js&logoColor=white"></a>
|
|
64
|
+
<a href="https://bytes.dev/archives/429"><img alt="Featured in Bytes issue 429" src="https://img.shields.io/badge/featured-Bytes%20%23429-111111?style=for-the-badge"></a>
|
|
65
|
+
<a href="https://www.detectionengineering.net/p/det-eng-weekly-issue-124-the-defcon"><img alt="Featured in Detection Engineering Weekly issue 124" src="https://img.shields.io/badge/featured-Detection%20Engineering%20Weekly-2563eb?style=for-the-badge&logo=substack&logoColor=white"></a>
|
|
66
|
+
</p>
|
|
16
67
|
|
|
17
|
-
|
|
68
|
+
<p align="center">
|
|
69
|
+
<a href="https://github.com/sorrycc/awesome-javascript"><img alt="Included in Awesome JavaScript" src="https://img.shields.io/badge/awesome-Awesome%20JavaScript-f7df1e?style=for-the-badge&logo=javascript&logoColor=black"></a>
|
|
70
|
+
<a href="https://github.com/dzharii/awesome-typescript"><img alt="Included in Awesome TypeScript" src="https://img.shields.io/badge/awesome-Awesome%20TypeScript-3178c6?style=for-the-badge&logo=typescript&logoColor=white"></a>
|
|
71
|
+
</p>
|
|
18
72
|
|
|
19
|
-
|
|
73
|
+
## Why It Exists
|
|
74
|
+
|
|
75
|
+
Your file upload endpoint is part of your attack surface.
|
|
76
|
+
|
|
77
|
+
Most upload handlers still trust filenames, extensions, or client-provided MIME types. That leaves room for renamed files, archive bombs, polyglots, active PDFs, and other risky payloads to land in storage before your app notices.
|
|
20
78
|
|
|
21
79
|
Without Pompelmi:
|
|
22
80
|
|
|
@@ -26,15 +84,27 @@ With Pompelmi:
|
|
|
26
84
|
|
|
27
85
|
`upload -> inspect bytes + structure -> allow | quarantine | reject -> store/process`
|
|
28
86
|
|
|
29
|
-
|
|
87
|
+
Why teams choose it:
|
|
30
88
|
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
|
|
89
|
+
- In-process and local-first. No cloud API, no daemon, no data egress.
|
|
90
|
+
- Built for the stuff attackers actually abuse: spoofed MIME, nested archives, ZIP bombs, traversal, polyglots, macro hints, and active documents.
|
|
91
|
+
- Typed and composable APIs with `scanBytes`, `scanFile`, policy packs, hooks, and optional YARA.
|
|
92
|
+
- Drop-in packages for Express, Next.js, Koa, NestJS, Fastify, CLI workflows, and React UI.
|
|
93
|
+
|
|
94
|
+
## Why People Star It
|
|
95
|
+
|
|
96
|
+
- It solves a real pain point fast: secure uploads are usually more dangerous and more annoying than they look.
|
|
97
|
+
- It is easy to adopt: `npm install`, add a policy, block risky files before storage.
|
|
98
|
+
- It stays privacy-first: no cloud dependency, no file egress, no extra scanning service to operate.
|
|
99
|
+
- It feels production-minded: structured verdicts, clear reasons, adapters, examples, docs, and active release history.
|
|
100
|
+
|
|
101
|
+
## Demo
|
|
36
102
|
|
|
37
|
-
|
|
103
|
+
<p align="center">
|
|
104
|
+
<img src="https://raw.githubusercontent.com/pompelmi/pompelmi/main/assets/malware-detection-node-demo.gif" alt="Pompelmi demo showing a risky upload being blocked" width="920">
|
|
105
|
+
</p>
|
|
106
|
+
|
|
107
|
+
## Quick Start
|
|
38
108
|
|
|
39
109
|
```bash
|
|
40
110
|
npm install pompelmi
|
|
@@ -51,68 +121,72 @@ const report = await scanBytes(file.buffer, {
|
|
|
51
121
|
});
|
|
52
122
|
|
|
53
123
|
if (report.verdict !== 'clean') {
|
|
54
|
-
return res.status(422).json({
|
|
124
|
+
return res.status(422).json({
|
|
125
|
+
error: 'Upload blocked',
|
|
126
|
+
reasons: report.reasons,
|
|
127
|
+
});
|
|
55
128
|
}
|
|
56
129
|
```
|
|
57
130
|
|
|
58
|
-
|
|
131
|
+
Start here next:
|
|
59
132
|
|
|
60
133
|
- [Getting started](https://pompelmi.github.io/pompelmi/getting-started/)
|
|
61
|
-
- [
|
|
134
|
+
- [Express guide](https://pompelmi.github.io/pompelmi/how-to/express/)
|
|
135
|
+
- [Examples](./examples)
|
|
62
136
|
- [Threat model and architecture](https://pompelmi.github.io/pompelmi/explaination/architecture/)
|
|
63
137
|
|
|
64
|
-
##
|
|
138
|
+
## What It Checks
|
|
139
|
+
|
|
140
|
+
- Extension, size, and declared MIME policy checks.
|
|
141
|
+
- Magic-byte validation for renamed or disguised files.
|
|
142
|
+
- Archive protections for ZIP bombs, traversal, and nesting depth.
|
|
143
|
+
- Heuristics for risky structures such as executables, polyglots, script-bearing documents, and macro hints.
|
|
144
|
+
- Optional YARA matching when you need signature-based rules.
|
|
145
|
+
|
|
146
|
+
## Frameworks
|
|
65
147
|
|
|
66
|
-
|
|
|
148
|
+
| Use case | Package or guide |
|
|
67
149
|
| --- | --- |
|
|
150
|
+
| Core library | `pompelmi` |
|
|
68
151
|
| Express | `@pompelmi/express-middleware` |
|
|
69
152
|
| Next.js | `@pompelmi/next-upload` |
|
|
70
|
-
| NestJS | `@pompelmi/nestjs-integration` |
|
|
71
153
|
| Koa | `@pompelmi/koa-middleware` |
|
|
154
|
+
| NestJS | `@pompelmi/nestjs-integration` |
|
|
72
155
|
| Fastify | `@pompelmi/fastify-plugin` |
|
|
73
|
-
|
|
|
156
|
+
| React UI | `@pompelmi/ui-react` |
|
|
157
|
+
| CLI | `@pompelmi/cli` |
|
|
74
158
|
|
|
75
|
-
##
|
|
159
|
+
## Why Not Just MIME Checks, Cloud AV, or ClamAV?
|
|
76
160
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
161
|
+
| Approach | Where it helps | Where it falls short |
|
|
162
|
+
| --- | --- | --- |
|
|
163
|
+
| File extensions or MIME checks only | Cheap allowlists and quick policy enforcement | Renamed files and client-provided MIME values are easy to fake. |
|
|
164
|
+
| DIY upload validation | Full control over your own rules | Easy to miss archive handling, polyglots, structured verdicts, and consistent fail-closed behavior. |
|
|
165
|
+
| Cloud scanning APIs | Outsourced detection and managed infrastructure | Adds data egress, network latency, and a hard dependency on an external service. |
|
|
166
|
+
| ClamAV or daemon-based setups | Familiar signature scanning and existing operations model | Adds process overhead and still benefits from an application-layer upload gate before storage. |
|
|
82
167
|
|
|
83
|
-
|
|
168
|
+
Pompelmi focuses on the upload gate itself. It can complement YARA or ClamAV. It is not presented as a full antivirus replacement.
|
|
84
169
|
|
|
85
|
-
|
|
86
|
-
- [Threat model and architecture](https://pompelmi.github.io/pompelmi/explaination/architecture/)
|
|
87
|
-
- [Examples directory](./examples)
|
|
88
|
-
- [Security policy](./SECURITY.md)
|
|
89
|
-
- [Tests](./tests)
|
|
170
|
+
## Star History
|
|
90
171
|
|
|
91
|
-
|
|
172
|
+
If you want to follow the project as it grows, star the repo and keep an eye on releases.
|
|
92
173
|
|
|
93
|
-
|
|
174
|
+
<p align="center">
|
|
175
|
+
<a href="https://star-history.com/#pompelmi/pompelmi&Date">
|
|
176
|
+
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=pompelmi/pompelmi&type=Date">
|
|
177
|
+
</a>
|
|
178
|
+
</p>
|
|
94
179
|
|
|
95
|
-
|
|
180
|
+
## Community
|
|
96
181
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
It adds a layered upload gate before storage or downstream processing. That helps catch spoofed files, archive bombs, polyglots, and common risky document structures.
|
|
104
|
-
|
|
105
|
-
### Is this a complete antivirus replacement?
|
|
106
|
-
|
|
107
|
-
No. Pompelmi is an upload security layer and risk-reduction control. It should sit inside a broader defense-in-depth design.
|
|
108
|
-
|
|
109
|
-
### Can it help in privacy-sensitive or regulated environments?
|
|
110
|
-
|
|
111
|
-
It can support internal control objectives by reducing upload risk and producing structured scan outcomes. It is not itself a compliance certification.
|
|
112
|
-
|
|
113
|
-
## Commercial / enterprise
|
|
182
|
+
- [Contributing guide](./CONTRIBUTING.md)
|
|
183
|
+
- [Roadmap](./ROADMAP.md)
|
|
184
|
+
- [GitHub Discussions](https://github.com/pompelmi/pompelmi/discussions)
|
|
185
|
+
- [GitHub Issues](https://github.com/pompelmi/pompelmi/issues)
|
|
186
|
+
- [Changelog](./CHANGELOG.md)
|
|
187
|
+
- [Security policy](./SECURITY.md)
|
|
114
188
|
|
|
115
|
-
|
|
189
|
+
Questions, docs fixes, examples, tests, and real-world integration feedback are all useful here.
|
|
116
190
|
|
|
117
191
|
## License
|
|
118
192
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pompelmi",
|
|
3
|
-
"version": "0.34.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.34.4",
|
|
4
|
+
"description": "Secure file uploads for Node.js. Scan untrusted files before storage with in-process, local-first checks for MIME spoofing, archive bombs, risky document structures, and optional YARA.",
|
|
5
5
|
"main": "./dist/pompelmi.cjs",
|
|
6
6
|
"module": "./dist/pompelmi.esm.js",
|
|
7
7
|
"type": "module",
|
|
@@ -215,48 +215,30 @@
|
|
|
215
215
|
"CHANGELOG*"
|
|
216
216
|
],
|
|
217
217
|
"keywords": [
|
|
218
|
-
"malware-scanner",
|
|
219
|
-
"file-upload-security",
|
|
220
218
|
"secure-file-upload",
|
|
219
|
+
"file-upload-security",
|
|
221
220
|
"upload-security",
|
|
222
|
-
"
|
|
223
|
-
"antivirus",
|
|
224
|
-
"malware-detection",
|
|
225
|
-
"threat-detection",
|
|
226
|
-
"security-scanner",
|
|
227
|
-
"file-scanner",
|
|
221
|
+
"upload-scanning",
|
|
228
222
|
"file-scanning",
|
|
223
|
+
"file-validation",
|
|
224
|
+
"malware-scanner",
|
|
225
|
+
"mime-sniffing",
|
|
226
|
+
"magic-bytes",
|
|
227
|
+
"archive-security",
|
|
228
|
+
"zip-bomb-protection",
|
|
229
229
|
"yara",
|
|
230
230
|
"yara-rules",
|
|
231
|
-
"
|
|
232
|
-
"
|
|
233
|
-
"koa-middleware",
|
|
234
|
-
"fastify-plugin",
|
|
235
|
-
"nextjs",
|
|
236
|
-
"next-js",
|
|
237
|
-
"nestjs",
|
|
238
|
-
"nuxt",
|
|
231
|
+
"local-first-security",
|
|
232
|
+
"self-hosted-security",
|
|
239
233
|
"nodejs-security",
|
|
240
|
-
"typescript-security",
|
|
241
|
-
"file-validation",
|
|
242
|
-
"upload-sanitization",
|
|
243
|
-
"mime-type-validation",
|
|
244
|
-
"magic-bytes",
|
|
245
|
-
"security",
|
|
246
|
-
"cybersecurity",
|
|
247
|
-
"devsecops",
|
|
248
|
-
"gdpr-compliance",
|
|
249
|
-
"hipaa-compliance",
|
|
250
|
-
"privacy-first",
|
|
251
|
-
"in-process-scanning",
|
|
252
|
-
"zero-cloud",
|
|
253
|
-
"self-hosted",
|
|
254
|
-
"node",
|
|
255
|
-
"nodejs",
|
|
256
234
|
"typescript",
|
|
235
|
+
"nodejs",
|
|
257
236
|
"express",
|
|
237
|
+
"nextjs",
|
|
238
|
+
"nestjs",
|
|
239
|
+
"fastify",
|
|
258
240
|
"koa",
|
|
259
|
-
"
|
|
241
|
+
"nuxt"
|
|
260
242
|
],
|
|
261
243
|
"directories": {
|
|
262
244
|
"example": "examples"
|