如果完整的堆疊跟蹤由日志記錄框架(此處為 Java Util Logging)記錄,則 Java 堆疊跟蹤可能包含敏感資訊(在我的情況下是密碼)。
如何避免在不丟失日志檔案中堆疊跟蹤中的其他重要資訊的情況下記錄此類敏感資訊?
例子:
package javalogspassword;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.logging.Logger;
public class JavaLogsPassword {
private static final Logger LOG = Logger.getLogger(JavaLogsPassword.class.getName());
public static void main(String[] args) {
Connection conn;
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost/test?"
"user=root&password=");
LOG.log(Level.FINER, "Connected");
try (Statement statement = conn.createStatement()) {
// this statement contains a syntax error
statement.execute("ALTER USER test IDENT BY '*Choose-a-good-password*'");
}
conn.close();
} catch (SQLException ex) {
// password '*Choose-a-good-password*' will be logged
LOG.throwing(JavaLogsPassword.class.getName(), "main", ex);
}
}
}
記錄器配置:logging.properties:
handlers= java.util.logging.FileHandler
.level= INFO
java.util.logging.FileHandler.pattern = java%u.log
javalogspassword.level = FINER
運行jar的命令:
java -Djava.util.logging.config.file=logging.properties -jar dist/JavaLogsPassword.jar
生成的檔案java0.log包含密碼。
uj5u.com熱心網友回復:
對此沒有解決辦法。資料不是黑白分明的;任何資料的安全敏感性都是灰色的。即使看似完全無害的東西,比如堆疊跟蹤中的行號或方法名稱,理論上也是“敏感的”。例如,它可能會讓人猜測您必須使用庫 AB 的 XY 版本,它具有已知的安全漏洞,我現在可以利用它。
這就是現實生活中的安全性如何運作:很少有單點故障可以最終指出:這是系統受到損害的唯一原因。相反,它幾乎總是由多個因素造成的,每個因素都有一個本身似乎并不那么重要的問題,但將它們放在一起,瞧。
因此:沒有解決方案- 日志資訊是敏感的。應該這樣對待。
當然,這聽起來不錯,但實際的明文密碼是黑夜,雖然所有日志資訊都必須是敏感的,但“仔細管理您的日志”和“只在其中列印密碼”之間是有區別的。
不幸的是,那里也沒有好的解決方案:有文化因素在起作用(要非常小心你在例外訊息和日志陳述句中塞入的內容。無論是什么本能讓你去的:無論如何,我會把整個 SQL直接在日志檔案中宣告 - 解決這個問題),但是文化本能很難灌輸并且幾乎不可能測驗(你如何單元測驗“整個代碼庫中沒有一行有記錄密碼的風險”?那是.. . 絕對不平凡)。
因此,相反,它更像是“看到它就撲滅它”:對于這種特定情況,您現在已經知道了,因此請解決問題。根據我的經驗,根據經驗,SQL 查詢并不包含整個陳述句,但如果包含,請使用 aPreparedStatement并通過設定密碼,.setString(1, ...)而不會。這再次涉及文化:在我的開發團隊中,將字串文字放入 SQL 陳述句是不可接受的,通常會進行 lint 檢查,并通過代碼審查進行嚴格監管。即使已知字串文字是可接受的并且完全不變 - 無論如何都要使用preparedstatements。如果 SQLException 包括整個陳述句,包括?即使使用preparedstatements,oof - 如果可以更正,請在JDBC 驅動程式的設定中進行搜索。如果您真的不能,請撰寫將 SQL 陳述句從例外中剝離出來的代碼(.query可能是wrap )——這可能但很復雜,不過我會先尋找替代方案。
這里的其他文化方面涉及不想要任何任何形式的此類直接敏感資訊不是設計的非常短暫。換句話說,在資料庫中使用純文本密碼是錯誤的 - 然后該錯誤以“哦,糟糕,通過日志泄露密碼真的很容易”的形式出現。修復不是“防止它出現在日志檔案中”,修復是“不要在資料庫中存盤未散列的密碼”。像加密一樣簡單的事情,即使解密密碼就在代碼庫中,因此不是特別保密的秘密,已經意味著審查日志的開發人員將需要積極承諾破壞他們的合同(即變成惡意的,并且如果您的程式員是惡意的,那么這是您的問題中最少的,安全方面!)以便真正知道那是什么。
你的開發團隊成員可能會被賄賂,有些人可能無法控制他們的好奇心,但安全不是非黑即白,而是灰色陰影,這已經有所幫助。
更好的是找到任何需要您擁有未散列密碼的行程并擺脫它們,因為沒有理由擁有這些。如果它是您系統中用戶的密碼,您在做什么?改用 bcrypt、scrypt 或其他一些密碼哈希設定。如果這是連接外部 API 所需的密碼,請與外部 API 提供者交談并告訴他們他們的設定是不可接受的 - 這應該是使用 JWT 或其他一些 PKI 授權/身份驗證方案而不是發送密碼約。等等。
換句話說,有答案。但沒有一勞永逸的萬能藥。
uj5u.com熱心網友回復:
這樣做的方法是
研究
查看日志并查看哪些錯誤型別產生了敏感資訊。
調整
實作一個執行安全日志記錄的類,并在捕獲可能包含敏感資訊的錯誤時將錯誤日志記錄委托給此類
抓住一切
您需要確保捕獲任何例外,并以最適合您需要的方式處理例外。
重構
查看專案中的每個捕獲,并查看是否存在可能包含敏感資訊的潛在捕獲例外。
等著瞧
完成該程序后,稍等片刻,然后再次檢查日志,看看是否有您最初錯過的案例。如果是這樣,則對以前未處理的案例應用相同的流程。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/365711.html
