編寫安全的互聯網應用非易事。Java Servlet/JSP/EJB 解決了 C/C++/Perl 時代大多數低級漏洞,但應用層邏輯漏洞(注入、越權、洩漏)仍需開發者守衛。本文聚焦 Java 平台固有的安全優勢與殘留風險點。
C 代碼固定緩衝區大小 char buf[1000],read() 不檢查邊界 → 溢出覆蓋返回地址/函數指針 → 執行任意代碼。
Java 以 String / byte[] 承載輸入:
String line = in.readLine(); —— 字符串大小動態匹配輸入,不可變,零溢出風險。char[] buf = new char[1000],越界訪問拋出 ArrayIndexOutOfBoundsException,JVM 保護運行時環境不被破壞,異常可捕獲處理,絕不會導致不可預期行為。Java 內存模型(邊界檢查、類型安全、垃圾回收)從根本上消除了緩衝區溢出攻擊面。
競態條件:檢查權限 → 使用資源 間隙被攻擊者利用(TOCTOU)。
Java 純內存操作無此問題,但文件操作仍存風險:
// 危險模式
File f = new File("temp.txt");
if (!f.exists()) f.createNewFile(); // 間隙可被搶佔
FileOutputStream out = new FileOutputStream(f);
防範:
Files.createFile(Path, FileAttribute...) (NIO.2) 原子創建並設置權限。Files.createTempFile(),JVM 保證唯一性。// 極度危險
String cmd = "ping " + request.getParameter("host");
Runtime.getRuntime().exec(cmd); // 輸入 "8.8.8.8; rm -rf /" → 災難
鐵律:
ProcessBuilder 列表形式:new ProcessBuilder("ping", host),參數不經 Shell 解析。PreparedStatement/JPA/Hibernate Criteria),嚴禁字符串拼接 SQL。DocumentBuilderFactory.setFeature("https://apache.org/xml/features/disallow-doctype-decl", true)。ObjectInputFilter (JDK 9+) 白名單類。Java 平台為你擋住了底層記憶體安全彈幕,但應用邏輯防線完全在你手中。將安全視為功能性需求的一部分,在每行代碼、每次 Code Review、每次發布中踐行纏深防禦。