mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-12 13:13:45 +01:00
65 lines
2.0 KiB
JavaScript
65 lines
2.0 KiB
JavaScript
const RAW_FIELDS = new Set(['body', 'query', 'params'])
|
|
|
|
function isReqIdentifier(node) {
|
|
return node && node.type === 'Identifier' && node.name === 'req'
|
|
}
|
|
|
|
module.exports = {
|
|
meta: {
|
|
type: 'problem',
|
|
docs: {
|
|
description:
|
|
'Disallow reading raw request input (req.body/req.query/req.params); validate it with parseReq() instead',
|
|
},
|
|
messages: {
|
|
noRawReqAccess:
|
|
'Do not read req.{{field}} directly; validate request input with parseReq() from @overleaf/validation-tools. Allowlisted infrastructure middleware may use getRawReqInput().',
|
|
},
|
|
},
|
|
create(context) {
|
|
return {
|
|
MemberExpression(node) {
|
|
if (!isReqIdentifier(node.object)) return
|
|
const property = node.property
|
|
const field =
|
|
!node.computed && property.type === 'Identifier'
|
|
? property.name
|
|
: node.computed &&
|
|
property.type === 'Literal' &&
|
|
typeof property.value === 'string'
|
|
? property.value
|
|
: null
|
|
if (field === null || !RAW_FIELDS.has(field)) return
|
|
// writes stay allowed: body parsers and middleware assign req.body
|
|
const parent = node.parent
|
|
if (
|
|
parent.type === 'AssignmentExpression' &&
|
|
parent.left === node &&
|
|
parent.operator === '='
|
|
) {
|
|
return
|
|
}
|
|
context.report({ node, messageId: 'noRawReqAccess', data: { field } })
|
|
},
|
|
VariableDeclarator(node) {
|
|
if (!isReqIdentifier(node.init)) return
|
|
if (node.id.type !== 'ObjectPattern') return
|
|
for (const prop of node.id.properties) {
|
|
if (
|
|
prop.type === 'Property' &&
|
|
!prop.computed &&
|
|
prop.key.type === 'Identifier' &&
|
|
RAW_FIELDS.has(prop.key.name)
|
|
) {
|
|
context.report({
|
|
node: prop,
|
|
messageId: 'noRawReqAccess',
|
|
data: { field: prop.key.name },
|
|
})
|
|
}
|
|
}
|
|
},
|
|
}
|
|
},
|
|
}
|