さびでハートブリード

Hacker Newsへのリンクの1つに対するコメントの中で、誰かがRustを使用するとHeartlbeedが妨げられ、コードがコンパイルさえされないと主張しました。 それは挑戦のように聞こえました!



スレッドはここから始まります 。 私は誰にも過失を見つけるつもりはありませんでしたが、Heartbleedを防ぐことについての声明は明確に定式化されました。 一般にメモリを操作することの安全性に関するあいまいな記述とは異なり、この特定の記述はテストできます。



RustにTLSスタック全体を実装する予定はありません。そのため、パスを切り、問題の規模を縮小します。 私のモデルが問題の本質を保持することを願っています。 簡単に言えば、目標は、ファイルシステム(ネットワーク)からファイル(パッケージ)を読み取り、それを送り返す(エコーのネットワークバージョンの一種)プログラムを作成することです。 エコー要求の長さは1バイトでエンコードされ、その後にデータが続きます。 これはTLSの脆弱性と同等です。 私たちのプログラムは、このようなパッケージyourping



myping



yourping



myping



パッケージで応答します。 パッケージのデータがmy



パッケージに漏れた場合、問題があります:heartbleed 1



簡単な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); }
      
      





プログラムは、 std::old_io



通常の使用による警告はありますが、コンパイルされます。 神はどんなコードを知っていますが、最悪ではありません。 たとえば、Cからmemcpyを呼び出すために、安全でないクロス言語インターフェイス(FFI)を使用できませんでした。



プログラムが単純な入力で何をするかを見てみましょう。



 $ 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.
      
      





ビンゴ! 機密データが漏洩しました。



もちろん、真のRustプログラマーがそのようなプログラムを作成することは決してないので、RustでHeartbleedをまだ表示していません。



Rustを休憩して、同等のCコードを見てみましょう。



 #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); }
      
      





調査では、実際のCプログラマーがそのようなプログラムを作成することはないことが示されました。 何がありますか?



真のCプログラマーが書かないコード:heartbleed

実際のRustプログラマーが作成しないコード:(読者のタスク)



投稿の意味は、Rustを非難することではありません。 ブリトー理解するのに十分賢いのであれば、GoやHaskellで同様のプログラムを書くことができます 。 要点は、Heartbleedのような脆弱性が何であるかを理解するまで、魔法の脆弱な言語に切り替えるだけでは、それらを回避することはほとんどできないということです。 はい、誰もがハートブリードについて聞いたことがありますが、それは必ずしも彼を良い例にするわけではありません。



おそらく、Heartbleedについての議論は、Heartbleed自体への言及としてではなく、他の大きくて恐ろしい問題の束として使用されました。 これにより引数が改善されるかどうかはわかりません。 「Heartbleedのような脆弱性でも、あまり似ていない」は、定義が不十分なクラスの問題です。 そのようなクラスに関するステートメントを評価することは困難です。



脆弱性とその解決について言えば、正確で注意する必要があります。 Heartbleed(Shellshockなど)にまつわる誇大広告は、引数を構築するための魅力的なターゲットになりますが、例と引数の互換性をチェックする価値があります。 間違った例は、誤った決定につながります。



注釈

1.ブリード-にじみ出る、放出する



参照資料




All Articles