HTTP request smuggling primitive: bare LF accepted as a request-line terminator in strict mode
Dieses Issue hat noch niemand übernommen.
Bewertung
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Anfängerfreundlichkeit
- 55/100
- Issue-Typ
- Bug
- Klarheit
- Klar beschrieben
- Aktivitätsstatus
- Aktiv
- Tech-Stack
- node.js, typescript
- Bereich
- backend-api-design, security
Rechercherichtung
Beginne in url.ts:176 und verfolge url.exit.toHTTP09 bis zu headers_start. Vergleiche dabei den Pfad für ein einzelnes LF mit der Prüfung LENIENT_OPTIONAL_CR_BEFORE_LF, die für andere Terminatoren der Request-Line verwendet wird. Füge Regressionstests für versionslose und versionierte Requests im Strict Mode hinzu und überprüfe anschließend, dass der Strict Mode den Fall mit einem einzelnen LF ablehnt, ohne HTTP/0.9-Header oder einen Body zu parsen.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
llhttp_set_lenient_optional_cr_before_lf documents that llhttp "would error when a LF is not
preceded by CR when terminating the request line", and that relaxing this exposes request smuggling.
url.ts:176 exits on a bare \n straight to the HTTP/0.9 adapter with no
LENIENT_OPTIONAL_CR_BEFORE_LF check — the only line terminator in the grammar that is ungated.
url.exit.toHTTP09 then continues into headers_start with no http_minor guard, so the message is
labelled HTTP/0.9 but headers and a Content-Length body are still parsed.
PoC
const http = require('http'), net = require('net');
const srv = http.createServer((req, res) => { // default parser, no options
let body = '';
req.on('data', c => body += c);
req.on('end', () => {
console.log(` ACCEPTED HTTP/${req.httpVersion} ${req.method} ${req.url}` +
` headers=${JSON.stringify(req.headers)} body=${JSON.stringify(body)}`);
res.end('ok');
});
});
srv.on('clientError', e => console.log(` REJECTED ${e.code}`));
const cases = [
['versionless + bare LF', 'GET /x\nHost: a\r\nContent-Length: 5\r\n\r\nhello'],
['versioned + bare LF', 'GET /x HTTP/1.1\nHost: a\r\n\r\n'],
];
srv.listen(0, async () => {
for (const [name, raw] of cases) {
console.log(name);
await new Promise(done => {
const c = net.connect(srv.address().port, '127.0.0.1', () => c.write(raw));
c.on('close', done); c.on('error', done);
setTimeout(() => c.destroy(), 300);
});
}
srv.close();
});
versionless + bare LF
ACCEPTED HTTP/0.9 GET /x headers={"host":"a","content-length":"5"} body="hello"
versioned + bare LF
REJECTED HPE_INVALID_VERSION
The same terminator is rejected when a version is present and accepted when it is absent. The
accepted message is reported as HTTP/0.9 yet carries headers and a body, neither of which HTTP/0.9
defines.
Scope, stated plainly: this path sets keepalive=0, and a pipelined follow-up request is rejected
with HPE_CLOSED_CONNECTION, so on its own it is a divergence from the documented strict-mode
guarantee rather than a demonstrated desync. Two requests parse on one connection only with
lenient_keep_alive also enabled.
- Vorherrschende Sprache
- TypeScript
- Sterne
- 1.9k
- Forks
- 237
- PR-Merge-Kennzahlen
- Keine gemergten PRs in 30 T.
Beitragsleitfaden
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus nodejs/llhttp
-
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 52/100
-
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 54/100
-
Schwierigkeit 5/5 Über eine Woche Anfängerfreundlichkeit 32/100
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 45/100
-
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 38/100
Ähnliche Issues
-
comp/dashboard P3 type/bug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 86/100
NousResearch/hermes-agent#117722 ·
-
clawsweeper:fix-shape-clear clawsweeper:queueable-fix clawsweeper:source-repro impact:ux-friction issue-rating: 🦞 diamond lobster no-stale P3
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 76/100
-
code-quality refactoring
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 84/100
github/gh-aw-firewall#8816 ·
-
integration:quickjs org:external priority:backlog topic:code-interpreter topic:middleware type:feature
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 74/100
langchain-ai/deepagents#6450 ·