IBM AppScan 安全掃描報告中部分問題的解決辦法

IBM AppScan 安全掃描:加密會話(SSLCookie 中缺少 Secure 屬性處理辦法


原因分析:

服務器開啓了Https時,cookie的Secure屬性應設爲true;

解決辦法:

1.服務器配置Https SSL方式,參考:https://support.microsoft.com/kb/324069/zh-cn

2.修改web.config,添加:

<system.web>
<httpCookieshttpOnlyCookies="true" requireSSL="true" />
<system.web>

See: http://msdn.microsoft.com/en-us/library/ms228262(v=vs.100).aspx

3.修改後臺寫Cookies時的設置 cookie.Secure = true

HttpResponse response= HttpContext.Current.Response;

var cookie = new HttpCookie(key, value);

cookie.HttpOnly = true;

cookie.Path = "/";

cookie.Expires = DateTime.Now.AddHours(1);

cookie.Secure = true;

response.AppendCookie(cookie);

 

參考網站:http://stackoverflow.com/questions/5978667/how-to-secure-the-asp-net-sessionid-cookie

 

 

IBM AppScan 安全掃描:支持弱 SSL 密碼套件

解決方法:

1.Server 2008(R2)

根據appScan的修訂建議訪問地址:http://msdn.microsoft.com/en-us/library/windows/desktop/bb870930(v=vs.85).aspx

裏面說了如何修改SSL 密碼套件的優先級和狀態,裏面有一堆的加密方式,很難知道哪些該保留,哪些改去掉(其實AppScan裏面已經有提示哪些該去掉);

 

經過一番資料查找,有一個名叫IIS Crypto的軟件工具,專門用來解決上面的問題;

軟件地址:https://www.nartac.com/Products/IISCrypto/Default.aspx

運行軟件設置他推薦的加密方式,然後重啓系統,再次掃描時,就不會報這個漏洞了。

 

參考資料:

1.http://msdn.microsoft.com/en-us/library/windows/desktop/bb870930(v=vs.85).aspx

2.http://security.stackexchange.com/questions/48325/identify-and-disable-weak-cipher-suites

3.https://www.nartac.com/Products/IISCrypto/Default.aspx

 

 

web安全之跨站請求僞造

CSRF

CSRFCross-site request forgery),中文名稱:跨站請求僞造.
因爲這個不是用戶真正想發出的請求,這就是所謂的請求僞造;因爲這些請求也是可以從第三方網站提交的,所以前綴跨站二字。

CSRF發生的場景如下圖所示:

用戶登錄訪問了一個受信任的站點,
在用戶還沒有退出登錄的時候,打開另外一個tab頁,訪問了網站B
B網站中,有CSRF攻擊代碼訪問網站A
發生的原因是,網站是通過cookie來識別用戶的,當用戶成功進行身份驗證之後瀏覽器就會得到一個
標識其身份的cookie,只要不關閉瀏覽器或者退出登錄,以後訪問這個網站會帶上這個cookie
1.
登錄受信任網站A,並在本地生成Cookie
2.
在不登出A的情況下,訪問危險網站B
你也許會說:如果我不滿足以上兩個條件中的一個,我就不會受到CSRF的攻擊
是的,確實如此,但你不能保證以下情況不會發生:
1.
你不能保證你登錄了一個網站後,不再打開一個tab頁面並訪問另外的網站。
2.
你不能保證你關閉瀏覽器了後,你本地的Cookie立刻過期,你上次的會話已經結束。
(事實上,關閉瀏覽器不能結束一個會話,但大多數人都會錯誤的認爲關閉瀏覽器就等於
退出登錄/結束會話了)如記住密碼功能等。
3.
上圖中所謂的攻擊網站,可能是一個存在其他漏洞的可信任的經常被人訪問的網站。
下面來看一個代碼實例,在網站A發佈了下面的代碼
用戶login,然後可以在input.jsp提交數據,提交的數據被dataupdate.jsp更新到後臺。
dataupdate.jsp
會檢查用戶是否登錄,如果沒有登錄會跳到login.jsp要求用戶登錄。

