一個關於SQL隱碼攻擊的簡單例子

陳俊成發表於2016-09-21

什麼是SQL隱碼攻擊?
SQL隱碼攻擊是利用某些資料庫的外部介面將使用者資料插入到資料庫的操作語言中,從而達到入侵資料庫乃至作業系統的目的。


資料庫有一張user表;表定義如下:

CREATE TABLE `user` (
  `id` char(35) NOT NULL,
  `mobile_num` char(20) NOT NULL,
  `user_name` char(30) DEFAULT NULL,
  `password` char(100) NOT NULL,
  `has_card` tinyint(1) NOT NULL DEFAULT '0',
  `salt` char(15) DEFAULT NULL,
  `token` char(65) DEFAULT NULL,
  `is_valid` tinyint(4) NOT NULL DEFAULT '1',
  PRIMARY KEY (`id`),
  UNIQUE KEY `mobile_num_UNIQUE` (`mobile_num`),
  UNIQUE KEY `user_name_UNIQUE` (`user_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

表結構如下:
這裡寫圖片描述

表中有這麼1行資料:
這裡寫圖片描述

進行普通登入操作時候,會講賬號和密碼作為引數傳進去,比如:

SELECT *
FROM USER
WHERE user_name='   '
AND PASSWORD='   ';

普通使用者會進行正常的輸入,這樣會得到正確的結果,如下:

SELECT *
FROM USER
WHERE user_name='username6'
AND PASSWORD='2d1e482bc247a2540cfe1679f93365f8';

但惡意使用者會根據MySQL的特性,只要知道使用者名稱,無需知道密碼就能查詢到資料,比如:

SELECT *
FROM USER
WHERE user_name='username6' OR '1=1' AND PASSWORD='222';

即,使用者在username的空格上只要填上:username6' OR '1=1;在password的空格上隨便填寫一串資料即可。(注意’1=1’只是一個varchar)


那如何去防止SQL隱碼攻擊呢?
在JAVA中可以採用預編譯的方法,儘量不要採用連線SQL語句的方法。例如:

String sql = "select * from user u where u.username=? and u.password=?";

preparedstatement ps = connection.preparestatement(sql);
ps.setString(1, "username5");
ps.setString(2, "aaa")

或者,自定義函式把前端資料的引數進行過濾,(1)拒絕已知的非法資料;(2)只接受已知的正確輸入

相關文章