Closed
Description
This issue is inspired by this blog.
Due to the specification, leading zero in IP string is interpreted as octal literals. So a IP address 0127.0.0.1
actually means 87.0.0.1
. As shown in the following example:
❯ ping 0127.0.0.1
PING 0127.0.0.1 (87.0.0.1): 56 data bytes
However, the Ipv4Addr
from the std library will recognize it as 127.0.0.1
instead. A simple code to demo the situation (playground link):
use std::net::Ipv4Addr;
fn parse(input: &str) {
let ip: Option<Ipv4Addr> = input.parse().ok();
println!("{} -> {:?}", input, ip);
}
fn main() {
parse("127.0.0.1");
parse("0127.0.0.1");
}
I expected to see this happen:
127.0.0.1 -> Some(127.0.0.1)
0127.0.0.1 -> Some(87.0.0.1)
Instead, this happened:
127.0.0.1 -> Some(127.0.0.1)
0127.0.0.1 -> Some(127.0.0.1)
Noted this bug may cause security vulnerabilities in certain cases. For example, a Rust program uses Ipv4Addr
doing some sanity check then passing the user string to other library or program.
Furthermore, the specification actually also allows hex format in IP string.
Meta
rustc --version --verbose
:
rustc 1.51.0 (2fd73fabe 2021-03-23)