Security Middleware
Content Security Policy
Configure Content Security Policy (CSP) with nonce and hash support to protect against XSS attacks and control resource loading.
Basic CSP Configuration
MoroJS provides built-in CSP middleware with support for nonces, hashes, and comprehensive directive configuration.
Enable Content Security Policytypescript
1import { middleware } from '@morojs/moro';
2
3// Basic CSP configuration
4app.use(middleware.csp({
5 directives: {
6 defaultSrc: ["'self'"],
7 scriptSrc: ["'self'", "'nonce-{NONCE}'"],
8 styleSrc: ["'self'", "'nonce-{NONCE}'"],
9 imgSrc: ["'self'", 'data:', 'https:']
10 },
11 reportOnly: false,
12 reportUri: '/api/csp-violations'
13}));
14
15// Access nonce in templates
16app.get('/page', (req, res) => {
17 const nonce = req.cspNonce;
18 return `<script nonce="${nonce}">alert('Safe');</script>`;
19});CSP Directives
- •
defaultSrc- Default source for all resources - •
scriptSrc- Allowed sources for JavaScript - •
styleSrc- Allowed sources for CSS - •
imgSrc- Allowed sources for images - •
connectSrc- Allowed sources for network requests - •
fontSrc- Allowed sources for fonts - •
objectSrc- Allowed sources for plugins - •
mediaSrc- Allowed sources for media
Advanced Configuration
Comprehensive CSP Setuptypescript
1import { middleware } from '@morojs/moro';
2
3// Advanced CSP configuration with nonce support
4app.use(middleware.csp({
5 directives: {
6 defaultSrc: ["'self'"],
7 scriptSrc: [
8 "'self'",
9 "'nonce-{NONCE}'", // Nonce for inline scripts
10 "'sha256-...'", // Hash for specific scripts
11 'https://cdn.example.com'
12 ],
13 styleSrc: [
14 "'self'",
15 "'nonce-{NONCE}'", // Nonce for inline styles
16 "'unsafe-inline'", // Allow inline styles (less secure)
17 'https://fonts.googleapis.com'
18 ],
19 imgSrc: ["'self'", 'data:', 'https:'],
20 connectSrc: ["'self'", 'https://api.example.com'],
21 fontSrc: ["'self'", 'https://fonts.gstatic.com'],
22 objectSrc: ["'none'"], // Block plugins
23 mediaSrc: ["'self'"],
24 frameSrc: ["'none'"], // Block iframes
25 baseUri: ["'self'"],
26 formAction: ["'self'"],
27 upgradeInsecureRequests: true
28 },
29 nonce: true, // Enable nonce generation
30 reportOnly: false, // Enforce policy (not just report)
31 reportUri: '/api/csp-violations'
32}));
33
34// Access nonce in route handlers
35app.get('/dashboard', (req, res) => {
36 const nonce = req.cspNonce;
37
38 return {
39 html: `
40 <script nonce="${nonce}">
41 // This script will be allowed
42 console.log('Safe script');
43 </script>
44 <style nonce="${nonce}">
45 /* This style will be allowed */
46 body { margin: 0; }
47 </style>
48 `
49 };
50});Nonce and Hash Support
Using Nonces and Hashestypescript
1// Nonce-based CSP (recommended)
2app.use(middleware.csp({
3 directives: {
4 scriptSrc: ["'self'", "'nonce-{NONCE}'"]
5 },
6 nonce: true
7}));
8
9// Hash-based CSP (for static scripts)
10app.use(middleware.csp({
11 directives: {
12 scriptSrc: [
13 "'self'",
14 "'sha256-abc123...'", // Hash of specific script
15 "'sha384-def456...'", // SHA-384 hash
16 "'sha512-ghi789...'" // SHA-512 hash
17 ]
18 }
19}));
20
21// Combined nonce and hash
22app.use(middleware.csp({
23 directives: {
24 scriptSrc: [
25 "'self'",
26 "'nonce-{NONCE}'", // For dynamic scripts
27 "'sha256-abc123...'" // For specific static scripts
28 ]
29 },
30 nonce: true
31}));
32
33// Generate hash for a script
34// Example: echo -n "alert('Hello');" | openssl dgst -sha256 -binary | openssl base64Best Practices
Do
- Use nonces for dynamic inline scripts/styles
- Use hashes for static scripts/styles
- Start with reportOnly: true in development
- Set objectSrc: ["'none'"] to block plugins
- Use upgradeInsecureRequests for HTTPS
- Monitor CSP violation reports
Don't
- Use 'unsafe-inline' for scripts
- Use 'unsafe-eval' unless necessary
- Allow '*' for any directive
- Skip CSP for production
- Ignore CSP violation reports
- Use weak CSP policies