关于用户输入的安全问题

用户输入:这是最基本的,也是最可能被忽视的一点。‘1+(-10000)’,这是什么?这就是‘黑客’最常用的一种方法,它多出现在当你的程序需要用户输入一个数 字时,比如,玩家可以把自己钱送给其他玩家,逻辑很简单,看看自己有没有这么多钱(if($my_money>$give_money)()),有 的话,给自己扣钱,并给其他玩家加钱。完成。但你试试下面这段程序:
[php]
<?php
$a="1+(-111111)";
$b=2;
if($b>$a)
{echo "xx";}
?>
[/php]
结果如何?你很吃惊嘛?就这样,你的程序有BUG了,还没完,你再试下下面这条 SQL
"update user_money set money=money-".$a." WHERE user_id=155"
类似的问题还有,用户在发言时输入了一个<,结果是你在输入这条发言时,就会有相当一部分显示不了这个页面,你的游戏也受到了怀疑。

数字:过滤数字,你首先想到的是什么方法或函数?intval?嗯,对于“1+(-10000)”这样的输入,这个没有问题,函数返回值是1,这个数字是安全的。注意!这个数字是安全的并不代表就都安全了,你再试试下面这个
[php]
<?php
echo intval(2200000000);
?>
[/php]
看到了嘛,又吓一跳吧,这都是血的教训啊。因为2200000000这个数已经超过了INT的取值范围(强行转化)。相类似的问题还有,在MYSQL5中(目前我不知道能不能设置),如果把字段设成UNSIGNED,那么0-1=42XXXXXXXX。
这里我提供两种解决办法:
1,用abs换掉intval,经初步 测试,abs这个函数是可信的,它不会对数字造成什么不良影响。
2,使用高精度函数及相关,如:
bcadd(),bccomp(),ctype_digi()
bcadd():两个任意精度的数字相加。
例如:
<?php

$a 
'1.234';
$b '5';

echo 
bcadd($a$b);     // 6
echo bcadd($a$b4);  // 6.2340

?>

bccomp():比较两个任意精度的数字。如果相等返回0 左边的参数大于右边的返回1 小于则返回-1
例:
<?php

echo bccomp('1''2'"\n"  // -1
echo bccomp('1.00001''1'3); // 0
echo bccomp('1.00001''1'5); // 1

?>
ctype_digi():检查是否是一个数字字符串,如果是数字字符串了返回true,否则返回false。
例如
<?php
$strings 
array('1820.20''10002''wsl!12');
foreach (
$strings as $testcase{
    if (
ctype_digit($testcase)) {
        echo 
"The string $testcase consists of all digits.\n";
    else {
        echo 
"The string $testcase does not consist of all digits.\n";
    }
}
?>

微观操作:同样用送钱的这个例子,你过滤了用户输入,用bccomp比较了用户要送的和他所有的,成功,可以送钱了。别忙,还有一个你可能不太相信但又确 实存在的问题。有一句古话:我们不可能两次跨过同一条河。它说的是时间是变化的,所以事物也是变化的。你有没有想如,如果在你验证过了他是不是有这么多钱 可送到你用UPDATE 语句为 他改钱的这一瞬间,另一个人把他的钱取走了?不可能吧?可能,非常可能。至少在我做游戏的这段时间,这种问题不止一次的出现过,要知道,比秒小的,有毫 秒,比毫秒小的有微秒,比微秒小的有皮秒....所以一切都可能发生。所以我个人一般在PHP程序验证之后,还会在UPDATE语句之中,再做一次验证, 即在WHERE语句中多加一句 AND MONEY>$a,这样的一个条件,基本不会对SQL执行效率产生什么影响,还能保证安全性,加上是很有意义的而 语句是否执行成功,才是能否给对方加钱的真正条件。相关的还有一点要说明,在做这样操作时,一定要把对玩家有损失的操作放在前面执行,类似给他加钱这样的 能让他HAPPY的操作放在后面,因为在没有引入事务的 数据库处理机制之前,程序中止也是可能且可怕的。对于可能出现多人抢同一资源的问题,也应该有很好的先后判断,这点不细说了,但同样重要。

日志:这个东西很重要,要知道,如果程序出了问题,找到是哪里出的问题,问题影响了多少人的多少数据,如何恢复,就全靠它了。日志一般分两种,一种是游戏 中需要用户的,比如救济品每人只能领一次,就是通过它来控制(其实是不应该算是程序日志范畴,只提一下)。另一种就是真正的日志,比如谁在什么时候给了谁 多少钱他输入的是什么数字,操作前送出方有多少钱,操作后又有多少。如果有了这样的日志记录,我想对钱这类重要数据流向,就很清晰了。在程序没有正常的运 行很长时间,经过时间的考验之前,这类日志数据是相当必要的。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值