pompelmi 0.34.4 → 0.34.5
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 +101 -150
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,193 +1,144 @@
|
|
|
1
1
|
<div align="center">
|
|
2
|
-
|
|
3
|
-
<
|
|
4
|
-
<
|
|
5
|
-
<
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
<
|
|
10
|
-
|
|
11
|
-
<p
|
|
12
|
-
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
<
|
|
16
|
-
|
|
17
|
-
<
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
<
|
|
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
|
-
|
|
2
|
+
<img src="assets/logo.svg" alt="Pompelmi logo" width="160" />
|
|
3
|
+
<h1>Pompelmi</h1>
|
|
4
|
+
<p>Local-first file upload scanning for Node.js.</p>
|
|
5
|
+
<p>
|
|
6
|
+
<a href="https://www.npmjs.com/package/pompelmi"><img alt="npm version" src="https://img.shields.io/npm/v/pompelmi"></a>
|
|
7
|
+
<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?label=ci"></a>
|
|
8
|
+
<a href="https://github.com/pompelmi/pompelmi/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/pompelmi/pompelmi"></a>
|
|
9
|
+
<a href="https://www.npmjs.com/package/pompelmi"><img alt="npm downloads" src="https://img.shields.io/npm/dm/pompelmi"></a>
|
|
10
|
+
</p>
|
|
11
|
+
<p>
|
|
12
|
+
<a href="https://github.com/sorrycc/awesome-javascript"><img alt="Mentioned in Awesome JavaScript" src="https://img.shields.io/badge/mentioned-Awesome%20JavaScript-f59e0b"></a>
|
|
13
|
+
<a href="https://github.com/dzharii/awesome-typescript"><img alt="Mentioned in Awesome TypeScript" src="https://img.shields.io/badge/mentioned-Awesome%20TypeScript-3178C6"></a>
|
|
14
|
+
<a href="https://nodeweekly.com/issues/594"><img alt="Featured in Node Weekly #594" src="https://img.shields.io/badge/featured-Node%20Weekly%20%23594-339933?logo=node.js&logoColor=white"></a>
|
|
15
|
+
<a href="https://bytes.dev/archives/429"><img alt="Featured in Bytes #429" src="https://img.shields.io/badge/featured-Bytes%20%23429-111111"></a>
|
|
16
|
+
</p>
|
|
17
|
+
<p>
|
|
18
|
+
<a href="https://www.detectionengineering.net/p/det-eng-weekly-issue-124-the-defcon"><img alt="Featured in Detection Engineering Weekly #124" src="https://img.shields.io/badge/featured-Detection%20Engineering%20Weekly%20%23124-0A84FF?logo=substack&logoColor=white"></a>
|
|
19
|
+
<a href="https://stackoverflow.blog/2026/02/23/defense-against-uploads-oss-file-scanner-pompelmi/"><img alt="Featured on Stack Overflow by Ryan Donovan" src="https://img.shields.io/badge/featured-Stack%20Overflow-F48024?logo=stackoverflow&logoColor=white"></a>
|
|
20
|
+
<a href="https://stackoverflow.blog/newsletter/issue-319-dogfooding-your-sdlc/"><img alt="Featured in The Overflow #319" src="https://img.shields.io/badge/featured-The%20Overflow%20%23319-F48024?logo=stackoverflow&logoColor=white"></a>
|
|
21
|
+
<a href="https://www.helpnetsecurity.com/2026/02/02/pompelmi-open-source-secure-file-upload-scanning-node-js/"><img alt="Featured in Help Net Security" src="https://img.shields.io/badge/featured-Help%20Net%20Security-2563eb"></a>
|
|
22
|
+
</p>
|
|
49
23
|
</div>
|
|
50
24
|
|
|
51
|
-
|
|
52
|
-
<img src="https://raw.githubusercontent.com/pompelmi/pompelmi/main/assets/readme-banner.png" alt="Pompelmi banner" width="100%">
|
|
53
|
-
</p>
|
|
25
|
+
Pompelmi inspects untrusted files before storage and helps you decide whether to allow, reject, or quarantine them before they reach downstream systems.
|
|
54
26
|
|
|
55
|
-
|
|
27
|
+
It is built for upload endpoints that cannot rely on filenames, extensions, or client-provided MIME types alone.
|
|
56
28
|
|
|
57
|
-
|
|
29
|
+
## Install
|
|
58
30
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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>
|
|
67
|
-
|
|
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>
|
|
31
|
+
```bash
|
|
32
|
+
npm install pompelmi
|
|
33
|
+
```
|
|
72
34
|
|
|
73
|
-
|
|
35
|
+
Requires Node.js 18+.
|
|
74
36
|
|
|
75
|
-
|
|
37
|
+
## Quick Start
|
|
76
38
|
|
|
77
|
-
|
|
39
|
+
```ts
|
|
40
|
+
import { scanBytes } from 'pompelmi';
|
|
78
41
|
|
|
79
|
-
|
|
42
|
+
const report = await scanBytes(file.buffer, {
|
|
43
|
+
ctx: {
|
|
44
|
+
filename: file.originalname,
|
|
45
|
+
mimeType: file.mimetype,
|
|
46
|
+
size: file.size,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
80
49
|
|
|
81
|
-
|
|
50
|
+
if (!report.ok) {
|
|
51
|
+
return res.status(422).json({
|
|
52
|
+
error: 'Upload blocked',
|
|
53
|
+
verdict: report.verdict,
|
|
54
|
+
reasons: report.reasons,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
```
|
|
82
58
|
|
|
83
|
-
|
|
59
|
+
## What Problem It Solves
|
|
84
60
|
|
|
85
|
-
|
|
61
|
+
Upload endpoints are part of your attack surface. A renamed executable, a risky PDF, or a hostile archive can look harmless until it is stored, unpacked, served, or parsed by another system.
|
|
86
62
|
|
|
87
|
-
|
|
63
|
+
Pompelmi adds checks at the upload boundary for:
|
|
88
64
|
|
|
89
|
-
-
|
|
90
|
-
-
|
|
91
|
-
-
|
|
92
|
-
-
|
|
65
|
+
- MIME spoofing and magic-byte mismatches
|
|
66
|
+
- Archive abuse such as ZIP bombs, traversal, and deep nesting
|
|
67
|
+
- Polyglot files and risky document structures
|
|
68
|
+
- Optional YARA-based signature matching
|
|
93
69
|
|
|
94
|
-
|
|
70
|
+
The goal is simple: inspect first, store later.
|
|
95
71
|
|
|
96
|
-
|
|
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.
|
|
72
|
+
## Why This Shape
|
|
100
73
|
|
|
101
|
-
|
|
74
|
+
- Plain Markdown, readable in GitHub and in a terminal
|
|
75
|
+
- Fast path first: install, example, then deeper links
|
|
76
|
+
- Minimal top-level detail, with docs and examples for everything else
|
|
102
77
|
|
|
103
|
-
|
|
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>
|
|
78
|
+
## Ecosystem
|
|
106
79
|
|
|
107
|
-
|
|
80
|
+
- `pompelmi`
|
|
81
|
+
- `@pompelmi/express-middleware`
|
|
82
|
+
- `@pompelmi/koa-middleware`
|
|
83
|
+
- `@pompelmi/next-upload`
|
|
84
|
+
- `@pompelmi/nestjs-integration`
|
|
85
|
+
- `@pompelmi/fastify-plugin`
|
|
86
|
+
- `@pompelmi/ui-react`
|
|
87
|
+
- `@pompelmi/cli`
|
|
108
88
|
|
|
109
|
-
|
|
110
|
-
npm install pompelmi
|
|
111
|
-
```
|
|
89
|
+
## Repository Layout
|
|
112
90
|
|
|
113
|
-
|
|
114
|
-
|
|
91
|
+
- `src/` core library
|
|
92
|
+
- `packages/` framework adapters and supporting packages
|
|
93
|
+
- `examples/` runnable examples
|
|
94
|
+
- `tests/` test coverage
|
|
95
|
+
- `website/` documentation site
|
|
115
96
|
|
|
116
|
-
|
|
117
|
-
filename: file.originalname,
|
|
118
|
-
mimeType: file.mimetype,
|
|
119
|
-
policy: STRICT_PUBLIC_UPLOAD,
|
|
120
|
-
failClosed: true,
|
|
121
|
-
});
|
|
97
|
+
## Development
|
|
122
98
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
});
|
|
128
|
-
}
|
|
99
|
+
```bash
|
|
100
|
+
pnpm install
|
|
101
|
+
pnpm test
|
|
102
|
+
pnpm build
|
|
129
103
|
```
|
|
130
104
|
|
|
131
|
-
|
|
105
|
+
## Links
|
|
132
106
|
|
|
133
|
-
- [
|
|
134
|
-
- [Express guide](https://pompelmi.github.io/pompelmi/how-to/express/)
|
|
107
|
+
- [Documentation](https://pompelmi.github.io/pompelmi/)
|
|
135
108
|
- [Examples](./examples)
|
|
136
|
-
- [
|
|
137
|
-
|
|
138
|
-
|
|
109
|
+
- [Contributing](./CONTRIBUTING.md)
|
|
110
|
+
- [Security](./SECURITY.md)
|
|
111
|
+
- [Roadmap](./ROADMAP.md)
|
|
139
112
|
|
|
140
|
-
|
|
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.
|
|
113
|
+
<!-- MENTIONS:START -->
|
|
145
114
|
|
|
146
|
-
##
|
|
115
|
+
## 🌟 Featured In
|
|
147
116
|
|
|
148
|
-
|
|
149
|
-
| --- | --- |
|
|
150
|
-
| Core library | `pompelmi` |
|
|
151
|
-
| Express | `@pompelmi/express-middleware` |
|
|
152
|
-
| Next.js | `@pompelmi/next-upload` |
|
|
153
|
-
| Koa | `@pompelmi/koa-middleware` |
|
|
154
|
-
| NestJS | `@pompelmi/nestjs-integration` |
|
|
155
|
-
| Fastify | `@pompelmi/fastify-plugin` |
|
|
156
|
-
| React UI | `@pompelmi/ui-react` |
|
|
157
|
-
| CLI | `@pompelmi/cli` |
|
|
117
|
+
*Last updated: March 20, 2026*
|
|
158
118
|
|
|
159
|
-
|
|
119
|
+
### 📋 Awesome Lists & Curated Collections
|
|
160
120
|
|
|
161
|
-
|
|
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. |
|
|
121
|
+
- [Awesome JavaScript](https://github.com/sorrycc/awesome-javascript) — sorrycc
|
|
122
|
+
- [Awesome TypeScript](https://github.com/dzharii/awesome-typescript) — dzharii
|
|
167
123
|
|
|
168
|
-
|
|
124
|
+
### 📰 Newsletters & Roundups
|
|
169
125
|
|
|
170
|
-
|
|
126
|
+
- [The Overflow Issue 319: Dogfooding your SDLC](https://stackoverflow.blog/newsletter/issue-319-dogfooding-your-sdlc/) — Stack Overflow (2026-03-04)
|
|
127
|
+
- [Hottest cybersecurity open-source tools of the month: February 2026](https://www.helpnetsecurity.com/2026/02/26/hottest-cybersecurity-open-source-tools-of-the-month-february-2026/) — Help Net Security (2026-02-26)
|
|
128
|
+
- [Bytes #429](https://bytes.dev/archives/429) — Bytes (2025-10-03)
|
|
129
|
+
- [Node Weekly Issue 594](https://nodeweekly.com/issues/594) — Node Weekly (2025-09-30)
|
|
130
|
+
- [Det. Eng. Weekly Issue #124 - The DEFCON hangover is real](https://www.detectionengineering.net/p/det-eng-weekly-issue-124-the-defcon) — Detection Engineering (2025-08-13)
|
|
171
131
|
|
|
172
|
-
|
|
132
|
+
### 🔗 Other Mentions
|
|
173
133
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=pompelmi/pompelmi&type=Date">
|
|
177
|
-
</a>
|
|
178
|
-
</p>
|
|
134
|
+
- [Defense against uploads: Q&A with OSS file scanner, pompelmi](https://stackoverflow.blog/2026/02/23/defense-against-uploads-oss-file-scanner-pompelmi/) — Stack Overflow (2026-02-23)
|
|
135
|
+
- [Pompelmi: Open-source secure file upload scanning for Node.js](https://www.helpnetsecurity.com/2026/02/02/pompelmi-open-source-secure-file-upload-scanning-node-js/) — Help Net Security (2026-02-02)
|
|
179
136
|
|
|
180
|
-
## Community
|
|
181
137
|
|
|
182
|
-
|
|
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)
|
|
138
|
+
*Found 9 mentions. To update, run `npm run mentions:update`.*
|
|
188
139
|
|
|
189
|
-
|
|
140
|
+
<!-- MENTIONS:END -->
|
|
190
141
|
|
|
191
142
|
## License
|
|
192
143
|
|
|
193
|
-
MIT
|
|
144
|
+
[MIT](./LICENSE)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pompelmi",
|
|
3
|
-
"version": "0.34.
|
|
3
|
+
"version": "0.34.5",
|
|
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",
|