问候,
这一次我花了几分钟就破解了!实际上你的要求中缺少一些细节,所以我试图通过不同的假设来解决问题,如下所述。
下面是从您的示例中提取的URL假设输入以及MySQL注入攻击(仅用于咯咯笑)以及商业名称的变体。键是预期的URL,值是要匹配的数据库值。
<?php
$names = array(
'bobs-big-boy'=>"bob's big boy",
'tom--jerry'=>'tom & jerry',
'tomjerry'=>'tom&jerry',
'one-two-three'=>'one, two, three',
'onetwothree'=>'one,two,three',
"anything' OR 'haxor'='haxor"=>'die-haxor-die',
);
?>
一个聪明的方式做一个最终运行MySQL的缺乏正则表达式替换的是使用SOUNDEX,而这种做法似乎在这种情况下,大部分工作取决于精确的你所需要的水平,密度和客户名称等。例如相似性,这会产生这些值的SOUNDEX值以上:
$soundex_test = $names;
$select = 'SELECT ';
foreach ($soundex_test as $name=>$dbname) {
echo '<p>'.$name.': '.soundex($name).' :: '.$dbname.': '.soundex($dbname).'</p>';
$select .= sprintf("SOUNDEX('%s'),", $name);
}
echo '<pre>MySQL queries with attack -- '.print_r($select,1).'</pre>';
因此,假设有没有客户名为“一,二,三”和独立的一个名为“onetwothree” ,这种方法应该很好地工作。
要使用这个方法,你的查询会是这个样子:
$soundex_unclean = $names;
foreach ($soundex_unclean as $name=>$dbname) {
$soundex_unclean[$name] = sprintf("SELECT * from the_records WHERE name SOUNDS LIKE '%s';", $name).' /* matches name field = ['.$dbname.'] */';
}
echo '<pre>MySQL queries with attack -- '.print_r(array_values($soundex_unclean),1).'</pre>';
然而,这里是一个,它对付注入攻击(注意新线)运行。我知道这是不是问题的重点,但ajreal提到的问题,所以我想对付它还有:
$soundex_clean = $names;
foreach ($soundex_clean as $name=>$dbname) {
// strip out everything but alpha-numerics and dashes
$clean_name = preg_replace('/[^[:alnum:]-]/', '', $name);
$soundex_unclean[$name] = sprintf("SELECT * from the_records WHERE name SOUNDS LIKE '%s';", $clean_name).' /* matches name field = ['.$dbname.'] */';
}
echo '<pre>MySQL queries with attack cleaned -- '.print_r($soundex_unclean,1).'</pre>';
如果这个方法不适合,你决定更换内嵌方法已经足够了,那么请记得在混音中添加逗号替换。作为这种方法的一个例子,我假设在这里,单引号,双引号,&符号和逗号(即',“,&和)是数据库中只包含四个特殊字符,但从URL,任何其他非字母数字字符,包含空格,转换为一个破折号(即 - )
首先,不与注入攻击应对运行:
$unclean = $names;
foreach ($unclean as $name=>$dbname) {
$regex_name = preg_replace('/[-]+/', '[^[:alnum:]]+', $name);
$unclean[$name] = sprintf("SELECT * from the_records WHERE REPLACE(REPLACE(REPLACE(REPLACE(name, ',', ''), '&', ''), '\"', ''), \"'\", '') REGEXP '%s'", $regex_name);
}
echo '<pre>MySQL queries with attack -- '.print_r($unclean,1).'</pre>';
其次,一个能处理攻击的跑步:
$clean = $names;
foreach ($clean as $name=>$dbname) {
$regex_name = preg_replace('/[^[:alnum:]-]/', '', $name);
$regex_name = preg_replace('/[-]+/', '[^[:alnum:]]+', $regex_name);
$clean[$name] = sprintf("SELECT * from the_records WHERE REPLACE(REPLACE(REPLACE(REPLACE(name, ',', ''), '&', ''), '\"', ''), \"'\", '') REGEXP '%s'", $regex_name);
}
echo '<pre>MySQL queries with attack cleaned -- '.print_r($clean,1).'</pre>';
Aaaand,这足够头脑风暴我一晚! = o)
将它们存储在数据库中,很傻。无需更改记录,只需添加另一列即可。 – 2010-12-04 07:45:47
我不拥有数据库,并且无法写入它。 – 2010-12-06 19:10:26
@pg:网址是否必须如此?约翰斯回答的作品,但它并不快。 – thejh 2010-12-06 19:50:13