• 網站安全框架ESAPI 使用介紹-上集

    OWASP 定義網站十大威脅,

    針對這十大威脅的防護設計與編碼有沒有現有的程式框架或是lib 可以使用?

    這就是 ESAPI 誕生的原因, 因為它提供許多程式語言程式庫,

    讓程式開發者只要使用相關的函數就可以達到網站安全的防護

    這篇文章針對十大威脅與ESAPI的使用做介紹

    A1. XSS Cross-Site Scripting

    要有效防止 XSS 的攻擊, 必須做到

    1. 輸入資料的驗證

    2. 輸出資料的編碼 (一定要)

    這邊特別強調就算輸入資料已經有所驗證, 輸出資料的編碼還是一定要!

    ESAPI 輸入資料驗證範例

    String validatedFirstName = ESAPI.validator().getValidInput("FirstName",
    	myForm.getFirstName(), "FirstNameRegex", 255, false, errorList);
    boolean isValidFirstName = ESAPI.validator().isValidInput("FirstName",
    	myForm.getFirstName(), "FirstNameRegex", 255, false);

    哪些HTML的輸出需要編碼呢?

    • 1. HTML entity
    • 2. HTML Attribute
    • 3. JavaScript
    • 4. CSS
    • 5. URL

    ESAPI Output Encoding

    ESAPI 輸出編碼範例

    //performing output encoding for the HTML context
    String safeOutput = ESAPI.encoder().encodeForHTML( clean encoded output Comment );

    A2. SQL Injection 的攻擊

    下列程式範例就會受到 SQL Injection 攻擊, 因為整個SQL 語句是由輸入變數動態產生

    String sqlString = "SELECT * FROM users WHERE fullname = '"
        + form.getFullName() + "' AND password = '" + form.getPassword() + "'";

    防護的方式通常建議

    1. Prepared Statement

    myPrepStmt = conn.prepareStatement("SELECT name FROM users WHERE id = ?");
    myPrepStmt.setInt(1, userID);

    2. ESAPI

    如果使用 ESAPI 範例如下, 將使用者輸入的參數編碼後再執行

    //ESAPI version of query
    Codec ORACLE_CODEC = new OracleCodec();		//we're using oracle
    String query = "SELECT name FROM users WHERE id = " +
       ESAPI.encoder().encodeForSQL( ORACLE_CODEC, validatedUserId)
       + " AND date_created >= '"
       + ESAPI.encoder().encodeForSQL( ORACLE_CODEC, validatedStartDate) +"'";
    myStmt = conn.createStatement(query);

    A3. 檔案上傳攻擊

    當網站提供檔案上傳時, 也間接開放一個駭客攻擊的管道

    可能遇到的風險與防護方式列舉如下

    檔案上傳風險 防護建議
    檔名與路徑輸入的驗證我們當然不希望駭客上傳“../../etc/passwd”覆蓋系統的密碼檔案
    可以使用ESAPI對檔名進行驗證
    ESAPI.validator().isValidFileName
    病毒掃描 ESAPI沒有提供掃毒功能這部分通常靠防毒軟體協助
    檔案大小檢查
    ServletFileUpload upload = new ServletFileUpload(factory);
    
    upload.setSizeMax(maxBytes);
    檔案型態檢查 isValidFileContentisValidFileUpload
    Direct object reference (DOR)直接被存取的問題 檔案上傳之後, 我們通常會將檔名編碼, 主要不讓使用者可以很容易的透過檔名就可以存娶自己或是其他人上傳的檔案因此就會利用到當檔案名稱對應到資源ID的方式建置方式.
    授權存取 ESAPI 也提供授權的機制, 讓經過授權的使用者才可以存取檔案

     

    A4. Direct object reference (DOR)

    這個威脅解決什麼問題呢?

    如果有特定資源存取的方式如下

    /users/viewDetail?id=35

    那麼駭客可以依照這樣的方式存取其他人的資源

    /users/viewDetail?id=36

    /users/viewDetail?id=37

    像這樣的問題要怎樣解決呢?

    有兩個方式可以解決

    • 1. 使用 ESAPI 的AccessReferenceMap
    • 2. 使用授權認證的機制

    Access Reference Map 範例程式

     Set fileSet = new HashSet();
     fileSet.addAll(...); // add direct references (e.g. File objects)
     AccessReferenceMap map = new AccessReferenceMap( fileSet );
     // store the map somewhere safe - like the session!
     String indRef = map.getIndirectReference( file1 );
     String href = "http://www.aspectsecurity.com/esapi?file=" + indRef );
     ...
     // if the indirect reference doesn't exist, it's likely an attack
     // getDirectReference throws an AccessControlException
     // you should handle as appropriate
     String indref = request.getParameter( "file" );
     File file = (File)map.getDirectReference( indref );

    一般的情況下兩個都會合用, 使用者授權與相對應的資源

     

    A5. CSRF攻擊

    要防止CSRF 攻擊, 比較有效的方式

    1. 過程中要求使用者再次確認

    2. 使用圖形驗證碼 (讓電腦無法自動輸入 )

    3. 使用 Random Token

      <form action="/transfer.do" method="post">
      <input type="hidden" name="CSRFToken" 
      value="OWY4NmQwODE4ODRjN2Q2NTlhMmZlYWE...
      wYzU1YWQwMTVhM2JmNGYxYjJiMGI4MjJjZDE1ZDZ...
      MGYwMGEwOA==">
      …
      </form>

    ESAPI 主要提供的是 Random Token的產生

     

     

    Posted by Tony @ 8:50 pm

  • Leave a Reply

    Your email address will not be published.