This document covers StreetJS’s built-in security features and best practices.
Authentication
JWT Tokens
StreetJS’s JwtService uses HMAC-SHA256 by default with configurable expiry.
1
2
3
4
5
import{JwtService}from'streetjs';constjwt=newJwtService(process.env.JWT_SECRET,{expiresIn:'1h'});consttoken=jwt.sign({userId:'123',roles:['user']});constpayload=jwt.verify(token);// throws if invalid or expired
JWT secrets must be at least 256 bits (32 bytes). Set via JWT_SECRET environment variable.
Refresh Tokens
The RefreshTokenService implements single-use refresh tokens with replay detection.
1
2
3
4
5
import{RefreshTokenService}from'streetjs';consttokenService=newRefreshTokenService({pool,jwtService});const{accessToken,refreshToken}=awaittokenService.issue(userId);constrefreshed=awaittokenService.refresh(refreshToken);// throws TokenReplayError on reuse
Audit logs use an HMAC-SHA256 hash chain to detect tampering.
XSS Protection
1
2
3
4
5
6
import{xssMiddleware,sanitizeString}from'streetjs';app.use(xssMiddleware);// Sanitizes all string body fields// Manual sanitizationconstsafe=sanitizeString(userInput);
Secure-by-default Cookies
ctx.setCookie(name, value, options?) follows the framework’s
secure-by-default, escape-hatch-explicit principle: cookies are written with the
secure option unless you explicitly opt out, and every opt-out is an explicit,
visible choice.
Defaults
When an option is not specified, setCookie resolves it to the secure default:
Flag
Default when unspecified
Emitted attribute
httpOnly
true
HttpOnly — cookie is not readable by JavaScript
secure
true in production (NODE_ENV === 'production'), otherwise omitted
Secure — cookie only sent over HTTPS
sameSite
'Lax'
SameSite=Lax — cookie not attached on cross-site sub-requests
1
2
// In production this emits: session=abc; HttpOnly; Secure; SameSite=Laxctx.setCookie('session','abc');
Explicit per-flag opt-out
Each secure default can be overridden by passing the flag explicitly. Opting out is
always deliberate:
Override
Effect
httpOnly: false
Omits HttpOnly (cookie becomes readable by JavaScript)
secure: false
Omits Secure regardless of runtime mode — even in production
secure: true
Forces Secure even outside production (e.g. behind a TLS-terminating proxy in development)
sameSite: 'Strict' \| 'Lax' \| 'None'
Emits the exact value you provide instead of the 'Lax' default
1
2
// Readable by JS, no Secure in dev, cross-site allowed — every relaxation is explicitctx.setCookie('theme','dark',{httpOnly:false,sameSite:'None',secure:true});
Leaving a flag undefined always falls back to the secure default; an opt-out must be
expressed explicitly to take effect.
Multiple cookies on one response
setCookie appends to the response’s Set-Cookie list rather than overwriting it.
Calling it N times produces N Set-Cookie values, preserved in the order they were
written, so pairing cookies (for example a session cookie and a CSRF cookie) are both
delivered to the client.
1
2
ctx.setCookie('session',sessionId);// first Set-Cookiectx.setCookie('csrf',csrfToken);// second Set-Cookie — the first is not dropped
Security Checklist
Set JWT_SECRET to a cryptographically random 256-bit value
Set KEK for field-level encryption
Set SESSION_KEY for session signing
Enable HTTPS in production
Configure ALLOWED_ORIGINS for CORS
Enable rate limiting on public endpoints
Enable CSRF protection for state-changing endpoints
Review @Classify annotations on all entity fields
Run npm audit --audit-level=high before each release