Introduction
The majority of website have a form where files are been uploaded.
Hacker could easily insert a malicious file that will create backdoor.
In this article we are going to improve your React, NextJS and ExpressJS site to be able to protect against this exploits.
Let's get started! ๐
๐ค What do we start with?
For our website, we will use a ready-made solution called pompelmi, a NPM package for detect easily if a file contains malware.
1. Installation
Inside the root of your project type
npm install pompelmi
# or: yarn add pompelmi / pnpm add pompelmi
And we installed all the need.
2.a โ๏ธ React
For React:
import React, { useState, useCallback } from 'react';
import { createRemoteEngine } from 'pompelmi';
const YARA_RULES = `
rule demo_contains_virus_literal {
strings:
$a = "virus" ascii nocase
condition:
$a
}
`;
export function FileScanner({ endpoint = 'http://localhost:8787/api/yara/scan' }) {
const [result, setResult] = useState(null);
const handleFile = useCallback(async (e) => {
const file = e.target.files?.[0];
if (!file) return;
const engine = await createRemoteEngine({
endpoint,
mode: 'json-base64',
rulesAsBase64: true,
});
const compiled = await engine.compile(YARA_RULES);
const bytes = new Uint8Array(await file.arrayBuffer());
const matches = await compiled.scan(bytes);
setResult(matches);
}, [endpoint]);
return (
<div>
<input type="file" onChange={handleFile} />
{result && (
<pre style={{ whiteSpace: 'pre-wrap', marginTop: '1rem' }}>
{JSON.stringify(result, null, 2)}
</pre>
)}
</div>
);
}
2.3 ๐ณ Next.JS
For NextJS:
// app/api/upload/route.ts
import { createNextUploadHandler } from '@pompelmi/next-upload';
export const runtime = 'nodejs'; // Next: Node runtime (not Edge)
export const dynamic = 'force-dynamic'; // optional: avoid route cache
const SimpleEicarScanner = { /* same as above */ };
export const POST = createNextUploadHandler({
scanner: SimpleEicarScanner,
includeExtensions: ['txt','png','jpg','jpeg','pdf','zip'],
allowedMimeTypes: ['text/plain','image/png','image/jpeg','application/pdf','application/zip'],
maxFileSizeBytes: 20 * 1024 * 1024,
timeoutMs: 5000,
concurrency: 4,
failClosed: true,
onScanEvent: (ev) => console.log('[scan]', ev)
});
}
3.c โ ExpressJS
For ExpressJS:
import express from 'express';
import multer from 'multer';
import { createUploadGuard } from '@pompelmi/express-middleware';
const app = express();
const upload = multer({ storage: multer.memoryStorage(), limits: { fileSize: 20 * 1024 * 1024 } });
// Simple demo scanner (replace with YARA rules in production)
const SimpleEicarScanner = {
async scan(bytes: Uint8Array) {
const text = Buffer.from(bytes).toString('utf8');
if (text.includes('EICAR-STANDARD-ANTIVIRUS-TEST-FILE')) return [{ rule: 'eicar_test' }];
return [];
}
};
app.post(
'/upload',
upload.any(),
createUploadGuard({
scanner: SimpleEicarScanner,
includeExtensions: ['txt','png','jpg','jpeg','pdf','zip'],
allowedMimeTypes: ['text/plain','image/png','image/jpeg','application/pdf','application/zip'],
maxFileSizeBytes: 20 * 1024 * 1024,
timeoutMs: 5000,
concurrency: 4,
failClosed: true,
onScanEvent: (ev) => console.log('[scan]', ev)
}),
(req, res) => {
res.json({ ok: true, scan: (req as any).pompelmi ?? null });
}
);
app.listen(3000, () => console.log('demo on http://localhost:3000'));
3 ๐ You're Ready!
All the things are done, now you malware detection integration is ready!
Repository: https://github.com/pompelmi/pompelmi
Warning โ ๏ธ: It's an Alpha, something will not work, the author takes no responsibility for any problems.
Disclosure: Iโm the author.
Top comments (0)