Web 安全淺談

1.1系統安全

1.1.1 客戶端腳本安全

(1)跨站腳本攻擊(XSS):


XSS攻擊,通常指黑客通過“html注入” 篡改了網頁,插入了惡意的腳本,從而在用戶瀏覽網頁的時候,控制用戶瀏覽器的一種攻擊。

最常見的XSS攻擊就是通過讀取瀏覽器的Cookie對象,從而發起“cookie劫持”,當前用戶的登錄憑證存儲於服務器的session中,而在瀏覽器中是以cookie的形式進行存儲的,cookie被劫持後,意味着攻擊者可以不通過密碼而直接登錄系統。我們也可以直接在瀏覽器中輸入腳本javascript:alert(document.cookie)來獲取當前cookie值。

目前防止“cookie劫持”的方法大致有:a. 輸入檢查,使用filter來過濾敏感的關鍵字;b. 將cookie與用戶ip地址進行綁定;c. 爲cookie植入HttpOnly標識。

   本系統採用的是第3種方式:爲cookie植入HttpOnly標識。一旦這個HttpOnly被設置,你在瀏覽器的 document對象中就看不到Cookie了,而瀏覽器在瀏覽的時候不受任何影響,因爲Cookie會被放在瀏覽器頭中發送出去(包括ajax的時 候),應用程序也一般不會在js裏操作這些敏感Cookie的,對於一些敏感的Cookie我們採用HttpOnly,對於一些需要在應用程序中用js操作的cookie我們就不予設置,這樣就保障了Cookie信息的安全也保證了應用。

具體代碼實現:在web服務器tomcat的配置文件server.xml中添加:

<Context docBase="E:\tomcat\apache-tomcat-6.0.24/webapps/netcredit" path="/netcredit" reloadable="false" useHttpOnly="true"/>
或者在項目的web.xml 配置如下:

<session-config>

         <cookie-config> 

           <http-only>true</http-only> 

        </cookie-config>

  </session-config>



     圖1-1 瀏覽器cookie截圖

(2)跨站點請求僞造(CSRF):


本系統採用了對抗CSRF最有效的防禦方法:驗證碼。

1.1.2 服務器端應用安全


服務器端的安全相對於客戶端來說顯的更加的重要,因爲服務器端的某個安全漏洞可能帶來的是致命的危險。因此我們對服務器端的安全更爲的慎重和重視。

(1)SQL注入攻擊:


Sql注入的的兩個關鍵條件:第一個是用戶能夠控制輸入;第二個是原本程序要執行的代碼,拼接了用戶輸入的數據。

根據上面兩個關鍵條件,系統爲防止sql注入使用了以下方法:

第一:使用預編譯語句,這也是防禦sql注入最有效的方法,完全摒棄代碼的直接拼接所帶來的危險。

public List<T> findByPage(final String hql, final Object[] values, final int offset,

           final int pageSize) {

       List<T> list = getHibernateTemplate().executeFind(new HibernateCallback(){

           public Object doInHibernate(Session session)

              throws HibernateException, SQLException{

              Query query=session.createQuery(hql);

              for (int i = 0 ; i < values.length ; i++){

                  query.setParameter( i, values[i]);

              }

              if(!(offset==0 && pageSize==0)){

                  query.setFirstResult(offset).setMaxResults(pageSize);

              }

              List<T> result = query.list();

              return result;

           }

       });

    return list;

    }      

第二:關閉web服務器的錯誤回顯功能,這樣可以防止攻擊者對系統進行攻擊後,通過回顯的詳細錯誤信息對攻擊內容進行調整,對攻擊者提供極大的便利。我們在項目的web.xml文件中添加以下示例代碼:
<error-page>

        <error-code>400</error-code>

        <location>/error400.jsp</location>

    </error-page>

第三:數據庫自身使用最小權限原則,系統程序不使用最高權限的root對數據庫進行連接,而是使用能滿足系統需求的最小權限賬戶進行數據庫連接,而且多個數據庫之間使用不同的賬戶,保證每個數據庫都有獨立對應的賬戶。


(2)文件上傳漏洞:


文件上傳漏洞是指用戶上傳了一個可執行的腳本文件,並通過腳本文件獲得了執行服務器端命令的能力,這樣將會導致嚴重的後果。而本系統內涉及到大量的圖片格式文件上傳,因此對於上傳問題的處理非常謹慎,並儘可能的達到安全標準。

