文章目录

经常有这样一个场景:需要保存用户注册之前访问的最后一个页面,从而在用户注册流程完毕后可以自动跳转至前一页面。类似的需求都可以描述为:用户传进来一个参数,这个参数是个url,然后程序接收到这个url参数后直接发送30x系列http状态码,直接将用户浏览器跳转到此url。

然而如果此url是个不可控的第三方页面,那么就可能引入安全问题。主要有以下两种:

  • 形如 http://www.facebook.com/?url=http://fake.com/evil.php 的页面,当用户看到之前的域名是facebook,实际上访问时候却是恶意的第三方的网站,就可能给用户一个误导,让用户以为是facebook带着他去了恶意网站。另外这样的连接上如果有挂马,被杀毒软件检测到也可能牵扯到facebook声誉。
  • 目前很多单位内部产品线的安全过滤策略是通过*.xxx.com域做控制的。而利用以上的连接插入恶意代码就有可能绕过这样的限制。

解决方案

  • 如果url是可以预知的,或者存在统一的模式。那么我们可以限制只允许跳转到某些固定的url中,做一个白名单限制,我们只要保证白名单中的URL不存在恶意代码即可。
  • 如果url未知,我们可以在程序中增加一步校验:首先在生成跳转的连接时,将接受过来的url通过一定的算法进行计算,算出一个唯一hash。随后将此hash作为变量传递给真正的跳转程序。跳转程序需要将用户提交的URL与hash进行比对。如果两者匹配,则说明此链接为我们系统生成的,而不是经过用户篡改过的恶意url;否则,如果用户提交过来的hash不匹配,则直接屏蔽,不予跳转。因此,只要保证算法不可预知,也基本保证了无法随意伪造跳转。
文章目录