軟體研發安全規範

weixin_34370347發表於2018-08-30

1 安全編碼原則

  1. 保持簡單,程式只實現指定的功能。
  2. 堅持最小許可權,把可能造成的危害降到最低。
  3. 預設不信任,採用白名單機制,只放行已知的操作。
  4. 永遠不要相信使用者的輸入,對所有輸入進行前臺和後臺兩次檢查。

2 常見WEB潛在問題

輸入驗證:嵌入到查詢字串、表單欄位、cookie 和 HTTP 頭中的惡意字串的攻擊。這些攻擊包括命令執行、跨站點指令碼(XSS)、SQL 注入和緩衝區溢位攻擊。

身份驗證:標識欺騙、密碼破解、特權提升和未經授權的訪問。

授權驗證:訪問保密資料或受限資料、篡改資料以及執行未經授權的操作。

配置管理:對管理介面進行未經授權的訪問、具有更新配置資料的能力以及對使用者帳戶和帳戶配置檔案進行未經授權的訪問。

敏感資料:洩露保密資訊以及篡改資料。

會話管理:捕捉會話識別符號,從而導致會話劫持及標識欺騙。

加密管理:訪問保密資料或帳戶憑據,或二者均能訪問。

引數操作:路徑遍歷攻擊、命令執行以及繞過訪問控制機制,從而導致資訊洩漏、特權提升和拒絕服務。

異常管理:拒絕服務和敏感的系統級詳細資訊的洩漏。

稽核和記錄:不能發現入侵跡象、不能驗證使用者操作,以及在診斷時出現困難。

3 基本開發安全規範

3.1 跨站點指令碼(XSS)防範

XSS的型別:反射型XSS、儲存型XSS、DOM型XSS。

跨站點指令碼防範的基本原則:

  1. 一切的輸入/輸出都是有害的,不要信任任何輸入/輸出資料。
  2. 所有傳遞過程都不能保障無侵入,執行前、儲存前、顯示前都要進行“資料清洗”。
  3. 所有的資料校驗、處理工作要在前端和伺服器端兩次進行。
  4. 目前所有的XSS通過com.keegoo.core.util.XSSUtil來過濾。

DOM-based XSS的防範當操作頁面中DOM物件的時候,要對其輸入的引數進行處理,防止XSS的注入。可採用escape、encodeURI、encodeURIComponent或自定義方法進行處理。示例:

