Live data from Hacker News

Fun with IP address parsing

blog.dave.tf

41–50 of 150 posts

Re: Fun with IP address parsing

#41
Writing a parser and saying "I'm dropping support for all these old ways of doing things" seems like poor form.

Unless there is a big reason, never drop backwards compatibility. In this case, supporting all those forms would be very do-able. The best way to support them would be to find some old BSD parsing code and port it, then you can be sure every corner case is handled the exact same way. Handling corner cases differently is a great way to introduce security vulnerabilities and crash/DoS bugs that every user of your library will have to be aware of.

Maintaining such code isn't really a good excuse here either - the code is only going to be a few thousand lines, is self contained with no dependencies, is easy to test, not going to change much with time, etc.

Basically, there is no benefit to removing this feature, so don't break what isn't broken.

Re: Fun with IP address parsing

#42

I'm not convinced these are "cursed". They may be the result of bygone networking conventions, implementation ideas that never came to mainstream fruition, flexibility for use-cases etc. Just because we don't understand something that looks strange, doesn't mean it's cursed, nor that one can simply turn one's nose up and say "I don't understand why these exist so I'll just ignore them when I implement x".

The bygone implementers clearly cursed us with their peculiar decision making. Just as we occasionally curse the implementers of the future (either knowingly or unknowingly) with our peculiar decision making.

Re: Fun with IP address parsing

#43

Writing a parser and saying "I'm dropping support for all these old ways of doing things" seems like poor form. Unless there is a big reason, never drop backwards compatibility. In this case, supporting all those forms would be very do-able. The best way to support them would be to find some old BSD parsing code and port it, then you can be sure every corner case is handled the exact same way. Handling corner cases d…

There is a good reason: many of the unusual forms are unused except as tricks and exploits. The whole internet uses IPv4 classless routing. There is no value in keeping pre-CIDR forms. Graybeards might object because they have been typing "127.1" for forty years. It's merely an old habit. Who is to say how big a reason is required to "never drop backwards compatibility"?

Re: Fun with IP address parsing

#45

These different representations also lead to frequent server side request forgery (SSRF) bypasses - someone might be blocking local IPv4 but you can still access their AWS metadata endpoint at ::ffff:169.254.169.254, etc. For anyone using Ruby, I'm the author of a gem [1] that comprehensively protects against SSRF bugs. For anyone using Golang I recommend this [2] blog post. [1]: https://github.com/arkadiyt/ssrf_filt…

Unfortunately the blacklisting approach that works on IPv4 is completely broken for IPv6 since you can't really know where your own services are. I still did not find a good generic way to protect IPv6 and ended up just disallowing it so far everywhere.

IPv6 has internal ranges defined just like IPv4 does - anything in an internal range should be blocked, and anything in an external range is safe to pass through.

Re: Fun with IP address parsing

#46
> This is the same IP address: 3232271615. You get that by interpreting the 4 bytes of the IP address as a big-endian unsigned 32-bit integer, and print that. This leads to a classic parlor trick: if you try to visit http://3232271615 , Chrome will load http://192.168.140.255.

This was the source of one of my favorite “bugs” ever. I was working on multiple mobile apps for a company, and they had a deep link setup that was incredibly basic: ://, which would take you to an article with a simple incrementing ID. This deep link system “just worked” on iOS and Android; take the URL, grab the host, parse it as an int, grab that story ID. Windows Phone, however… the integers we were parsing out were totally wrong, returning incredibly old stories!

Turned out that the host we were given by the frameworks from the URL was auto-converted to an IP in dotted-quad format, and then the int parser was just grabbing the last segment… which meant that we were always getting stories <256, instead of the ~40000 range we were expecting.

Re: Fun with IP address parsing

#47
post #43

Writing a parser and saying "I'm dropping support for all these old ways of doing things" seems like poor form. Unless there is a big reason, never drop backwards compatibility. In this case, supporting all those forms would be very do-able. The best way to support them would be to find some old BSD parsing code and port it, then you can be sure every corner case is handled the exact same way. Handling corner cases d…

There is a good reason: many of the unusual forms are unused except as tricks and exploits. The whole internet uses IPv4 classless routing. There is no value in keeping pre-CIDR forms. Graybeards might object because they have been typing "127.1" for forty years. It's merely an old habit. Who is to say how big a reason is required to "never drop backwards compatibility"?

The way to handle security problems with corner cases is to just return a parse error if something unusual is seen. With security, the rule is to be conservative with what you accept; anything unusual should be rejected.

In cases where backwards compatibility is needed, just use inet_pton() and let the libc maintainers deal with the bug reports (I believe inet_pton() dropped octal and hex support for ipv4 addresses)

Re: Fun with IP address parsing

#48
Wow, this. One thing I didn’t see mentioned was “0”. You mentioned it, but it didn’t grok to something I know to work in some implementations: “ping 0” behaves like “ping 127.0.0.1”.

Re: Fun with IP address parsing

#50

I'm not convinced these are "cursed". They may be the result of bygone networking conventions, implementation ideas that never came to mainstream fruition, flexibility for use-cases etc. Just because we don't understand something that looks strange, doesn't mean it's cursed, nor that one can simply turn one's nose up and say "I don't understand why these exist so I'll just ignore them when I implement x".

He’s joking with that word choice.
Post reply on HN