The Koa repository provides a lightweight middleware framework that requires developers to explicitly implement security controls, state management, and error handling. Koa protects against basic HTTP routing complexities and handles automatic response pipelines, but it does not protect by default against session forgery, missing authorization checks, improper MIME-sniffing, insecure proxy configurations, or unvalidated inputs. Developers must treat context state, session cookies, input media types, and reverse proxy boundaries as critical security surfaces that fail closed when misconfigured.
Essential implementation rules
Enforce Authorization and State Isolation
Attach authenticated user records and authorization scopes to ctx.state and use ctx.assert(ctx.state.user, 401, ...) to reject unauthenticated requests before executing restricted handlers. Because Koa resets ctx.state per request, attaching identity objects here ensures safe request-scoped isolation.
Configure Signed Session Cookies with Secure Attributes
Load long, cryptographically random signing secrets from environment variables into app.keys as an array to support key rotation. When issuing session tokens via ctx.cookies.set(), explicitly enable signed: true, httpOnly: true, secure: true, and sameSite: 'lax' or 'strict'.
Enable Request Context Isolation and Explicit Production Mode
Initialize Koa with { asyncLocalStorage: true } to maintain safe context isolation across asynchronous boundaries and event listeners. Explicitly set the environment mode during application instantiation or via process.env.NODE_ENV to prevent leaking stack traces and detailed error information.
Validate Content Types and Adapt Query Parameter Handling
Verify incoming request content types using ctx.is() before processing payloads, throwing an HTTP 415 error for unsupported types. In Koa v3, use standard URLSearchParams methods like .get() and .getAll() on ctx.querystring to retrieve and validate input parameters.
Secure Reverse Proxy and Subdomain Boundary Settings
Enable app.proxy = true only when running behind a trusted reverse proxy that sanitizes X-Forwarded-* headers, and configure app.subdomainOffset accurately to prevent host header spoofing and boundary manipulation.
Safely Handle File Downloads and MIME-Type Sniffing
When serving static files or downloadable attachments, set an explicit Content-Type like application/octet-stream and invoke ctx.attachment(filename) to enforce proper Content-Disposition headers and prevent browser MIME-sniffing.
Maintain Middleware Flow and Proper Error Handling
Ensure all non-terminal middleware explicitly calls and returns next() to maintain the execution chain and prevent security controls from being bypassed. When throwing HTTP errors using ctx.throw() in Koa v3, pass an explicit Error instance as the second argument rather than legacy string messages.
Manage Native Responses Securely and Prevent Injection
When bypassing Koa’s response pipeline by setting ctx.respond = false, manually finalize the native stream, set required security headers, and ensure the connection ends. For raw string responses, explicitly set ctx.type to prevent unwanted HTML interpretation or injection.
koa: All Security Cards
Approximately 3,553 tokens
On this card
Category: access control
Enforce Authorization Checks and Store Claims within ctx.state in Koa
Use when
Enforcing access control, verifying user roles, and managing request-scoped permissions across Koa middleware and route handlers.
Secure rules
Rule 1: Sign cookies that require tamper detection with long, random application keys
Configure app.keys with long, random secret values before setting signed cookies. Use { signed: true } for cookies whose integrity must be checked. Koa creates a corresponding signature cookie and uses it to detect tampering when the cookie is received. Multiple keys may be configured to support key rotation.
The values below are intentionally public dummy values. Replace them with independently generated secrets before deployment.
Rule 2: Use ctx.assert() to validate the presence of a user in ctx.state before executing restricted handlers
Use ctx.assert() to check identity information stored in ctx.state (the recommended namespace for passing data through middleware) and reject unauthenticated requests with an appropriate HTTP status before protected logic executes.
Use the Updated Koa v3 ctx.throw Signature with Error Instances
Use when
When throwing HTTP errors using ctx.throw() in Koa v3 to ensure proper argument types and signatures are supplied.
Secure rules
Rule 1: Pass an Error instance or explicit HTTP error as the second argument to ctx.throw() in Koa v3.
In Koa v3, the underlying http-errors dependency update requires passing an Error instance or explicit HTTP error to ctx.throw(status, error, properties) instead of legacy string message parameters. Always construct an explicit Error instance to ensure proper error handling and serialization.
const createError = require('http-errors');app.use(async (ctx, next) => { if (!ctx.state.user) { const error = new Error('User not found'); ctx.throw(404, error, { user: null }); } await next();});
Category: authentication
Secure authentication state and session handling in Koa
Use when
Implementing authentication middleware, protecting routes using context assertions, and issuing cryptographic session cookies.
Secure rules
Rule 1: Store authentication context within request-scoped state
Attach authenticated user records and authorization scopes inside upstream authentication middleware using ctx.state. Because Koa resets ctx.state to a fresh object for each incoming request context, attaching identity objects to ctx.state prevents cross-request data leaks.
Rule 2: Enforce authentication boundaries using context assertions
Pass resolved user authentication data down the middleware chain via ctx.state, and enforce authentication boundaries using ctx.assert(ctx.state.user, 401, ...) to halt execution when an unauthenticated request reaches protected routes, ensuring standardized HTTP 401 status handling.
Rule 3: Configure secure and signed cookies for session tokens
When issuing authentication tokens or session identifiers via ctx.cookies.set(), enable cryptographic signature validation with signed: true alongside security flags including httpOnly: true, secure: true, and explicit sameSite controls to prevent client-side tampering, session forgery, and XSS exposure.
Enable asyncLocalStorage for Request Context Isolation
Use when
Configuring the Koa application instance to manage request-scoped data and error contexts safely across asynchronous execution boundaries.
Secure rules
Rule 1: Enable asyncLocalStorage during application initialization to maintain safe request context isolation.
Pass { asyncLocalStorage: true } or a custom AsyncLocalStorage instance to the Koa application constructor. This ensures that ambient logging, tracing, or security context resolution via app.currentContext maintains safe context isolation across asynchronous execution boundaries and prevents leaking state between concurrent HTTP requests.
const Koa = require('koa');const app = new Koa({ asyncLocalStorage: true });app.use(async (ctx, next) => { ctx.state.user = { id: '123' }; await next();});app.on('error', (err) => { const currentCtx = app.currentContext; if (currentCtx) { console.error(`Error for user ${currentCtx.state.user?.id}:`, err.message); }});
Category: escape hatch
Safely manage native response handling and security headers when bypassing Koa response
Use when
When implementing custom low-level streaming or response handling by setting ctx.respond = false to bypass Koa’s built-in response pipeline.
Secure rules
Rule 1: Manually finalize native response streams and set all required security headers before ending the response when ctx.respond = false is used.
Setting ctx.respond = false bypasses Koa’s automatic response handling and security middleware header applications. You must explicitly set required security headers and ensure the native ctx.res stream is properly ended to prevent hanging connections.
Serving downloadable files and attachments to clients while preventing MIME-sniffing vulnerabilities.
Secure rules
Rule 1: Call ctx.attachment() when returning file streams to enforce proper Content-Disposition headers.
Use ctx.response.attachment([filename]) or ctx.attachment([filename]) when serving downloadable content to ensure correct Content-Disposition header formatting and prevent client browser MIME-sniffing vulnerabilities.
Use ctx.attachment and set explicit Content-Type when serving static files
Use when
Serving static files or file attachments to users through Koa while ensuring secure Content-Disposition and MIME-type handling.
Secure rules
Rule 1: Call ctx.attachment to configure safe Content-Disposition headers and prevent content-sniffing risks.
When serving static files intended for download, call ctx.attachment(filename) to automatically handle Content-Disposition generation. To prevent browsers from executing potentially dangerous files inline, set an explicit Content-Type such as application/octet-stream before invoking ctx.attachment().
Enforce Strict Request Content-Type Validation Before Body Processing
Use when
Validating incoming request content types against acceptable MIME types prior to parsing or processing payload data in Koa applications.
Secure rules
Rule 1: Use ctx.is() or ctx.request.is() to validate incoming request content types and reject unsupported types before processing payload data.
Check the incoming request MIME type using ctx.is() to ensure it matches the expected contract, such as application/json. If the content type does not match, reject the request by throwing an HTTP 415 Unsupported Media Type error.
app.use(async (ctx, next) => { if (ctx.method === 'POST') { if (!ctx.is('application/json')) { ctx.throw(415, 'Unsupported Media Type: expected application/json'); } } await next();});
Category: input driven boundary selection
Validate Host Headers and Configure Subdomain Offsets Securely
Use when
Implementing hostname or subdomain-based request routing using ctx.subdomains or ctx.hostname.
Secure rules
Rule 1: Configure subdomain offsets accurately and trust proxy headers only behind trusted reverse proxies.
Set app.subdomainOffset explicitly to match your domain structure and enable app.proxy only when your server sits behind a trusted reverse proxy that securely strips or overwrites untrusted X-Forwarded-Host headers to prevent boundary spoofing.
Adapt query parameter handling for URLSearchParams in Koa v3
Use when
When updating query parameter handling and validation logic during migration to Koa v3.x where URLSearchParams replaces legacy querystring parsing.
Secure rules
Rule 1: Use explicit URLSearchParams query methods to retrieve and validate input parameters.
Because Koa v3.x uses standard URLSearchParams for ctx.querystring, automatic bracket or object parsing for arrays and nested keys is not performed. Access query parameters using explicit methods like .get() and .getAll() to ensure input values are correctly retrieved for validation.
When deploying a Koa application behind a reverse proxy to manage network trust boundaries and inspect proxy headers safely.
Secure rules
Rule 1: Only enable proxy header trust when deployed behind a trusted reverse proxy.
Set app.proxy = true only when running behind a known reverse proxy that sanitizes or overrides incoming X-Forwarded-* headers. When enabled, configure app.maxIpsCount and app.proxyIpHeader to match your front-end proxy topology to prevent IP address spoofing and header injection.
Use safe escaping and explicit types for responses to prevent injection
Use when
When rendering dynamic user input in Koa response bodies or redirect fallback messages to prevent HTML-context injection.
Secure rules
Rule 1: Rely on built-in ctx.redirect HTML encoding and explicitly define response content types for raw string responses.
When returning untrusted string content to ctx.body, explicitly set ctx.type before assignment to prevent Koa from automatically inferring an HTML content type for strings starting with <. Additionally, rely on ctx.redirect for HTML redirect fallbacks rather than constructing manual HTML bodies.
Instantiating the Koa application in a production deployment to prevent development mode behaviors.
Secure rules
Rule 1: Explicitly set the environment mode during application instantiation to prevent exposing detailed error messages.
Pass the env option explicitly or ensure process.env.NODE_ENV is set when instantiating Koa. If omitted, Koa defaults to development mode, which can leak sensitive stack traces and internal error information to clients during runtime failures.
Load Cookie Signing Secrets Securely from Environment Variables
Use when
When configuring cookie signing keys and issuing signed cookies via app.keys in a Koa application.
Secure rules
Rule 1: Load cryptographically random cookie signing secrets from environment configuration and assign an array of keys to app.keys to support secret rotation.
Ensure that signing secrets are sufficiently long and never hardcoded as string literals in source code. Retrieve the secrets securely from environment variables and assign them as an array to app.keys to facilitate key rotation.
const Koa = require('koa');const app = new Koa();// Load secure, random secrets from environment variablesapp.keys = [ process.env.COOKIE_SECRET_PRIMARY, process.env.COOKIE_SECRET_PREVIOUS];app.use(async ctx => { ctx.cookies.set('session', 'user-data', { signed: true });});
Category: security control integrity
Maintain Middleware Control Flow by Explicitly Calling and Returning Next
Use when
Developing or modifying Koa middleware functions that handle request routing, authorization, or context-population.
Secure rules
Rule 1: Ensure all non-terminal middleware explicitly calls and returns next() to maintain the middleware execution chain.
Omitting next() prematurely halts the request processing pipeline, causing downstream security controls, validation checks, and route handlers to be skipped. Always invoke and return next() in non-terminal middleware to preserve security control integrity.
Configure Secure, Signed Session Cookies and Proxy Trust in Koa
Use when
Configuring session identifiers, cookie attributes, and cryptographic keys using ctx.cookies.set() and app.keys in a Koa application.
Secure rules
Rule 1: Set secure, signed, and restricted cookie attributes for session identifiers.
When issuing session cookies via ctx.cookies.set(), explicitly configure secure: true, sameSite: 'lax' (or 'strict'), signed: true, and httpOnly: true to prevent network interception, token tampering, and cross-site request vulnerabilities.
Rule 2: Configure strong cryptographic keys for signing session cookies.
Assign sufficiently long and cryptographically random secret keys to app.keys to ensure proper signature verification and protect session cookies against client-side forgery.
Rule 3: Enable proxy trust to correctly enforce secure session cookies behind a reverse proxy.
Set app.proxy = true when running Koa behind a TLS-terminating reverse proxy so that Koa properly respects forwarded headers like X-Forwarded-Proto and applies the Secure flag to session cookies.
Enforce Authorization Checks and Store Claims within ctx.state in Koa
Approximately 373 tokens
Use when
Enforcing access control, verifying user roles, and managing request-scoped permissions across Koa middleware and route handlers.
Secure rules
Rule 1: Sign cookies that require tamper detection with long, random application keys
Configure app.keys with long, random secret values before setting signed cookies. Use { signed: true } for cookies whose integrity must be checked. Koa creates a corresponding signature cookie and uses it to detect tampering when the cookie is received. Multiple keys may be configured to support key rotation.
The values below are intentionally public dummy values. Replace them with independently generated secrets before deployment.
Rule 2: Use ctx.assert() to validate the presence of a user in ctx.state before executing restricted handlers
Use ctx.assert() to check identity information stored in ctx.state (the recommended namespace for passing data through middleware) and reject unauthenticated requests with an appropriate HTTP status before protected logic executes.
Use the Updated Koa v3 ctx.throw Signature with Error Instances
Approximately 232 tokens
Use when
When throwing HTTP errors using ctx.throw() in Koa v3 to ensure proper argument types and signatures are supplied.
Secure rules
Rule 1: Pass an Error instance or explicit HTTP error as the second argument to ctx.throw() in Koa v3.
In Koa v3, the underlying http-errors dependency update requires passing an Error instance or explicit HTTP error to ctx.throw(status, error, properties) instead of legacy string message parameters. Always construct an explicit Error instance to ensure proper error handling and serialization.
const createError = require('http-errors');app.use(async (ctx, next) => { if (!ctx.state.user) { const error = new Error('User not found'); ctx.throw(404, error, { user: null }); } await next();});
Secure authentication state and session handling in Koa
Approximately 403 tokens
Use when
Implementing authentication middleware, protecting routes using context assertions, and issuing cryptographic session cookies.
Secure rules
Rule 1: Store authentication context within request-scoped state
Attach authenticated user records and authorization scopes inside upstream authentication middleware using ctx.state. Because Koa resets ctx.state to a fresh object for each incoming request context, attaching identity objects to ctx.state prevents cross-request data leaks.
Rule 2: Enforce authentication boundaries using context assertions
Pass resolved user authentication data down the middleware chain via ctx.state, and enforce authentication boundaries using ctx.assert(ctx.state.user, 401, ...) to halt execution when an unauthenticated request reaches protected routes, ensuring standardized HTTP 401 status handling.
Rule 3: Configure secure and signed cookies for session tokens
When issuing authentication tokens or session identifiers via ctx.cookies.set(), enable cryptographic signature validation with signed: true alongside security flags including httpOnly: true, secure: true, and explicit sameSite controls to prevent client-side tampering, session forgery, and XSS exposure.
Enable asyncLocalStorage for Request Context Isolation
Approximately 256 tokens
Use when
Configuring the Koa application instance to manage request-scoped data and error contexts safely across asynchronous execution boundaries.
Secure rules
Rule 1: Enable asyncLocalStorage during application initialization to maintain safe request context isolation.
Pass { asyncLocalStorage: true } or a custom AsyncLocalStorage instance to the Koa application constructor. This ensures that ambient logging, tracing, or security context resolution via app.currentContext maintains safe context isolation across asynchronous execution boundaries and prevents leaking state between concurrent HTTP requests.
const Koa = require('koa');const app = new Koa({ asyncLocalStorage: true });app.use(async (ctx, next) => { ctx.state.user = { id: '123' }; await next();});app.on('error', (err) => { const currentCtx = app.currentContext; if (currentCtx) { console.error(`Error for user ${currentCtx.state.user?.id}:`, err.message); }});
Safely manage native response handling and security headers when bypassing Koa response
Approximately 232 tokens
Use when
When implementing custom low-level streaming or response handling by setting ctx.respond = false to bypass Koa’s built-in response pipeline.
Secure rules
Rule 1: Manually finalize native response streams and set all required security headers before ending the response when ctx.respond = false is used.
Setting ctx.respond = false bypasses Koa’s automatic response handling and security middleware header applications. You must explicitly set required security headers and ensure the native ctx.res stream is properly ended to prevent hanging connections.
Use `response.attachment()` for Safe File Downloads
Approximately 351 tokens
Use when
Serving downloadable files and attachments to clients while preventing MIME-sniffing vulnerabilities.
Secure rules
Rule 1: Call ctx.attachment() when returning file streams to enforce proper Content-Disposition headers.
Use ctx.response.attachment([filename]) or ctx.attachment([filename]) when serving downloadable content to ensure correct Content-Disposition header formatting and prevent client browser MIME-sniffing vulnerabilities.
Use ctx.attachment and set explicit Content-Type when serving static files
Use when
Serving static files or file attachments to users through Koa while ensuring secure Content-Disposition and MIME-type handling.
Secure rules
Rule 1: Call ctx.attachment to configure safe Content-Disposition headers and prevent content-sniffing risks.
When serving static files intended for download, call ctx.attachment(filename) to automatically handle Content-Disposition generation. To prevent browsers from executing potentially dangerous files inline, set an explicit Content-Type such as application/octet-stream before invoking ctx.attachment().
Enforce Strict Request Content-Type Validation Before Body Processing
Approximately 215 tokens
Use when
Validating incoming request content types against acceptable MIME types prior to parsing or processing payload data in Koa applications.
Secure rules
Rule 1: Use ctx.is() or ctx.request.is() to validate incoming request content types and reject unsupported types before processing payload data.
Check the incoming request MIME type using ctx.is() to ensure it matches the expected contract, such as application/json. If the content type does not match, reject the request by throwing an HTTP 415 Unsupported Media Type error.
app.use(async (ctx, next) => { if (ctx.method === 'POST') { if (!ctx.is('application/json')) { ctx.throw(415, 'Unsupported Media Type: expected application/json'); } } await next();});
Validate Host Headers and Configure Subdomain Offsets Securely
Approximately 239 tokens
Use when
Implementing hostname or subdomain-based request routing using ctx.subdomains or ctx.hostname.
Secure rules
Rule 1: Configure subdomain offsets accurately and trust proxy headers only behind trusted reverse proxies.
Set app.subdomainOffset explicitly to match your domain structure and enable app.proxy only when your server sits behind a trusted reverse proxy that securely strips or overwrites untrusted X-Forwarded-Host headers to prevent boundary spoofing.
Adapt query parameter handling for URLSearchParams in Koa v3
Approximately 211 tokens
Use when
When updating query parameter handling and validation logic during migration to Koa v3.x where URLSearchParams replaces legacy querystring parsing.
Secure rules
Rule 1: Use explicit URLSearchParams query methods to retrieve and validate input parameters.
Because Koa v3.x uses standard URLSearchParams for ctx.querystring, automatic bracket or object parsing for arrays and nested keys is not performed. Access query parameters using explicit methods like .get() and .getAll() to ensure input values are correctly retrieved for validation.
When deploying a Koa application behind a reverse proxy to manage network trust boundaries and inspect proxy headers safely.
Secure rules
Rule 1: Only enable proxy header trust when deployed behind a trusted reverse proxy.
Set app.proxy = true only when running behind a known reverse proxy that sanitizes or overrides incoming X-Forwarded-* headers. When enabled, configure app.maxIpsCount and app.proxyIpHeader to match your front-end proxy topology to prevent IP address spoofing and header injection.
Use safe escaping and explicit types for responses to prevent injection
Approximately 200 tokens
Use when
When rendering dynamic user input in Koa response bodies or redirect fallback messages to prevent HTML-context injection.
Secure rules
Rule 1: Rely on built-in ctx.redirect HTML encoding and explicitly define response content types for raw string responses.
When returning untrusted string content to ctx.body, explicitly set ctx.type before assignment to prevent Koa from automatically inferring an HTML content type for strings starting with <. Additionally, rely on ctx.redirect for HTML redirect fallbacks rather than constructing manual HTML bodies.
Instantiating the Koa application in a production deployment to prevent development mode behaviors.
Secure rules
Rule 1: Explicitly set the environment mode during application instantiation to prevent exposing detailed error messages.
Pass the env option explicitly or ensure process.env.NODE_ENV is set when instantiating Koa. If omitted, Koa defaults to development mode, which can leak sensitive stack traces and internal error information to clients during runtime failures.
Load Cookie Signing Secrets Securely from Environment Variables
Approximately 217 tokens
Use when
When configuring cookie signing keys and issuing signed cookies via app.keys in a Koa application.
Secure rules
Rule 1: Load cryptographically random cookie signing secrets from environment configuration and assign an array of keys to app.keys to support secret rotation.
Ensure that signing secrets are sufficiently long and never hardcoded as string literals in source code. Retrieve the secrets securely from environment variables and assign them as an array to app.keys to facilitate key rotation.
const Koa = require('koa');const app = new Koa();// Load secure, random secrets from environment variablesapp.keys = [ process.env.COOKIE_SECRET_PRIMARY, process.env.COOKIE_SECRET_PREVIOUS];app.use(async ctx => { ctx.cookies.set('session', 'user-data', { signed: true });});
Maintain Middleware Control Flow by Explicitly Calling and Returning Next
Approximately 190 tokens
Use when
Developing or modifying Koa middleware functions that handle request routing, authorization, or context-population.
Secure rules
Rule 1: Ensure all non-terminal middleware explicitly calls and returns next() to maintain the middleware execution chain.
Omitting next() prematurely halts the request processing pipeline, causing downstream security controls, validation checks, and route handlers to be skipped. Always invoke and return next() in non-terminal middleware to preserve security control integrity.
Configure Secure, Signed Session Cookies and Proxy Trust in Koa
Approximately 447 tokens
Use when
Configuring session identifiers, cookie attributes, and cryptographic keys using ctx.cookies.set() and app.keys in a Koa application.
Secure rules
Rule 1: Set secure, signed, and restricted cookie attributes for session identifiers.
When issuing session cookies via ctx.cookies.set(), explicitly configure secure: true, sameSite: 'lax' (or 'strict'), signed: true, and httpOnly: true to prevent network interception, token tampering, and cross-site request vulnerabilities.
Rule 2: Configure strong cryptographic keys for signing session cookies.
Assign sufficiently long and cryptographically random secret keys to app.keys to ensure proper signature verification and protect session cookies against client-side forgery.
Rule 3: Enable proxy trust to correctly enforce secure session cookies behind a reverse proxy.
Set app.proxy = true when running Koa behind a TLS-terminating reverse proxy so that Koa properly respects forwarded headers like X-Forwarded-Proto and applies the Secure flag to session cookies.