我正在为我一直在努力的游戏创建一个数据库,我需要用户能够互相杀戮,所以我设置了这样的表:
...
`alive1` => Player 1's status
`alive2` => Player 2's status
`alive3` => Player 3's status
`alive4` => Player 4's status
...
我需要能够基于每个案例修改数据库中的这些列,并且可以直接从用户输入。但是,做这样的事情:
$stmt = $link->prepare("UPDATE `games` SET `alive{$_GET["player"]}`=0 WHERE `id`=?")
易受SQL注入攻击。有没有一种方法可以将列名“绑定”到查询中,以便我可以安全地修改表格?
$ _GET [“player”]的正确输入应该只是一个整数1..4,所以我想我可以直接检查输入,如果需要,并确保它是这四种可能性之一,但我是希望能有更优雅的解决方案。这可能会在稍后的另一个项目中再次出现,其中可能的输入集将会更大,并且对每个案例进行硬编码将非常耗时。
有什么想法吗?
答案 0 :(得分:1)
标识符不能绑定到预准备语句中,因此您应该将它们列入白名单。
通常,对于白名单,您需要创建一个有效标识符数组,并检查传递的标识符是否在列表中。例如:
$validColumns = array('alive1', 'alive2', 'alive3', 'alive4');
$col = 'alive' . $_GET["player"];
$isSafeToUse = in_array($col, $validColumns);
在你的情况下,你可以
$id = (int)$_GET["player"];
然后检查$id
是否在[1, 4]
范围内。
答案 1 :(得分:0)
我会使用正则表达式/^[1-4]$/
if(preg_match('/^[1-4]$/', $_GET['player'])){
$stmt = $link->prepare('UPDATE `games` SET `alive' . $_GET['player'] . '` =0 WHERE `id`=?');
} else {
die;
}
要将此功能用于将来的项目,您可以将其扩展为/^[0-9]{1,3}$/
,这样您就可以接受最多999