[html]viewplaincopyprint?

1.  login.jsp

2.  <body>

3.  <formaction="input.jsp"method="post">

4.  name<inputtype="text"name="name"size="50"><br>

5.  pwd<inputtype="password"name="password"size="50"><br>

6.  <inputtype="submit"value="submit">

7.  </form>

8.  <br>

9.  </body>

10. </html>

11.  

12. input.jsp

13. <body>

14. <%

15. //Sessionsession = request.getSession();

16. String username =(String)session.getValue("username");

17. System.out.println("username" + username);

18. if(null==username){

19. String uname = request.getParameter("name");

20. session.putValue("username",uname);

21. }

22.  

23. %>

24. <formaction="dataupdate.jsp"method="post">

25. <inputtype="text"name="comment"size="50"><br>

26. <inputtype="submit"value="submit">

27. </form>

28. <br>

29. </body>

30.  

31. dataupdate.jsp

32. <body>

33. <%

34. String username =(String)session.getValue("username");

35. System.out.println("username" + username);

36. if(null==username){

37. System.out.println("hasnot logged in");

38. response.sendRedirect("login.jsp");

39. }else{

40. String comment = request.getParameter("comment");

41.  

42. System.out.println("adda comment: " + comment);

43.  

44. out.write("commentis : " + comment);

45. }

46. %>

47. </body>

48. </html>

login.jsp
<body>
<form action="input.jsp" method="post">
name<input type="text" name="name" size="50"><br>
pwd<input type="password" name="password" size="50"><br>
<input type="submit" value="submit">
</form>
<br>
</body>
</html>
 
input.jsp
<body>
<%
  //Session session = request.getSession();
  String username = (String)session.getValue("username");
  System.out.println("username " + username);
  if(null==username){
    String uname = request.getParameter("name");
    session.putValue("username", uname);
  }
 
%>
<form action="dataupdate.jsp" method="post">
<input type="text" name="comment" size="50"><br>
<input type="submit" value="submit">
</form>
<br>
</body>
 
dataupdate.jsp
<body>
<%
  String username = (String)session.getValue("username");
  System.out.println("username " + username);
  if(null==username){
    System.out.println("has not logged in");
    response.sendRedirect("login.jsp");
  }else{
    String comment = request.getParameter("comment");
    
    System.out.println("add a comment: " + comment);
     
    out.write("comment is : " + comment);
  }
%>
</body>
</html>

表面上看起來好像沒有問題。
假設我們有另外一個網站B,它有一個網頁文件如下
如果在用戶登錄訪問網站A的同時訪問了網站B,訪問者在網站A的數據就會被假冒更新。
可以在後臺看到有如下的輸出:add a comment: fromcsrf

[html]viewplaincopyprint?

1.  <body>

2.  use a imgelement to send a get request <br>

3.  <imgsrc="http://www.a.com/prjWebSec/csrf/dataupdate.jsp?comment=fromcsrf">

4.  </body>

5.  </html>

<body>
use a img element to send a get request <br>
<img src="http://www.a.com/prjWebSec/csrf/dataupdate.jsp?comment=fromcsrf">
</body>
</html>

這裏網站A違反了HTTP規範,使用GET請求更新資源。那是不是用post請求就不會發生CSRF?
結果是同樣會發生。可以通過構造javascript構造form提交,如下面的代碼

[html]viewplaincopyprint?

1.  <body>

2.  </body>

3.  <scripttype="text/javascript">

4.   

5.  var frm= document.getElementById("viframe");

6.  functionsendcsrf()

