Skip to content

Properly log validation errors related to legacy IPv4 notations #498

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

Open
zackw opened this issue May 8, 2019 · 15 comments
Open

Properly log validation errors related to legacy IPv4 notations #498

zackw opened this issue May 8, 2019 · 15 comments
Assignees

Comments

@zackw
Copy link

zackw commented May 8, 2019

The current rev of the URL Standard specifies that the various legacy notations accepted by inet_aton for IPv4 addresses are validation errors, but rust-url silently accepts them (they're not even diagnosed via the syntax violation callback). I would like to have an option to reject these.

Examples of undesirable constructs:

# all are treated as equivalent to http://127.0.0.1/
http://127.0.1/
http://127.1/
http://0177.0.1/
http://0177.0.0.1/
http://0177.1/
http://0x7f.0.1/
http://0x7f.0.0.1/
http://0x7f.1/
http://2130706433/
http://0x7f000001/
http://017700000001/

# equivalent to http://127.0.0.8/ , not http://127.0.0.10/
http://0127.0.0.010/

See https://url.spec.whatwg.org/#concept-ipv4-parser (pay close attention to where it, and its subroutine https://url.spec.whatwg.org/#ipv4-number-parser , set the "validationErrorFlag") for gory details.

Previous discussion in #116.

@dekellum
Copy link
Contributor

dekellum commented May 8, 2019

I wasn't aware of this legacy edge case (thanks!), but I agree with your motivation. Seems exploitable for misuse. For example servers might have good reason to want to reject provided URLs to localhost. Do common IPv4 resolvers actually accept and resolve these examples to local ports?

If the violation callback was extended for this case, you would have the option of promoting the violation to your own error or other form of rejection? That would be a light-weight and (I think, reasonably) backward-compatible way to achieve it, while still making the implementation available in this crate. I'd use that!

@zackw
Copy link
Author

zackw commented May 8, 2019 via email

@dekellum
Copy link
Contributor

dekellum commented May 9, 2019

Indeed! I've suggested keeping it. :)

@SimonSapin
Copy link
Member

Aligning with the spec in terms of what inputs log a syntax violation sounds good.

@zackw
Copy link
Author

zackw commented May 10, 2019

@dekellum re

Do common IPv4 resolvers actually accept and resolve these examples to local ports?

The POSIX spec for getaddrinfo says that "address strings using Internet standard dot notation as specified in inet_addr are valid", and that does include all of the unusual syntaxes I listed.

@dekellum
Copy link
Contributor

@SimonSapin : Thanks. I think anyone implementing would be concerned about #462 Is it a reasonable time to decide that either way?

@nox
Copy link
Contributor

nox commented Jul 18, 2019

AFAIK if we want to do that we need a new variant for the syntax violation enum, so this will be a breaking change, so we want to do that for 2.0 I guess.

@nox nox changed the title Option to reject legacy inet_aton notation for IPv4 addresses Properly log validation errors related to legacy IPv4 notations Jul 18, 2019
@nox nox self-assigned this Jul 18, 2019
@dekellum
Copy link
Contributor

Would discouraging exhaustive matching (in itself a breaking change) on SyntaxViolation, and ideally ParseError, be good for 2.0, making this non-breaking when available? I can't parse the tracking in rust-lang/rust#44109 or guess what that stable MSRV would be, so likely the old fashion manual way with an unused variant would be best for now.

@SimonSapin
Copy link
Member

It looks like #[non_exhaustive] is not stable in any release so far.

@dekellum
Copy link
Contributor

Okay, would you entertain a PR to add an unused variant and rustdoc to each of these enums?

@dekellum
Copy link
Contributor

Also, having looked at these error types, they are in need of some other modernizations, like dropping description() impl and replacing with a Display impls. I could do that in same PR. Of interest?

@nox
Copy link
Contributor

nox commented Jul 19, 2019

I think it would be ok adding a doc(hidden) variant and making it extra clear in the docs that this enum is never expected to be exhaustively matched.

@nox
Copy link
Contributor

nox commented Jul 19, 2019

like dropping description() impl

Nah please leave that alone, no need to regress things for no reason and the implementation is trivial. You can definitely add a Display impl though.

@dekellum
Copy link
Contributor

IIRC, currentstd::error::Error default impls (now deprecated) description via Display, but I get your point, thanks.

@SimonSapin
Copy link
Member

description returns a &str that borrows &self (not for example a String) so it can’t be implemented based on Display (only the other way around is possible).

You can click on the [src] link in https://doc.rust-lang.org/std/error/trait.Error.html to quickly see the body of default methods.

bors-servo pushed a commit that referenced this issue Jul 23, 2019
Add unused variants to ParseError and SyntaxViolation enums

Per discussion in #498 (comment) , this adds a hidden unused variant to each of `ParseError` and `SyntaxViolation` enums so as to make future additions non-breaking changes.   This is the long standing manual way (e.g. originally used by`std::io::ErrorKind`), given lack of a stable feature and acceptable rust MSRV with rust-lang/rust#44109.

Also these types already implemented `Display` but having been burnt with `Debug` vs `Display` versions of the `fmt` function, I also disambiguated paths in these `Display` implementations.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/rust-url/525)
<!-- Reviewable:end -->
bors-servo pushed a commit that referenced this issue Jul 23, 2019
Add unused variants to ParseError and SyntaxViolation enums

Per discussion in #498 (comment) , this adds a hidden unused variant to each of `ParseError` and `SyntaxViolation` enums so as to make future additions non-breaking changes.   This is the long standing manual way (e.g. originally used by`std::io::ErrorKind`), given lack of a stable feature and acceptable rust MSRV with rust-lang/rust#44109.

Also these types already implemented `Display` but having been burnt with `Debug` vs `Display` versions of the `fmt` function, I also disambiguated paths in these `Display` implementations.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/rust-url/525)
<!-- Reviewable:end -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants