防止伪造跨站请求(转)
关联:
征服 Ajax 应用程序的安全威胁
AJAX 跨域请求 - JSONP获取JSON数据
跨站脚本
在媒体的帮助下,跨站脚本(XSS)成为了大家关注的焦点,当然它是绝对应当关注的。XSS 是 web 应用中最常见的安全隐患,许多流行的开放源代码的 PHP 应用程序受到 XSS 隐患的困扰。
XSS 攻击发生在下面的情况下:
-
对于可获得用户信任的特定站点。
用户没有必要用很高的等级信任任何网站,但是浏览器需要。例如,当浏览器在请求中发送 cookie,则意味着信任目标网站。对于不同的网站,用户可能有不同的浏览行为或者不同的安全防范等级。
-
通常包含显示外部数据的网站。
<?php class Crumb { CONST SALT = "your-secret-salt"; static $ttl = 7200; static public function challenge($data) { return hash_hmac('md5', $data, self::SALT); } static public function issueCrumb($uid, $action = -1) { $i = ceil(time() / self::$ttl); return substr(self::challenge($i . $action . $uid), -12, 10); } static public function verifyCrumb($uid, $crumb, $action = -1) { $i = ceil(time() / self::$ttl); if(substr(self::challenge($i . $action . $uid), -12, 10) == $crumb || substr(self::challenge(($i - 1) . $action . $uid), -12, 10) == $crumb) return true; return false; } } $uid = 112; if($_POST['submit'] == 'submit') echo Crumb::verifyCrumb($uid, $_POST['crumb']) ? 'good' : 'bad'; ?> <form method="post"> <input type="hidden" name="crumb" value="<?php echo Crumb::issueCrumb($uid)?>"> <input type="text" name="content"> <input type="submit" name="submit" value="submit"> </form>
-
通常网站信任用户的身份标识。用户的身份标识拥有着重要的地位。但是即便有安全的会话管理机制,CSRF 攻击仍然能够成功。而且事实上,对于这种情况 CSRF 攻击更加有效。
-
攻击者可随心所欲的执行 HTTP 请求。
在 CSRF 所有攻击方式中包含攻击者伪造一个看起来是其他用户发起的 HTTP 请求(事实上,跟踪一个用户发送的 HTTP 请求才是攻击者的目的)。有一部分技术可以用来完成这个,后面会演示一个使用特别技术的例子。
由于 CSRF 攻击包含伪造 HTTP 请求,熟悉底层 HTTP 协议就变得非常重要。
伪造跨站请求介绍
伪造跨站请求比较难以防范,而且危害巨大,攻击者可以通过这种方式恶作剧,发spam信息,删除数据等等。这种攻击常见的表现形式有:
伪造链接,引诱用户点击,或是让用户在不知情的情况下访问
伪造表单,引诱用户提交。表单可以是隐藏的,用图片或链接的形式伪装。
比较常见而且也很廉价的防范手段是在所有可能涉及用户写操作的表单中加入一个随机且变换频繁的字符串,然后在处理表单的时候对这个字符串进行检查。这个随机字符串如果和当前用户身份相关联的话,那么攻击者伪造请求会比较麻烦。
yahoo对付伪造跨站请求的办法是在表单里加入一个叫.crumb的随机串 ;而facebook也有类似的解决办法,它的表单里常常会有post_form_id和fb_dtsg。
实例:
参考:
PHP 安全指南 http://hhacker.com/files/200709/1/index.html
PHP 安全基础 http://www.97find.cn/PHP/