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.
Files changed (2) hide show
  1. package/README.md +132 -58
  2. package/package.json +17 -35
package/README.md CHANGED
@@ -1,22 +1,80 @@
1
- ![Pompelmi banner](./assets/readme-banner.png)
1
+ <div align="center">
2
2
 
3
- # Pompelmi
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
- [![GitHub stars](https://img.shields.io/github/stars/pompelmi/pompelmi?style=flat-square&logo=github)](https://github.com/pompelmi/pompelmi/stargazers)
6
- [![npm version](https://img.shields.io/npm/v/pompelmi?label=version&logo=npm)](https://www.npmjs.com/package/pompelmi)
7
- [![CI](https://img.shields.io/github/actions/workflow/status/pompelmi/pompelmi/ci.yml?branch=main&label=CI&logo=github)](https://github.com/pompelmi/pompelmi/actions/workflows/ci.yml)
9
+ <h1>Pompelmi</h1>
8
10
 
9
- In-process file upload security for Node.js.
11
+ <p><strong>Stop malicious uploads before they hit storage.</strong></p>
10
12
 
11
- Your file upload endpoint is part of your attack surface.
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
- Pompelmi is an open-source Node.js library that scans and blocks risky uploads before they hit storage or downstream processing. It runs in-process, with no cloud API, no daemon, and no required data egress.
57
+ Picked up by developer newsletters, security media, and curated awesome lists.
14
58
 
15
- Works with Express, Next.js, NestJS, Fastify, and Koa. The MIT-licensed core is the primary path in this repo.
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
- ## Why this matters
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
- Most upload handlers stop at extension checks or client-provided MIME types. That leaves gaps for spoofed files, archive bombs, polyglots, and script-bearing documents.
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
- ## Key protections
87
+ Why teams choose it:
30
88
 
31
- - Extension, size, and declared MIME policy checks.
32
- - Magic-byte validation for renamed or disguised files.
33
- - Archive controls for ZIP bombs, traversal, and nesting depth.
34
- - Heuristics for risky structures such as executables, polyglots, and script-bearing documents.
35
- - Optional YARA matching when you need signature-based rules.
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
- ## Quick start
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({ error: 'Upload blocked', reasons: report.reasons });
124
+ return res.status(422).json({
125
+ error: 'Upload blocked',
126
+ reasons: report.reasons,
127
+ });
55
128
  }
56
129
  ```
57
130
 
58
- Next steps:
131
+ Start here next:
59
132
 
60
133
  - [Getting started](https://pompelmi.github.io/pompelmi/getting-started/)
61
- - [Framework guides](https://pompelmi.github.io/pompelmi/how-to/express/)
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
- ## Framework support
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
- | Framework | Package or guide |
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
- | Nuxt/Nitro | guide in docs |
156
+ | React UI | `@pompelmi/ui-react` |
157
+ | CLI | `@pompelmi/cli` |
74
158
 
75
- ## Trust / production readiness
159
+ ## Why Not Just MIME Checks, Cloud AV, or ClamAV?
76
160
 
77
- - MIT-licensed core, typed APIs, framework adapters, and composable policy packs.
78
- - Structured verdicts, reasons, and rule matches for logging, quarantine, and review flows.
79
- - Public docs, examples, changelog, tests, and a security disclosure policy.
80
- - Local-first deployment model with no required cloud scanning dependency.
81
- - Built as a defense-in-depth upload gate, not a full antivirus replacement.
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
- Start here:
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
- - [Production readiness](https://pompelmi.github.io/pompelmi/production-readiness/)
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
- ## FAQ
172
+ If you want to follow the project as it grows, star the repo and keep an eye on releases.
92
173
 
93
- ### Does Pompelmi send files to a cloud API?
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
- No. Scanning runs in-process by default. File bytes do not need to leave your infrastructure.
180
+ ## Community
96
181
 
97
- ### Does it require ClamAV, a sidecar, or another daemon?
98
-
99
- No. Built-in heuristics work without a daemon. ClamAV and YARA integrations are optional.
100
-
101
- ### What does it help block?
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
- Commercial support and enterprise options are available for teams that need rollout help, advanced auditability, or additional operational features. The open-source MIT core remains the default path. See [Support options](https://pompelmi.github.io/pompelmi/support/) and [`@pompelmi/enterprise`](https://pompelmi.github.io/pompelmi/enterprise/).
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.2",
4
- "description": "In-process file upload security for Node.js no cloud API, no daemon, no data egress. TypeScript-first library with Express, Next.js, NestJS, Fastify, Koa, and Nuxt/Nitro adapters. Features magic-byte MIME validation, ZIP bomb protection, YARA integration, and layered heuristic scanning. Built for privacy-sensitive and self-hosted environments.",
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
- "virus-scanner",
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
- "zip-bomb-protection",
232
- "express-middleware",
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
- "fastify"
241
+ "nuxt"
260
242
  ],
261
243
  "directories": {
262
244
  "example": "examples"