fix(req.get): perform case-insensitive header lookup - #7395
Conversation
|
I won't close this yet, but in my opinion #5288 is the result of modifying Node.js API object in a way that violates requirements/assumptions stated in documentation and Express should not work around problems in code that uses it. |
|
I'm adding it as an idea for Express 6. It doesn't mean it'll be included—it's just something for us to discuss. |
kilisamemarisaaa
left a comment
There was a problem hiding this comment.
The fallback should only inspect own header properties. for...in also walks the prototype chain, so this change can return an inherited mixed-case property as if it were an HTTP header.
I reproduced the behavior represented by this head on Node 24.12.0:
const headers = Object.create({ 'X-Inherited': 'prototype-value' })
// Current direct lowercase lookup:
headers['x-inherited'] // undefined
// This PR's fallback:
getHeader(headers, 'x-inherited') // 'prototype-value'
Object.keys(headers) // []A real Node request's req.headers also had Object.prototype as its prototype in that environment, rather than a null prototype. This means an enumerable inherited property (including one introduced by unrelated prototype mutation) becomes observable through req.get() only after this change.
Could the loop use Object.keys(headers) or guard with Object.prototype.hasOwnProperty.call(headers, key), with a regression case using Object.create({ 'X-Filipe': 'inherited' })? Mixed-case own properties would still work without treating prototype state as request metadata.
Fixes #5288
This updates
req.get()/req.header()to perform a case-insensitive lookup when a header is present under a non-lowercase key.Previously, custom headers added directly to
req.headerswith mixed-case names, such asX-filipe, could not be read withreq.get('x-filipe'). This change preserves the fast direct lookup path, then falls back to scanning header keys case-insensitively.After this change, the same lookup returns the header value:
A regression test was added for custom mixed-case request headers.