Window.location=encodeURI(”http://www.dhgate.com”);
複製程式碼

對輸入/輸出進行Encode 將輸入/輸出進行轉義成HTML實體編碼(ISO 8859-1 Latin1)或其他編碼,使得其在瀏覽器中不可自動執行。

不要在html元素和屬性中使用未經轉義的不安全內容。如下面的示例:

<script>...NEVER PUT UNTRUSTED DATA HERE...</script>   
directly in a script 
<!--...NEVER PUT UNTRUSTED DATA HERE...-->             
inside an HTML comment 
<div ...NEVER PUT UNTRUSTED DATA HERE...=test />
in an attribute name 
<NEVER PUT UNTRUSTED DATA HERE... href="/test" />
in a tag name
<div attr=...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...>content</div>
inside UNquoted attribute 
<div attr='...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...'>content</div>
inside single quoted attribute
<div attr="...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...">content</div>
inside double quoted attribute
複製程式碼

3.2 防SQL隱碼攻擊規範

  1. 防SQL隱碼攻擊基本原則:所有使用者輸入都必須進行合法性校驗。所有資料庫SQL操作必須引數化
  2. 回收開發人員等操作生產庫許可權:減少開發人員、非DBA操作生產庫的許可權;資料庫資料查詢要有許可權分級和稽核。
  3. 儘量使用PreparedStatement代替Statement,一方面,在大多數情況下,使用PreparedStatement的效能將優於使用Statement,另外一方面,可以最大限度的減少SQL隱碼攻擊發生的可能行。
  4. 使用者提交的資料都應該做合法性校驗,避免使用者輸入‘,““,-,%,#,&,|,@,+等有可能導致SQL隱碼攻擊的危險字元給系統造成危害。

3.3 頁面元件安全防範

  1. 頁面標籤必須關閉,屬性值必須加引號。在頁面中使用的標籤不關閉,屬性值不加引號往往成為被攻擊點,攻擊者很容易的利用這些漏洞進行注入。避免這些漏洞的出現可以提高被攻擊的可能。

  2. Form提交方式必須選用POST。Form預設的提交方式是Get,這種方式將表單中資料的按照variable=value的形式,使用“?”新增至Action所指向的URL後面,各個變數之間使用“&”連線。所要傳遞的資訊量除受URL長度限制之外,資訊內容都顯示暴露。

    在使用Form的時候必須將提交方式置為POST。示例:

    <form action="…" method="post" target="_blank">…</form>
    複製程式碼
  3. 所有的非ASCII字元在URL中傳遞時都需要按照協商好的編碼方式做URL編碼。推薦使用encodeURI、encodeURIComponent或者自定義encode實現。encodeURI、encodeURIComponent預設都返回UTF8編碼的URL,區別在於encodeURI方法不會對下列字元進行編碼: ":"、"/"、";" 和 "?"。而encodeURIComponent則會對這些字元進行編碼處理。

  4. 儘量使用物件的innerText,不要使用innerHtml屬性。物件的innerText屬性預設會對輸入的資料進行encode,使得如果資料的資料還有html可執行標記時不會直接執行,而如果使用innerHtml屬性的話不會保障。

    <SPAN id=”Addr”></SPAN>
    <Script>
        // Using innerText renders the content safe.Addr.innerText=”…”;
        //Using innerHtml requires the use of HtmlEncode to make it 
        safe.Addr.innerHtml=””;
    </Script>
    複製程式碼
  5. 輸入框設定最大長度、輸入資料型別限制。輸入框一般是攻擊者比較鐘意的攻擊物件,攻擊者可以通過輸入框限制不足的弱點進行資料竊取(比如SQL隱碼攻擊)、或者製造迫害(如比XSS)。我們可以通過對輸入框最大長度、輸入資料型別的限制,從一定程度上防範這樣的攻擊。我們可以根據實際需求,對一些輸入框限定只允許輸入字母、數字等。同時對輸入的資料長度做限制。

  6. 關閉客戶端自動完成功能,減少駐留在客戶端資料

    <FORM … AUTOCOMPLETE=”OFF”/>
    <INPUT … AUTOCOMPLETE=”OFF”/>
    複製程式碼
  7. 設定/受限,防止指令碼執行。將/中security屬性設定為restricted後, Frame中的指令碼將不能執行(僅限於IE)。

    3.4 敏感資料的安全防範

  8. 不能任意在Cookie、Session、ServletContext中存放資料,對於這些物件中存放的資料,必須有統一定義、說明、Lifecycle的管理等。

對於敏感資訊都必須保障其私密性。在頁面顯示、操作互動中不可避免的會有一些如使用者的標識資訊、密碼、帳號資訊、涉及的金額資訊等敏感資料(保密性的資料)的存在。為保障這些資料不被曝露而提高安全性,我們要做到所有敏感資訊必須進行加密處理,不能以明文的形式存在於任何網路、記憶體及其它持久化介質中(如:資料庫、檔案磁碟系統等)。

所有的密碼、key、帳號等機密資訊都不能在URL中傳遞。

所有的密碼、key、銀行賬號等機密資訊都不能儲存到Cookie,Session、ServletContext中。

防止資訊洩漏:

在系統上線使用的log level對應的日誌輸出中不允許包含任何密碼、key、賬號等機密資訊。 SVN整合分支上的程式碼中不允許存留可用的system.out/err.print語句。 在測試/除錯階段所使用的測試頁面、單元測試模組等不允許提交到SVN整合分支上。 不允許將系統產生的錯誤異常資訊直接顯示給使用者,需要有統一的錯誤處理。

儘量減少不必要的資訊傳遞。在資訊的傳遞過程中,如果當前Step中的物件、物件的屬性、引數等在下一個Step中不需要,則不要再做傳遞,甚至可以顯式的銷燬。這樣可以有效的減少資訊被截獲的機率,特別是敏感資料(例如使用者密碼、賬戶資訊等等)。

3.5 WEB安全防範

Cookie的安全防範:

儲存於cookie中的敏感資料必須加密。 沒有特殊要求下,儘量使用會話cookie(非持久化)。 如果使用持久化cookie應該設定cookie超時。 啟用cookie安全傳輸,表示建立的 cookie 只能在https連線中被瀏覽器傳遞到伺服器端進行會話驗證,如果是http連線則不會傳遞該資訊。
Cookie[] cookies = request.getCookies();
for(Cookie cookie : cookies) {
    if (…) {
        // 設定cookie不持久化到客戶端磁碟上
        cookie.setMaxAge(-1);
        // 設定cookie超時, 120秒
        cookie.setMaxAge(120);
        // 啟用cookie安全傳輸
        cookie.setSecure(true);
        response.addCookie(cookie);
    }
}
複製程式碼

必須設定session的超時時間。web.xml中配置示例:

<session-config>
    <session-timeout>10</session-timeout>
</session-config>複製程式碼

必須構建統一的錯誤處理頁面。web.xml示例:

<error-page>
    <error-code>500</error-code>
    <location>/error.jsp</location>
</error-page>
複製程式碼

多執行緒中執行緒安全的防範:

儘量少用靜態(static)變數和static方法。(除了靜態常量:static final constants)。 儘量多執行緒框架(java.util.concurrent)構建多執行緒同步機制。 使用ThreadLocal避免多個執行緒之間類成員的共享衝突。 如非必要,不要使用synchronized關鍵字。必須要使用synchronized時,應將同步範圍最小化,即將同步作用到最需要的地方,避免大塊的同步塊或方法等。

增加Referer的檢查,防止非法訪問。Referer是HTTP Header中的一個欄位,當瀏覽器想伺服器傳送請求時,Referer用來通知伺服器請求發起的位置。

相關文章