
沒人喜歡被管束。當交警要求你規範駕駛減速行駛時,你的第一反應很少會是由衷感謝。但當你開車經過一輛撞在樹上的汽車,周圍閃爍著警燈,救援設備四處可見時,或許你會意識到警察的建議是有道理的。
對於 FBI 和 CISA 對緩衝區溢出問題的嚴厲態度,這一點毋庸置疑。這些機構關注可能威脅企業 IT 系統、造成嚴重事故的安全漏洞,他們已經見過太多類似情況,因此感到憤怒。編寫代碼時犯錯並不是罪過,任何值得做的人類活動都難免會出錯。問題在於這類漏洞是可以避免的,而且幾十年來一直如此,但大型科技公司仍在源源不斷地產生這樣的問題,就像教堂長椅上不斷湧出的蛀蟲。他們說"夠了",這種說法很有道理。
你應該都了解緩衝區溢出。當程式設計師將數據從 A 移動到 B,卻沒有檢查 A 是否總能裝入 B 時,就會出現問題。當 A 裝不下時,數據就會被複製到 B 之外的內存中,這可能會造成災難性後果。讓我們把那塊內存稱為 C,代表災難 (Catastrophe)。或混亂 (Chaos)。或者就是 C 語言本身。
聯邦機構建議的眾多解決方案之一是放棄 C 語言及其混亂的家族,轉而使用具有健全防禦機制、能夠防止緩衝區溢出的現代語言。C 語言顯然不具備這種特性。它就像一把沒有安全防護的電鋸,誕生於這樣一個時代:如果程式設計師想要切斷自己的股動脈,那是他們的自由。有些馬戲團演員可以玩雜耍電鋸,但你絕對不會想在聖誕節把電鋸雜耍套裝作為家庭禮物送人。
正如聯邦機構指出的,你不必完全放棄 C 語言就能提高安全性。你可以通過多種方式進行更好的測試,可以使用安全的編碼實踐和檢查工具。現在的電腦可以在幾分鐘內編譯整個 Linux 源代碼。沒有理由不利用這種原始計算能力來做更多的代碼測試工作。
這正是安全漏洞觀察者感到沮喪的核心原因。這些公司在沒人要求的 AI 上燒掉數十億美元,卻不願意花費一小部分資金來清理自己製造的混亂。
所有向他人提供服務和商品的人都要承擔責任和後果。一個將 240 伏電路接到 115 伏插座的電工活不了多久。同樣,一個用一英寸管道做馬桶出水口的水管工也會遇到真正的緩衝區溢出問題。然而,像 Microsoft 這樣的公司在明知可以避免的情況下,仍然對數百萬客戶這樣做,而且可以繼續這樣做而不受懲罰。
是的,測試成本很高,而且不能保證絕對安全。但是請想想:如果測試的代碼本身錯誤較少,測試就會變得更快、更容易、更便宜。當某類錯誤在流程早期就被消除時,就不需要再檢查這類錯誤了。這就把我們帶回到編碼平台的選擇,特別是編程語言的選擇這個話題。
改變語言很困難,而且你在某個領域越優秀,改變就越困難。世界上最好的電鋸雜耍者不會想換成精密安全切割器。如果你的業務建立在電鋸雜耍套裝的生態系統上,而流的血不是你的,那為什麼這是別人的事?對一個組織來說,挑戰不僅僅是技術層面的,還包括文化和個人層面,這不應該被低估。看看 Linux 核心中關於 Rust 的爭論,其中 Linus 不得不用他的馴獸鞭來馴服一些大傢伙。
但這些都不是不做出改變的藉口。終有一天,C 語言會成為 21 世紀的 COBOL,這一天來得越快,資訊高速公路上的血跡就會越少。當你明知如何把事情做好卻依然做得很糟糕時,遲早會導致無關緊要,甚至滅絕。一旦你擁有高效的流程和優秀的人才,編寫和發布更好的代碼就會成為競爭優勢。
轉型成本是一次性的,而持續的節省是永遠的。你想多快到達那裡?你正在做什麼來實現這一目標?
當罪過變成犯罪時,站在正義一邊也是很好的。如果不良實踐被多次指出卻仍被故意忽視,那麼將其定為可訴訟就成為可能。一個新法律,甚至僅僅是對現有法律的一個法庭案例就可以做到這一點——由於可避免的糟糕代碼造成的漏洞使公司明確承擔責任。從法律角度定義糟糕的代碼很難,但將使用公認的良好方法作為可接受的辯護符合邏輯。
這個列表不會包括"不要使用 C 語言",至少不會立即包括。如果問題持續足夠長的時間,有一天可能會需要這樣做。最好不要讓這種情況發生,而是讓 C 語言成為歷史,至少在生產代碼中是這樣,因為這些代碼不僅可能切斷你自己的腿,還可能傷害數百萬用戶。那些電鋸最好儘快生鏽掉。