最近,網(wǎng)上頻繁出現(xiàn)了關(guān)于php join攻擊的報道,引發(fā)了人們對于php應(yīng)用程序的注重。如果說網(wǎng)站是門房,那么php就是門衛(wèi),對于違法的請求進行攔截。然而,對于join攻擊絕不容忍。那么php join攻擊具體是什么呢?
簡單來說,join攻擊就是攻擊者利用join條件不嚴(yán)謹(jǐn),在請求多表查詢時使用特定代碼獲取被攻擊網(wǎng)站的數(shù)據(jù)。攻擊者可以通過拼接join條件,語句注入或其他手段從而達到竊取用戶信息、服務(wù)器敏感信息等目的。
比如下面這段代碼:
$sql = "SELECT a.*, b.* FROM table_a a join table_b b ON a.id = b.id WHERE a.name = '".$_REQUEST['name']."'"; mysql_query($sql);
攻擊者就可以通過修改參數(shù)name來進行數(shù)據(jù)竊取。例如輸入以下字串:
tom' union select 1, 2, 3, 4, 5, 6, user(), 8,9,10,11 --+
形成的sql語句為:
SELECT a.*, b.* FROM table_a a join table_b b ON a.id = b.id WHERE a.name = 'tom' union select 1, 2, 3, 4, 5, 6, user(), 8,9,10,11 --+'
攻擊者就可以獲得頁面上的用戶信息和服務(wù)器端信息。
另外,下面這個是比較難以發(fā)現(xiàn)的join注入方式。假設(shè)有兩張表a和b,查詢a表中的一個字段時我們使用了連接b表來查找。有一個關(guān)聯(lián)條件是a.id=b.id,這個條件阻止了除了擁有a.id值的記錄之外的所有b表記錄的顯示,因為id只存在于a表中。
SELECT a.*, b.* FROM table_a a left join table_b b ON a.id = b.id WHERE a.name = '".$_REQUEST['name']."'
這個查詢的關(guān)聯(lián)條件也很容易成為攻擊者的目標(biāo)。當(dāng)看到這樣的代碼時,他們可以通過以下的方式進行注入:
bob' and extractvalue(1, concat(0x3a, (select column_name from information_schema.columns where table_name='a' limit 0,1), 0x3a)) --+
經(jīng)過注入后的SQL語句會變成如下所示:
SELECT a.*, b.* FROM table_a a left join table_b b ON a.id = b.id WHERE a.name = 'bob' and extractvalue(1, concat(0x3a, (select column_name from information_schema.columns where table_name='a' limit 0,1), 0x3a)) --+
上面的語句中,攻擊者試圖獲取a表第一個列的列名。因為查詢中的關(guān)聯(lián)條件并不要求b.id必須等于a.id,所以攻擊者可以通過這種方式竊取服務(wù)器敏感信息。
一般可以通過以下幾種措施來避免php join攻擊:
1. 盡量避免直接拼接sql語句,使用prepare語句查詢數(shù)據(jù)庫。$stmt = $db->prepare("SELECT a.*, b.* FROM table_a a join table_b b ON a.id = b.id WHERE a.name = ?"); $stmt->bind_param("s", $_REQUEST['name']); $stmt->execute();2. 檢查傳入的參數(shù),避免特殊字符和附加代碼。
$name = mysql_real_escape_string($_REQUEST['name']); $sql = "SELECT a.*, b.* FROM table_a a join table_b b ON a.id = b.id WHERE a.name = '$name'";
以上是php join攻擊的簡介及對策。