數據庫安全審計是目前使用最為廣泛的數據庫安全技術,也正因此,用戶對此項技術提出了更高的要求。影響審計結果準確性的因素有很多,其中對參數化語句的精確審計是其中一個難點。
參數綁定是數據庫編程中常用的一種方法,通過這種方法,數據庫系統(tǒng)可以減少編譯次數,快速執(zhí)行,提升效率,但在筆者所見到的若干數據庫審計產品中,在這種情況下都出了不少的錯誤。有的是漏審了語句,有的是記錄下了操作的語句,但將具體執(zhí)行時所使用的參數記錯或漏記了。
為了詳解這種情況,我們來看一下參數綁定的基本概念。我們在常規(guī)的圖形化或命令行工具中,往往都是直接寫上SQL語句,比如:
Select * from person_info where id=’12XXXXX6722’;
在這里查詢條件是身份證號碼。根據身份證號碼查詢個人信息,是一種常用功能,也是會重復使用的語句,為了提升效率,編程中可以這么寫:
String sql1=’Select * from person_info where id=?;’
PreparedStatement pStmt = testConn.getConnection().prepareStatement(sql);
pStmt.setInt(1, ’12XXXXX6722’);
pStmt.execute();
下一次再使用時,就不用再發(fā)送語句了,可以直接發(fā)送:
pStmt.setInt(1, ’22XXXXX5399’);
pStmt.execute();
對于數據庫審計系統(tǒng)而言,單純地記錄下來‘Select * from person_info where id=?’是存在缺陷的,因為你無法明確額操作人員到底訪問了哪個用戶的信息,必須明確下來具體的參數才行。
這就要求將設定的參數,與Prepare的語句有效的關聯(lián),形成可視化的審計記錄展現:
Select * from person_info where id=’12XXXXX6722’;
Select * from person_info where id=’22XXXXX5399’;
這實際上要求審計系統(tǒng)比起單純的記錄語句要完成更多的工作;其中一個重要任務的就是句柄追蹤,本質上SQL語句的執(zhí)行過程追蹤就是句柄追蹤過程。在上面顯示的例子中,pStmt.execute(),在通訊過程中并不發(fā)送具體的語句,而僅是告知服務器要執(zhí)行哪個語句句柄,服務器端會根據內部記錄的句柄所對應的已經編譯完成的SQL語句的執(zhí)行計劃,進行語句執(zhí)行。數據庫審計要完成相應的工作,需要執(zhí)行類似的過程,在系統(tǒng)的內部也維護這樣的映射關系;同時由于大多數數據庫的句柄,是在會話級的,句柄是可重用的,因此在數據庫審計中還要有效地維護句柄與session的關聯(lián),以及句柄的消亡。
在句柄維護之外,另一個有挑戰(zhàn)的工作就是參數的還原。參數的還原,首要的是要明確參數所對應的句柄;在調用pStmt.setInt(1, ’22XXXXX5399’)時,在網絡中發(fā)送的包,會標明這個參數是針對哪個句柄的,是針對第幾個參數的。作為數據庫審計產品,需要將參數與語句進行映射;更重要地要準確地填回參數所在的位置。
上面的例子只是為了說明概念,舉了最簡單的示例,實際情況中參數的綁定情況遠比這個復雜。我么將在后面的文章中展示相對復雜的實際示例,并詳細說明數據庫安全審計技術對各類參數化語句的解析原理,能夠更實際的看到數據庫審計結果的準確度差異。