7.  {

8.  var form1 = document.createElement("form");

9.  form1.id = "form1";

10. form1.name = "form1";

11. document.body.appendChild(form1);

12.  

13. var input = document.createElement("input");

14. input.type = "text";

15. input.name = "comment";

16. input.value = "fromcsrf post";

17.  

18. form1.appendChild(input);

19. form1.method = "POST";

20. form1.action = "http://www.a.com/prjWebSec/csrf/dataupdate.jsp";

21. form1.submit();

22. document.body.removeChild(form1);

23. }

24. sendcsrf();

25. </script>

26. </html>

<body >
</body>
  <script type="text/javascript">
 
    var frm= document.getElementById("viframe");
    function sendcsrf()  
    {  
        var form1 = document.createElement("form");  
        form1.id = "form1";  
        form1.name = "form1";  
        document.body.appendChild(form1);  
    
        var input = document.createElement("input");  
        input.type = "text";  
        input.name = "comment";  
        input.value = "from csrf post";  
    
        form1.appendChild(input);  
        form1.method = "POST";  
        form1.action = "http://www.a.com/prjWebSec/csrf/dataupdate.jsp";  
        form1.submit();  
        document.body.removeChild(form1);  
    } 
    sendcsrf();
    </script>
</html>

防止方法:
1
,利用referer判斷,
但是用戶有可能設置瀏覽器使其在發送請求時不提供 Referer,這樣的用戶也將不能訪問網站。
2
,在請求中添加 token 並驗證
關鍵在於在請求中放入黑客所不能僞造的信息,並且該信息不存在於 cookie 之中,
可以在服務器端生成一個隨機碼,然後放在formhidden元素中,form提交的時候在服務器端檢查。

 

會話標識未更新:登錄頁面加入以下代碼

Java代碼

  1. request.getSession(true).invalidate();//清空session
  2. Cookie cookie = request.getCookies()[0];//獲取cookie
  3. cookie.setMaxAge(0);//讓cookie過期
    request.getSession(true).invalidate();//清空session
    Cookie cookie = request.getCookies()[0];//獲取cookie
    cookie.setMaxAge(0);//讓cookie過期


不是很明白session的機制,高手路過可以指教一下。
2.跨站點請求僞造:
在出錯的url加參數sessionid。

Java代碼

  1. response.getWriter().write( "<script>parent.location.href='dbase/admin/loginJsp.action?sessionId="+sessionId+"'</script>");
response.getWriter().write(  "<script>parent.location.href='dbase/admin/loginJsp.action?sessionId="+sessionId+"'</script>");


如果帶參數報ssl錯誤,使用下面的post方式傳值:

Java代碼

  1. response.getWriter().write(
  2. "<script language=\"javascript\"> " +
  3. "document.write(\"<form action=dbase/admin/loginJsp.action method=post name=formx1 style='display:none'>\");" +
  4. "document.write(\"<input type=hidden name=name value='"+sessionId+"'\");" +
  5. "document.write(\"</form>\");" +
  6. "document.formx1.submit();" +
  7. "</script>"
  8. );
response.getWriter().write(
      "<script language=\"javascript\"> " +
      "document.write(\"<form action=dbase/admin/loginJsp.action method=post name=formx1 style='display:none'>\");" +
      "document.write(\"<input type=hidden name=name value='"+sessionId+"'\");" +
      "document.write(\"</form>\");" +
      "document.formx1.submit();" +
      "</script>"
      );


3.啓用不安全HTTP方法

