Skip to content
beta

Shield - Security Headers

The Shield module in Harpia provides middleware that automatically sets a wide range of HTTP security headers, helping to safeguard your application against common vulnerabilities such as XSS, clickjacking, and content sniffing.

  1. Security Headers:
    • Content Security Policy (CSP): Restricts sources for scripts, styles, and other resources.
    • Cross-Origin Policies: Controls how resources are shared across origins.
    • Strict Transport Security (HSTS): Enforces HTTPS connections.
    • Referrer Policy: Controls the information sent in the Referer header.
    • X-Content-Type-Options: Prevents MIME type sniffing.
    • X-Frame-Options: Protects against clickjacking.
    • X-XSS-Protection: Disables browser XSS filters (if not needed).
    • Nonce Support: Generates cryptographic nonces for CSP inline scripts/styles.
  2. Customizable:
    • Override default headers by passing options to the constructor.
    • Merge custom directives with sensible defaults.
  3. Middleware:
    • Easily integrate into your application as middleware.
  4. Template Engine Integration:
    • Automatic nonce generation for secure inline scripts/styles.
    • Seamless integration with the template engine.

You can create and apply Shield middleware to your app in a few lines:

shield.ts
import { Shield } from "harpiats/shield";
import type { Harpia } from "harpiats";
const instance = new Shield({
useNonce: true, // Enable nonce generation, false as default.
});
export const shield = {
middleware: (server: Harpia) => instance.middleware(server),
instance: instance,
}

Apply the shield middleware in your server setup:

server.ts
import { harpia } from "harpia";
import { shield } from "./shield";
const app = harpia();
// Apply security headers middleware
app.use(shield.middleware());
// Your routes
app.get("/", (req, res) => {
res.send("Hello, World!");
});
app.listen({ port: 3000 }, () => console.log("Server running on http://localhost:3000"));

If you want to use the harpia template engine:

import { harpia } from "harpia";
import { shield } from "./shield";
import { engine } from "./template-engine";
const app = harpia();
// Apply security headers middleware
app.use(shield.middleware(app));
// Setup template engine
engine.configure(app, shield.instance);

To understand more about the harpia template engine, see the Template Engine section.

The Shield constructor accepts a configuration object to override default header values:

const instance = new Shield({
contentSecurityPolicy: {
directives: {
"default-src": ["'self'", "https://trusted.com"],
"script-src": ["'self'"]
}
},
strictTransportSecurity: {
maxAge: 31536000, // 1 year
includeSubDomains: true,
preload: true
}
});
export const shield = {
middleware: (server: Harpia) => instance.middleware(server),
instance: instance,
};

If not customized, the following CSP directives are applied by default:

{
"default-src": ["'self'"],
"base-uri": ["'self'"],
"font-src": ["'self'", "https:", "data:"],
"form-action": ["'self'"],
"frame-ancestors": ["'self'"],
"img-src": ["'self'", "data:"],
"object-src": ["'none'"],
"script-src": ["'self'"],
"script-src-attr": ["'none'"],
"style-src": ["'self'"],
"upgrade-insecure-requests": []
}

Need a deeper dive on CSP?
Check out the Content Security Policy (CSP) guide on MDN for examples, explanations, and best practices.

HeaderDefault Value
Cross-Origin-Opener-Policysame-origin
Cross-Origin-Resource-Policysame-origin
Origin-Agent-Cluster?1
Referrer-Policyno-referrer
Strict-Transport-Securitymax-age=15552000; includeSubDomains
X-Content-Type-Optionsnosniff
X-DNS-Prefetch-Controloff
X-Download-Optionsnoopen
X-Frame-OptionsSAMEORIGIN
X-Permitted-Cross-Domain-Policiesnone
X-Powered-Byremoved
X-XSS-Protection0 (disabled)
useNoncefalse (disabled)
  • Always review CSP settings to fit your asset sources.
  • Avoid "unsafe-inline" unless absolutely necessary.
  • Use preload with HSTS only after confirming HTTPS readiness across your subdomains.
<!-- Use @set to define a variable to hold the nonce value -->
@set nonce = generateNonce() @endset
<!DOCTYPE html>
<html>
<head>
<title>Secure Page</title>
</head>
<body>
<h1>Hello, {{ name }}!</h1>
<!-- Secure inline script with nonce -->
<script nonce="{{ nonce }}">
console.log("This script is CSP-compliant");
</script>
<!-- Secure inline styles with nonce -->
<style nonce="{{ nonce }}">
body { color: blue; }
</style>
</body>
</html>

generateNonce() is a Template Engine Plugin. You can see more about the plugins in Template Engine section.

  • Nonce Security: Each nonce is unique per request and automatically invalidated after use. Since the generateNonce() plugin generates a new value on each call, you should cache it using @set if you need to use it in multiple places.
  • CSP Compliance: Use @set nonce = generateNonce() @endset to cache the nonce value in templates.
  • Development: Consider adding ‘unsafe-inline’ for easier development with hot reload.
  • Production: Remove unsafe directives and rely exclusively on nonces for inline content.

The Shield module provides enterprise-grade security headers with zero configuration while remaining fully customizable for your specific needs.