pompelmi 0.35.2 → 0.35.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 +139 -114
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,29 +1,81 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="./assets/logo.svg" alt="Pompelmi logo" width="120" />
|
|
3
|
+
|
|
4
|
+
<h1>Pompelmi</h1>
|
|
5
|
+
|
|
6
|
+
<p><strong>Secure file uploads in Node.js before storage.</strong></p>
|
|
7
|
+
|
|
8
|
+
<p>
|
|
9
|
+
Open-source route-level upload security for Node.js teams that need to
|
|
10
|
+
inspect untrusted files before disk, object storage, previews, or
|
|
11
|
+
downstream parsers.
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
<p><code>clean</code> · <code>suspicious</code> · <code>malicious</code></p>
|
|
15
|
+
|
|
16
|
+
<p>
|
|
17
|
+
MIME spoofing · risky archives · document and binary signals · optional
|
|
18
|
+
YARA
|
|
19
|
+
</p>
|
|
20
|
+
|
|
21
|
+
<p>
|
|
22
|
+
<sub>Express · Next.js · NestJS · Fastify · Koa · Nuxt/Nitro · S3 quarantine flows · CI/CD</sub>
|
|
23
|
+
</p>
|
|
24
|
+
|
|
25
|
+
<p>
|
|
26
|
+
<a href="https://www.npmjs.com/package/pompelmi"><img alt="npm version" src="https://img.shields.io/npm/v/pompelmi" /></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?label=ci" /></a>
|
|
28
|
+
<a href="https://codecov.io/gh/pompelmi/pompelmi"><img alt="codecov" src="https://codecov.io/gh/pompelmi/pompelmi/graph/badge.svg" /></a>
|
|
29
|
+
<a href="https://github.com/pompelmi/pompelmi/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/pompelmi/pompelmi?style=social" /></a>
|
|
30
|
+
</p>
|
|
31
|
+
|
|
32
|
+
<p>
|
|
33
|
+
<a href="https://pompelmi.app/"><strong>Docs</strong></a>
|
|
34
|
+
·
|
|
35
|
+
<a href="https://pompelmi.app/getting-started/"><strong>Getting started</strong></a>
|
|
36
|
+
·
|
|
37
|
+
<a href="https://pompelmi.app/#browser-preview"><strong>Browser preview</strong></a>
|
|
38
|
+
·
|
|
39
|
+
<a href="./examples/demo"><strong>Express demo</strong></a>
|
|
40
|
+
·
|
|
41
|
+
<a href="./examples/README.md"><strong>Examples</strong></a>
|
|
42
|
+
</p>
|
|
43
|
+
|
|
44
|
+
<p><sub>Node.js 18+ · MIT</sub></p>
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
<p align="center">
|
|
48
|
+
<strong>Mentioned by</strong>
|
|
49
|
+
<a href="https://nodeweekly.com/issues/594">Node Weekly</a>,
|
|
50
|
+
<a href="https://stackoverflow.blog/2026/02/23/defense-against-uploads-oss-file-scanner-pompelmi/">Stack Overflow</a>,
|
|
51
|
+
<a href="https://www.helpnetsecurity.com/2026/02/02/pompelmi-open-source-secure-file-upload-scanning-node-js/">Help Net Security</a>,
|
|
52
|
+
<a href="https://github.com/sorrycc/awesome-javascript">Awesome JavaScript</a>,
|
|
53
|
+
and
|
|
54
|
+
<a href="https://github.com/dzharii/awesome-typescript">Awesome TypeScript</a>
|
|
55
|
+
</p>
|
|
56
|
+
|
|
57
|
+
<p align="center">
|
|
58
|
+
<sub>If you want upload security to start at the route boundary instead of after storage, consider starring the repo.</sub>
|
|
59
|
+
</p>
|
|
60
|
+
|
|
61
|
+
> Upload endpoints are part of your attack surface. Pompelmi helps Node.js teams scan files before storage and make the decision while the route still has context: accept, quarantine, or reject.
|
|
2
62
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
[](https://www.npmjs.com/package/pompelmi)
|
|
6
|
-
[](https://github.com/pompelmi/pompelmi/actions/workflows/ci.yml)
|
|
7
|
-
[](https://github.com/pompelmi/pompelmi/stargazers)
|
|
8
|
-
|
|
9
|
-
Pompelmi helps reduce:
|
|
63
|
+
## Quick Start
|
|
10
64
|
|
|
11
|
-
|
|
12
|
-
- risky archive structures such as ZIP bombs, traversal, and deep nesting
|
|
13
|
-
- risky document and binary patterns such as PDF actions, Office macro hints, PE signatures, and polyglot files
|
|
14
|
-
- store-first upload flows that need a clean / suspicious / malicious verdict before persistence
|
|
15
|
-
- known malicious matches when you plug in YARA or another scanner
|
|
65
|
+
Install the core package:
|
|
16
66
|
|
|
17
|
-
|
|
67
|
+
```bash
|
|
68
|
+
npm install pompelmi
|
|
69
|
+
```
|
|
18
70
|
|
|
19
|
-
|
|
71
|
+
This is the core pattern: inspect bytes, get a verdict, and only store clean files.
|
|
20
72
|
|
|
21
73
|
```ts
|
|
22
74
|
import { scanBytes, STRICT_PUBLIC_UPLOAD } from 'pompelmi';
|
|
23
75
|
|
|
24
|
-
const report = await scanBytes(file.buffer, {
|
|
25
|
-
filename: file.originalname,
|
|
26
|
-
mimeType: file.mimetype,
|
|
76
|
+
const report = await scanBytes(req.file.buffer, {
|
|
77
|
+
filename: req.file.originalname,
|
|
78
|
+
mimeType: req.file.mimetype,
|
|
27
79
|
policy: STRICT_PUBLIC_UPLOAD,
|
|
28
80
|
failClosed: true,
|
|
29
81
|
});
|
|
@@ -35,128 +87,101 @@ if (report.verdict !== 'clean') {
|
|
|
35
87
|
reasons: report.reasons,
|
|
36
88
|
});
|
|
37
89
|
}
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
Need a local scan in under a minute? Start with [Getting started](https://pompelmi.github.io/pompelmi/getting-started/). Want a preview of the verdict flow first? Open the [browser preview](https://pompelmi.github.io/pompelmi/#browser-preview). Want a minimal server route? See [examples/demo](./examples/demo).
|
|
41
90
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
## Why It Exists
|
|
45
|
-
|
|
46
|
-
Upload endpoints are part of your attack surface. A file can look harmless at the form layer and only become dangerous after storage, extraction, rendering, or downstream parsing.
|
|
47
|
-
|
|
48
|
-
Pompelmi keeps the first decision inside the application path, where the route still knows the file class, the trust level, and the right failure mode.
|
|
91
|
+
return res.status(200).json({ verdict: report.verdict });
|
|
92
|
+
```
|
|
49
93
|
|
|
50
|
-
|
|
94
|
+
Start with [Getting started](https://pompelmi.app/getting-started/) for a local scan in under a minute, open the [browser preview](https://pompelmi.app/#browser-preview) to inspect the verdict flow without sending files anywhere, or run the minimal [Express demo](./examples/demo).
|
|
51
95
|
|
|
52
|
-
|
|
53
|
-
- memory-backed multipart routes in Express, Next.js, NestJS, Fastify, and Koa
|
|
54
|
-
- quarantine and promotion workflows for S3 or other object storage
|
|
55
|
-
- document, image, and archive routes that need different policies
|
|
56
|
-
- CI/CD or internal artifact scanning before promotion
|
|
96
|
+
## Why teams use Pompelmi
|
|
57
97
|
|
|
58
|
-
|
|
98
|
+
- File upload endpoints are not just form validation. Files can become risky after storage, extraction, rendering, or downstream parsing.
|
|
99
|
+
- Pompelmi keeps the first trust decision inside the application path, where the route still knows the file class, trust level, storage path, and failure mode.
|
|
100
|
+
- It gives Node.js teams a practical way to build secure file uploads with route-level decisions instead of bolting checks on after persistence.
|
|
59
101
|
|
|
60
|
-
|
|
61
|
-
- Next.js: [Docs](https://pompelmi.github.io/pompelmi/how-to/nextjs/) · [Example](./examples/next-app-router)
|
|
62
|
-
- NestJS: [Docs](https://pompelmi.github.io/pompelmi/how-to/nestjs/) · [Example app](./examples/nestjs-app)
|
|
63
|
-
- Fastify: [Docs](https://pompelmi.github.io/pompelmi/how-to/fastify/) · [Package](./packages/fastify-plugin)
|
|
64
|
-
- Koa: [Docs](https://pompelmi.github.io/pompelmi/how-to/koa/) · [Package](./packages/koa-middleware)
|
|
65
|
-
- Nuxt/Nitro: [Docs](https://pompelmi.github.io/pompelmi/how-to/nuxt-nitro/)
|
|
66
|
-
- S3 / object storage: [Tutorial](https://pompelmi.github.io/pompelmi/tutorials/secure-s3-presigned-uploads-with-malware-scanning/) · [Use case](https://pompelmi.github.io/pompelmi/use-cases/s3-presigned-upload-security/)
|
|
67
|
-
- CI/CD: [Use case](https://pompelmi.github.io/pompelmi/use-cases/cicd-artifact-scanning/) · [Blog](https://pompelmi.github.io/pompelmi/blog/cicd-scan-build-artifacts/)
|
|
102
|
+
## What it checks
|
|
68
103
|
|
|
69
|
-
|
|
104
|
+
- MIME sniffing, magic-byte validation, and extension mismatch detection
|
|
105
|
+
- Risky archives such as ZIP bombs, traversal attempts, deep nesting, and entry-count abuse
|
|
106
|
+
- Risky document and binary signals such as PDF actions, Office macro hints, PE headers, and polyglot files
|
|
107
|
+
- Optional YARA-based matches when you want malware scanning uploads as part of the flow
|
|
108
|
+
- Verdicts and reasons you can use for fail-closed routes, quarantine flows, and auditability
|
|
70
109
|
|
|
71
|
-
|
|
72
|
-
- [Getting started](https://pompelmi.github.io/pompelmi/getting-started/)
|
|
73
|
-
- [Use cases](https://pompelmi.github.io/pompelmi/use-cases/)
|
|
74
|
-
- [Comparisons](https://pompelmi.github.io/pompelmi/comparisons/)
|
|
75
|
-
- [Tutorials](https://pompelmi.github.io/pompelmi/tutorials/)
|
|
76
|
-
- [Examples index](./examples/README.md)
|
|
77
|
-
- [Demo example](./examples/demo)
|
|
78
|
-
- [Featured in](https://pompelmi.github.io/pompelmi/featured-in/)
|
|
79
|
-
- [Translations](https://pompelmi.github.io/pompelmi/translations/)
|
|
80
|
-
- [Contributing](./CONTRIBUTING.md)
|
|
81
|
-
- [Security](./SECURITY.md)
|
|
82
|
-
- [Roadmap](./ROADMAP.md)
|
|
110
|
+
## Where it fits in the upload pipeline
|
|
83
111
|
|
|
84
|
-
|
|
112
|
+
1. Receive the upload into memory or an isolated staging or quarantine area.
|
|
113
|
+
2. Scan the bytes with a route policy.
|
|
114
|
+
3. Act on the verdict: `clean`, `suspicious`, or `malicious`.
|
|
115
|
+
4. Persist, quarantine, or reject based on the route's rules.
|
|
85
116
|
|
|
86
|
-
|
|
117
|
+
That inspect-first, store-later shape is where Pompelmi is strongest.
|
|
87
118
|
|
|
88
|
-
|
|
119
|
+
## What it is and isn't
|
|
89
120
|
|
|
90
|
-
|
|
121
|
+
| Approach | Useful for | What it misses |
|
|
122
|
+
| --- | --- | --- |
|
|
123
|
+
| Browser MIME and extension checks | Fast client-side hints and UX feedback | Client MIME and filenames are easy to spoof |
|
|
124
|
+
| File-type or magic-byte validation only | Confirming a file looks like the claimed type | Archive abuse, risky internal structure, and route policy decisions |
|
|
125
|
+
| Antivirus or YARA only | Known malicious matches and signature-style detection | Route context, spoofing checks, and before-storage handling |
|
|
126
|
+
| Pompelmi at the upload route | Node.js file upload security, scan files before storage, and verdict-driven workflow decisions | It is not a full antivirus replacement on its own |
|
|
91
127
|
|
|
92
|
-
|
|
128
|
+
## Supported frameworks and workflows
|
|
93
129
|
|
|
94
|
-
|
|
130
|
+
| Stack or workflow | Links |
|
|
131
|
+
| --- | --- |
|
|
132
|
+
| Express | [Docs](https://pompelmi.app/how-to/express/) · [Minimal example](./examples/express-minimal) · [Demo](./examples/demo) |
|
|
133
|
+
| Next.js | [Docs](https://pompelmi.app/how-to/nextjs/) · [Example](./examples/next-app-router) · [Package](./packages/next-upload) |
|
|
134
|
+
| NestJS | [Docs](https://pompelmi.app/how-to/nestjs/) · [Package](./packages/nestjs) · [Example app](./examples/nestjs-app) |
|
|
135
|
+
| Fastify | [Docs](https://pompelmi.app/how-to/fastify/) · [Package](./packages/fastify-plugin) |
|
|
136
|
+
| Koa | [Docs](https://pompelmi.app/how-to/koa/) · [Package](./packages/koa-middleware) |
|
|
137
|
+
| Nuxt/Nitro | [Docs](https://pompelmi.app/how-to/nuxt-nitro/) · [Example](./examples/nuxt-nitro) |
|
|
138
|
+
| S3 / object storage | [Tutorial](https://pompelmi.app/tutorials/secure-s3-presigned-uploads-with-malware-scanning/) · [Use case](https://pompelmi.app/use-cases/object-storage-promotion-workflows/) |
|
|
139
|
+
| CI/CD | [Use case](https://pompelmi.app/use-cases/cicd-artifact-scanning/) · [Blog](https://pompelmi.app/blog/cicd-scan-build-artifacts/) |
|
|
95
140
|
|
|
96
|
-
|
|
97
|
-
- archive controls such as ZIP bombs, traversal, entry counts, expansion limits, and nesting limits
|
|
98
|
-
- common heuristics for risky PDFs, Office macro hints, executables, and other suspicious structures
|
|
99
|
-
- optional YARA-based signature matching
|
|
100
|
-
- route-level `clean`, `suspicious`, and `malicious` decisions with quarantine-friendly workflows
|
|
141
|
+
## Demo, preview, and examples
|
|
101
142
|
|
|
102
|
-
|
|
143
|
+

|
|
103
144
|
|
|
104
|
-
-
|
|
105
|
-
-
|
|
106
|
-
-
|
|
107
|
-
-
|
|
108
|
-
- `@pompelmi/nestjs-integration`
|
|
109
|
-
- `@pompelmi/fastify-plugin`
|
|
110
|
-
- `@pompelmi/ui-react`
|
|
111
|
-
- `@pompelmi/cli`
|
|
145
|
+
- [Browser preview](https://pompelmi.app/#browser-preview) for a fast local look at the verdict UX without uploading files anywhere
|
|
146
|
+
- [Express demo](./examples/demo) for a tiny upload gate that returns `clean`, `suspicious`, or `malicious` before storage
|
|
147
|
+
- [Examples index](./examples/README.md) for framework-specific and production-oriented patterns
|
|
148
|
+
- [Docs home](https://pompelmi.app/) for guides, comparisons, use cases, and tutorials
|
|
112
149
|
|
|
113
|
-
##
|
|
150
|
+
## Why star this repo
|
|
114
151
|
|
|
115
|
-
|
|
116
|
-
- `packages/` framework adapters and supporting packages
|
|
117
|
-
- `examples/` runnable examples
|
|
118
|
-
- `tests/` test coverage
|
|
119
|
-
- `website/` public docs, blog, and discovery site
|
|
120
|
-
|
|
121
|
-
## Development
|
|
122
|
-
|
|
123
|
-
```bash
|
|
124
|
-
pnpm install
|
|
125
|
-
pnpm test
|
|
126
|
-
pnpm build
|
|
127
|
-
```
|
|
152
|
+
Pompelmi is focused on a real gap in most Node.js stacks: secure file uploads that make a decision before storage, not after. If that matches how you want upload security to work, star the repo to follow the project and help more teams discover the inspect-before-storage model.
|
|
128
153
|
|
|
129
154
|
<!-- MENTIONS:START -->
|
|
130
155
|
|
|
131
|
-
##
|
|
132
|
-
|
|
133
|
-
Full page: [pompelmi.github.io/pompelmi/featured-in](https://pompelmi.github.io/pompelmi/featured-in/)
|
|
134
|
-
|
|
135
|
-
*Last updated: March 20, 2026*
|
|
136
|
-
|
|
137
|
-
### Awesome Lists & Curated Collections
|
|
156
|
+
## Mentioned by
|
|
138
157
|
|
|
139
|
-
- [
|
|
140
|
-
- [
|
|
158
|
+
- [Node Weekly](https://nodeweekly.com/issues/594)
|
|
159
|
+
- [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
|
|
160
|
+
- [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
|
|
161
|
+
- [Awesome JavaScript](https://github.com/sorrycc/awesome-javascript)
|
|
162
|
+
- [Awesome TypeScript](https://github.com/dzharii/awesome-typescript)
|
|
163
|
+
- [See all mentions](https://pompelmi.app/featured-in/)
|
|
141
164
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
- [The Overflow Issue 319: Dogfooding your SDLC](https://stackoverflow.blog/newsletter/issue-319-dogfooding-your-sdlc/) — Stack Overflow (2026-03-04)
|
|
145
|
-
- [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)
|
|
146
|
-
- [Bytes #429](https://bytes.dev/archives/429) — Bytes (2025-10-03)
|
|
147
|
-
- [Node Weekly Issue 594](https://nodeweekly.com/issues/594) — Node Weekly (2025-09-30)
|
|
148
|
-
- [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)
|
|
149
|
-
|
|
150
|
-
### Other Mentions
|
|
165
|
+
<!-- MENTIONS:END -->
|
|
151
166
|
|
|
152
|
-
|
|
153
|
-
- [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)
|
|
167
|
+
## Docs
|
|
154
168
|
|
|
169
|
+
- [Getting started](https://pompelmi.app/getting-started/)
|
|
170
|
+
- [Use cases](https://pompelmi.app/use-cases/)
|
|
171
|
+
- [Comparisons](https://pompelmi.app/comparisons/)
|
|
172
|
+
- [Tutorials](https://pompelmi.app/tutorials/)
|
|
173
|
+
- [Browser preview](https://pompelmi.app/#browser-preview)
|
|
174
|
+
- [Featured in](https://pompelmi.app/featured-in/)
|
|
175
|
+
- [Translations](https://pompelmi.app/translations/)
|
|
155
176
|
|
|
156
|
-
|
|
177
|
+
## Commercial support
|
|
157
178
|
|
|
158
|
-
|
|
179
|
+
The MIT core remains the primary path. Teams that need private rollout help, architecture review, or policy tuning can use the existing [enterprise support path](https://pompelmi.app/enterprise/).
|
|
159
180
|
|
|
160
|
-
##
|
|
181
|
+
## Project
|
|
161
182
|
|
|
162
|
-
[
|
|
183
|
+
- [Contributing](./CONTRIBUTING.md)
|
|
184
|
+
- [Security](./SECURITY.md)
|
|
185
|
+
- [Roadmap](./ROADMAP.md)
|
|
186
|
+
- [GitHub Discussions](https://github.com/pompelmi/pompelmi/discussions)
|
|
187
|
+
- [License](./LICENSE)
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pompelmi",
|
|
3
|
-
"version": "0.35.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.35.4",
|
|
4
|
+
"description": "Inspect untrusted uploads before storage in Node.js. Open-source upload security with checks for spoofing, archive abuse, risky document and binary signals, and optional YARA.",
|
|
5
5
|
"main": "./dist/pompelmi.cjs",
|
|
6
6
|
"module": "./dist/pompelmi.esm.js",
|
|
7
7
|
"type": "module",
|