Files
Jakob Ackermann 81df324bcc [monorepo] prepare for zod everywhere epic (#36027)
GitOrigin-RevId: f082ae7fc7857fa72b2c1823645050bd4f6df305
2026-09-17 11:42:46 +00:00

71 lines
2.1 KiB
JavaScript

// @ts-check
/**
* Access to the request-input lockdown installed by our patched express
* (see .yarn/patches/express-npm-*.patch).
*
* With REQ_LOCKDOWN_MODE=warn|throw, express captures parsed request input in
* the symbol-keyed fields below and turns the public req.body / req.query /
* req.params into accessors that warn or throw on read. Request input must be
* read through parseReq(), which validates it against a zod schema, or — for
* the small allowlist of infrastructure middleware that legitimately needs
* unvalidated input (authentication, rate limiting, CSRF, ...) — through
* getRawReqInput() so that the access is explicit and greppable.
*
* The symbols live in the global symbol registry, shared with the express and
* body-parser patches.
*/
const RAW_BODY = Symbol.for('overleaf.lockdown.rawBody')
const RAW_QUERY = Symbol.for('overleaf.lockdown.rawQuery')
const RAW_PARAMS = Symbol.for('overleaf.lockdown.rawParams')
const INSTALLED = Symbol.for('overleaf.lockdown.installed')
/**
* @typedef {import('express').Request} Request
*/
/**
* Whether the lockdown accessors are installed on this request
* (REQ_LOCKDOWN_MODE=warn|throw).
*
* @param {Request} req
* @returns {boolean}
*/
function isLockdownInstalled(req) {
// @ts-ignore symbol-keyed field added by the express patch
return Boolean(req[INSTALLED])
}
/**
* Read raw, unvalidated request input, bypassing the lockdown.
*
* Allowlisted infrastructure middleware only — application code (routes,
* controllers) must use parseReq() with a zod schema instead.
*
* @param {Request} req
* @returns {{ params: any, query: any, body: any }}
*/
function getRawReqInput(req) {
if (!isLockdownInstalled(req)) {
return { params: req.params, query: req.query, body: req.body }
}
return {
// @ts-ignore symbol-keyed fields added by the express patch
params: req[RAW_PARAMS],
// @ts-ignore
query: req[RAW_QUERY],
// @ts-ignore
body: req[RAW_BODY],
}
}
module.exports = {
RAW_BODY,
RAW_QUERY,
RAW_PARAMS,
INSTALLED,
isLockdownInstalled,
getRawReqInput,
}