📜 ⬆️ ⬇️

Heartbleed on Rust

In the comments to one of the links to Hacker News, someone claimed that using Rust would prevent Heartlbeed, that the code would not even compile. It sounded like a challenge!

The thread starts here . I was not going to find fault with anyone, but the Heartbleed prevention statement turned out to be well formulated. Unlike vague statements about the safety of working with memory in general, this particular statement can be tested.

I do not plan to implement the entire TLS stack on Rust, so I will cut off the path and reduce the scale of the problem. I hope that my model will keep the essence of the problem. In a nutshell, the goal is to write a program that reads a file (package) from the file system (network) and sends it back (a kind of network version of echo). The length of the echo request will be encoded in one byte, followed by the data. This is equivalent to a TLS vulnerability. Our program will accept a couple of such packages, yourping and myping , and respond with yourecho and myecho . If any data from your package is leaked to my package, we have a problem: heartbleed 1 .

Let's start with a simple program on Rust.
')
 use std::old_io::File; fn pingback(path : Path, outpath : Path, buffer : &mut[u8]) { let mut fd = File::open(&path); match fd.read(buffer) { Err(what) => panic!("say {}", what), Ok(x) => if x < 1 { return; } } let len = buffer[0] as usize; let mut outfd = File::create(&outpath); match outfd.write_all(&buffer[0 .. len]) { Err(what) => panic!("say {}", what), Ok(_) => () } } fn main() { let buffer = &mut[0u8; 256]; pingback(Path::new("yourping"), Path::new("yourecho"), buffer); pingback(Path::new("myping"), Path::new("myecho"), buffer); } 

The program is compiled, albeit with warnings due to lame use of std::old_io . Not God knows what the code, but not the worst. For example, I managed not to use insecure cross-language interfaces (FFI) to call memcpy from C.

Let's see what the program does with simple input.

 $ echo \#i have many secrets. this is one. > yourping $ echo \#i know your > myping $ ./bleed $ cat yourecho #i have many secrets. this is one. $ cat myecho #i know your secrets. this is one. 

Bingo! Secret data flowed away.

Of course, a real Rust programmer will never write such a program, so probably I haven’t yet demonstrated Heartbleed on Rust.

Let's take a break from Rust and look at the equivalent C code.

 #include <fcntl.h> #include <unistd.h> #include <assert.h> void pingback(char *path, char *outpath, unsigned char *buffer) { int fd; if ((fd = open(path, O_RDONLY)) == -1) assert(!"open"); if (read(fd, buffer, 256) < 1) assert(!"read"); close(fd); size_t len = buffer[0]; if ((fd = creat(outpath, 0644)) == -1) assert(!"creat"); if (write(fd, buffer, len) != len) assert(!"write"); close(fd); } int main(int argc, char **argv) { unsigned char buffer[256]; pingback("yourping", "yourecho", buffer); pingback("myping", "myecho", buffer); } 

The survey revealed that no real C programmer would ever write such a program. What do we have?

code that no real C: heartbleed programmer will write
code that no real programmer on Rust will write: (task for the reader)

The meaning of the post is not in censure Rust. I could write a similar program on Go, or even on Haskell, if I were smart enough to understand a burrito . The point is that until we understand what vulnerabilities are like Heartbleed, we can hardly avoid them by simply switching to a magic vulnerable language. Yes, everyone has heard of Heartbleed, but this does not necessarily make it a good example.

Perhaps the Heartbleed argument was not used as a reference to Heartbleed itself, but to a bundle of other big and scary problems. Not sure if this makes the argument better. “Vulnerabilities like Heartbleed but not too similar” is a poorly defined class of problems. It is difficult to assess any claims about such a class.

Speaking of vulnerabilities and their resolution, we need to be precise and careful. Hip raised around Heartbleed (Shellshock, etc.) makes it an attractive target for constructing arguments, but it is worth checking the compatibility of the example and the argument. Erroneous examples lead to erroneous decisions.

Notes

1. bleed - ooze out

Links

Source: https://habr.com/ru/post/249537/


All Articles