本系統主要通過對上傳文件詳細的格式驗證:

第一步:通過後綴名來簡單判斷文件的格式。

public static boolean isPicture(String pInput) throws Exception{

      // 獲得文件後綴名

      String tmpName = pInput.substring(pInput.lastIndexOf(".") + 1,

                                  pInput.length());

      // 聲明圖片後綴名數組

      String imgeArray [] = { "jpg", "png", "jpeg" };

      // 遍歷名稱數組

      for(int i = 0; i<imgeArray.length;i++){ 

          // 判斷符合全部類型的場合

          if(imgeArray [i].equals(tmpName.toLowerCase())){

              return true;

          }

        }

      return false;

    }

第二步:通過讀取文件的前兩個字符進行對比,例如png格式圖片的前兩個字符爲8950,而jpg格式的圖片前兩個字符爲ffd8。

public static String bytesToHexString(byte[] src) {

        StringBuilder stringBuilder = new StringBuilder();

        if (src == null || src.length <= 0) {

            return null;

        }

        for (int i = 0; i < src.length; i++) {

            int v = src[i] & 0xFF;//byte to int

            String hv = Integer.toHexString(v);

            if (hv.length() < 2) {

                stringBuilder.append(0);

            }

            stringBuilder.append(hv);

        }

        return stringBuilder.toString();

    }  
第三步:如果上傳的爲圖片,則獲取相應的高度和寬度,如果存在相應的寬度和高度則可認爲上傳的是圖片。
public static boolean isImage(File imageFile) {

        if (!imageFile.exists()) {

            return false;

        }

        Image img = null;

        try {

            img = ImageIO.read(imageFile);

            if (img == null || img.getWidth(null) <= 0 || img.getHeight(null) <= 0) {

                return false;

            }

            return true;

        } catch (Exception e) {

            return false;

        } finally {

            img = null;

        }

   }
如果以上驗證都成功通過,本系統在對文件進行存儲時會將文件名進行重命名處理,並且設置相應的web服務器,默認不顯示目錄。因爲文件上傳如果需要執行代碼,則需要用戶能夠訪問到這個文件,因此使用隨機數改寫了文件名,將極大的增加攻擊的成本,甚至根本無法成功實施攻擊。

//對文件的名稱進行重命名

StringBuilder sb = new StringBuilder().append(new Date().getTime()).append(".").append(fileMsg[1]);

(3)認證與會話管理:


  認證實際上就是一個驗證憑證的過程,因此我們對登錄密碼有着嚴格的規定:密碼要求長度在8位以上並且包含字母,數字,符號兩種以上的組合。並將密碼加密後再進行數據庫的存儲。爲防止一些暴力破解手段,又出於用戶體驗的考慮,本系統採用用戶登錄時默認不進行驗證碼的輸入,但密碼三次輸入失敗後需要進行驗證碼的輸入,連續五次輸入錯誤後,該用戶的ip地址將被封,可以在一段時間後自動解封或者後臺管理員手動解封。涉及到系統資金有關的操作,例如投標,我們還需要用戶設置並提供支付密碼,而提現等操作我們還配備短信驗證碼功能。以此來增強驗證的可靠性。

  當用戶登錄完成後,在服務器端會創建一個新的會話(Session),會話中保存着用戶的狀態和相關信息,服務器端維護所有在線用戶的Session,而瀏覽器則是將SessionId加密後保存在cookie中,這裏就出現了前面提到了“cookie劫持“問題,本系統通過將cookie中植入HttpOnly成功解決該問題。本系統還給Session設置了一個有效時間,來保證在有效時間後Session將自動銷燬,以防止Session長連接所帶來的安全隱患。在web.xml文件中添加以下代碼:
<session-config>

     <session-timeout>30</session-timeout>

</session-config>

(4)訪問控制:


訪問控制實際上就是建立用戶和權限之間的對應關係,本系統採用的是“基於角色的訪問控制”,根據相應功能模塊的劃分相應的權限,並將相應的權限分配給不同的角色,再將角色分配給用戶,用戶就擁有了該角色所持有的權限。具體的設計與實現分析請見1.2 Annotation和Struts2攔截器實現基於角色的垂直權限管理。



更多可見鏈接。

轉自:http://www.cnblogs.com/shenliang123/p/3835116.html


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章