@owasp-webshield/express
v2.0.0
Published
Express adapter for OWL (OWASP Webshield Library): middleware for authentication, access control, CSRF, validation, security headers, SSRF checks and security error handling
Maintainers
Readme
@owasp-webshield/express
Express adapter for OWL (OWASP Webshield Library). It provides middleware for authentication, access control, CSRF, input validation, security headers, SSRF checks and security error handling, built on @owasp-webshield/core and @owasp-webshield/node. It works with Express 4.18+ and 5.
Installation
npm install @owasp-webshield/core @owasp-webshield/expressAn ES module with TypeScript declarations. It needs Node.js 20.19+ or 22.12+, which can also load it from CommonJS with require(). In TypeScript, the declarations add req.owl (session, outboundUrl) to Express's Request type.
Quick start
import express from "express";
import { createOwlClient, SecurityLogger } from "@owasp-webshield/core";
import {
assertHardened,
csrfProtection,
errorHandler,
requireAuth,
requirePermission,
securityHeaders,
validate
} from "@owasp-webshield/express";
const logger = new SecurityLogger();
assertHardened({ debug: process.env.NODE_ENV !== "production" }, { logger }); // throws on unsafe config
const owl = createOwlClient({ roles: { editor: { permissions: ["write:reports"] } } });
const app = express();
app.use(securityHeaders());
app.use(express.json());
app.use(requireAuth({ verifyToken: (token) => sessionStore.lookup(token) })); // -> req.owl.session
app.use(csrfProtection());
app.post("/reports",
requirePermission("write", "reports", owl),
validate({ title: { required: true, type: "string", maxLength: 120 } }, { allowUnknownFields: false }),
(req, res) => res.status(201).json(req.body)
);
app.use(errorHandler({ logger }));verifyToken is called on every request, so sessions are never shared between users. Return the user's { userId, roles }, or null for an unknown or expired token.
Middleware
| Category | Export |
|---|---|
| A01 Access Control | requirePermission(action, resource, checker) |
| A03 Injection Defense | validate(schema, options), sanitizeBody(fields, options) |
| A05 Security Misconfiguration | securityHeaders(overrides), assertHardened(config, options) |
| A07 Auth Session | requireAuth({ verifyToken }) |
| A08 Data Integrity | csrfProtection(options), issueCsrfToken(res, options) |
| A09 Logging Monitoring | errorHandler({ logger }) |
| A10 SSRF Defense | guardOutboundUrl(getUrl, { guard }) |
Security failures become JSON responses (400/401/403, with the SecurityErrorCode in error). A 500 never includes the error's message.
Documentation
- Node & Express integration guide
- API reference
- Runnable example (owl-enabled-vue-express-incident-desk)
License
Apache-2.0. See the main repository for the full license text and contribution guidelines.
