现在有一个WEB游戏登录接口,大致就是传递用户名、服务器ID、用户IP、登录时间完成游戏登录信息生成的功能。
链接大约是这样的:
http://sample.com/login.php?user=test&server=s1&userip=127.0.0.1&ts=1380270507&sign=72c361803a5b116e0682581fe958fdee
为了防止伪造请求,这些参数都需要进行签名。签名方式大致是把这些参数拼接起来再加一个KEY进行MD5运算。只要任何一个参数被修改,md5值都会发生改变,签名检查就无法通过。
对于大部分用户来说,这样的登录流程都是没有问题的,但有近期却收到部分用户无法登录游戏的反馈,经过检查服务器日志,发现无法登录的用户都是因为调用接口时签名错误了。在仔细分析发现签名错误的链接确实是合法生成的,并非伪造或者其他恶意攻击,之后再对比各个参数才找到问题原因,URL链接中的IP跟链接生成时的IP不同,被替换掉了,所以造成签名错误。
但分析了好久也没找出IP是被哪里替换掉的,由于从链接生成到用户使用修改后的链接访问服务器之间几乎没有时间差,可以排除用户自己手动替换的可能性,并且IP被替换后会生成无法登录,所以也不太可能是用户自己使用了特别的软件导致这样。在之后分析发现有问题的用户全部是中国移动用户,所以猜测可能是移动的节点服务器搞的鬼,在经过一系列测试发现移动服务器会将URL中的用户IP替换为自己服务器的IP,推测可能是移动服务器内部使用了某种代理导致此种情况。
找到原因了想要解决就很简单了,稍加修改下链接中的用户IP,让移动服务器识别不出来就发了,比如把IP中的”.“替换成"_"(读取时再反向替换回来),这样就不是标准IP格式了,就不会被替换掉了,烦人的签名错误也可以解决了。
示例:
http://sample.com/login.php?user=test&server=s1&userip=127_0_0_1&ts=1380270507&sign=402ab0fc2ca7f898ecac0104302f271b
总结:由于上述情况的存在,在URL链接中直接传递IP有一定风险,可以修改IP格式,先转换成整型或者其他非IP格式,或者改为在POST中请求,可以很好避免被代理服务器意外地替换IP,以致用户无法正常访问或者服务器获得到非期望的用户IP。
原创: