securexpress
v2.2.7
Published
All-in-one Express security middleware with safe defaults, L7 anti-DDoS, Helmet, CORS guard, adaptive rate limit, bot guard, CSRF, CAPTCHA gate, script injection, signed URLs, stats, and middleware utilities.
Maintainers
Readme
securexpress — Production Guide
Panduan ini khusus untuk menjalankan securexpress di production dengan aman, stabil, dan tidak terlalu agresif memblokir user normal.
Catatan penting:
securexpressmemperkuat keamanan Layer 7 / HTTP pada aplikasi Express.js. Untuk serangan DDoS besar di Layer 3/4 atau bandwidth attack, tetap gunakan Cloudflare, firewall VPS, reverse proxy, load balancer, atau proteksi hosting.
1. Tujuan Production Config
Production config yang baik harus:
- aman untuk API dan web
- tidak merusak request normal
- tidak inject ke JSON/API
- tidak expose error internal
- tidak hardcode secret
- tidak terlalu berat secara default
- punya log dan request ID
- punya rate limit khusus route sensitif
- punya proteksi file sensitif
- siap dipakai di balik Cloudflare/Nginx/Apache
2. Install
npm install securexpress express dotenvUntuk test lokal:
npm install
npm test
npm run check3. .env Production
Buat file .env:
NODE_ENV=production
PORT=3000
# wajib random panjang
SECUREXPRESS_COOKIE_SECRET=ganti_dengan_random_secret_panjang_minimal_32_karakter
# untuk endpoint statistik securexpress
SECUREXPRESS_STATS_KEY=ganti_dengan_key_admin_panjang
# untuk signed URL jika dipakai
SECUREXPRESS_SIGNED_URL_SECRET=ganti_dengan_signed_url_secret_panjang
# captcha optional
TURNSTILE_SITE_KEY=
TURNSTILE_SECRET_KEY=
RECAPTCHA_SITE_KEY=
RECAPTCHA_SECRET_KEY=Generate secret di Node.js:
node -e "console.log(require('crypto').randomBytes(48).toString('hex'))"4. Contoh Server Production Lengkap
server.js
"use strict";
require("dotenv").config();
const express = require("express");
const securexpress = require("securexpress");
const app = express();
app.disable("x-powered-by");
/**
* Body parser harus sebelum securexpress jika kamu ingin fitur seperti
* inputSanitizer, csrf, methodOverride body, dan API handler membaca JSON.
*/
app.use(express.json({
limit: "1mb",
strict: true
}));
app.use(express.urlencoded({
extended: true,
limit: "1mb"
}));
app.use(securexpress({
/**
* Gunakan strict untuk production.
* Jika user banyak terkena block, turunkan ke "balanced".
*/
preset: "strict",
/**
* true jika pakai Cloudflare/Nginx/Reverse Proxy.
*/
trustProxy: true,
/**
* Default ON, tetap biarkan ON.
*/
requestId: true,
headers: true,
compression: true,
bodyGuard: true,
ddos: true,
botGuard: true,
cache: true,
/**
* CORS: jangan pakai "*" jika memakai cookie/session/credential.
*/
cors: true,
corsOptions: {
origins: [
"https://domainmu.com",
"https://www.domainmu.com"
],
credentials: true
},
/**
* Header/body/url guard.
*/
bodyGuardOptions: {
maxBodySize: "1mb",
maxUrlLength: 2048,
maxHeaderCount: 80,
maxHeaderBytes: 16 * 1024,
timeoutMs: 15000
},
/**
* Rate limit adaptif untuk route sensitif.
*/
adaptiveRateLimit: {
enabled: true,
rules: [
{
path: "/api/login",
windowMs: 60 * 1000,
limit: 5
},
{
path: "/api/register",
windowMs: 60 * 1000,
limit: 5
},
{
path: "/api/password-reset",
windowMs: 60 * 1000,
limit: 3
},
{
path: "/api",
windowMs: 60 * 1000,
limit: 120
}
]
},
/**
* Lindungi file sensitif.
*/
staticShield: {
enabled: true
},
/**
* Honeypot path untuk scanner.
*/
honeypot: {
enabled: true
},
/**
* Sanitizer ringan.
* Jangan anggap ini pengganti validasi input.
*/
inputSanitizer: {
enabled: true,
trim: true,
nullBytes: true,
stripScript: true,
blockMongoOperators: true
},
/**
* Header response time.
*/
responseTime: {
enabled: true
},
/**
* Logger request sederhana.
* Untuk trafik sangat besar, arahkan logger ke pino/winston.
*/
requestLogger: {
enabled: true,
format: "tiny"
},
/**
* Logger security event.
*/
securityLogger: {
enabled: true,
slowMs: 2000
},
/**
* Endpoint statistik internal.
* Jangan aktif tanpa key.
*/
stats: {
enabled: true,
path: "/securexpress/stats",
key: process.env.SECUREXPRESS_STATS_KEY
},
/**
* CSRF hanya aktifkan jika memakai cookie/session berbasis browser.
* Untuk pure REST API pakai Bearer Token, biasanya tidak perlu.
*/
csrf: {
enabled: false
},
/**
* Captcha gate default OFF.
* Aktifkan untuk halaman web publik yang sering diserang bot.
*/
captchaGate: {
enabled: false
},
/**
* Script injection default OFF.
* Aktifkan hanya untuk halaman HTML, bukan API.
*/
scriptInjection: {
enabled: false
},
/**
* HTTPS redirect.
* Aktifkan jika HTTPS memang sudah benar di proxy/domain.
*/
httpsRedirect: {
enabled: true,
exclude: ["/health", "/securexpress/health"]
}
}));
app.get("/health", securexpress.health());
app.get("/", (req, res) => {
res.json({
success: true,
message: "API running",
requestId: req.id
});
});
app.get("/api/data", (req, res) => {
res.json({
success: true,
data: "protected data",
requestId: req.id
});
});
app.post("/api/login", (req, res) => {
res.json({
success: true,
message: "login endpoint example"
});
});
/**
* Handler akhir.
*/
app.use(securexpress.notFoundHandler);
app.use(securexpress.errorHandler({
exposeInternal: false,
exposeStack: false
}));
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`Production server running on port ${port}`);
});5. Production Config Minimal
Jika ingin ringan:
app.use(securexpress({
preset: "balanced",
trustProxy: true,
cors: true,
corsOptions: {
origins: ["https://domainmu.com"]
},
staticShield: {
enabled: true
},
honeypot: {
enabled: true
},
responseTime: {
enabled: true
}
}));6. Production Config Super Ketat
Gunakan ini jika API sering diserang.
app.use(securexpress({
preset: "strict",
trustProxy: true,
cors: true,
corsOptions: {
origins: ["https://domainmu.com"],
credentials: true
},
bodyGuardOptions: {
maxBodySize: "512kb",
maxUrlLength: 1536,
maxHeaderCount: 60,
maxHeaderBytes: 8192,
timeoutMs: 10000
},
adaptiveRateLimit: {
enabled: true,
rules: [
{ path: "/api/login", windowMs: 60000, limit: 3 },
{ path: "/api/register", windowMs: 60000, limit: 3 },
{ path: "/api/password-reset", windowMs: 60000, limit: 2 },
{ path: "/api", windowMs: 60000, limit: 60 }
]
},
botGuard: true,
staticShield: { enabled: true },
honeypot: { enabled: true },
inputSanitizer: { enabled: true },
responseTime: { enabled: true },
securityLogger: { enabled: true },
stats: {
enabled: true,
key: process.env.SECUREXPRESS_STATS_KEY
}
}));Jika user normal banyak kena block, turunkan:
preset: "balanced"7. Fitur yang Aman ON di Production
Disarankan ON:
requestId: true
headers: true
compression: true
bodyGuard: true
ddos: true
botGuard: true
cache: true
staticShield: { enabled: true }
honeypot: { enabled: true }
responseTime: { enabled: true }
securityLogger: { enabled: true }8. Fitur yang Sebaiknya Tetap OFF Kecuali Butuh
Fitur ini berguna, tapi bisa memengaruhi user experience jika salah konfigurasi:
captchaGate: { enabled: false }
scriptInjection: { enabled: false }
csrf: { enabled: false }
signedUrl: { enabled: false }
aiBotControl: { enabled: false }
realIpGuard: { enabled: false }
methodOverride: { enabled: false }
routeGuard: { enabled: false }
httpsRedirect: { enabled: false }9. Urutan Middleware yang Benar
Urutan disarankan:
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(securexpress({...}));
app.use(routes);
app.use(securexpress.notFoundHandler);
app.use(securexpress.errorHandler());Jangan letakkan errorHandler sebelum routes.
10. Cloudflare Setup
Jika pakai Cloudflare:
trustProxy: trueAktifkan di Cloudflare:
- SSL/TLS Full atau Full Strict
- WAF managed rules
- Bot Fight Mode jika perlu
- Rate limiting jika tersedia
- Cache static assets
- Turnstile untuk form login/register
Jangan mengandalkan Express saja untuk DDoS besar.
11. Nginx Reverse Proxy
Contoh Nginx:
server {
listen 80;
server_name domainmu.com www.domainmu.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name domainmu.com www.domainmu.com;
client_max_body_size 1m;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 30s;
proxy_connect_timeout 10s;
proxy_send_timeout 30s;
}
}Di Express:
trustProxy: true12. PM2 Production
Install PM2:
npm install -g pm2Jalankan:
pm2 start server.js --name securexpress-api
pm2 save
pm2 startupLihat log:
pm2 logs securexpress-apiRestart:
pm2 restart securexpress-api13. Docker Production
Dockerfile:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
ENV NODE_ENV=production
EXPOSE 3000
CMD ["node", "server.js"]Build:
docker build -t securexpress-api .Run:
docker run -d \
--name securexpress-api \
-p 3000:3000 \
--env-file .env \
securexpress-api14. API Key Auth di Production
Aktifkan untuk API private/internal.
apiKeyAuth: {
enabled: true,
keys: [
process.env.API_KEY_1,
process.env.API_KEY_2
],
exclude: [
"/health",
"/public"
]
}Client:
curl https://domainmu.com/api/private \
-H "x-api-key: YOUR_API_KEY"Jangan taruh API key di frontend.
15. CSRF Protection
Aktifkan CSRF jika:
- memakai cookie session
- ada form HTML
- user login via browser
csrf: {
enabled: true,
exclude: [
"/api/webhook",
"/health"
]
}Frontend harus kirim header:
X-CSRF-TokenToken tersedia di response header:
X-CSRF-Token: tokenUntuk REST API dengan Bearer token di header, CSRF biasanya tidak wajib.
16. CAPTCHA Gate
Aktifkan untuk halaman publik yang sering diserang bot.
Cloudflare Turnstile:
captchaGate: {
enabled: true,
provider: "turnstile",
title: "Verifikasi keamanan",
turnstile: {
siteKey: process.env.TURNSTILE_SITE_KEY,
secretKey: process.env.TURNSTILE_SECRET_KEY
},
exclude: [
"/api",
"/health",
"/assets"
]
}Jangan aktifkan CAPTCHA untuk API JSON kecuali memang dibutuhkan.
17. Script Injection
Script injection berguna untuk:
- loading screen
- watermark
- browser challenge
- security beacon
Aktifkan hanya untuk web HTML:
scriptInjection: {
enabled: true,
loadingScreen: true,
watermark: true,
securityBeacon: true,
browserChallenge: false,
exclude: [
"/api",
"/health",
"/assets"
]
}Jangan aktifkan jika aplikasi kamu full JSON API.
18. Signed URL
Untuk file private:
signedUrl: {
enabled: true,
secret: process.env.SECUREXPRESS_SIGNED_URL_SECRET,
protect: ["/private-file"]
}Generate URL:
const url = securexpress.createSignedUrl(
"/private-file/report.pdf",
process.env.SECUREXPRESS_SIGNED_URL_SECRET,
300
);Hasil URL berlaku 300 detik.
19. Security Stats
Aktifkan dengan key:
stats: {
enabled: true,
path: "/securexpress/stats",
key: process.env.SECUREXPRESS_STATS_KEY
}Akses:
curl https://domainmu.com/securexpress/stats \
-H "x-api-key: YOUR_STATS_KEY"Jangan aktifkan stats tanpa key.
20. Input Sanitizer
Aktifkan sebagai lapisan ringan:
inputSanitizer: {
enabled: true,
trim: true,
nullBytes: true,
stripScript: true,
blockMongoOperators: true
}Tetap wajib validasi input di route:
if (!email || !email.includes("@")) {
return res.status(400).json({ error: "INVALID_EMAIL" });
}21. Static Shield
Aktifkan untuk mencegah file sensitif kebuka:
staticShield: {
enabled: true
}Default blokir:
.env.pem.key.crt.sql.sqlite.db.bak.log.config.gitnode_modules
22. Route Guard
Untuk blokir method/path tertentu:
routeGuard: {
enabled: true,
denyMethods: ["TRACE"],
denyPaths: ["/internal", "/debug"]
}23. HTTPS Redirect
Aktifkan jika domain sudah pakai SSL:
httpsRedirect: {
enabled: true,
exclude: ["/health"]
}Jika pakai Cloudflare/Nginx:
trustProxy: trueKalau HTTPS redirect menyebabkan loop, matikan dulu dan cek header:
X-Forwarded-Proto24. AI Bot Control
Jika ingin mengatur AI crawler:
aiBotControl: {
enabled: true,
defaultAction: "allow",
block: ["gptbot", "claudebot"]
}Atau block semua AI bot kecuali tertentu:
aiBotControl: {
enabled: true,
defaultAction: "block",
allow: ["chatgpt-user"]
}25. Real IP Guard
Aktifkan hanya jika kamu tidak memakai proxy dan ingin menolak header IP palsu.
realIpGuard: {
enabled: true
}Jika pakai Cloudflare/Nginx, jangan aktifkan ini kecuali paham konfigurasi proxy.
26. Error Handler Production
Gunakan:
app.use(securexpress.errorHandler({
exposeInternal: false,
exposeStack: false
}));Jangan expose stack trace di production.
27. Logging Production
Untuk trafik besar, jangan terlalu banyak console.log.
Gunakan:
- PM2 logs
- Pino
- Winston
- Cloud logging
- Grafana/Loki
- ELK
Contoh custom logger:
const logger = {
info: (...args) => console.log(...args),
warn: (...args) => console.warn(...args),
error: (...args) => console.error(...args)
};
app.use(securexpress({
logger,
securityLogger: {
enabled: true
}
}));28. Testing Sebelum Deploy
Jalankan:
npm test
npm run checkTest endpoint:
curl -i http://localhost:3000/health
curl -i http://localhost:3000/.env
curl -i http://localhost:3000/api/data
curl -i http://localhost:3000/securexpress/stats -H "x-api-key: YOUR_STATS_KEY"Expected:
/healthstatus 200/.envstatus 404- API normal status 200
- stats perlu API key
29. Troubleshooting
429 Too Many Requests
Penyebab:
- rate limit terlalu ketat
- traffic user tinggi
- bot/flood
Solusi:
- turunkan
presetkebalanced - naikkan limit adaptive route
- cek Cloudflare/Nginx
- cek IP user apakah semua terbaca sama karena proxy salah
Pastikan:
trustProxy: truejika pakai proxy.
CORS Error
Penyebab:
- domain frontend belum masuk
origins - pakai credentials tapi origin
* - OPTIONS diblokir
Solusi:
cors: true,
corsOptions: {
origins: ["https://frontendmu.com"],
credentials: true
}HTTPS Redirect Loop
Penyebab:
- proxy tidak kirim
X-Forwarded-Proto trustProxybelum aktif
Solusi:
trustProxy: trueNginx:
proxy_set_header X-Forwarded-Proto $scheme;CAPTCHA Muncul di API
Tambahkan exclude:
captchaGate: {
enabled: true,
exclude: ["/api", "/health", "/assets"]
}Script Injection Merusak Response
Pastikan exclude API:
scriptInjection: {
enabled: true,
exclude: ["/api", "/health", "/assets"]
}Semua User Terbaca IP Sama
Penyebab:
- reverse proxy
- trust proxy salah
Solusi:
trustProxy: true30. Checklist Production
Sebelum go-live:
- [ ]
NODE_ENV=production - [ ]
app.disable("x-powered-by") - [ ] semua secret dari
.env - [ ] tidak ada API key hardcode
- [ ]
trustProxy: truejika pakai Cloudflare/Nginx - [ ] CORS origin bukan
*jika pakai credentials - [ ] body limit sesuai kebutuhan
- [ ] adaptive rate limit aktif untuk login/register/reset password
- [ ] static shield aktif
- [ ] honeypot aktif
- [ ] security logger aktif
- [ ] stats endpoint pakai key
- [ ] error handler tidak expose stack
- [ ] PM2/Docker restart policy aktif
- [ ] Cloudflare/WAF aktif untuk DDoS besar
- [ ] backup dan monitoring aktif
- [ ]
npm testlulus - [ ]
npm run checklulus
31. Contoh Final Singkat
app.use(securexpress({
preset: "strict",
trustProxy: true,
cors: true,
corsOptions: {
origins: ["https://domainmu.com"],
credentials: true
},
staticShield: { enabled: true },
honeypot: { enabled: true },
inputSanitizer: { enabled: true },
responseTime: { enabled: true },
securityLogger: { enabled: true },
adaptiveRateLimit: {
enabled: true,
rules: [
{ path: "/api/login", windowMs: 60000, limit: 5 },
{ path: "/api", windowMs: 60000, limit: 120 }
]
},
stats: {
enabled: true,
key: process.env.SECUREXPRESS_STATS_KEY
}
}));32. Prinsip Aman
securexpress adalah lapisan tambahan. Tetap lakukan:
- validasi input di route
- auth/session/JWT yang benar
- hashing password dengan bcrypt/argon2
- database query aman
- HTTPS
- secret di env
- backup
- monitoring
- update dependency berkala
Keamanan terbaik adalah berlapis.
