<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>程默的博客 &#187; web安全</title>
	<atom:link href="http://blog.chacuo.net/category/web-tech/web-safe/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.chacuo.net</link>
	<description>web原理、web架构、web安全、web性能、服务器性能、服务器架构、服务器安全;你不能预知明天，但你可以利用今天。你不能样样顺利，但你可以事事尽力!</description>
	<lastBuildDate>Mon, 31 Aug 2020 15:33:40 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>web应用安全 简介</title>
		<link>http://blog.chacuo.net/1353.html</link>
		<comments>http://blog.chacuo.net/1353.html#comments</comments>
		<pubDate>Mon, 09 Feb 2015 15:33:57 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web安全]]></category>
		<category><![CDATA[web应用安全]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=1353</guid>
		<description><![CDATA[一晃有一年多没有写博客了，每次想提笔写写，由于总是感觉要写的太多了，总是对自己说：“想清楚想明白再写”，这样就 [...]]]></description>
				<content:encoded><![CDATA[<p>一晃有一年多没有写博客了，每次想提笔写写，由于总是感觉要写的太多了，总是对自己说：“想清楚想明白再写”，这样就一直拖延。 另外一个原因是，觉得也没有什么人看，就这样耽搁下来了。 人是个有惰性的物种，只要惰性战胜了自己，就会找到很多理由让自己偷懒下。好了，闲话少说了，言归正传了。</p>
<p>&nbsp;</p>
<p>做了多年的web开发，遇到过很多刚刚毕业的兄弟以及刚入行的朋友。 经常在做一些功能时候，从技术设计本身出现各种问题。 他们在程序语言方面非常熟悉，但是做出来经常出现重大安全隐患！主要是用代码实现需求时候，考虑不全面，因此存在各种设计缺陷，产生技术漏洞！一些书本只会教我们 怎么样去实现功能， 而不会说 怎么样完美、无bug实现。这也是我 想写 应用安全的原因！ 希望给所有做web开发朋友，一些借鉴，写出更完美的程序！</p>
<p>上一段简单代码吧，限制只有某个a.com 来源站点，可以访问一个页面，我们代码一般如下：</p>
<div class="cnblogs_code" style="border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; padding-bottom: 5px; padding-top: 5px; padding-left: 5px; border-left: #cccccc 1px solid; padding-right: 5px; background-color: #f5f5f5">
<pre>&lt;?<span style="color: #000000">php
</span><span style="color: #008000">//</span><span style="color: #008000">读取reffer</span>
<span style="color: #800080">$reffer</span> = <span style="color: #0000ff">isset</span>(<span style="color: #800080">$_SERVER</span>["HTTP_REFFER"])?<span style="color: #800080">$_SERVER</span>["HTTP_REFFER"]:''<span style="color: #000000">;

</span><span style="color: #0000ff">if</span>(<span style="color: #008080">strpos</span>(<span style="color: #800080">$reffer</span>,"a.com")===<span style="color: #0000ff">false</span><span style="color: #000000">)
{
    </span><span style="color: #0000ff">exit</span>('禁止访问!'<span style="color: #000000">);
}

</span><span style="color: #008000">//</span><span style="color: #008000">//继续执行</span></pre>
</div>
<p>以上代码，大家应该在一些demo里面，还有书本上面都有看到过，并且也会这样写的。 据说，weixin分享地址时候，也通过这种方式来检查是不是它们的域名呢。 </p>
<p>问题出在那里呢？</p>
<p>一个 url 地址格式是： 协议://user：<a href="mailto:pass@host/path?query#hash">pass@host/path?query#hash</a>&nbsp; ，可以看到 如果只是简单检测uri 里面是否有a.com ，是不是太容易被绕过了？ 只要自己地址是<a href="http://b.com#a.com">http://b.com#a.com</a>&nbsp; ，是不是一样可以访问我们资源了？</p>
<p>&nbsp;</p>
<p>哈哈， 是不是回想起自己某时候也这么写过呢！<img class="wlEmoticon wlEmoticon-smilewithtongueout" style="border-top-style: none; border-bottom-style: none; border-right-style: none; border-left-style: none" alt="吐舌笑脸" src="http://blog.chacuo.net/wp-content/uploads/2015/02/wlEmoticon-smilewithtongueout.png">&nbsp; ，希望这个例子能够激发您的兴趣，我们除了能实现逻辑，好的程序员，应该要做到安全稳定、实现高性能程序！ 当然，我们接下来主要讲的是怎么安全实现常见web应用功能。</p>
<p>接下来章节，我就以做一个 简单网页 ‘留言薄’来说吧！&nbsp; “啊？ 为什么是 做留言薄呢”， 其实一个留言板里面功能，也能涉及到我们方方面面了，麻雀虽小、五脏俱全啦！ 另外， 记忆最深刻的的，我第一次学习web程序时候，也是从留言薄开始的呢！</p>
<p>&nbsp;</p>
<p>待续……，先跟朋友们说晚安了！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/1353.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>web应用安全参数检测方法（检测输入参数方法）</title>
		<link>http://blog.chacuo.net/360.html</link>
		<comments>http://blog.chacuo.net/360.html#comments</comments>
		<pubDate>Fri, 19 Jul 2013 08:48:33 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web安全]]></category>
		<category><![CDATA[参数检查]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=360</guid>
		<description><![CDATA[前面我们说到，web应用安全的基数是，做好参数检测！就像是小区防止小偷，必须把好所有进入门。然后，对进入人员进 [...]]]></description>
				<content:encoded><![CDATA[<p>前面我们说到，web应用安全的基数是，做好参数检测！就像是小区防止小偷，必须把好所有进入门。然后，对进入人员进行检测！这些我们都清楚的，就是有时候在web应用中，对输入参数检测时候发现困难！因为，输入参数字符可以各种各样，长度也不相同！我们从什么维度准确标识出我所需要的格式呢？</p>
<p>这里我观点是，应用对参数检测可以分为2个关卡，第一个关卡可以是，保证参数输入安全。第二个关卡是保证它是业务所需要的值。一个应用，保证安全是最基础的。我们第一关检测参数，怎么样做比较好呢？</p>
<p><strong>标识参数方法？</strong></p>
<p>所有web传入都是字符串，我们怎么样标识字符串呢？字符串都是有字符组成的，常见是ascii码，对于中文网站，有gb2312,gbk等字符。从这里看，字符个数会很多。它们之间如果做长度不一组合字符串，将会更多了。 因此，再一次说明，不要用现在字符串方法，来检测！有可能你需要限制是无底洞！可以说，对于我们一个web应用参数，90%以上，基本在ascii码就可以，很少参数会突变到这100多个字符范围。所以，标识一个字符串，可以从以下2个方面来限制：</p>
<blockquote><p>1、字符串 中字符范围 （如：如果是手机号0-9，用户名可能是字母+数字之类）</p>
<p>2、字符串 长度 （如手机号是：11位，用户名可能是：6-15位）</p>
</blockquote>
<p>以上方法可以保证，不在用户需要字符范围的字符，一定不能进入后端！我们看看一般例子！</p>
<blockquote>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #009933; font-style: italic;">/**
*读取get值
*@copyright  http://blog.chacuo.net
*@author 8292669
*@param $k string get参数名称
*@param $p string 正则表达式内容
*@return string|array 读取值
*/</span>
<span style="color: #000000; font-weight: bold;">function</span> input_get<span style="color: #009900;">&#40;</span><span style="color: #000088;">$k</span><span style="color: #339933;">,</span><span style="color: #000088;">$p</span><span style="color: #339933;">=</span><span style="color: #0000ff;">'.*'</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$v</span> <span style="color: #339933;">=</span> <span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$k</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>?<span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$k</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">:</span><span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$v</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$_v</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$v</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$k</span><span style="color: #339933;">=&gt;</span><span style="color: #000088;">$_v1</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
			<span style="color: #000088;">$_v</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$k</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=!</span><span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/^&quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$p</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;$/&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$_v1</span><span style="color: #009900;">&#41;</span>?<span style="color: #0000ff;">''</span><span style="color: #339933;">:</span><span style="color: #000088;">$_v1</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #b1b100;">return</span>  <span style="color: #000088;">$_v</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #339933;">!</span><span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/^&quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$p</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;$/&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$v</span><span style="color: #009900;">&#41;</span>?<span style="color: #0000ff;">''</span><span style="color: #339933;">:</span><span style="color: #000088;">$v</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

</blockquote>
<p>测试：var_dump(input_get(&#8216;a&#8217;,'\d+&#8217;),input_get(&#8216;b&#8217;,'\d+&#8217;));&nbsp; 读取a,b参数，都为数字的！ </p>
<blockquote><pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/07/image2.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="web应用安全参数检测方法" border="0" alt="web应用安全参数检测方法" src="http://blog.chacuo.net/wp-content/uploads/2013/07/image_thumb2.png" width="881" height="372"></a> </pre>
<pre>因为参数b输入是：2ccc，因此不是0-9字符。所以返回为空字符串！</pre>
</blockquote>
<p>上面这样每次输入正则表达式确实很麻烦的，其实，一个应用，业务字段，应该都比较固定，我们可以再在该基础上面，进一步封装些，取独立业务字段函数。如：input_getUser($k) 专门读取用户名，input_getQQ($k)专门读取QQ号。如此类推，然后我们发现真的需要独立写检测的变得非常少了！</p>
<p><strong>怎么样限制中文字符？</strong></p>
<p>我有一个真实姓名框，需要输入真实姓名！我该怎么样检测？我们知道常见中文字符表是gb2312，其实中国人取名字现在都需要在常见汉字里面挑选。也就是在区位码表中找。所以，我们问题就变成了，怎么样检查用户输入是不是在gb2312字符集中。gb2312是多字节的，一个中文都是2个字节。只要我们先对好范围就可以了。 gb2312字符集表，我们可以查看：<a title="gb2312字符集、编码表" href="http://doc.chacuo.net/gb2312" target="_blank">http://doc.chacuo.net/gb2312</a> ，</p>
<blockquote><pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/07/image3.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="gb2312字符集" border="0" alt="gb2312字符集" src="http://blog.chacuo.net/wp-content/uploads/2013/07/image_thumb3.png" width="887" height="559"></a> </pre>
<p>第一个字节范围是：A1-F7 第2个字节范围是A1-FE ，因此我们正则表达式可以写成：[\xA1-\xF7][\xA1-\xFE] 就可以对2个字节限制了。 “怎么拿过去用不了?”，这里我们做中文限制，只完成第一步，在指定字符集中，找好需要用到中文的字符编码。第二步，就是你要将原字符串转码为该字符集编码。如：你如果是utf-8编码，你需要将获取字符串先转码为gb2312，然后再用gb2312字符位置 正则表达式来检测！ 如果，你不转码，你发现刚刚找的那个字符位置正则表达式毫无用处了！通过这个，我们注意做中文位置检测时注意：</p>
<p>1、选择好字符集，找好字符位置，准备好字符范围的正则表达式</p>
<p>2、将待检测字符串，转码为选号的字符集的编码</p>
</blockquote>
<p>现在，我们知道了字符串检测方法了，无论简单参数、还是复杂中文字符参数！我们都可以轻松完成了！通过字符串中字符范围定位需要字符在实际检测中，非常安全！ 因为，很多经常出现问题字符，都不会出现在应用的参数中！只要我们保证第一个关卡，只允许包含业务相关的字符的字符串进入！应用安全，基本上没有问题！好了，就到这里吧！欢迎朋友们发表自己观点！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/360.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>web应用安全之基础（输入参数检查必要性）</title>
		<link>http://blog.chacuo.net/331.html</link>
		<comments>http://blog.chacuo.net/331.html#comments</comments>
		<pubDate>Wed, 10 Jul 2013 11:51:49 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web安全]]></category>
		<category><![CDATA[参数检查]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=331</guid>
		<description><![CDATA[好几天没有写了，电脑一直有问题，还没有修好！本来开机故障，修理了下！现在是彻底开机不了！算了，随它去吧，该换个 [...]]]></description>
				<content:encoded><![CDATA[<p>好几天没有写了，电脑一直有问题，还没有修好！本来开机故障，修理了下！现在是彻底开机不了！算了，随它去吧，该换个品牌了！先不说这些，我们进入正题，看看web应用安全基数，为什么是输入参数检查！开发web应用，工作中代码审核、漏洞修复！基本是我们对输入参数检查不够！</p>
<blockquote><p><strong>主要问题出现在3个方面：</strong></p>
<p>1、对检查认识不够！经常忘记必要参数检测，特别对于一些页面只是传值，而没有写入到后端存储的参数，更是很容易遗漏！</p>
<p>2、对那些是输入的、那些是系统环境参数 有些没有明白，导致错误的放过该检查的参数！</p>
<p>3、检查方法不正确、往往检查过后，还存在问题！ </p>
</blockquote>
<p>&#160;</p>
<p>我说说自己的一些看法吧，所有一切首先要认识到参数检查的重要性！</p>
<p><strong>为什么要参数检查？</strong></p>
<p>我们还是从生活中来看吧，现在社会上，下班回家进入小区，门口保安要检查门卡，有卡才可以进入！到公司了，进门禁系统，公司需要刷员工卡，然后进入公司！现在学校、机关等等，我们发现都会有个检查的，大家都很清楚，它的目的是保证大家安全，让一些自己允许的人才可以进入！我们发现，所有检查地点，都是在分界隔离地方，也就是在进入的入口上！</p>
<p>从上面这些场景，我们发现生活中，为了我们安全！在进入一些私人区域，都有检查口。其实web检查也是可以比拟的！web参数是最前端用户与系统接口地方，因此这个地方检查是必要的！我们只能允许满足要求的进入后端系统！这也是保证后端系统安全的前提！</p>
<p><strong>漏掉该检查地方隐患！</strong></p>
<p>这个问题，同样存在！前段时间，听到一个新闻，一个很高档的小区有很好的安全门禁检查！但是，它的地下车库到楼上，就没有增加检查！后来，一些别有用心的人，专门租车，从地下车库上到居民楼，进行偷盗！还有个新闻，一个小区进门地方，如果是单人的话，会检查，但是如果你开车进入，特别是名牌车！基本上不检查！后来，也导致一伙别有用心的人，驾车进入偷盗！我们做web应用，一定要知道那些参数来源于用户端输入，php代码里面的：$_GET,$_POST,$_REQUEST,$_SERVER,$_COOKIE,$_FILES等。那些来自用户，那些是系统！清清楚楚，明明白白检查！</p>
<p><strong>怎么样检查才正确？</strong></p>
<p>这些我们也可以看看现实生活中，我们发现公司、小区、学校，每个进入的人，都要有一张发的卡，只有持卡人才可以进入！这个是限定用户范围的，只有限定范围才可以进入！这种检查方法，很常用的，也很安全！换个思路，如果小区里面，认为自己小区高档，来小区的都穿着不错。因此，把检查改为：穿正装可以进入！这样一来，如果刚好小区里面有人因为某种原因，而穿着匆忙，可能不让进入！而另外，对于别有用心的人，买套正式衣服应该很容易！因此，也很容易逃过检查！</p>
<p>从上面两个例子我们不难发现，生活中经常检测是：通过发卡，限定用户群；而少用排除法方法！这也是，我们web参数检查中推荐的方法，限定参数的范围；不做、少做参数过滤替换检查！</p>
<p>好了，上面这些方法其实都来自生活，大家一看都明白！如果真的遇到做参数检查时候，有些迷糊！不妨想想生活中例子！其实，程序都是解决实际生活中问题，并且很多都来自于生活！参数需要检查、并且需要正确检查！下一节我将，谈谈对于参数检查范围检查的一些自己看法！欢迎大家交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/331.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>京东商城Jsonp 资源越权限访问漏洞分析</title>
		<link>http://blog.chacuo.net/323.html</link>
		<comments>http://blog.chacuo.net/323.html#comments</comments>
		<pubDate>Fri, 28 Jun 2013 10:55:34 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web安全]]></category>
		<category><![CDATA[JSONP]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=323</guid>
		<description><![CDATA[最近比较忙，电脑一直有问题，还没有修理好。本来以前买个电脑才3000来块，现在刚好过保几个月，然后修下说要70 [...]]]></description>
				<content:encoded><![CDATA[<p>最近比较忙，电脑一直有问题，还没有修理好。本来以前买个电脑才3000来块，现在刚好过保几个月，然后修下说要700多，如果换配件要1000多。这个电脑现在买个新二手，应该也就千把块，够黑了。呵呵，不说这么些了。今天我们继续分析京东商城Jsonp使用漏洞之二，未对资源访问进行授权。</p>
<p>对于Jsonp漏洞，这里我就不细说了，详细可以看：<a href="http://blog.chacuo.net/295.html">Jsonp常见安全漏洞分析(京东商城Jsonp 漏洞分析)</a> ，从上面文章，我们知道jsonp是可以跨域名调用的。<font color="#0000ff"><u>这个漏洞是：没有授权网站，可以直接在该站点访问jsonp接口资源。</u></font><font color="#000000">可能有朋友会问题：“这个漏洞有什么影响呢？”，一般我们常见有：</font></p>
<blockquote><p><font style="background-color: #ffffff" face="Arial">1.对于存在漏洞的网站来说：jsonp资源给外部调用，浪费接口资源，也给调用带来压力</font></p>
<p><font style="background-color: #ffffff" face="Arial">2.利用者，可以通过jsonp获取网站资源，构造钓鱼站点，或者给用户发送钓鱼站点。获取用户在漏洞网站上面的用户信息（用户登陆情况下），或者偷偷操作用户功能！</font></p>
</blockquote>
<p><strong>具体我们看看实例：</strong></p>
<blockquote><pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image45.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="京东商城jsonp漏洞" border="0" alt="京东商城jsonp漏洞" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb45.png" width="854" height="297" /></a> </pre>
<pre>我们看看，如果有个另外域名站点，怎么样调用该信息！</pre>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Content-Type: text/html; charset=utf-8&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span>
&lt;script&gt;
function jsonp13724(d)
{
	console.log(d);
}
&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;http://my.jd.com/order/rec.action?jsoncallback=jsonp13724&quot;&gt;
&lt;/script&gt;</pre></td></tr></table></div>

<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image46.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="京东商城jsonp漏洞" border="0" alt="京东商城jsonp漏洞" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb46.png" width="853" height="514" /></a> </pre>
<pre>&#160;</pre>
</blockquote>
<p>总结，通过上面例子，对于jsonp跨站访问，带来资源别越权调用漏洞。我们应该知道了它的原理。如果要防止这类越权访问，我们一般只需要对<u><font color="#0000ff">访问来源：reffer进行授权 </font></u>这是最简单的方法！ 也是最常用方法了。如果有朋友会问，这个漏洞有什么危害呀，看起来好像没有什么问题？如果一个站点别有用心站点(这里叫A站)，在京东商城上面发了一个链接。有不小心朋友点过去。这个时候，你刚好自己登陆了。这个时候，A站就可以悄悄读到你在京东商城一些信息了。到此，对京东商城jsonp漏洞都分析完毕，国内这么大一个商城，在这个方面使用，几乎没有做任何检测，确实有些不应该！希望，以上分析对即将应用jsonp朋友有所帮助！也需要大家发表自己看法！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/323.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GBK字符编码（字符集）缺陷攻击（注入）原理</title>
		<link>http://blog.chacuo.net/312.html</link>
		<comments>http://blog.chacuo.net/312.html#comments</comments>
		<pubDate>Mon, 24 Jun 2013 09:38:08 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web安全]]></category>
		<category><![CDATA[GBK缺陷]]></category>
		<category><![CDATA[字符编码]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=312</guid>
		<description><![CDATA[上一节，我们分析了。选择不同编码可能会导致程序带来本身潜在的漏洞。这次我们以GBK编码为例，看看怎么样通过该编 [...]]]></description>
				<content:encoded><![CDATA[<p>上一节，我们分析了。选择不同编码可能会导致程序带来本身潜在的漏洞。这次我们以GBK编码为例，看看怎么样通过该编码注入到系统中。目前很多开源系统都存在类似的注入问题。我们先来，从一个Demo开始！</p>
<p><strong>GBK字符集漏洞注入原理</strong></p>
<blockquote>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$u</span><span style="color: #339933;">=</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'u'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>? <span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'u'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">:</span><span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$u</span><span style="color: #339933;">=</span><span style="color: #990000;">addslashes</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$u</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$sql</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;select * from user where user='<span style="color: #006699; font-weight: bold;">$u</span>'&quot;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>以上是我们写的一个测试例子（GBK编码），现在很多开源系统，比较少的进行统一参数过滤，有时候为了防止注入，就直接对参数进行转义处理。我们看看，这样一个例子，我们怎么样注入进系统！</p>
</blockquote>
<blockquote>
<table class="table" border="1" rules="all" cellspacing="0" width="820" frame="box">
<thead>
<tr valign="top">
<th width="316">步骤</th>
<th width="617">备注</th>
</tr>
</thead>
<tbody>
<tr>
<td valign="top" width="316">1.传入值%D5%27 or 1=1#</td>
<td valign="top" width="617">u参数参入上面值 (%27 对应是“’”&#160; 单引号字符)</td>
</tr>
<tr>
<td valign="top" width="316">2.GET获取的值</td>
<td valign="top" width="617">0xD50x27 or 1=1# </td>
</tr>
<tr>
<td valign="top" width="316">3.Addslashes后值</td>
<td valign="top" width="617">0xD50x5C0x27 or 1=1 (意思是：誠’ or 1=1#’)&#160; #字符后面被注释掉</td>
</tr>
<tr>
<td valign="top" width="316">4.sql值 将变成</td>
<td valign="top" width="617">select * from user where user=’誠’ or 1=1#’</td>
</tr>
<tr>
<td valign="top" colspan="2">#号是sql注释符号，后面字符将截取掉</td>
</tr>
</tbody>
</table>
<pre>&#160;</pre>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image44.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="GBK编码漏洞注入测试" border="0" alt="GBK编码漏洞注入测试" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb44.png" width="821" height="280" /></a> </pre>
</blockquote>
<p>GPC转义打开，或者是通过addslashes函数，会自动在字符是单引号（<i>&#8216;</i>）、双引号（<i>&quot;</i>）、反斜线（<i>\</i>）与 NUL（<b><tt>NULL</tt></b> 字符）等字符前面增加“\”字符（0x5c)，例子里面，我们采用一个特殊前面字节0xD5，它将与该字节组合变成：0xD50x5c ，刚好是gbk字符集中字符：”誠“ 了。 后面的0&#215;27这个单引号被保留下来了！</p>
<p><strong>GBK字符集漏洞注入总结</strong></p>
<p>呵呵，这个很有意思吧，好了。我们来总结下，这类注入是2个条件的。<u><font color="#0000ff">第一是：gbk编码，第二是：程序采用了转义方法，转义了输入。</font></u> 这2个条件不苛刻，目前大部分开源系统都有gbk,utf-8编码的源码，剩下的就去看看，源码里面有没有用类似转义方法，过滤字符串了。如果有，那么这个系统某个功能，你可以去渗透下了。这个编码漏洞，网上面提的很多，不过很多时候，没有引起开发人员的足够重视，还是在不断的重现！</p>
<p>那么我们如果要注入一个参数，我们该选择什么样的入参参数呢？其实这种转义字符是单引号（<i>&#8216;</i>）、双引号（<i>&quot;</i>）、反斜线（<i>\</i>）与 NUL（<b><tt>NULL</tt></b> 字符），我们这些字符往往在程序中有特殊作用，我们只需要在前面加<strong><font color="#0000ff"><u>一个在&gt;7F字符，后面接一个%27（<i>&#8216;</i>）、%22（<i>&quot;</i>）、%5C（<i>\</i>）、%00（<tt>NULL</tt> 字符）</u></font></strong>，就可以自己让这4个字符，可以逃脱转义了。</p>
<p>好了，这个漏洞原理及注入过程分析就这些了。我们开发时候，需要注意这个问题，特别是使用GBK编码开发程序，要有这个方面的预备知识，对于自己开发安全的代码会有帮助的。更多的<a title="GBK字符集" href="http://doc.chacuo.net/gbk" rel="GBK字符集" target="_blank">GBK编码</a>，可以看<a href="http://doc.chacuo.net/gbk">http://doc.chacuo.net/gbk</a> ！（这里有很多落在5c中文字符呢）也欢迎讨论！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/312.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GBK字符编码（字符集）缺陷导致web安全漏洞</title>
		<link>http://blog.chacuo.net/309.html</link>
		<comments>http://blog.chacuo.net/309.html#comments</comments>
		<pubDate>Fri, 21 Jun 2013 09:21:34 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[web安全]]></category>
		<category><![CDATA[GBK缺陷]]></category>
		<category><![CDATA[字符编码]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=309</guid>
		<description><![CDATA[很多时候，一个web站点，选择什么样的字符编码，我们不会太过在意的。象中文网站，我们一般用gb2312,gbk [...]]]></description>
				<content:encoded><![CDATA[<p>很多时候，一个web站点，选择什么样的字符编码，我们不会太过在意的。象中文网站，我们一般用gb2312,gbk,gb18030,也可以用utf-8。但是，可能我们不知道，选择不同编码，可能因此导致程序本身设计缺陷。</p>
<p><strong>多字节编码由来</strong></p>
<p>我们先来看看最常用的，最小字符集是ascii，对应的二级制可以表示为：00-7F 编码 。它也是我们计算机使用最早通用的字符集。前期几乎可以表示所有英文字符。后来，更多使用计算机国家加入后，我们就想在计算机中表示中文字符。我们知道常见中文就有7000多个字符。ascii码就只有128字符，只有0-127编码位置，远远不够用了。因此，我们就开始制作更大字符集，并且保证兼容ascii编码。要支持更多字符，选择更大字符集。我们只能用多个字节来描述一个字符了。为了很好的与ascii码，区分开来！一般做法是：每个字节值都大于&gt;7F，如果是2个字节，那么就是：[&gt;7F][&gt;7F]。这样编码，保证很好的与ascii区分开，并且扩大了字符集。像gb2312范围在[0xA1-0xF7][0xA1-0xFE](中间很多没有填满)，它完全保证所有字节在A0之上，也就完全满足在7F之上了。</p>
<p><strong>GBK编码漏洞缘由</strong></p>
<p>通过上面的分析，我们知道gb2312编码是很好的跟ascii码分开了。 那么我们看看，GBK编码呢，它是完全兼容gb2312（就是说在gb2312字符集中每个字符位置，与gbk字符集里面位置完全一致，而且包含于gb2312)，但是，它有2万多个字符。从上面看，只能选择往下排序了。 就是从A1A0往下排了，我们发现它编码实际范围是：[0x81-0xFE]([0x40-0x7E|0x80-0xFE] ) （<a title="gbk字符集" href="http://doc.chacuo.net/gbk" rel="gbk字符集" target="_blank">GBK编码</a>），我们发现由2个字节组成，首字节范围在7F之上，而第2个字节，有一部分在0&#215;40-0x7E了。这就是导致bug原因。我们看看下面例子吧！</p>
<blockquote><p><font style="background-color: #ffffff" face="Arial">从ASCII码表中，我们知道0&#215;40-0x7E 包含字符有：“<a href="mailto:&ldquo;A-Za-z@[\">A-Za-z@[\</a>]^_`{|}~”，一共有63字符呢。</font></p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image43.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="GBK编码漏洞" border="0" alt="GBK编码漏洞" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb43.png" width="574" height="251" /></a> </pre>
<p>选择gbk编码，运行上面代码，就一条简单的命令导致出现错误，说字符串 赋值 没有结束！ 呵呵，估计很多人看到这个就会认为是php 出Bug了。但是，如果我们变成$a=”誠a”，发现可以正常运行了。是不是觉得很奇葩啦！！</p>
<p>&#160;</p>
</blockquote>
<p>原因分析:我们知道文件存在磁盘都是二级制方式，无论你存什么字符，最终都是以<strong>该字符的在所选字符集中字符编码保存</strong>。php解析时候，最小分析单元是字节。无论你是多字节还是单字节字符。最终都是按照字节来处理的。<font color="#0000ff"><u>“誠”&#160; GBK编码是 D55C，php按字节来解释，5C对应字符是“\” 字符。后面直接跟个‘”’，相当于被转义了。 因为没有闭合，因此出现错误！</u>。</font><font color="#000000">大家看出问题所在了吧，按自己处理的话，会自然把多字节拆成单字节了。这样就会出现很多奇怪问题了。 </font></p>
<p>总结：通过上面讲解，我们知道了多字节编码过程，以及GBK导致简单程序出错的原因。其实，我们很多程序语言里面，都会以单个字节来解析的。这样，当你选择多字节GBK编码中文时，刚好有字节落在特殊位置，将会出现奇怪错误问题。而且，还将给系统带来本身的漏洞，后面我再说说，GBK编码缺陷，导致漏洞、以及专门利用该编码漏洞缺陷进行系统入侵！好了，先到这里了，欢迎交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/309.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>京东商城Jsonp 漏洞分析 （京东商城XSS漏洞）</title>
		<link>http://blog.chacuo.net/304.html</link>
		<comments>http://blog.chacuo.net/304.html#comments</comments>
		<pubDate>Thu, 20 Jun 2013 07:27:45 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web安全]]></category>
		<category><![CDATA[JSONP]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=304</guid>
		<description><![CDATA[继续我们jsonp 安全使用分享吧！上一篇文章我们提到jsonp使用，常见2种类型漏洞出现！详细可以看看：Js [...]]]></description>
				<content:encoded><![CDATA[<p>继续我们jsonp 安全使用分享吧！上一篇文章我们提到jsonp使用，常见2种类型漏洞出现！详细可以看看：<a href="http://blog.chacuo.net/295.html">Jsonp常见安全漏洞分析</a> ，今天我们来结合实例分析下该漏洞的测试、及利用过程吧！</p>
<p><strong>题外话</strong></p>
<p>为什么我选择是京东商城来分析它的jsonp 漏洞呢，其实主要原因最近6.18一直在做活动，我也买了不少便宜东西。现在该商城越做越好了。它系统也非常庞大，速度性能也很好。当时在购物时候，只是想看看，它的系统分离设计方面。通过分析页面http请求，发现有很多jsonp调用（也许跟换域名有关系，2种域名都可以访问，中间用jsonp交换数据），于是就看看，jsonp常见2种安全方面，有没有做处理。结果一测试。发现完全没有做任何处理，几乎是完完全全暴露出来。个人认为，对于这么大站点，这一点还是头一次遇到！居然，没有任何参数处理、以及资源授权！</p>
<p><strong>京东商城Jsonp xss漏洞分析</strong></p>
<blockquote>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image40.png"><img style="display: inline; border-width: 0px;" title="京东商城xss漏洞" alt="京东商城xss漏洞" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb40.png" width="853" height="379" border="0" /></a></pre>
<p>我们看到，该请求就是一个jsonp，</p>
<p>默认返回：jsonp13**********({&#8220;Identity&#8221;:{&#8220;Name&#8221;:&#8221;",&#8221;IsAuthenticated&#8221;:false}})，我们知道callback传入参数，会在response中 作为函数调用名称返回！</p></blockquote>
<p><strong>分析callback 字符范围</strong></p>
<blockquote><p><span style="background-color: #ffffff; font-family: Arial;">1、测试下有没有屏蔽常见特殊字符” &lt;&gt; ()&#8217;&#8221;;. {}“，以下这些字符，经常会用到xss里面的。</span></p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image41.png"><img style="display: inline; border-width: 0px;" title="京东商城callback没有屏蔽特殊字符" alt="京东商城callback没有屏蔽特殊字符" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb41.png" width="841" height="523" border="0" /></a></pre>
<pre></pre>
</blockquote>
<p>到这里，分析说明这里存在着xss注入漏洞的。而且，可以选择很多种方法注入！ 本编文章，旨在说明jsonp xss漏洞成因！不会具体去扩大漏洞拿到其它什么权限。以下还有个很有意思事情，callback其实，jd对一些特殊字符串做了处理的。我们看看：</p>
<blockquote>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image42.png"><img style="display: inline; border-width: 0px;" title="image" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb42.png" width="832" height="470" border="0" /></a></pre>
<pre></pre>
</blockquote>
<p>从上图中，我们可以看到，京东商城，对输入callback对一些特定的字符串进行了屏蔽处理！这也是，我们做xss漏洞检查时候，经常出现问题。<span style="color: #0000ff;"><span style="text-decoration: underline;">屏蔽字符串能够屏蔽完吗？常见26字符，长度不一任意组合。该有多少字符串呢？ </span></span><span style="color: #000000;">很多朋友，在做安全检测时候，就是屏蔽某些觉得很不安全的标签就认为安全了。 其实，我们发现这样做法只能是一时安全，过不了多久，你会发现又有新的字符串出现。你会为此花费大量的人力物力！</span><span style="color: #0000ff;"><span style="text-decoration: underline;">好了，做类似事情，我们最好方法是，认证那些觉得安全的字符，予以放行！ </span></span></p>
<p>其实，<strong>为什么用白名单方法放行允许的字符呢？ 而不是去过滤一些字符串。</strong>原因刚刚说了，字符串太多了。过滤不过来！另外是，我们自己每个业务参数，会用到那些字符其实我们更清楚。另外有人会问，<strong>为什么不去屏蔽不用的字符呢？</strong>我们知道基础<a title="ascii码" href="http://doc.chacuo.net/ascii" target="_blank" rel="ascii码">ascii码</a>有0-127,128字符。往往我们，不会用到的字符可能更多呢，我们去过滤不会用到字符，有时候更困难！</p>
<p><strong>正确检查jsonp callback方法</strong></p>
<p>建议收到callback函数对它进行白名单字符范围检测！我们可以用一般函数检测规范来检查就可以了。 既然它是一个函数名称，<strong>一般都是字符+数字+下划线+点号（对象分割）。</strong>那么我们检测变得非常简单，代码类似如：</p>
<blockquote>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$callback</span> <span style="color: #339933;">=</span> <span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'callback'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>?<span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'callback'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">:</span><span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/^[0-9a-zA-Z_.]+$/&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$callback</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'参数错误！'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

</blockquote>
<p>后记：以上是分析一个jsonp xss漏洞过程。要检测一个站点是否有该漏洞，其实简单方法，就是看通过参数传入进去的特殊字符，是不是原原本本的response 返回出来。 如果有朋友问我，怎么样利用该漏洞，它能做点什么？ 你可以把它比作一个蚁穴，能带来多大危害，看蚂蚁怎么样啃食啦！这些年，sql注入几乎难找了，不过xss漏洞是头号杀手。只要有xss漏洞出现，几乎可以做到无所不能，就看利用的人怎么用了。 以上漏洞，我反馈京东商城，这么好的一个网站，不能因为这个小小xss，给用户带来大的安全隐患了！最后，欢迎朋友提出自己建议！还有一个忘记说了，就是它的jsonp访问权限完全没有限制，下次再分享吧！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/304.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Jsonp常见安全漏洞分析(京东商城Jsonp 漏洞分析)</title>
		<link>http://blog.chacuo.net/295.html</link>
		<comments>http://blog.chacuo.net/295.html#comments</comments>
		<pubDate>Wed, 19 Jun 2013 08:45:39 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web安全]]></category>
		<category><![CDATA[JSONP]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=295</guid>
		<description><![CDATA[JSONP（JSON with Padding）是资料格式 JSON 的一种“使用模式”，可以让网页从别的网域 [...]]]></description>
				<content:encoded><![CDATA[<p><b>JSONP</b>（<b>JSON with Padding</b>）是资料格式 JSON 的一种“使用模式”，可以让网页从别的网域要资料。这个解释来自于互联网上面的答案。jsonp只是 一种使用json模式，之所以能够很广泛使用。主要用它来解决跨域访问问题。可以方便跨域名传输数据。一些是一个jsonp的例子。但是，正确的使用jsonp是至关重要的，用得不好。将带来重要资料把超范围访问，还会带来各自xss漏洞。</p>
<p><strong>JSONP跨域请求例子</strong></p>
<blockquote><p>传统的ajax ，往往是 XMLHttpRequest ，读取一个接口，返回类似: {&#8220;Name&#8221;: &#8220;小明&#8221;, &#8220;Rank&#8221;: 7} json值。一般我们都采用xmlhttprequest方法通过状态判断执行请求是否完毕。</p>
<p>JSONP的使用模式里，该URL回传的是由自定义传入函数名，动态生成JSON作为该函数入参，这就是JSONP 的“填充（padding）”或是“前辍（prefix）”的由来。</p>
<p>请求：</p>
<pre>&lt;script type="text/javascript"
         src="http://www.example.com/RetrieveUser?UserId=1823&amp;callback=parseResponse"&gt;
     &lt;/script&gt;</pre>
<pre>返回：</pre>
<pre>parseResponse({"Name": "Cheeso", "Id" : 1823, "Rank": 7})</pre>
<pre></pre>
<pre></pre>
</blockquote>
<p>parseResponse是传入参数值决定的，这样好处通过script标签可以解决跨域问题，并且只要script src地址加载完，js解析引擎就开始执行src地址返回 js内容了。 我们使用者不用关心，什么时候src地址加载解析完。只用写好接收函数：parseResponse，到时候自动回执行该项目。比传统ajax确实多了很多方便！目前，象google翻译，地图等都用该方法。实现了跨域及异步调用！</p>
<p><strong>JSONP漏洞将来自哪里？</strong></p>
<p>它给我们带来的发布，是毫无疑问的。那么它将会有哪些漏洞呢？首先，我们知道，<span style="text-decoration: underline;"><span style="color: #0000ff;">一切输入是有害的</span></span>。传入callback 值会在结果里面直接返回。因此，如果该参数过滤不严格。可以随便输入：callback值为：alert(‘1’);parseResponse  字符串。返回结果会打印个alert窗口，然后也会正常执行。</p>
<p>那么另外我们知道，flash是可以跨域的。flash请求外部资源，现在都有个”<em>crossdomain.xml</em>”，可以授权允许那些来源的站点，访问指定站点的资源。其实目的就是为了防止，资源被越权调用了。 如果我们不对其授权，那么任何网站都可通过：创建script标记，读取我网站资源了！这个安全项，也就是是否有对访问来源进行了授权访问！</p>
<p><strong>JSONP漏洞总结：</strong></p>
<p>知道了JSONP漏洞点主要有：callback参数注入、资源访问授权设置！我们其实，可以通过这2项，来检测我们的做的JSONP项目，里面是否有安全隐患了。好了，今天先分析到这里。这些漏洞都是，技术实现型漏洞！只要，我们明白了方法，杜绝是很容易的。之所以会出现类似安全隐患，更多来自，<span style="color: #0000ff;"><span style="text-decoration: underline;">不知道这里有类似安全问题！ </span>，</span><span style="color: #000000;">题外话、发发感慨！！现在网上看到很多教程，以及书籍都只会讲，怎么样使用某个功能，它的方法、技巧等等！很少解决，技术功能点安全避免漏洞的调用方法！</span><span style="color: #0000ff;"><span style="text-decoration: underline;">做一个功能很重要，但是我始终认为，开发一个安全、稳定功能是最基础的前提。 如果做的功能不安全，稳定！它急着上线，只会带来更大的风险、或是损失！！！</span> </span><span style="color: #000000;">  欢迎大家交流，提出更换的建议！（”什么？这里不是说京东商城有JSONP漏洞吗？“  ”对!没错！” 今天我这里分析漏洞点，大家可以找找京东商城这方面使用漏洞，我们下次分享实例！)</span></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/295.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>php header 重定向常出现功能(使用)漏洞</title>
		<link>http://blog.chacuo.net/276.html</link>
		<comments>http://blog.chacuo.net/276.html#comments</comments>
		<pubDate>Sat, 15 Jun 2013 09:45:28 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web安全]]></category>
		<category><![CDATA[header]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=276</guid>
		<description><![CDATA[php header函数功能强大，可以给用户发送各种header头信息，只要header头里面能够发送的内容， [...]]]></description>
				<content:encoded><![CDATA[<p>php header函数功能强大，可以给用户发送各种header头信息，只要header头里面能够发送的内容，都可以通过header函数来完成。如发送302跳转，设置cookie，发送401认证，发现last-modify等等！ HTTP/1.1 specification for more information on <acronym>HTTP</acronym> headers，都可以用该函数完成。总之一句话，任何服务区response应答的头信息几乎都可以用它来发送。如：</p>
<blockquote>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image34.png"><img style="background-image: none; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="response 服务器响应头" alt="response 服务器响应头" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb34.png" width="572" height="222" border="0" /></a></pre>
</blockquote>
<pre></pre>
<pre>这里我们经常用header发送302跳转，会发现一个问题。在走查代码时候，遇到很多同人会有类似操作代码，如：</pre>
<blockquote>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Content-type: text/html; charset=utf-8&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//判断用户是否授权</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'用户未授权'</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;location:forbidden.php&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">///下面是进行摸个记录操作</span>
<span style="color: #666666; font-style: italic;">//删除条记录，或者修改某条记录……</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="php" style="font-family:monospace;">&nbsp;</pre></td></tr></table></div>

</blockquote>
<p>这类代码，在开发中很常见，我们会发现，一个没有权限用户，操作该记录，网页会跳转到未授权页面，但是：<strong>记录任然被修改了</strong>，问题我们找到了，一般操作人员，对于js跳转会知道是前端浏览器跳转的。但是对于php操作跳转，<span style="color: #9b00d3;"><span style="text-decoration: underline;">错误认为是服务器跳转，好像php以执行到location，然后就终止了下面运行。 </span></span><span style="color: #000000;">其实，知道header函数真实意义就很容易理解了：<b>header()</b> is used to send a raw <acronym>HTTP </acronym>header！</span></p>
<p>header location 302实际上只是如下：</p>
<blockquote>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image35.png"><img style="background-image: none; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="response 服务器302响应头" alt="response 服务器302响应头" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb35.png" width="576" height="266" border="0" /></a></pre>
<pre>跟其它普通echo 函数没有多大区别，只是给header信息头,echo 一行而已。</pre>
<pre></pre>
</blockquote>
<p><strong>屏蔽Bug方法：</strong></p>
<pre></pre>
<p>知道了，发送header跳转，服务器不会终止程序，因此为了安全起见。<span style="text-decoration: underline;"><span style="color: #9b00d3;">header locaction后，最好加一句exit()函数。</span></span> 这样，php解析引擎就会停止解析了！我们正确方法是封装个header_302方法</p>
<blockquote>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #666666; font-style: italic;">/*header_302跳转*
 * *
 *@author http://blog.chacuo.net/
 * @param string $url 跳转url
 */</span>
<span style="color: #000000; font-weight: bold;">function</span>  header_302<span style="color: #009900;">&#40;</span><span style="color: #000088;">$url</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">headers_sent</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'header 已经发送过！'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;location:<span style="color: #006699; font-weight: bold;">$url</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

</blockquote>
<p>后记：这类问题，不光出在php程序中，其它很多header loction跳转语言程序，原理相同。都有类似功能，很多时候。都是使用时候没有注意，造成的。 容易在代码走查中，遗漏掉！好了，先到这里，欢迎交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/276.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>web文件操作常见安全漏洞（目录、文件名检测漏洞）</title>
		<link>http://blog.chacuo.net/152.html</link>
		<comments>http://blog.chacuo.net/152.html#comments</comments>
		<pubDate>Wed, 05 Jun 2013 10:35:54 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web安全]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[文件操作漏洞]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=152</guid>
		<description><![CDATA[做web开发，我们经常会做代码走查，很多时候，我们都会抽查一些核心功能，或者常会出现漏洞的逻辑。随着技术团队的 [...]]]></description>
				<content:encoded><![CDATA[<p>做web开发，我们经常会做代码走查，很多时候，我们都会抽查一些核心功能，或者常会出现漏洞的逻辑。随着技术团队的壮大，组员技术日益成熟。 常见傻瓜型SQL注入漏洞、以及XSS漏洞。会越来越少，但是我们也会发现一些新兴的隐蔽性漏洞偶尔会出现。这些漏洞，跟多来自开发人员，对一个函数、常见模块功能设计不足，遗留下的问题。以前我们能够完成一些功能模块，现在要求是要安全正确方法完成模块才行。 接下来，我会分享一些常见功能模块，由于设计原因导致漏洞出现。下面，我们先看下，读取文件型功能漏洞。</p>
<p>我们先看下下面一段代码，通过用户输入不同目录，包含不同文件</p>
<blockquote><pre style="text-indent: 0px" lang="php">&lt;?php
///读取模块名称
$mod = isset($_GET['m'])?trim($_GET['m']):'index';

///过滤目录名称不让跳转到上级目录
<strong><u>$mod = str_replace("..",".",$mod);</u></strong>

///得到文件
<strong><u>$file = "/home/www/blog/".$mod.".php";</u></strong>

///包含文件
@include($file);

</pre>
<pre></pre>
</blockquote>
<p>这段代码，可能在很多朋友做的程序里面有遇到过，对于新人来说，也是很容易出现这样问题，记得走查遇到该代码时候，我问到，你这个代码安全方面能做到那些？</p>
<p>答：1. 对”..”目录有做替换，因此用户传入模块名里面有有..目录都会被替换掉了。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.构造拼接file名称，有前面目录限制，有后面扩展名限制，包含文件就会限制在该目录了</p>
<ul>
<li>
<h3><strong>这段代码真的做到了目录安全检测吗？</strong></h3>
</li>
</ul>
<p>我们来测试下，如果$mod传入这个值将会是什么样的结果。</p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image1.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb1.png" width="587" height="96"></a> </p>
<p>$mod 通过构造输?mod=&#8230;%2F&#8230;%2F&#8230;%2F&#8230;%2Fetc%2Fpasswd%00 ，我们看结果将是：</p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image2.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb2.png" width="593" height="304"></a> </p>
<p>居然include(“/etc/passwd”)文件了。 </p>
<ul>
<li>
<h3><strong>怎么逃脱了我参数限制呢？</strong></h3>
</li>
</ul>
<h3><strong></strong>&nbsp;</h3>
<p><strong>首先：</strong>做参数过滤类型去限制用户输入本来就不是一个好方法，一般规则是：<u><font color="#0000ff">能够做检测的，不要做替换 </font></u>只要是检测不通过的，直接pass 掉！这是我们的一个原则。过滤失败情况，举不胜举，我们来看看，实际过程。</p>
<p>1、输入”…/…/…/” 通过把”..” 替换为”.”后</p>
<p>2、结果是”../../../” 就变成了这个了</p>
<p>有朋友就会说，如果我直接替换为空格是不是就好了？在这个里面确实可以替换掉。但是不代表以后你都替换为空格就好了。再举例子下。如：有人将字符串里面javascript替换掉。代码如下：</p>
<blockquote>
<p>……</p>
<p><font style="background-color: #ffffff" face="Arial">$msg = str_replace(“javascript”,””,$msg);</font></p>
</blockquote>
<p><u>看似不会出现了javascript了，但是，如果输入:jjavascriptavascript 替换，会替换掉中间一个变为空格后。前面的”j” 跟后面的会组成一个新的javascript了。 </u></p>
<p><strong>其次：</strong>我们看看，怎么逃脱了，后面的.php 限制呢。用户输入的参数有：”etc/passwd/0” ，\0字符非常特殊，一段连接后，文件名称变成了”……etc/passwd\0.php”，你打印出该变量时候，还是正确的。但是，一段放入到文件读写操作方法里面，\0后面会自动截断。操作系统，只会读取……etc/passwd文件了。 “\0”会出现在所有文件系统读写文件变量中。都会同样处理。这根c语言\0作为字符串完整标记有关系。</p>
<p>通过上面分析，大家发现做文件类型操作时候，一不注意将产生大的漏洞。而且该漏洞就可能引发一系列安全问题。</p>
<ul>
<li>
<h3><strong>该怎么做文件类操作呢？</strong></h3>
</li>
</ul>
<p>到这里，估计有人就会思考这个，做文件读写操作时候，如果路径里面有变量时候，我该怎么样做呢？有人会说，替换可以吗？ “可以”，但是这个方法替换不严格，将会出现很多问题。而且，对于初写朋友，也很难杜绝。做正确的事情，选择了正确的方法，会从本身杜绝问题出现可能了。 这里，我建议：对于变量做白名单限制。</p>
<ol>
<li><strong>什么是白名单限制</strong><br />
<blockquote>
<p><font style="background-color: #ffffff" face="Arial">举例来说：</font></p>
<p>$mod = isset($_GET['m'])?trim($_GET['m']):&#8217;index&#8217;;<font style="background-color: #ffffff" face="Arial"> ///读取模块名称后</font></p>
<p><font style="background-color: #ffffff" face="Arial">mod变量值范围如果是枚举类型那么：</font></p>
<p><font style="background-color: #ffffff" face="Arial">if(!in_array($mod,array(‘user’,’index’,’add’,’edit’))) exit(‘err!!!’);</font></p>
<p><font style="background-color: #ffffff" face="Arial">完全限定了$mod，只能在这个数组中，<strong>够狠！！！！</strong></font></p>
<p>&nbsp;</p>
</blockquote>
<li><strong>怎么做白名单限制</strong></li>
</ol>
<p>通过刚才例子，我们知道如果是枚举类型，直接将值放到list中即可，但是，有些时候，这样不够方面。我们还有另外一个白名单限制方法。就是<strong>限制字符范围</strong></p>
<blockquote>
<p><font style="background-color: #ffffff" face="Arial">举例来说：</font></p>
<p>$mod = isset($_GET['m'])?trim($_GET['m']):&#8217;index&#8217;;<font style="background-color: #ffffff" face="Arial"> ///读取模块名称后</font></p>
<p>我限制知道$mod是个目录名称，对于一般站点来说，就是字母加数字下划线之类。</p>
<p>if(!preg_match(“/^\w+$/”,$mod)) exit(‘err!!!’);</p>
<p>字符只能是：[A-Za-z0-9_] 这些了。<strong>够狠！！！</strong></p>
</blockquote>
<p>&nbsp;</p>
<p><strong>总结：</strong>是不是发现，白名单限制方法，做起来其实很简单，你知道那个地方要什么，就对输入检测必须是那些。而且，检测自己已知的，比替换那些未知的字符，是不是简单多了。 好了，先到这里，正确的解决问题方法，会让文件简单，而且更安全！！欢迎交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/152.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>web上存漏洞及原理分析、防范方法（安全文件上存方法）</title>
		<link>http://blog.chacuo.net/142.html</link>
		<comments>http://blog.chacuo.net/142.html#comments</comments>
		<pubDate>Mon, 03 Jun 2013 10:08:42 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web安全]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[上存漏洞]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=142</guid>
		<description><![CDATA[看我上两篇，我们知道，上存漏洞常见有，文件名检测漏洞，还有就是文件格式检查漏洞。 另外还有个一个，就是保存文件 [...]]]></description>
				<content:encoded><![CDATA[<p>看我上两篇，我们知道，上存漏洞常见有，<a href="http://blog.chacuo.net/136.html" target="_blank">文件名检测漏洞</a>，还有就是<a href="http://blog.chacuo.net/141.html" target="_blank">文件格式检查漏洞</a>。 另外还有个一个，就是保存文件存在漏洞。这类漏洞，主要是可以读取用户传入路径名称，采用不正确的过滤方法，导致恶意用户，将文件上存到非预期的地方，带来安全隐患。</p>
<p>其实，我们抓住几个地方即可，我们先来分析下，既然用户要上存文件，而且文件将是多种多样格式；可能有的文件内容与用户传入格式不一致，有的文件内容还夹杂木马代码。 那么，我们让用户上存文件，跟站点文件做一个分别授权，做隔离。</p>
<ul>
<li>
<h3><strong><span style="text-decoration: underline;">让保存上存目录独立开来，目录权限只读不能执行</span></strong></h3>
</li>
</ul>
<p>这一步从系统设计加以授权，无论你上次什么文件，都不可能执行到。就算我不做任何检测，你的文件都上存到这里了，也不会对我系统构成安全。（如果有用户上存一些反动言语的图片，那另外需要处理的）</p>
<h3></h3>
<ul>
<li>
<h3><strong><span style="text-decoration: underline;">不直接使用服务器传入值，所有都要进行检测</span></strong></h3>
</li>
</ul>
<p>这类跟我们做一切输入都是有害原则一样，对于客户端传入的：type, name ，都要进行判断，不直接使用。对于要生成到某个目录，某个文件名。</p>
<p><span style="text-decoration: underline;"><strong>文件名</strong>最好方法是：自己写死目录（不要读取传入目录），文件名，最好自己随机生成，不读取用户文件名。文件扩展名，可以取最右边”.”后面字符。</span></p>
<p>以上2个方法，刚好从2个方面对上存做了整体约束。</p>
<p>方法2 ： 保存上存文件名，按照自己指定目录写入，并且文件名自己生成的。</p>
<p>方法1：只要保证文件写对了位置，然后从配置上，对写入目录进行权限控制，这个是治本。可以做到，你无论上存什么文件，都让你没有权限跳出去可以运行。</p>
<p>&nbsp;</p>
<p>以上2个方法，一起使用，可以保证文件正确存到地方，然后，权限可以控制。 这里顺便说明下， 判断用户上存文件是否满足要求类型，就直接检查文件扩展名，只要满足扩展名就让上存。 反正，做了执行权限限制，你不按要求上存内容，也无妨。 反正，不能执行，也不会有多大危害性的。</p>
<ul>
<li><strong>正确步骤：</strong></li>
</ul>
<p><span style="text-decoration: underline;"><span style="color: #0000ff;">1.读取文件名，验证扩展名是不是在范围内</span></span></p>
<p><span style="text-decoration: underline;"><span style="color: #0000ff;">2.自己定义生成的文件名，目录，扩展名可以来自文件名扩展名。 其它值，都自己配置，不读取上存中内容</span></span></p>
<p><span style="text-decoration: underline;"><span style="color: #0000ff;">3.将文件 移到新目录(这个目录权限设置只读)</span></span></p>
<p>&nbsp;</p>
<p>好了，以上是一般操作方法，希望对大家有帮助，也欢迎朋友们交流！也希望提供更好的方法！接下来，我会在web 开发中，常见一些方法功能安全设计方面继续写一些我的心得，看法！ 欢迎大家随时交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/142.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>web上存漏洞及原理分析、防范方法（文件类型检测漏洞）</title>
		<link>http://blog.chacuo.net/141.html</link>
		<comments>http://blog.chacuo.net/141.html#comments</comments>
		<pubDate>Sun, 02 Jun 2013 08:59:00 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web安全]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[上存漏洞]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=141</guid>
		<description><![CDATA[通过上一篇文章，我们知道wed上存漏洞，最常见一种是文件名检测漏洞，接下来，我们看看另外一种漏洞，上存文件类型 [...]]]></description>
				<content:encoded><![CDATA[<p>通过上一篇文章，我们知道wed上存漏洞，<a href="http://blog.chacuo.net/136.html" target="_blank">最常见一种是文件名检测漏洞</a>，接下来，我们看看另外一种漏洞，上存文件类型漏洞，这也是一种较为容易出现问题。</p>
<p>我当时就想，既然我知道我需要允许上存什么样的文件，那么，我就只允许你上存该文件。只要我文件类型判断准确了，你想上存能够执行的代码。我都给阻止掉，不就行了吗？ 这确实，是个好的方法，但是我们再做的时候，往往会出现下面一些问题。</p>
<p>这里我们看下常见实现的php代码。 这里，常见两个问题是：</p>
<blockquote><p><font style="background-color: #ffffff" face="Arial"></font></p>
<p><font style="background-color: #ffffff" face="Arial"><strong><u>1.读取文件type,直接做文件类型判断</u></strong></font></p>
<p><font style="background-color: #ffffff" face="Arial"><u><strong>2.通过工具分析文件格式，以此来确认文件类型</strong></u></font></p>
<p><font style="background-color: #ffffff" face="Arial"></font></p>
</blockquote>
<ul>
<li>
<h3><strong>问题一：读取文件type，判断文件类型</strong></h3>
</li>
</ul>
<blockquote><pre>&#160;</pre>
<pre style="text-indent: 0px">if(isset($_FILES['img']))
{
    $file = save_file($_FILES['img']);
	if($file===false) exit('上存失败！');
	
	echo &quot;上存成功！&quot;,$file;
}



function check_file($img)
{
	///读取文件
	if($img['error']&gt;0) return false;
	
	$type = $img['type'];
	$filename = $img['name'];
	
	
	///读取文件扩展名
	$len=strrpos($filename,&quot;.&quot;);
	if($len===false) return false;
	
	//得到扩展名
	$ext = strtolower(substr($filename,$len+1));
	
	///判断文件类型
	<strong><u><font color="#0000ff">if($type &amp;&amp; preg_match('%^image/.+$%',$type)) return $ext;</font></u></strong>
	
	return false;
}

function save_file($img)
{
	$ext = check_file($img);
	if(!ext) return false;
	
	//格式检测ok，准备移动数据
	<strong><u><font color="#0000ff">$filename = time().$ext;</font></u></strong>
	$newfile = &quot;upload/&quot; .$filename;
	if(!move_uploaded_file($img[&quot;tmp_name&quot;],$newfile)) return false;
	
	return $newfile;

}</pre>
</blockquote>
<h3><strong></strong></h3>
<p>以上加蓝色代码，是关键，这个里面我们直接读取type类型，也就是文件内容。通过第一篇知识：<a href="http://blog.chacuo.net/108.html" target="_blank">web上存漏洞及原理分析、防范方法</a> 我们知道，type来自浏览器端浏览器自动传入变量。 如果是浏览器，这个值一般没有问题。但是，如果是来自用户自己组织的包，他可以给type 设置个：image/jpeg值， 然后，给name 一个 index.php 值。 </p>
<p><u><font color="#ff0000">估计大家已经看到问题，这样一来，我们生成的文件$filename变成为：time().’php’了。 就创建一个php文件。</font></u></p>
<ul>
<li>
<h3><strong>通过工具分析文件格式，以此来确认文件类型</strong></h3>
</li>
</ul>
<h1><strong></strong></h1>
<p>我们已经清楚知道了,type值是可以随便构造的，这类检查用户类型方法。是没有任何作用，恶意用户，可以随便给一个php文件发送上来，传一个image类型。 那么，肯定有朋友会说，我直接用php程序，去分析用户传入的tmp_name 文件格式，这个总靠谱吧！ 我们看看下面代码。</p>
<blockquote>
<pre style="text-indent: 0px">function check_file($img)
{
	///读取文件
	if($img['error']&gt;0) return false;
	
	$typelist = array(array(&quot;FFD8FFE1&quot;,&quot;jpg&quot;),
	array(&quot;89504E47&quot;,&quot;png&quot;),
	array(&quot;47494638&quot;,&quot;gif&quot;),
	array(&quot;49492A00&quot;,&quot;tif&quot;),
	array(&quot;424D&quot;,&quot;bmp&quot;));
	
	$file = $img['tmp_name'];
	$filename = $img['name'];
	
	
	///读取文件扩展名
	$len=strrpos($filename,&quot;.&quot;);
	if($len===false) return false;
	
	//得到扩展名
	$ext = strtolower(substr($filename,$len+1));
	
	///判断文件类型
	//读取文件开头15字节，一般通过这些字节值，可以确定它的格式
	$file = @fopen($file,&quot;rb&quot;);
	$bin = fread($file, 15);
	
	foreach ($typelist as $v)
	{
		$blen=strlen(pack(&quot;H*&quot;,$v[0])); //得到文件头标记字节数
		$tbin=substr($bin,0,intval($blen)); ///需要比较文件头长度
		 
		<strong><u><font color="#0000ff">if(strtolower($v[0])==strtolower(array_shift(unpack(&quot;H*&quot;,$tbin))))</font></u></strong> 
		{
			return $ext;
		}
	}
	
	return false;
}</pre>
</blockquote>
<p>该方法，直接分析用户传入文件格式，然后决定该文件类型，是否允许保存！这套，我们看来非常可靠方法，应该很准确，应该没有问题，不读取type,自己来分析格式。 其实：如果用户传入一个文件，前面4字节是：89504E47， 然后，后面加入一段&lt;?php代码 。上存的文件名称是image.php 。这样一来，我们发现，这段代码保存为php文件了。 只是这个文件，前面一部分可能是图片格式，后面一部分，只纯粹的php 程序。 通过浏览器，去访问下这个，还真的可以运行呢。 很久以前，就有人做过image图片木马。可以去百度搜索：”<u>将php木马隐藏在图片里</u>” ，这样做出的文件，你用画图软件看是个图片，你如果用php运行这段代码，里面php能够执行了。 </p>
<p>&#160;</p>
<p>好了，我们总结下，看来通过type判断类型，以及通过文件格式检测类型。 都不能很好解决，准确判断用户上存文件格式了。 其实，我们反过来想想，文件格式，不是通过一个简单字节标识码就能够准确判断的。 如果真的要去检测文件类型，我们该用什么方法呢？如果真的要检测格式，例如是图片，可以用php gd库，直接去打开文件，然后再保存一次。 这样，里面不合法的代码会去掉的。但是，我们想想，这样该会花费多大的性能呢？</p>
<p>综上所述，其实，去判断文件内容格式，不是明智的方法。 会非常复杂，而且也容易出现问题。想准确判断，还会消耗大量的服务器资源。除非万不得已，我们不要去尝试做这种操作。 接下来，对于安全上存方法，我会说说思路，欢迎交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/141.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>web上存漏洞及原理分析、防范方法（文件名检测漏洞）</title>
		<link>http://blog.chacuo.net/136.html</link>
		<comments>http://blog.chacuo.net/136.html#comments</comments>
		<pubDate>Sat, 01 Jun 2013 15:09:59 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web安全]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[上存漏洞]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=136</guid>
		<description><![CDATA[我们通过前篇：web上存漏洞及原理分析、防范方法 学习，已经知道后端获取服务器变量，很多来自客户端传入的。跟普 [...]]]></description>
				<content:encoded><![CDATA[<p>我们通过前篇：<a href="http://blog.chacuo.net/108.html">web上存漏洞及原理分析、防范方法</a> 学习，已经知道后端获取服务器变量，很多来自客户端传入的。跟普通的get,post没有什么不同。下面我们看看，常见出现漏洞代码。</p>
<h3><font style="font-weight: bold">1、检测文件类型，并且用用户上存文件名保存</font></h3>
<blockquote><pre style="text-indent: 0px">if(isset($_FILES['img']))
{
    $file = save_file($_FILES['img']);
	if($file===false) exit('上存失败！');
	
	echo &quot;上存成功！&quot;,$file;
}

function check_file($img)
{
	///读取文件
	if($img['error']&gt;0) return false;
	
	$tmpfile = $img['tmp_name'];
	$filename = $img['name'];
	
	
	///读取文件扩展名
	$len=strrpos($filename,&quot;.&quot;);
	if($len===false) return false;
	
	//得到扩展名
	$ext = strtolower(substr($filename,$len+1));
	if(!in_array($ext,array('jpg','jpeg','png'))) return false;
	return true;
}

function save_file($img)
{
	if(!check_file($img)) return false;
	
	//格式检测ok，准备移动数据
	<strong>$filename = $img['name'];</strong>
	$newfile = &quot;upload/&quot; .$filename;
	if(!move_uploaded_file($img[&quot;tmp_name&quot;],$newfile)) return false;
	
	return $newfile;

}
?&gt;</pre>
</blockquote>
<p>以上代码，对输入类型也做了判断，看了没有问题。但是问题，确恰恰出现在对获取的用户名变量检测上面。直接获取传入用户名，然后存为文件。 有朋友会说：<strong>这些文件名都是我电脑里面存在的，文件名格式都受限于操作系统对文件名定义。 </strong>但是，需要注意是，对于$_FILES里面获取变量，是直接来自http request请求。它跟普通获取其它get,post变量一样。 因此，别有用心的人，往往会自己模拟浏览器，给服务器发送一个特殊文件名。然后，让存文件时候，能够正常保存为自己格式。</p>
<p>前些年，”\0” 在字符串中，保存为文件，会自动截断后面内容。 如：$filename 构造为：”a.php\0.jpg” ，我们想想，将会变成怎么样？</p>
<p>$newfile = “upload/a.php\0.jpg” 因为，对扩展名验证，最右边”.”后面字符是jpg ，是允许图片格式。 但是，我们一以该文件名，保存。 发现磁盘会在upload目录下面生成a.php ，\0后面所有字符，被自动截断。</p>
<p>该漏洞，风靡一时。当时几乎大多数上存网站都有漏洞。一时，很多平台关闭了上存。其实，根本原因就在此。我们拿到文件名，自己作为最终生成文件名保存了。&#160; 好的方法，是<strong>自己随机生成文件名+读取扩展名 。</strong>这样可以组织输入特殊字符，在进行文件保存时候，被抛弃或截断了。</p>
<p>php4时代这个漏洞可以利用，到php5时代，生成的变量文件名值中，会自动过滤掉”\0” ，这样无论用户构造怎么样的特殊”\0”用户名，都会被截断。 但是 ，目前这类漏洞，在asp,jsp 等站点。还经常有出现。老版本的php站点也会经常出现。</p>
<p>&#160;</p>
<p>好了，今天先到这里，后面还有2种其它常见方法，后面给出！欢迎交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/136.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>web上存漏洞及原理分析、防范方法</title>
		<link>http://blog.chacuo.net/108.html</link>
		<comments>http://blog.chacuo.net/108.html#comments</comments>
		<pubDate>Thu, 30 May 2013 15:42:34 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web安全]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[上存漏洞]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=108</guid>
		<description><![CDATA[网站提供上存功能，是很多站点经常会有功能，商城，论坛还有常见一些网盘站点。常见互联网上面，我们也是经常听说，某 [...]]]></description>
				<content:encoded><![CDATA[<p>网站提供上存功能，是很多站点经常会有功能，商城，论坛还有常见一些网盘站点。常见互联网上面，我们也是经常听说，某某站点出现上存漏洞，某某开源项目有上存漏洞。 从互联网开始出现动态程序，上存漏洞像幽灵一样，频繁的出现在各种系统中。为什么，一个上存漏洞会这么频繁出现呢。而且，有些系统反复修补，多次还没有修补成功！其实主要问题，还是出现在上存原理上面。我们先看看，上存过程。</p>
<ul>
<li>
<h3><span style="font-weight: bold">网站上存过程分析</span></h3>
</li>
</ul>
<blockquote><div>
<div>
<pre><span style="color: #0000ff">&lt;?</span>php
<a style="color: #ffa500" href="http://www.php.net/header">header</a>(&quot;<span style="color: #8b0000">Content-type: text/html; charset=utf-8</span>&quot;); 
<a style="color: #0000ff" href="http://www.php.net/if">if</a>($_FILES)
{
	<a style="color: #0000ff" href="http://www.php.net/echo">echo</a> '<span style="color: #8b0000">&lt;pre&gt;</span>';
	<a style="color: #ffa500" href="http://www.php.net/var_dump">var_dump</a>($_FILES);
	<a style="color: #0000ff" href="http://www.php.net/echo">echo</a> '<span style="color: #8b0000">&lt;/pre&gt;</span>';
}
<span style="color: #0000ff">?&gt;</span>
<span style="color: #0000ff">&lt;</span><span style="color: #800000">form</span> <span style="color: #ff0000">action</span>=<span style="color: #0000ff">&quot;&quot;</span> <span style="color: #ff0000">enctype</span>=<span style="color: #0000ff">&quot;multipart/form-data&quot;</span> <span style="color: #ff0000">method</span>=<span style="color: #0000ff">&quot;POST&quot;</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;</span><span style="color: #800000">input</span> <span style="color: #ff0000">type</span>=<span style="color: #0000ff">&quot;file&quot;</span> <span style="color: #ff0000">name</span>=<span style="color: #0000ff">&quot;txt&quot;</span> <span style="color: #ff0000">size</span>=<span style="color: #0000ff">&quot;50&quot;</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;</span><span style="color: #800000">input</span> <span style="color: #ff0000">name</span>=<span style="color: #0000ff">&quot;Submit&quot;</span> <span style="color: #ff0000">type</span>=<span style="color: #0000ff">&quot;submit&quot;</span> <span style="color: #ff0000">value</span>=<span style="color: #0000ff">&quot;提交&quot;</span> <span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">form</span><span style="color: #0000ff">&gt;</span></pre>
</p></div>
<div></div>
</p></div>
</blockquote>
<p>&#160;</p>
<p>以上是个简单测试例子，我们看看</p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/05/image22.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/05/image_thumb22.png" width="738" height="459" /></a></p>
<p><strong>我们来分析下：</strong></p>
<p>name来自 上存时候选择文件名称</p>
<p>type 是文件类型， 这个类型那里来的呢？呵呵，这里非常关键的。 很多时候，很多同人会认为，这个是服务器自动判断生成的。 如果是这样想，觉得也有可能。 php 封装了上存，它自带类库好像可以的。&#160; 但是，反过来想想，你随便选择个什么格式文件，都会有格式类型。这样一想，我们推断这个值，可能也来自用户输入的。 我们来抓包看看我们类型。</p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/05/image23.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/05/image_thumb23.png" width="856" height="334" /></a></p>
<p><strong>type值 也来自，用户输入值了。</strong></p>
<p>size来自程序计算上存文件大小，这个是自动计算的。 相比我们都清楚的。</p>
<h3></h3>
<h3></h3>
<ul>
<li>
<h3><span style="font-weight: bold">你说这么多有啥样呢？</span></h3>
</li>
</ul>
<p>想必有朋友开始问了，我上面分析上存文件格式 ，跟开发出现漏洞有什么关联呢。 其实，我们想想，上面说的，一个文件名称name属性，以及文件类型type属性。 在我们上存文件，后端处理时候，会经常用到的。 作为开发者，在使用这2个变量，一定要继续执行“<strong>一切输入代码是有害的</strong>”原则。你在使用时候，要把它当作，跟其它get,post 获取变量一样处理。 要检测，过滤一切输入变量。</p>
<p>我们经常做功能是，限定用户输入必须是某种格式文件，然后保存为该格式。分析到这里，下面有很多需要继续分析地方，今天先提出大纲。接下来会分析这样常见3类上存漏洞。</p>
<p><span style="text-decoration: underline">1. 使用用户文件名，生成文件，特殊字符过滤不严格，导致文件生成出现漏洞</span></p>
<p><span style="text-decoration: underline">2.移动文件目录时候，由于采用用户传入的文件名拼接，生成到错误目录</span></p>
<p><span style="text-decoration: underline">3.相信用户输入type 类型，直接将用户文件名保存为文件</span></p>
<p>&#160;</p>
<p>好了，下一篇我会举例逐步分析这3种常见漏洞，欢迎朋友们提出你的观点，与我交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/108.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>web站点获取用户IP的安全方法 HTTP_X_FORWARDED_FOR检验</title>
		<link>http://blog.chacuo.net/103.html</link>
		<comments>http://blog.chacuo.net/103.html#comments</comments>
		<pubDate>Wed, 29 May 2013 15:28:30 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web安全]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=103</guid>
		<description><![CDATA[通过上一篇，获取用户Ip地址通用方法常见安全隐患(HTTP_X_FORWARDED_FOR) ，我们已经意 识 [...]]]></description>
				<content:encoded><![CDATA[<p>通过上一篇，<a href="http://blog.chacuo.net/98.html">获取用户Ip地址通用方法常见安全隐患(HTTP_X_FORWARDED_FOR)</a> ，我们已经意 识到直接从http_x_forwarded_for中读取用户IP，跟我们直接从一个get,post值中读取其实没有两样。web参数检测里面一个基本原则：“一切输入都是有害的”，因此，只要是输入我们就需要进行过滤。</p>
<ul>
<li>
<h3><span style="font-weight: bold;">安全过滤后的getIP函数</span></h3>
</li>
</ul>
<blockquote>
<pre>  function getIP() {
	$realip = ''; //设置默认值
	if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
		$realip = $_SERVER['HTTP_X_FORWARDED_FOR'];
	} elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
		$realip = $_SERVER['HTTP_CLIENT_IP'];
	} else {
		$realip = $_SERVER['REMOTE_ADDR'];
	}

	preg_match('/^((?:\d{1,3}\.){3}\d{1,3})/',$realip,$match);
	return $match?$match[0]:false;
}</pre>
</blockquote>
<p>&nbsp;</p>
<p>以上函数，增加了IP判断，只会读取以Ip格式数据开头，并且第一个满足IP格式值。如果没有返回false。 这样就可以读取到满足格式的IP，验证了数据的IP格式。</p>
<ul>
<li>
<h3><span style="font-weight: bold;">如果我读取互联网的IP，用户传入局域网的IP，我应该直接过滤掉</span></h3>
</li>
</ul>
<p>我们在一些网站上面，经常可以看到提示，非法的IP地址，其实一部分是IP地址格式错误，一部分可能是读取到IP地址，不满足互联网上面允许IP格式。 以下这个函数，是通过IANA站点规范，封装了个函数。 通过输入IP地址，能够准确知道，该IP是不是可以在互联网应用。</p>
<p>&nbsp;</p>
<blockquote>
<pre>//互联网允许使用IP地址</pre>
<pre>function ipType2($ip) {
	$iplist = explode(".", $ip);

	if ($iplist[0] &gt;= 224 &amp;&amp; $iplist[0] &lt;= 239)
		return '多播';
	if ($iplist[0] &gt;= 240 &amp;&amp; $iplist[0] &lt;= 255)
		return '保留';

	if (preg_match('/^198\.51\.100/', $ip))
		return 'TEST-NET-2，文档和示例';
	if (preg_match('/^203\.0\.113/', $ip))
		return 'TEST-NET-3，文档和示例';

	if (preg_match('/^192\.(18|19)\./', $ip))
		return '网络基准测试';

	if (preg_match('/^192\.168/', $ip))
		return '专用网络[内部网]';

	if (preg_match('/^192\.88\.99/', $ip))
		return 'ipv6to4中继';
	if (preg_match('/^192\.0\.2\./', $ip))
		return 'TEST-NET-1，文档和示例';
	if (preg_match('/^192\.0\.0\./', $ip))
		return '保留（IANA）';
	if (preg_match('/^192\.0\.0\./', $ip))
		return '保留（IANA）';

	if ($iplist[0] == 172 &amp;&amp; $iplist[1] &lt;= 31 &amp;&amp; $iplist[1] &gt;= 16)
		return '专用网络[内部网]';

	if ($iplist[0] == 169 &amp;&amp; $iplist[1] == 254)
		return '链路本地';
	if ($iplist[0] == 127)
		return '环回地址';
	if ($iplist[0] == 10)
		return '专用网络[内部网]';
	if ($iplist[0] == 0)
		return '本网络（仅作为源地址时合法）';

	return 'InterNet网地址';
}</pre>
</blockquote>
<p>当你输入IP地址，它返回是“&#8217;InterNet网地址&#8217; ，那么这个IP地址不光格式正确，而且是互联网上面合法的IP地址。 这个函数很复杂，其实就是排除很多非互联网使用IP地址。 我们常见的192,127,10开头地址估计都很熟悉了。 但实际上，很多IP地址是保留的，或者留作它用。 不能作为互联网 IP使用。 有了以上两个函数，我们不光可以读到正确格式IP地址，还能够保证读到是互联网上面IP地址。 以上是工作中常使用的函数，欢迎朋友们交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/103.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>获取用户Ip地址通用方法常见安全隐患(HTTP_X_FORWARDED_FOR)</title>
		<link>http://blog.chacuo.net/98.html</link>
		<comments>http://blog.chacuo.net/98.html#comments</comments>
		<pubDate>Tue, 28 May 2013 15:27:51 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web安全]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=98</guid>
		<description><![CDATA[分析过程 这个来自一些项目中，获取用户Ip，进行用户操作行为的记录，是常见并且经常使用的。 一般朋友，都会看到 [...]]]></description>
				<content:encoded><![CDATA[<ul>
<li>
<h3><span style="font-weight: bold;">分析过程</span></h3>
</li>
</ul>
<p>这个来自一些项目中，获取用户Ip，进行用户操作行为的记录，是常见并且经常使用的。 一般朋友，都会看到如下通用获取IP地址方法。</p>
<blockquote>
<pre>function getIP() { 
	if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { 
		$realip = $_SERVER['HTTP_X_FORWARDED_FOR']; 
	} elseif (isset($_SERVER['HTTP_CLIENT_IP'])) { 
		$realip = $_SERVER['HTTP_CLIENT_IP']; 
	} else { 
		$realip = $_SERVER['REMOTE_ADDR']; 
		} 
		return $realip; 
	}</pre>
<pre></pre>
</blockquote>
<p>这个是网上常见获取，ip函数，用这些值获取IP,我们首先要弄清楚，这些数据是从那个地方传过来的。</p>
<ul>
<li>
<h3><span style="font-weight: bold;">IP获取来源</span></h3>
</li>
</ul>
<p>1.&#8217;REMOTE_ADDR&#8217;  是远端IP，默认来自tcp 连接是，客户端的Ip。可以说，它最准确，确定是，只会得到直接连服务器客户端IP。如果对方通过代理服务器上网，就发现。获取到的是代理服务器IP了。</p>
<p>如：a-&gt;b(proxy)-&gt;c  ,如果c 通过&#8217;REMOTE_ADDR&#8217; ，只能获取到b的IP,获取不到a的IP了。</p>
<p><strong>另外:</strong>该IP想篡改将很难实现，在传递知道生成php server值，都是直接生成的。</p>
<p>2.&#8217;HTTP_X_FORWARDED_FOR&#8217;，&#8217;HTTP_CLIENT_IP&#8217; 为了能在大型网络中，获取到最原始用户IP，或者代理IP地址。对HTTp协议进行扩展。定义了实体头。</p>
<p>HTTP_X_FORWARDED_FOR = clientip,proxy1,proxy2  所有IP用”,”分割。 HTTP_CLIENT_IP 在高级匿名代理中，这个代表了代理服务器IP。既然是http协议扩展一个实体头，并且这个值对于传入端是信任的，信任传入方按照规则格式输入的。以下以x_forword_for例子加以说明，正常情况下，这个值变化过程。</p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/05/image18.png"><img style="background-image: none; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/05/image_thumb18.png" width="656" height="314" border="0" /></a></p>
<p>&nbsp;</p>
<ul>
<li>
<h3><span style="font-weight: bold;">分析Bug风险点：</span></h3>
</li>
</ul>
<p>通过刚刚分析我们发现，其实这些变量，来自http请求的：x-forword-for字段，以及client-ip字段。 正常代理服务器，当然会按rfc规范来传入这些值。但是，当一个用户直接构造该x-forword-for值，发送给用户用户，那将会怎么样呢？</p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/05/image19.png"><img style="background-image: none; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/05/image_thumb19.png" width="633" height="298" border="0" /></a>图（1）</p>
<p>第2步，修改x-forword-fox值，我们看看结果</p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/05/image20.png"><img style="background-image: none; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/05/image_thumb20.png" width="691" height="528" border="0" /></a></p>
<p>&nbsp;</p>
<p>第三步，我们再修改下看看会怎么样？</p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/05/image21.png"><img style="background-image: none; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/05/image_thumb21.png" width="751" height="571" border="0" /></a></p>
<p>&nbsp;</p>
<p>哈哈，看到上面结果没，x-forwarded-for不光可以自己设置值，而且可以设置任意格式值。 这样一来，好比就直接有一个可以写入任意值的字段。并且服务器直接读取，或者写入数据库，或者做显示。它将带来危险性，跟一般对入输入没有做任何过滤检测，之间操作数据源结果一样。 并且容易带来隐蔽性。</p>
<ul>
<li>
<h3><span style="font-weight: bold;">结论：</span></h3>
</li>
</ul>
<p>上面getip函数，除了客户端可以任意伪造IP，并且可以传入任意格式IP。 这样结果会带来2大问题，其一，如果你设置某个页面，做IP限制。 对方可以容易修改IP不断请求该页面。 其二，这类数据你如果直接使用，将带来SQL注册，跨站攻击等漏洞。至于其一，可以在业务上面做限制，最好不采用IP限制。 对于其二，这类可以带来巨大网络风险。我们必须加以纠正。</p>
<p>需要对getip 进行修改，得到安全的getip函数。</p>
<p>这类问题，其实很容易出现，以前我就利用这个骗取了大量伪装投票。有它的隐蔽性，其实只要我们搞清楚了，某些值来龙去脉的话。理解了它的原理，修复该类bug将是非常容易。</p>
<p>题外话，做技术，有三步，先要会做，会解决；后要思考为什么要这么做，原因原理是什么；最后是怎么样做，有没有其它方法。多问问自己，你发现距离技术真理越来越近。你做事会越来越得心应手的！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/98.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
