系統安全架構方面的探討


一、基礎設施安全

這個不用多說,服務器、操作系統都要用正規的高質量的,安裝殺毒軟件防火牆,使用攻擊檢測系統。

二、應用系統安全

開發程序的時候,應當事先知道並在代碼層面處理大部分常見的安全問題。

1.sql注入

mybatis就使用#比使用$能規避掉很多sql注入攻擊。

2.csrf(跨站請求偽造)攻擊

大致三種方法,①在filter中驗證HTTP Referer字段,②在請求地址中添加token並驗證,③在HTTP頭中自定義屬性並驗證,一般我是通過toekn驗證,
具體參見https://www.ibm.com/developerworks/cn/web/1102_niugang_csrf/

3.xss(跨站腳本)攻擊

總體的防御思路是對輸入(和URL參數)進行過濾,對輸出進行編碼。
java代碼示例

public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
    HttpServletRequest orgRequest = null;

    public XssHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
        orgRequest = request;
    }
    /**
     * 覆蓋getParameter方法,將參數名和參數值都做xss過濾。<br/>
     * 如果需要獲得原始的值,則通過super.getParameterValues(name)來獲取<br/>
     * getParameterNames,getParameterValues和getParameterMap也可能需要覆蓋
     */
    @Override
    public String getParameter(String name) {
        String value = super.getParameter(xssEncode(name));
        if (value != null) {
            value = xssEncode(value);
        }
        return value;
    }
    /**
     * 覆蓋getHeader方法,將參數名和參數值都做xss過濾。<br/>
     * 如果需要獲得原始的值,則通過super.getHeaders(name)來獲取<br/>
     * getHeaderNames 也可能需要覆蓋
     */
    @Override
    public String getHeader(String name) {
        String value = super.getHeader(xssEncode(name));
        if (value != null) {
            value = xssEncode(value);
        }
        return value;
    }
    /**
     * 將容易引起xss漏洞的半角字符直接替換成全角字符
     *
     * @param s
     * @return
     */
    private static String xssEncode(String s) {
        if (s == null || s.isEmpty()) {
            return s;
        }
        StringBuilder sb = new StringBuilder(s.length() + 16);
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            switch (c) {
            case '>':
                sb.append('>');// 全角大於號
                break;
            case '<':
                sb.append('<');// 全角小於號
                break;
            case '\'':
                sb.append('‘');// 全角單引號
                break;
            case '\"':
                sb.append('“');// 全角雙引號
                break;
            case '&':
                sb.append('&');// 全角
                break;
            case '\\':
                sb.append('\');// 全角斜線
                break;
            case '#':
                sb.append('#');// 全角井號
                break;
            case '%':    // < 字符的 URL 編碼形式表示的 ASCII 字符(十六進制格式) 是: %3c
                processUrlEncoder(sb, s, i);
                break;
            default:
                sb.append(c);
                break;
            }
        }
        return sb.toString();
    }
    public static void processUrlEncoder(StringBuilder sb, String s, int index){
        if(s.length() >= index + 2){
            if(s.charAt(index+1) == '3' && (s.charAt(index+2) == 'c' || s.charAt(index+2) == 'C')){    // %3c, %3C
                sb.append('<');
                return;
            }
            if(s.charAt(index+1) == '6' && s.charAt(index+2) == '0'){    // %3c (0x3c=60)
                sb.append('<');
                return;
            }            
            if(s.charAt(index+1) == '3' && (s.charAt(index+2) == 'e' || s.charAt(index+2) == 'E')){    // %3e, %3E
                sb.append('>');
                return;
            }
            if(s.charAt(index+1) == '6' && s.charAt(index+2) == '2'){    // %3e (0x3e=62)
                sb.append('>');
                return;
            }
        }
        sb.append(s.charAt(index));
    }
    /**
     * 獲取最原始的request
     *
     * @return
     */
    public HttpServletRequest getOrgRequest() {
        return orgRequest;
    }
    /**
     * 獲取最原始的request的靜態方法
     *
     * @return
     */
    public static HttpServletRequest getOrgRequest(HttpServletRequest req) {
        if (req instanceof XssHttpServletRequestWrapper) {
            return ((XssHttpServletRequestWrapper) req).getOrgRequest();
        }
        return req;
    }
}
View Code