Java代碼

  1. 修改web工程中或者服務器web.xml,增加安全配置信息,禁用不必要HTTP方法
  2. <security-constraint>
  3. <web-resource-collection>
  4. <url-pattern>/*</url-pattern>
  5. <http-method>PUT</http-method>
  6. <http-method>DELETE</http-method>
  7. <http-method>HEAD</http-method>
  8. <http-method>OPTIONS</http-method>
  9. <http-method>TRACE</http-method>
  10. </web-resource-collection>
  11. <auth-constraint>
  12. </auth-constraint>
  13. </security-constraint>
  14. <login-config>
  15. <auth-method>BASIC</auth-method>
  16. </login-config>
修改web工程中或者服務器web.xml,增加安全配置信息,禁用不必要HTTP方法
  <security-constraint>  
   <web-resource-collection>  
      <url-pattern>/*</url-pattern>  
      <http-method>PUT</http-method>  
      <http-method>DELETE</http-method>  
      <http-method>HEAD</http-method>  
      <http-method>OPTIONS</http-method>  
      <http-method>TRACE</http-method>  
   </web-resource-collection>  
   <auth-constraint>  
   </auth-constraint>  
 </security-constraint>  
 <login-config>  
   <auth-method>BASIC</auth-method>  
 </login-config>


4.已解密登錄請求
配置SSL,具體見http://serisboy.iteye.com/admin/blogs/1320231
在web.xml加入如下配置。

Java代碼

  1. <security-constraint>
  2. <web-resource-collection >
  3. <web-resource-name >SSL</web-resource-name>
  4. <url-pattern>/*</url-pattern>
  5. </web-resource-collection>
  6. <user-data-constraint>
  7. <transport-guarantee>CONFIDENTIAL</transportguarantee>
  8. </user-data-constraint>
  9. </security-constraint>
<security-constraint>  
       <web-resource-collection >  
              <web-resource-name >SSL</web-resource-name>  
              <url-pattern>/*</url-pattern>  
       </web-resource-collection> 
       <user-data-constraint>  
              <transport-guarantee>CONFIDENTIAL</transportguarantee>  
       </user-data-constraint>  
</security-constraint> 


5.高速緩存的ssl頁面

Java代碼

  1. 頁面
  2. <meta http-equiv="Pragma" contect="no-cache">
頁面
<meta http-equiv="Pragma" contect="no-cache">

 

Java代碼

  1. java代碼
  2. response.setHeader("Pragma", "No-cache");
java代碼
response.setHeader("Pragma", "No-cache");


6.目錄列表
配置文件目標拒絕訪問。
在conf/web.xml下:

Java代碼

  1. <servlet>
  2. <servlet-name> default </servlet-name>
  3. <servlet-class> org.apache.catalina.servlets.DefaultServlet </servlet-class>
  4. <init-param>
  5. <param-name> debug </param-name>
  6. <param-value> 0 </param-value>
  7. </init-param>
  8. <init-param>
  9. <param-name> listings </param-name>
  10. <param-value> false </param-value>
  11. </init-param>
  12. <load-on-startup> 1 </load-on-startup>
  13. </servlet>
<servlet> 
<servlet-name> default </servlet-name> 
<servlet-class> org.apache.catalina.servlets.DefaultServlet </servlet-class> 
<init-param> 
<param-name> debug </param-name> 
<param-value> 0 </param-value> 
</init-param> 
<init-param> 
<param-name> listings </param-name> 
<param-value> false </param-value> 
</init-param> 
<load-on-startup> 1 </load-on-startup> 
</servlet> 


把listings對應的value設置爲fasle.
或者把上面的這個servlet加到你的虛擬路徑下的web-inf/web.xml 中,把
servlet-name改爲其它的,再加一下servlet-mapping

Java代碼

  1. <servlet>
  2. <servlet-name> default1 </servlet-name>
  3. <servlet-class> org.apache.catalina.servlets.DefaultServlet </servlet-class>
  4. <init-param>
  5. <param-name> debug </param-name>
  6. <param-value> 0 </param-value>
  7. </init-param>
  8. <init-param>
  9. <param-name> listings </param-name>
  10. <param-value> false </param-value>
  11. </init-param>
  12. <load-on-startup> 1 </load-on-startup>
  13. </servlet>
  14. <servlet-mapping>
  15. <servlet-name> default1 </servlet-name>
  16. <url-pattern> / </url-pattern>
  17. <servlet-mapping> 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章