A Boundary-First Security Review for TypeScript and Edge Runtime
Review runtime input, Edge Runtime constraints, authentication, caching, secrets, and browser defenses without treating TypeScript as a security boundary.
4 min read

A successful TypeScript check does not prove that JSON, cookies, headers, or environment variables received at runtime are safe. Type annotations are erased from the JavaScript output, so runtime boundaries require separate checks. The official TypeScript introduction explains this erasure model.
This article does not offer a setting that makes every application secure. Start by identifying the application's assets, attackers, data, and authentication design, then connect each boundary to an implementation and a failure test.
1. List trust boundaries first
Before implementing controls, record where external or differently trusted values enter.
| Boundary | Examples | Possible impact |
|---|---|---|
| URL and body | query, JSON, FormData | invalid action or resource exhaustion |
| Authentication | Cookie, Authorization | impersonation or privilege escalation |
| Cache key | path, headers, user state | response leakage between users |
| External API | JSON, status, redirect | incorrect action or SSRF candidate |
| Secrets | environment variables, keys | disclosure or forged signatures |
| Browser output | HTML, scripts, headers | XSS and related risks |
For each boundary, define the source, accepted shape, maximum size, and failure response. An “internal” API should not automatically become a trusted source.
2. Narrow from unknown at runtime
Do not turn an external payload into a trusted type with an assertion alone. This example checks required fields without a validation dependency:
type SignupInput = {
email: string;
displayName: string;
};
export function parseSignupInput(value: unknown): SignupInput {
if (typeof value !== "object" || value === null || Array.isArray(value)) {
throw new Error("invalid body");
}
const input = value as Record<string, unknown>;
if (
typeof input.email !== "string" ||
input.email.trim().length < 1 ||
input.email.length > 254 ||
typeof input.displayName !== "string" ||
input.displayName.trim().length < 1 ||
input.displayName.length > 80
) {
throw new Error("invalid fields");
}
return { email: input.email, displayName: input.displayName };
}
Length and character rules must match the product requirement. As the OWASP Input Validation Cheat Sheet explains, syntactic validity and semantic validity are separate checks.
3. Test the Edge Runtime assumptions
An Edge Runtime is not identical to a Node.js runtime. Check the supported APIs and restrictions in the current Vercel Edge Runtime documentation, then test the production-like deployment for:
- required crypto, stream, and encoding APIs;
- dependencies that expect Node.js-only APIs;
- timeout, response-size, and region behavior; and
- accidental exposure of sensitive values in errors or logs.
Geographic distribution alone is not proof of DDoS resistance or application security.
4. Review authentication and caching together
A shared cache can disclose an authenticated response even when input validation is correct. Review each route for:
- separate authentication and authorization checks;
- no shared caching of user-specific responses;
- all required variation in the cache key;
- cookie attributes and lifetime selected from the threat model; and
- tests for expiry, key rotation, and clock skew.
Avoid universal claims such as “every access token must last 15 minutes” or “a cookie is safe.” HttpOnly limits JavaScript access to a cookie, but it does not resolve every XSS or CSRF risk.
5. Fail safely when secrets are missing
Do not continue with an undefined signing or API secret. Fail explicitly during startup or early request handling:
export function requireSecret(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Missing required secret: ${name}`);
return value;
}
Never log the secret value, and use separate values and permissions for Preview and Production. Vercel's Conformance rules can provide additional automated checks, but they do not replace an application review.
6. Test CSP in Report-Only mode
CSP is one browser defense layer. The OWASP Content Security Policy Cheat Sheet describes observing violations with Content-Security-Policy-Report-Only before enforcing the policy.
For a site using external scripts or nonces, inventory the generated HTML and required requests, then inspect violations and behavior on representative pages. The existence of a CSP header is not evidence that XSS has been eliminated.
Review completion checklist
- Every trust boundary has accepted-shape, size, and failure-response tests.
- Authenticated, unauthenticated, and unauthorized requests are separate cases.
- User-specific cache behavior has been tested.
- Missing required secrets fail safely.
- Logs and error bodies omit secrets and personal data.
- CSP and relevant headers are inspected in rendered HTML.
- Runtime differences are executed in a production-like Edge environment.
Map sample inputs to rejection reasons
The function above is a minimal type-and-length boundary example, not complete email validation, ownership verification, or registration authorization. It also rejects an empty email and whitespace-only display name, but permitted characters and normalization remain business decisions.
| Test input | Expected result |
|---|---|
null or an array | invalid body |
| Numeric, empty, or over-254-character email | invalid fields |
| Whitespace-only or over-80-character displayName | invalid fields |
| Required strings within the limits | Return two fields; do not infer verified ownership |
These are design expectations. Test the production-like API separately to ensure invalid input receives an appropriate 400-class response without a stack trace or secrets.
Conclusion
TypeScript, an Edge Runtime, and CSP operate at different layers. Do not use type checking as input validation, edge delivery as proof of attack resistance, or response headers as a security guarantee. A review becomes repeatable only when threats and boundaries are listed and every control has a corresponding failure test.
Primary sources checked
Important claims should also link to the relevant source in the article body.
- Content Security Policy Cheat SheetOWASP Foundation · security-guidance · Checked: 2026-07-26
- Input Validation Cheat SheetOWASP Foundation · security-guidance · Checked: 2026-07-26
- Conformance rulesVercel · official-documentation · Checked: 2026-07-26
- Edge RuntimeVercel · official-documentation · Checked: 2026-07-26
- TypeScript for the New ProgrammerMicrosoft · official-documentation · Checked: 2026-07-26