XSS的全稱是跨站腳本(Cross Site Scripting),是WEB應用程序中最多見到的手段之一。跨站腳本指的是者在網頁中嵌入惡意腳本程序, 當用戶打開該網頁時,腳本程序便開始在客戶端的瀏覽器上執行,以盜取客戶端cookie、 盜取用戶名密碼、下載執行病毒程序等等。java
爲了避免和層疊樣式表 (Cascading Style Sheets,CSS)的縮寫混淆,故將跨站腳本縮寫爲XSSsql
有一種場景,用戶在表單上輸入一段數據後,提交給服務端進行持久化,其餘頁面上須要從服務端將數據取出來展現。仍是使用以前那個表單nick,用戶輸入暱稱以後,服務端會將nick保存,並在新的頁面展示給用戶,當普通用戶正常輸入hollis,頁面會顯示用戶的 nick爲hollis:數據庫
<body> hollis </body>
可是,若是用戶輸入的不是一段正常的nick字符串,而是<script>alert("haha")</script>, 服務端會將這段腳本保存起來,當有用戶查看該頁面時,頁面會出現以下代碼:編程
<body> <script> alert("haha") </script> </body>
其影響就是可能會在頁面直接彈出對話框。後端
XSS之因此會發生,是由於用戶輸入的數據變成了代碼。所以,咱們須要對用戶輸入的數據進行HTML轉義處理,將其中的「尖括號」、「單引號」、「引號」 之類的特殊字符進行轉義編碼。瀏覽器
現在不少開源的開發框架自己默認就提供HTML代碼轉義的功能,如流行的jstl、Struts等等,不須要開發人員再進行過多的開發。使用jstl標籤進行HTML轉義,將變量輸出,代碼 以下:緩存
<c:out value="${nick}" escapeXml="true"></c:out>
安全
只須要將escapeXml設置爲true, jstl就會將變量中的HTML代碼進行轉義輸出。服務器
CSRF的全稱是跨站請求僞造(cross site request forgery), 是一種對網站的惡意利用,你能夠這麼理解CSRF者盜用了你的身份,以你的名義向第三方網站發送惡意請求。CRSF能作的事情包括利用你的身份發郵件、發短信、進行交易轉帳等等,甚至盜取你的帳號。cookie
儘管聽起來跟XSS跨站腳本有點類似,但事實上CSRF與XSS差異很大,XSS利用的是站點內的信任用戶,而CSRF則是經過假裝來自受信任用戶的請求來利用受信任的網站。
假設某銀行網站A,他以GET請求來發起轉帳操做,轉帳的地址爲www.xxx.com/transfer.do?accountNum=10001&money=10000,accountNum參數表示轉帳的目的帳戶,money參數表示轉帳金額。 而某大型論壇B上,一個惡意用戶上傳了一張圖片,而圖片的地址欄中填的並非圖片的地址,而是前面所說的轉帳地址:
<img src="http://www.xxx.com/transfer.do?accountNum=10001&money=10000">
當你登錄網站A後,沒有及時登出,這個時候你訪問了論壇B,不幸的事情發生了,你會發現你的帳戶裏面少了10000塊......
爲何會這樣呢,在你登錄銀行A的時候,你的瀏覽器端會生成銀行A的cookie,而當你訪問論壇B的時候,頁面上的<img>標籤須要瀏覽器發起一個新的HTTP請求,以得到圖片資源, 當瀏覽器發起請求的時候,請求的倒是銀行A的轉帳地址www.xxx.com/transfer.do?accoun tNum=10001&money=10000,而且會帶上銀行A的cookie信息,結果銀行的服務器收到這個請求後,會認爲是你發起的一次轉帳操做,所以你的帳戶裏邊便少了10000塊。
cookie設置爲HttpOnly
CSRF很大程度上是利用了瀏覽器的cookie,爲了防止站內的XSS漏洞盜取cookie,須要在cookie中設置"HttpOnly"屬性,這樣經過程序(如JavascriptS腳本、Applet等)就沒法讀取到cookie信息,避免了者僞造cookie的狀況出現。
增長token
CSRF之因此可以成功,是由於者能夠僞造用戶的請求,該請求中全部的用戶驗證信息都存在於cookie中,所以者能夠在不知道用戶驗證信息的狀況下直接利用用戶的cookie來經過安全驗證。由此可知,抵禦CSRF的關鍵在於:在請求中放入者所不能僞造的信息,而且該信息不存在於cookie之中。鑑於此,系統開發人員能夠在HTTP請求中以參數的形式加入一個隨機產生的token,並在服務端進行token校驗,若是請求中沒有token或者token內容不正確,則認爲是CSRF而拒絕該請求。
經過Referer識別
根據HTTP協議,在HTTP頭中有一個字段叫Referer,它記錄了該HTTP請求的來源地址。在一般狀況下,訪問一個安全受限頁面的請求都來自於同一個網站。好比某銀行的轉帳是經過用戶訪問http://www.xxx.com/transfer.do頁面完成,用戶必須先登陸www.xxx.com,而後經過點擊頁面上的提交按鈕來觸發轉帳事件。當用戶提交請求時,該轉帳請求的Referer值就會是提交按鈕所在頁面的URL(本例爲www.xxx.com/transfer.do)。若是者要對銀行網站實施CSRF,他只能在其餘的網站構造請求,當用戶經過其餘網站發送請求到銀行時,該請求的Referer的值是其餘網站的地址,而不是銀行轉帳頁面的地址。所以,要防護CSRF,銀行網站只須要對於每個轉帳請求驗證其Referer值,若是是以www.xxx.com域名開頭的地址,則說明該請求是來自銀行網站本身的請求,是合法的。若是 Referer是其餘網站的話,就有多是CSRF,則拒絕該請求。
所謂SQL注入,就是經過把SQL命令假裝成正常的HTTP請求參數,傳遞到服務端,欺騙服務器最終執行惡意的SQL命令,達到目的。者能夠利用SQL注入漏洞,查詢非受權信息, 修改數據庫服務器的數據,改變表結構,甚至是獲取服務器root權限。總而言之,SQL注入漏洞的危害極大,者採用的SQL指令,決定的威力。當前涉及到大批量數據泄露的事件,大部分都是經過利用SQL注入來實施的。
假設有個網站的登陸頁面,以下所示:
假設用戶輸入nick爲zhangsan,密碼爲password1,則驗證經過,顯示用戶登陸:
不然,顯示用戶沒有登陸:
**下面是一段普通的JDBC的Java代碼,這段代碼就能夠被利用,進行SQL注入*:
Connection conn = getConnection(); String sql = "select * from hhuser where nick = '" + nickname + "'" + " and passwords = '" + password + "'"; Statement st = (Statement) conn.createStatement(); ResultSet rs = st.executeQuery(sql); List<UserInfo> userInfoList = new ArrayList<UserInfo>(); while (rs.next()) { UserInfo userinfo = new UserInfo(); userinfo.setUserid(rs.getLong("userid")); userinfo.setPasswords(rs.getString("passwords")); userinfo.setNick(rs.getString("nick")); userinfo.setAge(rs.getInt("age")); userinfo.setAddress(rs.getString("address")); userInfoList.add(userinfo); }
當用戶輸入nick爲zhangsan,密碼爲' or '1'='1的時候,意想不到的事情出現了,頁面顯示爲login狀態:
當用戶在密碼欄輸入「' or '1'='1」後,代碼中的SQL語句就會被拼接成:
"select * from hhuser user where nick = 'zhangsan' and passwords = '' or '1'='1'",由於or後面的1=1是恆爲true的,因此,該語句的執行結果就會有正常的數據返回。從而繞過密碼校驗。
以上即是一次簡單的、典型的SQL注入。固然,SQL注入的危害不只如此,假設用戶輸入用戶名zhangsan,在密碼框輸入' ;drop table aaa;-- 會發生什麼呢?
使用預編譯語句
預編譯語句PreparedStatement是java.sql中的一個接口,繼承自Statement接口。經過 Statement對象執行SQL語句時,須要將SQL語句發送給DBMS,由DBMS先進行編譯後再執行。而預編譯語句和Statement不一樣,在建立PreparedStatement對象時就指定了SQL語句,該語句當即發送給DBMS進行編譯,當該編譯語句須要被執行時,DBMS直接運行編譯後的SQL語句,而不須要像其餘SQL語句那樣首先將其編譯。
前面介紹過,引起SQL注入的根本緣由是惡意用戶將SQL指令假裝成參數傳遞到後端數據庫執行, 做爲一種更爲安全的動態字符串的構建方法,預編譯語句使用參數佔位符來替代須要動態傳入的參數,這樣者沒法改變SQL語句的結構,SQL語句的語義不會發生改變,即使用戶傳入相似於前面' or '1'='1這樣的字符串,數據庫也會將其做爲普通的字符串來處理。
使用ORM框架
由上文可見,防止SQL注入的關鍵在於對一些關鍵字符進行轉義,而常見的一些ORM框架,如 ibatis、hibernate等,都支持對相應的關鍵字或者特殊符號進行轉義,能夠經過簡單的配置, 很好的預防SQL注入漏洞,下降了普通的開發人員進行安全編程的門檻。 Ibatis的insert語句配置:
<insert id="insert" parameterClass="userDO">
insert into users(gmt_create,gmt_modified,userid,user_nick,address,age,sex) values(now(),now(),#userId#,#userNick#,#address#,#age#,#sex#)
</insert>
經過#符號配置的變量,ibatis可以對輸入變量的一些關鍵字進行轉義,防止SQL注入***。
避免密碼明文存放
對存儲的密碼進行單向Hash,如使用MD5對密碼進行摘要,而非直接存儲明文密碼,這樣的好處就是萬一用戶信息泄露,即圈內所說的被「」,沒法直接獲取用戶密碼,而只能獲得一串跟密碼相差十萬八千里的Hash碼。
處理好相應的異常
後臺的系統異常,極可能包含了一些如服務器版本、數據庫版本、編程語言等等的信息,甚至是數據庫鏈接的地址及用戶名密碼,者能夠按圖索驥,找到對應版本的服務器漏洞或者數據庫漏洞進行,所以,必需要處理好後臺的系統異常,重定向到相應的錯誤處理頁面,而不是任由其直接輸出到頁面上。
在上網的過程當中,咱們常常會將一些如圖片、壓縮包之類的文件上傳到遠端服務器進行保存, 文件上傳指的是惡意者利用一些站點沒有對文件的類型作很好的校驗這樣的漏洞, 上傳了可執行的文件或者腳本,而且經過腳本得到服務器上相應的權利,或者是經過誘導外 部用戶訪問或者下載上傳的病毒或者文件,達到目的。
爲了防範用戶上傳惡意的可執行文件和腳本,以及將文件上傳服務器當作免費的文件存儲服務器使用,須要對上傳的文件類型進行白名單(非黑名單,這點很是重要)校驗,而且限制上傳文件的大小,上傳的文件,須要進行從新命名,使者沒法猜想到上傳文件的訪問路徑。
對於上傳的文件來講,不能簡單的經過後綴名稱來判斷文件的類型,由於惡意能夠將可執行文件的後綴名稱改爲圖片或者其餘的後綴類型,誘導用戶執行。所以,判斷文件類型須要使用更安全的方式。不少類型的文件,起始的幾個字節內容是固定的,所以,根據這幾個字節的內容,就能夠肯定文件類型,這幾個字節也被稱爲魔數(magic number)。
DDoS(Distributed Denial of Service),即分佈式拒絕服務,是目前最爲強大、最難以防護的方式之一。前不久(2018-03-01),GitHub就遭受了一次比較嚴重的DDoS,個人文章《GitHub遭受的DDoS究竟是個什麼鬼?》中有關於此次和DDoS的詳細介紹。這裏再也不贅述。
DDoS的有不少種類型,如依賴蠻力的ICMP Flood、UDP Flood等等,隨着硬件性能的提高,須要的機器規模愈來愈大,組織大規模的愈來愈困難,如今已經不常見,還有就是依賴協議特徵以及具體的軟件漏洞進行的,如Slowloris,Hash碰撞等等,這類主要利用協議以及軟件漏洞發起,須要在特定環境下才會出現,更多的者採用的是前面兩種的混合方式,即利用了協議、系統的缺陷,又具有了海量的流量, 如SYN Flood、DNS Query Flood等等。
DNS Query Flood其實是UDP Flood的一種變形,因爲DNS服務在互聯網中不可替代的做用,一旦DNS服務器癱瘓,影響甚大。
DNS Query Flood採用的方法是向被的服務器發送海量的域名解析請求,一般,請求解析的域名是隨機生成,大部分根本就不存在,而且經過僞造端口和客戶端IP,防止查詢請求被ACL過濾。被的DNS服務器在接收到域名解析請求後,首先會在服務器上查找是否有對應的緩存, 因爲域名是隨機生成的,幾乎不可能有相應的緩存信息,當沒有緩存,而且該域名沒法直接由該DNS服務器進行解析的時候,DNS服務器會向其上層DNS服務器遞歸查詢域名信息,直到全球互聯網的13臺根DNS服務器。大量不存在的域名解析請求,給服務器帶來了很大的負載,當解析請求超過必定量的時候,就會形成DNS服務器解析域名超時,這樣者便達成了目的。
CC(Challenge Collapsar)屬於DDoS的一種,是基於應用層HTTP協議發起的DDos,也被稱爲HTTP Flood。
CC的原理是這樣的,者經過控制的大量「肉雞」或者利用從互聯網上搜尋的大量匿名的HTTP代理,模擬正經常使用戶給網站發起請求直到該網站拒絕服務爲止。大部分網站會經過CDN以及分佈式緩存來加快服務端響應,提高網站的吞吐量,而這些精心構造的HTTP請求每每有意避開這些緩存,須要進行屢次DB查詢操做或者是一次請求返回大量的數據,加速系統 資源消耗,從而拖垮後端的業務處理系統,甚至連相關存儲以及日誌收集系統也沒法倖免。
喜歡的能夠關注個人公衆號,java小瓜哥的分享平臺,平時整理的資料都放在裏面了