Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overzealous link header validation in writeEarlyHints #46453

Closed
khalsah opened this issue Jan 31, 2023 · 5 comments · Fixed by #46466 · May be fixed by #46464
Closed

Overzealous link header validation in writeEarlyHints #46453

khalsah opened this issue Jan 31, 2023 · 5 comments · Fixed by #46466 · May be fixed by #46464
Labels
confirmed-bug Issues with confirmed bugs. good first issue Issues that are suitable for first-time contributors. http Issues or PRs related to the http subsystem.

Comments

@khalsah
Copy link
Contributor

khalsah commented Jan 31, 2023

Version

v19.5.0

Platform

Darwin Kernel Version 22.2.0: Fri Nov 11 02:03:51 PST 2022; root:xnu-8792.61.2~4/RELEASE_ARM64_T6000 arm64

Subsystem

http

What steps will reproduce the bug?

import { createServer } from "node:http";

const server = createServer((req, res) => {
  res.writeEarlyHints({
    link: "<https://fonts.gstatic.com/>; rel=preconnect; crossorigin",
  });
  res.end();
});

server.listen(3000);

How often does it reproduce? Is there a required condition?

No response

What is the expected behavior?

No response

What do you see instead?

node:internal/validators:473
    throw new ERR_INVALID_ARG_VALUE(
    ^

TypeError [ERR_INVALID_ARG_VALUE]: The argument 'hints' must be an array or string of format "</styles.css>; rel=preload; as=style". Received '<https://fonts.gstatic.com/>; rel=preconnect; crossorigin'
    at new NodeError (node:internal/errors:399:5)
    at validateLinkHeaderFormat (node:internal/validators:473:11)
    at validateLinkHeaderValue (node:internal/validators:493:5)
    at ServerResponse.writeEarlyHints (node:_http_server:310:16)
    at Server.<anonymous> (file:///Users/hargo/Code/wyyerd/i7n/test.mjs:4:7)
    at Server.emit (node:events:512:28)
    at parserOnIncoming (node:_http_server:1067:12)
    at HTTPParser.parserOnHeadersComplete (node:_http_common:119:17) {
  code: 'ERR_INVALID_ARG_VALUE'
}

Node.js v19.5.0

Additional information

This appears to be an overzelous validation that requires all link parameters to be followed by an =.

Per the ABNF in RFC8288 https://www.rfc-editor.org/rfc/rfc8288.html#section-3 the = is optional along with the parameter value.

Additionally it seems that the validation restricts parameters to a preset list of those headers currently defined by the HTML spec. This seems in conflict with RFC8288 which doesn't appear to place any restrictions on parameters, which seems more relevant that the parameters that happen to be specified in the current HTML specification.

@VoltrexKeyva VoltrexKeyva added the http Issues or PRs related to the http subsystem. label Feb 1, 2023
@bnoordhuis
Copy link
Member

PR welcome, although the regex used to validate the header is... wrgh.

writeEarlyHints() was added in #44180 and then its validation was updated #44874. Personally I don't see the value in being so rigid. @nodejs/http what was the thinking there?

@mcollina
Copy link
Member

mcollina commented Feb 1, 2023

https://github.com/orgs/nodejs/teams/http what was the thinking there?

This is just a bug and no one caught it.
As for the script validation, the contributor proposed it and it seemed ok to me.

Can you take a look @anonrig @Uzlopak? You both discussed this problem in: https://github.com/nodejs/node/pull/44820/files#r983969846.

@mcollina mcollina added confirmed-bug Issues with confirmed bugs. good first issue Issues that are suitable for first-time contributors. labels Feb 1, 2023
khalsah added a commit to khalsah/node that referenced this issue Feb 1, 2023
khalsah added a commit to khalsah/node that referenced this issue Feb 1, 2023
khalsah added a commit to khalsah/node that referenced this issue Feb 1, 2023
Removes the requirement that every call to writeEarlyHints include a
`link` header. While the `link` header is clearly the most common usage
of `103 Early Hints`, I could find no requirement to include a `link`
header as part of [RFC8297](https://www.rfc-editor.org/rfc/rfc8297.html).

Additionally this removes the existing incorrect validation of the Link
header format in favor of only validating that it is a valid header
value. While the validation could be updated to better match [RFC8288
Section 3](https://www.rfc-editor.org/rfc/rfc8288.html#section-3), it
appears it would be the only place in the node.js code base where we
proactively validate header values beyond verifying they are valid at
the HTTP protocol layer.

Fixes: nodejs#46453
khalsah added a commit to khalsah/node that referenced this issue Feb 1, 2023
Removes the requirement that every call to writeEarlyHints include a
`link` header. While the `link` header is clearly the most common usage
of `103 Early Hints`, I could find no requirement to include a `link`
header as part of [RFC8297](https://www.rfc-editor.org/rfc/rfc8297.html).

Additionally this removes the existing incorrect validation of the Link
header format in favor of only validating that it is a valid header
value. While the validation could be updated to better match [RFC8288
Section 3](https://www.rfc-editor.org/rfc/rfc8288.html#section-3), it
appears it would be the only place in the node.js code base where we
proactively validate header values beyond verifying they are valid at
the HTTP protocol layer.

Fixes: nodejs#46453
@climba03003
Copy link
Contributor

I really doesn't know why Link header is the only exception to own a validation.
Maybe it provide a better DX, but in-consistence on behavior really cause a lot of confusion to the user.

SRHerzog added a commit to SRHerzog/node that referenced this issue Feb 17, 2023
Updated regex for "Link" header validation to better match the
specification in RFC 8288 section 3. Does not check for valid URI
format but handles the rest of the header more permissively than
before. Alternative to another outstanding PR that disables validation
entirely.

Fixes: nodejs#46453
Refs: https://www.rfc-editor.org/rfc/rfc8288.html#section-3
Refs: nodejs#46464
nodejs-github-bot pushed a commit that referenced this issue Feb 23, 2023
Updated regex for "Link" header validation to better match the
specification in RFC 8288 section 3. Does not check for valid URI
format but handles the rest of the header more permissively than
before. Alternative to another outstanding PR that disables validation
entirely.

Fixes: #46453
Refs: https://www.rfc-editor.org/rfc/rfc8288.html#section-3
Refs: #46464
PR-URL: #46466
Reviewed-By: Yagiz Nizipli <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Paolo Insogna <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
targos pushed a commit that referenced this issue Mar 13, 2023
Updated regex for "Link" header validation to better match the
specification in RFC 8288 section 3. Does not check for valid URI
format but handles the rest of the header more permissively than
before. Alternative to another outstanding PR that disables validation
entirely.

Fixes: #46453
Refs: https://www.rfc-editor.org/rfc/rfc8288.html#section-3
Refs: #46464
PR-URL: #46466
Reviewed-By: Yagiz Nizipli <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Paolo Insogna <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
danielleadams pushed a commit that referenced this issue Apr 11, 2023
Updated regex for "Link" header validation to better match the
specification in RFC 8288 section 3. Does not check for valid URI
format but handles the rest of the header more permissively than
before. Alternative to another outstanding PR that disables validation
entirely.

Fixes: #46453
Refs: https://www.rfc-editor.org/rfc/rfc8288.html#section-3
Refs: #46464
PR-URL: #46466
Reviewed-By: Yagiz Nizipli <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Paolo Insogna <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
@nithin-murali-arch
Copy link

Can this also be fixed on Node 18?

@ShogunPanda
Copy link
Contributor

@nithin-murali-arch Isn't this fixed in 18.16.0? #46466 has been backported there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed-bug Issues with confirmed bugs. good first issue Issues that are suitable for first-time contributors. http Issues or PRs related to the http subsystem.
Projects
None yet
7 participants