npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

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.

Readme

securexpress — Production Guide

Panduan ini khusus untuk menjalankan securexpress di production dengan aman, stabil, dan tidak terlalu agresif memblokir user normal.

Catatan penting: securexpress memperkuat 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 dotenv

Untuk test lokal:

npm install
npm test
npm run check

3. .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: true

Aktifkan 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: true

12. PM2 Production

Install PM2:

npm install -g pm2

Jalankan:

pm2 start server.js --name securexpress-api
pm2 save
pm2 startup

Lihat log:

pm2 logs securexpress-api

Restart:

pm2 restart securexpress-api

13. 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-api

14. 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-Token

Token tersedia di response header:

X-CSRF-Token: token

Untuk 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
  • .git
  • node_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: true

Kalau HTTPS redirect menyebabkan loop, matikan dulu dan cek header:

X-Forwarded-Proto

24. 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 check

Test 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:

  • /health status 200
  • /.env status 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 preset ke balanced
  • naikkan limit adaptive route
  • cek Cloudflare/Nginx
  • cek IP user apakah semua terbaca sama karena proxy salah

Pastikan:

trustProxy: true

jika 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
  • trustProxy belum aktif

Solusi:

trustProxy: true

Nginx:

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: true

30. Checklist Production

Sebelum go-live:

  • [ ] NODE_ENV=production
  • [ ] app.disable("x-powered-by")
  • [ ] semua secret dari .env
  • [ ] tidak ada API key hardcode
  • [ ] trustProxy: true jika 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 test lulus
  • [ ] npm run check lulus

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.