【常见Web应用安全问题】
Web应用程序的安全性问题依其存在的形势划分,种类繁多,这里不准备介绍所有的,只介绍常见的一些。
常见Web应用安全问题安全性问题的列表: 1、跨站脚本攻击(CSS or XSS, Cross Site Scripting) |
相信绝大多数人对跨站脚本弱点已经早有耳闻。2006年全球网络安全弱点Top10排名当中,它荣登榜首!为什么它有如此之大的影响力呢?个人觉得原因有三:
其一、攻击难度小。不管是技术还是实现攻击的成本上都比较容易;
其二、它存在的载体(浏览器)使用极其广泛;
其三、它所依赖的技术被广泛的应用与支持(Javascript,VB Script, HTML,ActiveX, Flash)。
说了这么多,它到底是什么呢?
XSS是一种存在Web应用中,允许黑客以最终用户的身份向Web应用注入恶意脚本,以愚弄其他用户或获取其他用户重要数据和隐私信息为目的的一种攻击形式。
XSS可使用的技术有JavaScript、VBScript、 ActiveX、 或 Flash, 且通常通过页面表单提交注入到web应用中并最终在用户的浏览器客户端执行。例如,一个没有经过安全设计并实现的论坛,当你在跟贴时在正文输入这样的代码:
<script>alert(document.cookie);</script>
当其它用户浏览时便会弹出一个警告框,内容显示的是浏览者当前的cookie串。
试想如果我们注入的不是以上这个简单的测试代码,而是一段经常精心设计的恶意脚本,当用户浏览此帖时,cookie信息就可能成功的被攻击者获取。此时浏览者的帐号就很容易被攻击者掌控了。
说到这,一些初学者可能还不太清楚它的危害到底在哪里,不用着急,我会在后续的文章中详细给大家介绍有关“Web工作原理”内容,到时你就会很清楚的理解这些了。有关XSS的攻击实例、手段和方法是多种多样的,你的脚本技能加上你的安全知识决定了你对其理解的深度。
顺便提一句:你可能无法成为XSS安全弱点的攻击专家,但是你可以成为安全检测专家。因为从安全检测角度来说,你无需证明问题的严重性细节,只需要证明此类问题存在就可以了。
(等Web工作原理部分讲完再深入):
不管是上述的哪一种技术实现的XSS攻击,最终都离不开这三点:
其一是浏览器的解析,其二是脚本语法,其三是脚本需要一定的长度。
对于浏览器的解析是不在话下了,我不能因为这各类型问题的存在就改写浏览器使其不支持脚本解析。
所以,能做就是控制脚本注入的语法要素。比如:javascript离不开:“<”、“>”、“(”、“)”、“;”...等等,所以我们只需要在输入或输出时对其进行字符过滤或转义处理就可以了。一般我们会采用转义的方式来处理,转义字符是会使用到HTML的原始码(Web工作原理中会介绍),因为原始码是可以被浏览器直接识别的,所以使用起来非常方便。
允许可输入的字符串长度限制也可以一定程度上控制脚本注入。比如:页面表单中姓名,我可以只允许你输入5个字符,请问你还有办法进行Javascript的脚本注入吗?显然不行了。
还需要您注意的是:我这里所述的过滤、检测、限制等等策略,一定一定要在Web Server那一端去完成,而不是使用客户端的Javascript或者VBScript...去做简单的检查。因为真正的攻击者不会仅仅依赖于浏览器去做攻击,而更多的往往是借助于第三方工具,根本就可以绕过你精心设计制作的客户端Javascript进行过滤、检测或限制手段的。
跨站式脚本(Cross-Site Scripting)
XSS又叫CSS (Cross Site Script) ,跨站脚本攻击。它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意用户的特殊目的。
使用过ASP的同学一定见过这样的代码:
<%
Response . Write ( Request . Querystring ( "name" ))
%>
假如我传入的name的值为:
这样就可以直接盗取用户的cookie。所以我就可以发送一条链接地址让别人去点:
当然这样做没有一点隐蔽性,虽然前面的xxx.com瞒过了少数人,但大多数人可以辨认出后面的javascript代码,所以,我只需要将后面的javascript代码转换成URL的16进制,如:
上面的URL你还认得吗?除非你把它转换出来。(进制转换可以使用Napkin工具,哎,太坏了。。有人问Napkin的下载地址,贴在这里好了:http://www.0x90.org/releases/napkin/Napkin-1.0-Windows.zip)
2. 没有严格区分“数据”和“代码”
发现大名鼎鼎的淘宝网也存在这样的漏洞,我们在搜索框中输入:
这样,我们已经修改了淘宝原有的页面,在下面嵌入了百度的首页。效果如图:
我尝试在各种不同网站寻找 XSS漏洞, baidu, amazon.cn, youku.com, dangdang.com等等。结果,我发现XSS漏洞非常普遍!其实XSS利用的是网页的回显,即,接收用户的输入,然后再在页面显示用户的输入。总结 一下几个可能会出现漏洞的地方:
- 搜索引擎
- 留言板
- 错误页面
通过在上面那些类型的页面输入一些特殊的字符(包括< > / "),如:</?jjkk>,然后在结果页中的源码处搜索是否存在原样的:</?jjkk>,如果存在,恭喜你,发现了一个XSS漏洞。
1. DOM-based cross-site scripting
页面本身包含一些DOM对象的操作,如果未对输入的参数进行处理,可能会导致执行恶意脚本。如下面一些DOM操作:
document . URLUnencoded
document . location ( and many of its properties )
document . referrer
window . location ( and many of its properties )
举个例子,假如某个脆弱的页面的代码如下:
<TITLE> Welcome! </TITLE>
Hi
<SCRIPT>
var pos = document . URL . indexOf ( "name=" ) + 5 ;
document . write ( document . URL . substring ( pos , document . URL . length ));
</SCRIPT>
<BR>
Welcome to our system
…
</HTML>
攻击者使用如下的URL访问时,则非常危险:
试了一下,貌似IE、FireFox等浏览器默认对<script>alert(document.cookie)</script>进行了编码,阻止了脚本的执行。但是对于DOM操作还是要更加谨慎啊,比如把上面的页面修改一下,安全性就增强了不少:
var pos = document . URL . indexOf ( "name=" ) + 5 ;
var name = document . URL . substring ( pos , document . URL . length );
if ( name . match ( /^[a-zA-Z0-9]$/ ))
{
document . write ( name );
}
else
{
window . alert ( "Security error" );
}
</SCRIPT>
2. Reflected cross-site scripting
也被称为None-Persistent cross-site scripting,即,非持久化的XSS攻击,是我们通常所说的,也是最常用,使用最广的一种方式。它通过给别人发送带有恶意脚本代码参数的URL,当URL地址被打开时,特有的恶意代码参数被HTML解析、执行。它的特点是非持久化,必须用户点击带有特定参数的链接菜能引起。
3. Persistent cross-site scripting
持久化XSS攻击,指的是恶意脚本代码被存储进被攻击的数据库,当其他用户正常浏览网页时,站点从数据库中读取了非法用户存入非法数据,恶意脚本代码被执行。这种攻击类型通常在留言板等地方出现。
我们来试一把Reflected cross-site scripting。当我们在某网站输入参数XXX,发现参数XXX原样的出现在了页面源码中:
OK,可以开始做文章了,我们将XXX替换为:abc"/><script>alert('haha')</script><a href=",返回的HTML代码如下:
这样,<script>alert('haha')</script>被执行了。这里再举例一些XSS攻击行为:
<IMG SRC=javascript:alert('XSS')>
<IMG SRC="javascript:alert(String.fromCharCode(88,83,83))">
<IMG SRC="jav ascript:alert('XSS');">
<SCRIPT/XSS SRC="http://example.com/xss.js"></SCRIPT>
<<SCRIPT>alert("XSS");//<</SCRIPT>
<iframe src=http://example.com/scriptlet.html <
<INPUT TYPE="IMAGE" SRC="javascript:alert('XSS');">
<BODY BACKGROUND="javascript:alert('XSS')">
<BODY ONLOAD=alert(document.cookie)>
<BODY onload!#$%&()*~+-_.,:;?@[/|"]^`=alert("XSS")>
<IMG DYNSRC="javascript:alert('XSS')">
<IMG DYNSRC="javascript:alert('XSS')">
<BR SIZE="&{alert('XSS')}">
<IMG SRC='vbscript:msgbox("XSS")'>
<TABLE BACKGROUND="javascript:alert('XSS')">
<DIV STYLE="width: expression(alert('XSS'));">
<DIV STYLE="background-image: url(javascript:alert('XSS'))">
<STYLE TYPE="text/javascript">alert('XSS');</STYLE>
<STYLE type="text/css">BODY{background:url("javascript:alert('XSS')")}</STYLE>
<?='<SCRIPT>alert("XSS")</SCRIPT>'?>
<A HREF="javascript:document.location='http://www.example.com/'">XSS</A>
<IMG SRC=javascript:alert('XSS')>
<EMBED SRC="http://ha.ckers.org/xss.swf" AllowScriptAccess="always"></EMBED>
a="get";
b="URL(""";
c="javascript:";
d="alert('XSS');"")";
eval(a+b+c+d);
更加详细的列表请参见 5
- 盗取各类用户帐号,如机器登录帐号、用户网银帐号、各类管理员帐号
- 控制企业数据,包括读取、篡改、添加、删除企业敏感数据的能力
- 盗窃企业重要的具有商业价值的资料
- 非法转账
- 强制发送电子邮件
- 网站挂马
- 控制受害者机器向其它网站发起攻击
- 必须明确:一切输入都是有害的,不要信任一切输入的数据。
- 缓和XSS问题的首要法则是确定哪个输入是有效的,并且拒绝所有别的无效输入。
-
替换危险字符,如:"&", "<", ">", ""","'", "/", "?",";", ":", "%", "<SPACE>", "=", "+"。各种语言替换的程度不尽相同,但是基本上能抵御住一般的XSS攻击。
-
python的cgi.escape函数:
def escape ( s , quote = None ):
'''Replace special characters "&", "<" and ">" to HTML-safe sequences.
If the optional flag quote is true, the quotation mark character (")
is also translated.'''
s = s . replace ( "&" , "&" ) # Must be done first!
s = s . replace ( "<" , "<" )
s = s . replace ( ">" , ">" )
if quote :
s = s . replace ( '"' , """ )
return s -
ASP中的Server.HTMLEncode:
< %= Server.HTMLEncode("The paragraph tag: <P> ") %> -
ASP.NET的Server.HtmlEncode及Server.UrlEncode:
String TestString = "This is a <Test String>." ;
String EncodedString = Server . HtmlEncode ( TestString );
Server . UrlEncode ( Request . Url . ToString ()); -
PHP的htmlspecialchars方法:
<?php
$new = htmlspecialchars ( "<a href='test'>Test</a>" , ENT_QUOTES );
echo $new ; // <a href='test'>Test</a>
?> -
JAVA中的java.net.URLEncode.encode:
String mytext = java . net . URLEncoder . encode ( "中国" , "utf-8" );
-
- 有些网站使用过滤javascript关键字的办法来防止XSS,其实是很不明智的,因为XSS有时候根本就不需要javascript关键字或者对javascript关键字进行格式变化来躲过过滤。
-
为所有的标记属性加上双引号。应该说这也不是万全之策,只是在转义了双引号的前提下的一道安全保障。比如:
不加双引号时,onclick被执行了:<a href= http://www.xxx.com/detail.asp?id=2008 οnclick= 'javascrpt:alert(' haha ')' >加上了双引号,onclick不会被执行:< a href = "http://www.xxx.com/detail.asp?id=2008 οnclick='javascrpt:alert('haha')'" > - 将数据插入到innerText属性中,脚本将不会被执行。如果是innerHTML属性,则必须确保输入是安全的。如ASP.NET中:
<% @ Page Language = "C#" AutoEventWireup = "true" %>
< html >
< body >
< span id = "Welcome1" runat = "server" > </ span >
< span id = "Welcome2" runat = "server" > </ span >
</ body >
</ html >
< script runat = "server" >
private void Page_Load ( Object Src , EventArgs e )
{
// Using InnerText renders the content safe–no need to HtmlEncode
Welcome1 . InnerText = "haha" ;
// Using InnerHtml requires the use of HtmlEncode to make it safe
Welcome2 . InnerHtml = "Hello, " + Server . HtmlEncode ( "haha" );
}
</ Script > -
使用IE6.0SP1的cookie选项HttpOnly,注意,HttpOnly只能阻止恶意脚本读取cookie,并不能阻止XSS攻击。比如在ASP.NET中:
HttpCookie cookie = new HttpCookie ( "Name" , "ZhangChangrong" );
cookie . Path = "/; HttpOnly" ;
Response . Cookies . Add ( cookie ); -
使用IE的<IFrame>的Security属性,设置为restricted后,frame中的脚本将不能执行(仅限于IE)。如:
<iframe security= "restricted" src= "http://www.somesite.com/somepage.htm" ></frame> -
ASP.NET中的ValidateRequest配置选项。默认情况下,这个功能是开启的,这个功能将会检查用户是否试图在cookie、查询字符串以及HTML表格中设置HTML或脚本。如果请求包含这种潜在的危险输入,就会抛出一个HttpRequestValidationException异常。我在尝试试探当当网的XSS漏洞时发现这个异常信息,可以说当当网使用了ValidateRequest这个选项,或者从另一方面说,也许是无意中启用了这一选项,同时,将错误信息抛出给用户是非常不安全的。
-
给一个页面设置ValidateRequest选项:
<% @ Page Language = "C#" ValidateRequest = "false" %> -
在Machine.config中设置全局ValidateRequest选项,注意,如果在Web.config中重新设置,不会覆盖Machine.config中的这一设置:
< system . web >
< pages buffer = "true" validateRequest = "true" />
</ system . web > - 让我们来目睹当当网给我们带来的这一盛况:
-
- 在一些必须使用到HTML标签的地方,比如公告栏,可以使用其他格式的标示代替,比如论坛中广泛使用的BBCode,用[i]...["i]来表示斜体。
- 然而,对于一些允许用户输入特定HTML的地方,强烈建议使用正则表达式进行匹配。比如:
if ( /^(?:["s"w"?"!","."'""]*|(?:"<"/"?(?:i|b|p|br|em|pre)">))*$/i )
{
#Cool, it's valid input
}
- 查找所有包含用户输入的入口。
- 跟踪流入应用程序的每一个数据。
- 确定数据是否与输出有关系。
- 如果与输出有关,它是不是原始数据,是不是经过处理的?
-
Michael Howard, David LeBlanc. "Writing Secure Code"
- Mike Andrews, James A. Whittaker "How to Break Web Software"
-
Klein, Amit (July 4, 2005). "DOM Based Cross Site Scripting or XSS of the Third Kind". Web Application Security Consortium. Retrieved on 2008-05-28.
下一篇 : (原创)攻击方式学习之(2) - SQL注入(SQL Injection)
作者:CoderZh(CoderZh的技术博客 - 博客园)
微博:http://t.sina.com.cn/coderzh
出处:http://coderzh.cnblogs.com
文章版权归本人所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
同源策略以及cookie安全策略
1、引言
跨站点请求伪造(Cross—Site Request Forgery).以下简称CSRF。是一种广泛存在的网站漏洞。Gmail、YouTube等著名网站都有过CSRF漏洞.甚至包括“ING DIRECT”这样的荚国第四大储蓄银行的金融机构网站。2009年3月著名网络安全机构SANS与MITRE结合来自全球超过30个软件工作者及安全专家,将CSRF列为最危险的25个编程错误之一。
2、现有的Web安全缺陷
2.1 Web安全策略
与CSRF有关的主要有三个Web安全策略:同源策略、Cookie安全策略和Flash安全策略。
2.1.1同源策略
同源指的是:同协议,同域名和同端口。同源策略,简单地说就是要求动态内容(例如,JavaScript或者VBScript)只能读取或者修改与之同源的那些HTTP应答和Cookie.而不能读取来自不同源的内容。浏览器的同源策路限制了脚本只能访问同源下的资源。
同源策略仅仅阻止了脚本读取来自其他站点的内容.但是却没有防止脚本向其他站点发出请求。因为CSRF攻击是由于某些请求被发出,而引起在服务器端执行了某些动作所引起的,所以同源策略无法防止CSRF攻击。
2.1.2 Cookie安全策略
RFC2109定义了Cookie的安全策略。服务器设置Cookie值并为Cookie设置安全属性。Cookie的安全属性包括了Domain、Path、Secure、Expires、MaxAge和HttpOnly等。Cookie安全策略类似于同源策略并且要比同源策略更安全一些,但是利用脚本,可以把Cookie的安全级别降低.甚至Cookie的path属性可以被完全绕过。如果一位攻击者可以突破或绕过两源策略的话,就可以通过DOM的变量document.cookie轻松读取Cookie。
2.1.3 Flash安全策略
默认时,Flash的安全策略与同源策略非常类似,来自于某个域的Flash应用只可以读取来自该域的响应。但是Flash的安全策略并不被同源策略限制.Adobe公司定义了F1ash的跨域策略,该策略通常定义在一个名为crossdomain.xml的策略文件中。该文件定义了哪些域可以和当前域通信。错误的配置文件可能导致兀ash突破同源策略。导致受到迸一步的攻击。安全研究人员曾经对500个顶级网站进行了分析.发现其中有143个站点使用了crossdomain.xml策略文件。而在这143个站点中。又有47个站点对来自第三方站点的连接完全接受,这可能导致CSRF漏洞。
2.2 Web认证方式和浏览器的安全缺陷
现在的Web应用程序几乎都是使用Cookie来识别用户身份以及保存会话状态。浏览器在最初加入Cookie功能时并没有考虑安全因素。假设一个网站使用了Cookie,当一个用户完成身份验证之后.浏览器得到一个标识用户身份的Cookie,只要不退出或关闭浏览器。以后访问相同网站下的页面的时候,对每一个请求浏览器都会“智能”地主动附带上该网站的Cookie来标识自己,用户不需要重新认证就可以被网站识别。当第三方WEB页面产生了指向当前网站域下的请求时,该请求也会带上当前网站的Cookie。这种认证方式,称之为隐式认证。
不同浏览器对于Cookie的处理不尽相同,Internet Explorer默认阻止向第三方发送当前的Cookie(见213节),而Firefox和Chrome则默认没有限制。
现在很多用户上网使用多窗口或多标签页浏览器,例如傲游、Firefox、Opera等。这些浏览器在方便用户的同时也增大了风险,因为它们只有一个进程运行,Cookie在各个窗121或标签页之问是共享的。
除了Cookie认证方式之外,其他Web认证机制也面临同样的问题。比如HTTP基本认证,用户通过认证后。浏览器仍会“智能”地把用户名和口令附加到之后第三方发给站点的请求中。即使网站使用了安全套接字(SSL)来加密连接.浏览器也会”智能“地自动把SSL认证信息加到第三方发给站点的请求中。
2.3 P3P的副作用
Internet Explorer在处理Cookie时,还遵守P3P(Platform forPrivaey Preferenees)规范。P3P是W3C制定的一项关于Cookie的隐私保护标准,要求网站向用户表明它对用户隐私的处理。比如将收集哪些信息。信息做何用途等。如果该站点的信息收集行为同用户设定的标准相符,则两者之闻关于个人隐私信息的协定就可以自动地缔结,而用户可毫无阻碍地浏览该站点;如果不符,浏览器会提醒用户,由用户决定是否对自己制定的个人隐私策略作出修改以进入该网站,双方最终通过一个双向的选择达成用户个人隐私策略。
P3P策略产生了一个副作用:如果一个网站设置了有效的P3P策略,Internet Explorer允许第三方到它的Web请求自动带上Cookie。网站可能遭到CSRF攻击;如果一个网站没有设置P3P策略或者P3P策略无效,第三方到它的Web请求不会带有该网站的Cookie,反而免受CSRF攻击
3、CSRF攻击的原理
网站是通过隐式认证认证用户时,只要不关闭浏览器或者退出,以后访问相同网站时,浏览器会自动在请求中附带上认证信息。如果浏览器被其它网页控制请求了这个网站的URL,可能会执行一些用户不希望的功能。
下面用例子来说明:
假设某个网站(example.com)保存了用户的电子邮件地址信息.并且通过这个邮箱地址实现密码恢复等功能。网站仅采用了Cookie的隐式认证方式来验证用户.用户在验证登录后可以用如下这个URL来更改自己的邮件地址设置:http://www.2cto.com /setemail=邮件地址
那么攻击者只要创建一个HTML页面包含以下代码:
< IMG src=“ http://www.2cto.com /setemail = 新邮件地址”>
当已经登录过example.com的用户访问这个页面的时候,浏览器就会向example.com发出请求改变用户的邮箱地址。
对于所有使用隐式的认证方式并且没有采取针对CSRF攻击的自我保护措施的网站,几乎都可能存在CSRF漏洞。
4、CSRF与XSS比较
Cross—Site Scripting Cxssl允许攻击者将恶意代码注入到受害网站的网页上,其他使用者在观看网页时就会受到影响。这类攻击通常包含了HTML以及客户端脚本语言。
CSRF与之相比区别在于:XSS攻击需要借助脚本语言,CSRF攻击则未必需要脚本语言:XSS需要受害站点接受用户输人来保存恶意代码。而CSRF攻击可能从第三方网站发起;XSS产生的主要原因是对用户输入没有正确过滤.CSRF产生的主要原因是采用了隐式的认证方式。如果一个网站存在XSS漏洞。那么它很大可能也存在CSRF漏洞。即使一个网站能够完美地坊御XsS漏洞,却未必能够防御CSRF。
另外,CSRF与XSS也不是截然分开的,一个攻击可能既是CSRF攻击。又是XSS攻击。
5.防范CSRF攻击
为了防范CSRF攻击,理论上可以要求对每个发送至该站点的请求都要显式的认证来消除威胁。比如重新输入用户名和口令。但实际上这会导致严重的易用性问题。所以,提出的防范措施既要易于实行,又不能改变现有的Web程序模式和用户习惯,不能显著降低用户体验。
5.1服务器端的防范措施
(1)对于网站所有接受用户输入的内容进行严格的过滤。这条措施不止针对CSRF漏洞,而主要是减少XSS漏洞的可能性。而一个有XSS漏洞的网站,很难保证它对CSRF是安全的。这条措施是其它安全措施的基础。
(2)GET方法只用于从服务器端读取数据,POST方法用于向服务器端提交或者修改数据。仅使用POST方法提交和修改数据不能防范CSRF攻击,但是会增加攻击的难度。避免攻击者简单地使用< IMG >等标签就能通过GET方法进行CSRF攻击。
同时,这样做也符合RFC2616推荐的Web规范。
(3)在所有POST方法提交的数据中提供一个不可预测的参数(在转到页面之前服务端生成,比如:ACTION类),比如一个随机数。或者一个根据时间计算的HASH值。并且在Cookie中也同样保存这个参数。把这个参数嵌入标签保存在FORM表单中,当浏览器提交POST请求到服务器端时.从POST数据中取出这个参数并且和Cook.ie中的值做比较,如果两个值相等则认为请求有效,不相等则拒绝。根据同源策略和Cookie的安全策略,第三方网页是无法取得Cookie中的参数值的.所以它不能构造出相同随机参数的POST请求。
另外,为了保证一个用户同时打开多个表单页面。所有页面都能正常工作,在一次会话的有效期内。只使用同一个随机参数。也就是说,在会话初始化的时候生成一个随机参数,在以后的页面和Cookie中,都使用这个参数。直到会话结束,新的会话开始时,才生成新的参数,否则会只有用户最后一次打开的页面才能正常提交POST请求.多标签或多窗口浏览器会不能正常工作。
(4)在关键的服务器端远程调用动作之前,增加人机交互环节。例如CAPTCHA人机区分识别程序㈣(典型应用如图片验证码)。
(5)利用Cookie安全策略中的安全属性,但是不要完全依赖Cookie安全策略中的安全属性,只信任同源策略,并围绕同源策略来打造Web应用程序的安全性。
(6)正确配置网站针对Flash的跨域策略文件。严格限制跨域、跨站的请求。
5.2客户端的防范措施
(1)保持浏览器更新,尤其是安全补丁,包括浏览器的Flash插件等的更新。同时也要留意操作系统、杀毒、防火墙等软件的更新。
(2)访问敏感网站(比如信用卡、网上银行等)后,主动清理历史记录、cookie记录、表单记录、密码记录,并重启浏览器才访问其他网站。不要在访问敏感网站的同时上其它网站。
(3)推荐使用某些带有“隐私浏览”功能的浏览器,比如Safail。“隐私浏览”功能可以让用户在上网时不会留下任何痕迹。浏览器不会存储Cookie和其它任何资料.从而CSRF也拿不到有用的信息。IE 8把它叫做“InPfivate浏览”,Chrome称作“Incognito模式”。
Cookie全接触:定义、用途、安全及禁用方法
什么是Cookie?
Cookie,有时也用其复数形式Cookies,指某些网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据(通常经过加密)。定义于RFC2109(已废弃),最新取代的规范是RFC2965.
Cookie最早是网景公司的前雇员Lou Montulli在1993年3月的发明。
Cookies就是服务器暂存放在你的电脑里的资料(.txt格式的文本文件),好让服务器用来辨认你的计算机。当你在浏览网站的时候,Web服务器会先送一小小资料放在你的计算机上,Cookies 会帮你在网站上所打的文字或是一些选择都记录下来。当下次你再访问同一个网站,Web服务器会先看看有没有它上次留下的Cookies资料,有的话,就会依据Cookie里的内容来判断使用者,送出特定的网页内容给你。商家可以从cookie获得用户信息,如喜欢什么产品。
Cookie是当你浏览某网站时,网站存储在你机器上的一个小文本文件,它记录了你的用户ID,密码、浏览过的网页、停留的时间等信息,当你再次来到该网站时,网站通过读取Cookie,得知你的相关信息,就可以做出相应的动作,如在页面显示欢迎你的标语,或者让你不用输入ID、密码就直接登录等。
Cookie中的内容大多数经过了加密处理,因此在我们看来只是一些毫无意义的字母数字组合,只有服务器的CGI处理程序才知道它们真正的含义。
Cookie总是保存在客户端中,按在客户端中的存储位置,可分为内存Cookie和硬盘Cookie.
内存Cookie由浏览器维护,保存在内存中,浏览器关闭后就消失了,其存在时间是短暂的。硬盘Cookie保存在硬盘里,有一个过期时间,除非用户手工清理或到了过期时间,硬盘Cookie不会被删除,其存在时间是长期的。所以,按存在时间,可分为非持久Cookie和持久Cookie.
Cookie的种类
1. Session Cookie这个类型的cookie只在会话期间内有效,即当关闭浏览器时就会被浏览器删除。设置session cookie的办法是:在创建cookie不设置Expires即可。
2. Persistent Cookie持久型cookie顾名思义就是会长期在用户会话中生效。当你设置cookie的属性Max-Age为1个月的话,那么在这个月里每个相关URL的http请求中都会带有这个cookie.所以它可以记录很多用户初始化或自定义化的信息,比如什么时候第一次登录及弱登录态等
3. Secure cookie安全cookie是在https访问下的cookie形态,以确保cookie在从客户端传递到Server的过程中始终加密的。这样做大大的降低的cookie内容直接暴露在黑客面前及被盗取的概率。
4. HttpOnly Cookie
设置成httponly的cookie只能在http(https)请求上传递。也就是说httponly cookie对客户端脚本语言(javascript)无效,从而避免了跨站攻击时JS偷取cookie的情况。当你使用javascript在设置同样名字的cookie时,只有原来的httponly值会传送到服务器。(document.cookie 无效)
5. 第三方cookie
则是种植在不同于浏览器地址栏的域名下。例如:用户访问a.com时,在ad.google.com设置了个cookie.广告。
6. Super Cookie超级cookie是设置公共域名前缀上的cookie.通常a.b.com的cookie可以设置在a.b.com和b.com,而不允许设置在。com上。
7. Zombie Cookie僵尸cookie是指那些删不掉的,删掉会自动重建的cookie.僵尸cookie是依赖于其他的本地存储方法,例如flash的share object,html5的local storages等,当用户删除cookie后,自动从其他本地存储里读取出cookie的备份,并重新种植。
Cookie 的用途
1. 会话管理
记录用户的登录状态是cookie最常用的用途。通常web服务器会在用户登录成功后下发一个签名来标记session的有效性,这样免去了用户多次认证和登录网站。
记录用户的访问状态,例如导航啊,用户的注册流程啊
2. 个性化信息
用来记忆用户相关的信息,以方便用户在使用和自己相关的站点服务。例如:ptlogin会记忆上一次登录的用户的QQ号码,这样在下次登录的时候会默认填写好这个QQ号码
用来记忆用户自定义的一些功能。用户在设置自定义特征的时候,仅仅是保存在用户的浏览器中,在下一次访问的时候服务器会根据用户本地的cookie来表现用户的设置。例如google将搜索设置(使用语言、每页的条数,以及打开搜索结果的方式等等)保存在一个COOKIE里。
3. 记录用户的行为
记录用户的点击流和某个产品或商业行为的操作率和流失率
Cookie的安全问题
1.Cookie欺骗
Cookie记录着用户的帐户ID、密码之类的信息,如果在网上传递,通常使用的是MD5方法加密。这样经过加密处理后的信息,即使被网络上一些别有用心的人截获,也看不懂,因为他看到的只是一些无意义的字母和数字。然而,现在遇到的问题是,截获Cookie的人不需要知道这些字符串的含义,他们只要把别人的Cookie向服务器提交,并且能够通过验证,他们就可以冒充受害人的身份,登陆网站。这种方法叫做Cookie欺骗。
Cookie欺骗实现的前提条件是服务器的验证程序存在漏洞,并且冒充者要获得被冒充的人的Cookie信息。目前网站的验证程序要排除所有非法登录是非常困难的,例如,编写验证程序使用的语言可能存在漏洞。而且要获得别人Cookie是很容易的,用支持Cookie的语言编写一小段代码就可以实现(具体方法见三),只要把这段代码放到网络里,那么所有人的Cookie都能够被收集。如果一个论坛允许HTML代码或者允许使用Flash标签就可以利用这些技术收集Cookie的代码放到论坛里,然后给帖子取一个吸引人的主题,写上有趣的内容,很快就可以收集到大量的Cookie.在论坛上,有许多人的密码就被这种方法盗去的。至于如何防范,目前还没有特效药,我们也只能使用通常的防护方法,不要在论坛里使用重要的密码,也不要使用IE自动保存密码的功能,以及尽量不登陆不了解底细的网站。
2.Flash的代码隐患
Flash中有一个getURL()函数,Flash可以利用这个函数自动打开指定的网页。因此它可能把你引向一个包含恶意代码的网站。打个比方,当你在自己电脑上欣赏精美的Flash动画时,动画帧里的代码可能已经悄悄地连上网,并打开了一个极小的包含有特殊代码的页面。这个页面可以收集你的Cookie、也可以做一些其他的事情,比如在你的机器上种植木马甚至格式化你的硬盘等等。对于Flash的这种行为,网站是无法禁止的,因为这是Flash文件的内部行为。我们所能做到的,如果是在本地浏览尽量打开防火墙,如果防火墙提示的向外发送的数据包并不为你知悉,最好禁止。如果是在Internet上欣赏,最好找一些知名的大网站。
禁用浏览器cookie的办法
用户可以改变浏览器的设置,以使用或者禁用Cookies.
微软 Internet Explorer
工具 > Internet选项 > 隐私页调节滑块或者点击"高级",进行设置。
Mozilla Firefox
工具> 选项> 隐私(注: 在Linux版本中,是如下操作:编辑 > 首选项 > 隐私 , 而Mac则是:Firefox > 属性 > 隐私)
查看源网页设置Cookies选项设定阻止/允许的各个域内Cookie查看Cookies管理窗口,检查现存Cookie信息,选择删除或者阻止它们
苹果计算机 Safari
Safari > 预置 > 安全标签选择以下的选项总是
接受 Cookies永不 接受 Cookies
删除flash cookie的办法:
1.点击操作系统的"开始"按钮,再点击"控制面板".
2.在打开的"控制面板"中点击 "Flash Player".
3.在打开的"flash player 设置管理器"中选择"存储",再点击"全部删除"按钮。
4.最后选中"删除所有站点数据和设置",然后点击"删除数据"按钮就即可。
接受 Cookies
仅从您浏览的站点 (例如,不接受来自其它站点的广告) 预设的选项。
您可以显示所有驻留在您浏览器中的 cookies,也可随时将它们之一删除。
NETSCAPE "PREFERENCE\ADVANCED\COOKIES",在出现的窗口中有三个选项,选择"DISABLECOOKIES"即可关闭COOKIE.在IE中,选择"查看"/"INTERNET选项"/"高级",在随后出现的窗口中找到"COOKIES"一项,选择"禁止所有的COOKIE 使用"可关闭COOKIE.
Konqueror如果没有设置cookie列表,请记住在域名前面加入".",例如。,否则百度将不会读取cookie(针对KDE 3.3)。
tomcat httponly-cookie设置
tomcat httponly-cookie设置
tomat6
很多只依赖于cookie验证的网站来说,HttpOnly cookies是一个很好的解决方案,在支持
HttpOnly cookies的浏览器中(IE6以上,FF3.0以上),javascript是无法读取和修改HttpOnly
cookies,或许这样可让网站用户验证更加安全。
JAVAEE从6.0支持专门的setHttpOnly和isHttpOnly方法,即servlet3.0规范中添加了这两个方法
得API,在此以前的版本只能用response.setHeader("SET-COOKIE,...")的方式来支持,另外还
需要看浏览器对httpOnly的支持,IE从6开始支持,其它版本在上面引入的链接里写的很清楚。
Servlet 2.5不支持在Cookie上直接设置HttpOnly属性
Using Java to Set HttpOnly
String sessionid = request.getSession().getId();
response.setHeader("SET-COOKIE", "JSESSIONID=" + sessionid + "; HttpOnly");
public class CookieFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse rsp = (HttpServletResponse) response;
Cookie[] cookies = req.getCookies();
if (cookies != null) {
Cookie cookie = cookies[0];
if (cookie != null) {
/*cookie.setMaxAge(3600);
cookie.setSecure(true);
resp.addCookie(cookie);*/
//Servlet 2.5不支持在Cookie上直接设置HttpOnly属性,3.0支持cookie.setHttpOnly(true);
String value = cookie.getValue();
StringBuilder builder = new StringBuilder();
builder.append("JSESSIONID=" + value + "; ");
builder.append("Secure; ");
builder.append("HttpOnly; ");
Calendar cal = Calendar.getInstance();
cal.add(Calendar.HOUR, 1);
Date date = cal.getTime();
Locale locale = Locale.CHINA;
SimpleDateFormat sdf =
new SimpleDateFormat("dd-MM-yyyy HH:mm:ss",locale);
builder.append("Expires=" + sdf.format(date));
rsp.setHeader("Set-Cookie", builder.toString());
}
}
chain.doFilter(req, resp);
}
public void destroy() {
}
public void init(FilterConfig arg0) throws ServletException {
}
}
Servlet 3.0 (Java EE 6) 也可以在 web.xml 配置如下:
<session-config>
<cookie-config>
<http-only>true</http-only>
</cookie-config>
<session-config>
cookie工具类,解决servlet3.0以前不能添加httpOnly属性的问题
由于使用的servlet版本是2.5,不支持httpOnly的属性,故做了个工具类来实现cookie的
httpOnly的功能。全类如下:
/**
* cookie工具类,解决servlet3.0以前不能添加httpOnly属性的问题
*
* @author zhang-long
* @createTime 2013-6-20
*/
public class CookieUtil {
/**
*
* @param response HttpServletResponse类型的响应
* @param cookie 要设置httpOnly的cookie对象
*/
public static void addHttpOnlyCookie(HttpServletResponse response, Cookie cookie){
// 判断对象是否存在null的情况
if(checkObjIsNull(response) || checkObjIsNull(cookie)){
return;
}
//依次取得cookie中的名称、值、最大生存时间、路径、域和是否为安全协议信息
String cookieName = cookie.getName();
String cookieValue = cookie.getValue();
int maxAge = cookie.getMaxAge();
String path = cookie.getPath();
String domain = cookie.getDomain();
boolean isSecure = cookie.getSecure();
StringBuffer strBufferCookie = new StringBuffer();
strBufferCookie.append(cookieName + "=" + cookieValue + ";");
if(maxAge >= 0){
strBufferCookie.append("Max-Age=" + cookie.getMaxAge() + ";");
}
if(!checkObjIsNull(domain)){
strBufferCookie.append("domain=" + domain + ";");
}
if(!checkObjIsNull(path)){
strBufferCookie.append("path=" + path + ";");
}
if(isSecure){
strBufferCookie.append("secure;HTTPOnly;");
}else{
strBufferCookie.append("HTTPOnly;");
}
response.addHeader("Set-Cookie",strBufferCookie.toString());
}
private static boolean checkObjIsNull(Object obj){
if(obj == null){
return true;
}
return false;
}
}
使用举例:
Cookie cookie1=new Cookie("n","cookieValue1");
cookie1.setMaxAge(500);
Cookie cookie2=new Cookie("cookieName2","cookieValue2");
Cookie cookie3=new Cookie("cookieName3","cookieValue3");
cookie3.setSecure(true);
Cookie cookie4=new Cookie("cookieName4","cookieValue4");
cookie4.setSecure(true);
CookieUtil.addHttpOnlyCookie(response, cookie1);
CookieUtil.addHttpOnlyCookie(response, cookie2);
CookieUtil.addHttpOnlyCookie(response, cookie3);
CookieUtil.addHttpOnlyCookie(response, cookie4);
例子中黑色的部分只有在JS中无法读出!
tomat7
一般的Cookie都是从document对象中获得的,现在浏览器在设置 Cookie的时候一般都接受一
个叫做HttpOnly的参数,跟domain等其他参数一样,一旦这个HttpOnly被设置,你在浏览器的
document对象中就看不到Cookie了,而浏览器在浏览的时候不受任何影响,因为Cookie会被放
在浏览器头中发送出去(包括ajax的时 候),应用程序也一般不会在js里操作这些敏感Cookie的
,对于一些敏感的Cookie我们采用HttpOnly,对于一些需要在应用程序中用js操作的cookie我
们就不予设置,这样就保障了Cookie信息的安全也保证了应用。
如果你正在使用的是兼容 Java EE 6.0 的容器,如 Tomcat 7,那么 Cookie 类已经有了
setHttpOnly 的方法来使用 HttpOnly 的 Cookie 属性了。
cookie.setHttpOnly(true);
设置完后生成的 Cookie 就会在最后多了一个 ;HttpOnly
另外使用 Session 的话 jsessionid 这个 Cookie 可通过在 Context 中使用 useHttpOnly 配置来
启用 HttpOnly(tomcat\conf\server.xml),例如:
<Context path="" docBase="D:/WORKDIR/oschina/webapp" reloadable="false"
useHttpOnly="true"/> //tomcat7以后默认是不TRUE。
Servlet 3.0 (Java EE 6) 也可以在 web.xml 配置如下:
<session-config>
<cookie-config>
<http-only>true</http-only>
</cookie-config>
<session-config>
对于 .NET 2.0 应用可以在 web.config 的 system.web/httpCookies 元素使用如下配置来启用
HttpOnly
<httpCookies httpOnlyCookies="true" …>
而程序的处理方式如下:
C#:
HttpCookie myCookie = new HttpCookie("myCookie"); myCookie.HttpOnly = true;
Response.AppendCookie(myCookie);
VB.NET:
Dim myCookie As HttpCookie = new HttpCookie("myCookie") myCookie.HttpOnly =
TrueResponse.AppendCookie(myCookie)
.NET 1.1 只能手工处理:
Response.Cookies[cookie].Path += ";HttpOnly";
PHP 从 5.2.0 版本开始就支持 HttpOnly
session.cookie_httponly = True