引言 隨着互聯網的發展,人們在享受互聯網帶來的便捷的服務的時候,也面臨着我的的隱私泄漏的問題。小到一個擁有用戶系統的小型論壇,大到各個大型的銀行機構,互聯網安全問題都顯得格外重要。而這些網站的背後,則是支撐整個服務的核心數據庫。能夠說數據庫就是這些服務的命脈,沒有數據庫,也就無從談起這些服務了。 對於數據庫系統的安全特性,主要包括數據獨立性、數據安全性、數據完整性、併發控制、故障恢復等方面。而這些裏面顯得比較重要的一個方面是數據的安全性。因爲開發人員的設計不周到,以及數據庫的某些缺陷,很容易讓黑客發現系統的漏洞,從而形成巨大的損失。 接下來本文將會介紹很是常見的一種攻擊數據庫的方法:SQL注入,以及使用在項目使用Java開發的狀況下如何使用SpringMVC的攔截器實現防止SQL注入的功能。 SQL注入 SQL注入簡介 通俗的講,SQL注入就是惡意黑客或者競爭對手利用現有的B/S或者C/S架構的系統,將惡意的SQL語句經過表單等傳遞給後臺SQL數據庫引擎執行。好比,一個黑客能夠利用網站的漏洞,使用SQL注入的方式取得一個公司網站後臺的全部數據。試想一下,若是開發人員不對用戶傳遞過來的輸入進行過濾處理,那麼遇到惡意用戶的時候,而且系統被發現有漏洞的時候,後果將是使人不可思議的。最糟糕的是攻擊者拿到了數據庫服務器最高級的權限,能夠對整個數據庫服務器的數據作任何操做。 一般狀況下,SQL注入攻擊通常分爲如下幾個步驟: 判斷WEB環境是否能夠注入SQL。對於一個傳統的WEB網頁來講,若是是一個簡單的靜態頁面,好比地址爲http://www.news.com/100.html的網頁,這是一個簡單的靜態頁面,通常不涉及對數據庫的查詢。而若是這個網頁的網址變成了:http://www.news.com/news.asp?id=100 那麼,這就是一個根據主鍵id來查詢數據的動態網頁了。攻擊者每每可以在 id=100的後面加上一些本身的SQL,用來「欺騙」過應用程序。 尋找SQL注入點。當攻擊者肯定某個頁面可使用SQL注入以後,他通常會尋找能夠SQL注入的點。而這些點每每就是網頁或者應用程序中的用於向服務器發送用戶數據的表單了。通常的流程是,客戶端經過這些表單發送一些用戶信息的字段,好比用戶名和密碼,接着服務器就會根據這些字段去查詢數據庫。而若是用戶輸入了一些非法的字符,好比’這個符號,那麼在SQL解析的時候,解析的結果可能並非應用開發人員想象中那樣。 尋找系統的後臺。這一點就創建在破壞者對整個系統的瞭解程度上面了,若是攻擊者對整個系統瞭如指掌,那麼實現攻擊也就是一件很簡單的事情了。 入侵和破壞。當攻擊者攻破系統以後,整個系統從某種意義上來說已經失去意義了。 SQL注入案例 一個簡單的PHP登陸驗證SQL注入 好比一個公司有一個用來管理客戶的客戶管理系統,在進入後臺進行管理的時候須要輸入用戶名和密碼。 假設在客戶端傳給服務器的字段分別爲用戶名username和密碼password,那麼若是用來處理登陸的服務器端代碼對用戶的輸入作如下處理: 上面的PHP代碼就是首先獲取客戶端POST過來的填寫在表單裏面的用戶名和密碼,接着要MySQL去執行下面這條SQL語句: SELECT `id` FROM `users` WHERE `username` = username AND `password` = password; 能夠看到上面的代碼沒有對用戶的輸入作任何的過濾,這是很是容易遭到黑客攻擊的。 好比,一個用戶在輸入用戶名的輸入框裏面輸入了 user’;SHOW TABLES;-- 那麼就會解析爲下面的SQL: SELECT `id` FROM `users` WHERE `username` = ‘user’;SHOW TABLES;-- AND `password` = password; 能夠看到被解析的SQL被拆分爲了2條有用的SQL: (1)SELECT `id` FROM `users` WHERE `username` = ‘user’; (2)SHOW TABLES; 然後面驗證密碼的部分就被註釋掉了。這樣攻擊者就輕鬆的得到了這個數據庫裏面的全部表的名字。一樣的道理,若是攻擊者在輸入框裏面輸入: ’;DROP TABLE [table_name];-- 那麼,這一張表就被刪除了,可見後果是很是嚴重的。 而用戶若是在用戶名輸入框裏面輸入了:user’or 1=1-- 那麼會被解析成: SELECT `id` FROM `users` WHERE `username` = ‘user’ or 1=1-- AND `password` = password; 這裏能夠看到1=1永遠爲真,這樣不用輸入用戶名就直接能夠登入系統了。 一個ASP新聞動態頁面的id查詢 好比有一個新聞網站的動態頁面是這種格式: http://www.news.com/news.asp?id=100 那麼當用戶在瀏覽器的地址框裏面輸入 http://www.news.com/news.asp?id=100;and user>0 那麼若是這個網站的數據庫用的是SQL Server的話,那麼SQL Server在解析的時候,因爲user是SQL Server的一個內置變量,它的值就是當前鏈接數據庫的用戶,那麼SQL在執行到這裏的時候會拿一個類型爲nvarchar的和一個int類型的比較。比較過程當中就必然涉及類型的轉化,然而不幸的是,轉化過程並非一路順風,出錯的時候SQL Server將會給出相似將nvarchar值」aaa」轉爲爲int的列時發生語法錯誤。這個時候攻擊者就輕鬆的得到了數據庫的用戶名。 SpringMVC攔截器防止SQL注入 爲了有效的減小以及防止SQL注入的攻擊,開發人員在開發的時候必定不要期待用戶的輸入都是合理的,當用戶輸入完畢以後,應該嚴謹的對用戶提交的數據進行格式上的檢查以及過濾,儘量的減小被注入SQL 的風險。 通常來講,不一樣的服務器端語言都有不一樣的解決方案。好比拿中小型企業採用得最多的PHP語言來講,PHP的官方就爲開發者提供了這樣的一些函數,好比mysql_real_escape_string()等。 接下來會詳細介紹如何經過SpringMVC的攔截器實現防止SQL注入的功能。 這裏以個人大數據人才簡歷庫的攔截器爲例。 自定義攔截器類實現HandlerInterceptor接口 package com.data.job.util.interceptor; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Enumeration; /** * 防止SQL注入的攔截器 * * @author tyee.noprom@qq.com * @time 2/13/16 8:22 PM. */ public class SqlInjectInterceptor implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception { Enumeration names = request.getParameterNames(); while (names.hasMoreElements()) { String name = names.nextElement(); String[] values = request.getParameterValues(name); for (String value : values) { value = clearXss(value); } } return true; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object o, ModelAndView modelAndView) throws Exception { } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) throws Exception { } /** * 處理字符轉義 * * @param value * @return */ private String clearXss(String value) { if (value == null || "".equals(value)) { return value; } value = value.replaceAll("<", "<").replaceAll(">", ">"); value = value.replaceAll("\\(", "(").replace("\\)", ")"); value = value.replaceAll("'", "'"); value = value.replaceAll("eval\\((.*)\\)", ""); value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\""); value = value.replace("script", ""); return value; } } 配置攔截器 SQL注入總結 安全問題從古至今都有着很是高的關注度,現在互聯網高速發達,各類網絡應用層出不窮。不論是如今煊赫一時的雲計算和大數據,仍是傳統的B/S或者C/S架構的網絡應用,數據的安全性是相當重要的。從應用層面來說,網絡應用的開發者能夠經過完善軟件的架構,儘可能減小由於BUG而致使的數據泄漏的問題。開發者能夠不斷的審視與完善本身的系統,站在攻擊者的角度上去開發某些關鍵的安全性要求比較高的環節,如銀行支付部分等,這樣可以在必定程度上面減小SQL注入等應用層面攻擊數據庫的風險。
做者: noprom
連接:http://www.imooc.com/article/6137
來源:慕課網javascript