具體參見https://www.cnblogs.com/digdeep/p/4695348.html

4.文件上傳漏洞防御

大致思路:①文件上傳的目錄設置為不可執行 ②判斷文件類型 ③使用隨機數改寫文件名和文件路徑 ④單獨設置文件服務器的域名 ⑥在客戶端和服務器端對用戶上傳的文件名和文件路徑等項目進行雙重驗證 ⑦服務器端添加白名單過濾 ⑧對%00截斷符進行檢測 ⑨對HTTP包頭的content-type也和上傳文件的大小進行檢查
具體參見http://blog.csdn.net/u014609111/article/details/52701827

5.路徑遍歷攻擊防御

最有效的辦法就是權限控制,謹慎處理傳向文件系統API的參數,凈化數據:對用戶傳過來的文件名參數進行硬編碼或統一編碼,對文件類型進行白名單控制,對包含惡意字符或者空字符的參數進行拒絕。

三、數據保密安全

1.存儲安全(存在在可靠的設備,實時,定時備份)

2.保存安全(重要的信息加密保存,選擇合適的人員復雜保存和檢測等)

3.傳輸安全(防止數據竊取和數據篡改)

常用的加解密算法(單項散列加密[MD5,SHA],對稱加密[DES,3DES,RC]),非對稱加密[RSA]等。
目前大多數網站和app的接口都是采用http協議,但是http協議很容易就通過抓包工具監聽到內容,甚至可以篡改內容,為了保證數據不被別人看到和修改,可以通過以下幾個方面避免。

①重要數據進行加密傳輸

常見的是傳密碼的時候對密碼進行MD5(本質是一種散列算法,和AES等加密算法不一樣,因為不是加密,所以不可以解密,網上的所謂MD5解密,其實是在海量數據里的一種反推)加密。

②非重要數據進行簽名

簽名的目的是為了防止篡改,比如http://www.xxx.com/getnews?id=1,獲取id為1的新聞,如果不簽名那么通過id=2,就可以獲取2的內容等等。怎樣簽名呢?通常使用sign,比如原鏈接請求的時候加一個sign參數,sign=md5(id=1),服務器接受到請求,驗證sign是否等於md5(id=1),如果等於說明正常請求。這會有個弊端,假如規則被發現,那么就會被偽造,所以適當復雜一些,還是能夠提高安全性的。
我自己的一個項目是用SHA 256(也是一種散列算法)加密做sign的,具體的規則是調接口的時候,把每個參數加上一個key(一個任意字符串標記,比如網站的域名)拼接成一個整個字符串,然后用SHA 256加密,把加密好的字符串也一起傳到后台,后台再拿每個參數加上key進行SHA 256加密,拿加密好的字符串與傳過來的加密過的字符串比對。

③用token驗證登陸態

http是無狀態的,也就是服務器沒法自己判斷兩個請求是否有聯系,那么登錄之后,以后的接口怎么判定是否登錄呢,簡單的做法,在數據庫中存一個token字段(名字隨意),當用戶調用登陸接口成功的時候,就將該字段設一個值,(比如aes(過期時間)),同時返回給前端,以后每次前端請求帶上該值,服務器首先校驗是否過期,其次校驗是否正確,不通過就讓其登陸。(redis 做這個很方便哦,key有過期時間)

4.防重放機制

防止別有用心的人獲取到請求地址,然后原封不動的連續重復請求,導致系統阻塞和數據庫負載,需要有防重放機制,http://www.cnblogs.com/yjf512/p/6590890.html

重放攻擊

 閱讀文章

基於http協議的api接口對於客戶端的身份認證方式以及安全措施 http://www.cnblogs.com/gmou/p/4458754.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM