Pinkie,感谢您发布的代码。
$sql = 'SELECT a.videote as videote, b.user_name as user_name'.
' FROM '.$video.' as a,'.$users.' as b'.
' where b.user_name=$_GET['user'] and... //if i replace $_GET['user'] with john then it works
这里有几个问题,但我们可以通过它们。
更改字符串时会引入语法错误。你有正确的想法$video
和$users
。但是,在添加$_GET['user']
时,PHP认为第一个撇号正在结束当前字符串。
考虑以下因素:
' where b.user_name=$_GET['user'] and...'
看起来像两个字符串,由单词 “用户” 分隔:
' where b.user_name=$_GET[' user '] and...'
这不是正确的语法,所以返回500错误。我猜,如果你想你的错误会消失:
' where b.user_name=' . $_GET['user'] . ' and...'
下一个问题是,如果用户要发送一个精心制作的价值,为“用户”的参数,它们可能会导致查询的行为以你不打算的方式。
试试这个:创建一个名为的login.php文件,包含以下内容:
<?php
// Just display the output; no HTML formatting needed
header("Content-Type: text/plain");
// This must succeed, or mysql_real_escape_string() won't have any effect
mysql_connect('mysql_host', 'mysql_user', 'mysql_password')
OR die(mysql_error());
$safeQuery = 'SELECT count(*) FROM users WHERE user=\'' . mysql_real_escape_string($_GET['username']) . '\' AND pass=\'' . mysql_real_escape_string($_GET['password']) . '\';';
echo " safeQuery is: $safeQuery\n";
$unsafeQuery = 'SELECT count(*) FROM users WHERE user=\'' . $_GET['username'] . '\' AND pass=\'' . $_GET['password'] . '\';';
echo "unsafeQuery is: $unsafeQuery\n";
?>
负载login.php?username=bob&password=sample
。输出看起来合理的:
safeQuery is: SELECT count(*) FROM users WHERE user='bob' AND pass='sample';
unsafeQuery is: SELECT count(*) FROM users WHERE user='bob' AND pass='sample';
现在尝试加载login.php?username=bob&password=sample' OR 'hello'='hello"
:
safeQuery is: SELECT count(*) FROM users WHERE user='bob' AND pass='sample\' OR \'hello\'=\'hello';
unsafeQuery is: SELECT count(*) FROM users WHERE user='bob' AND pass='sample' OR 'hello'='hello';
的安全查询将返回零,除非你有一个叫鲍勃其密码真的是sample' OR 'hello'='hello"
用户。
但是,不安全的版本将返回数据库中用户的总数。 WHERE子句现在是:
WHERE user='bob' AND pass='sample' OR 'hello'='hello'
的OR 'hello'='hello'
将在所有情况下,条件为真,即使bob
不存在或具有比其他sample
密码。
部分查询甚至可能被注释掉。尝试login.php?username=bob' --
:
safeQuery is: SELECT count(*) FROM users WHERE user='bob\' --' AND pass='';
unsafeQuery is: SELECT count(*) FROM users WHERE user='bob' --' AND pass='';
password参数现在被忽略,因为它嵌入在SQL注释中。
因此,即使您只是执行SELECT语句,如果其输入未被转义,结果也可以由聪明的用户操纵。
您可以使用mysql_real_escape_string来防止这些不良值。此功能将在必要时添加反斜杠,以防止输入数据作为SQL执行。
$sql = 'SELECT a.videote as videote, b.user_name as user_name'.
' FROM '.$video.' as a,'.$users.' as b'.
' where b.user_name=\'' . mysql_real_escape_string($_GET['user']) . '\' and...';
实施例1从php.net page for mysql_real_escape_string具有使用sprintf的一个很好的例子:
$query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",
mysql_real_escape_string($user),
mysql_real_escape_string($password));
每个%s
被替换为参数(在它们的顺序依次指定)。这样可以更轻松地保持查询的可读性,同时防止错误的输入数据。
你可以发布相关的代码位?另外,加载x.php或content.php时是否返回服务器错误? – GargantuChet 2011-06-03 01:58:31
@GargantuChe检查更新的文章 – Pinkie 2011-06-03 02:09:26
@GargantuChe也500错误是由content.php而不是x。php – Pinkie 2011-06-03 02:10:07