关于mysql_real_escape_string和strip_slashes的混淆
我有用户输入他们的名字,如:O'riley
。关于mysql_real_escape_string和strip_slashes的混淆
在我将这些数据输入MySQL DB之前,我运行了mysql_real_escape_string
。
问题是,当我选择这些数据以供显示和稍后使用时,它会显示为:O\'riley
。
很明显,这是预期的操作。我想知道的是,如果有人确定我可以将其存储在数据库中(仍然可以安全地转义可能的恶意代码),那么在每次我调用整个数据的输出时,我不必在输出上使用strip_slashes()
Web应用程序?或者,我在这里错过了什么?
谢谢。
UPDATE 请参考Deceze的回答中的意见。
谢谢大家的答案。我会将+50奖励出去,但我想告诉我真正的解决方案,所有人都帮助过...
我对所有发布的数据ASONON执行mysql_real_escape_string
(在任何处理之前) 。所以,加了一个斜线以逃避提交的'
角色。这,我们知道是正常的。
但是,没有理由在DB条目中显示反斜杠\
,对吧?逃跑在那里确保输入了'
。
原来,在转义后,我会保存变量以重新加载到会话中的页面,以防用户在验证所有表单字段时发现错误。在这种情况下,用户的输入(以前的O'riley
现在被打印到他们的屏幕O\'riley
。然后,用户没有抓住这个 - 所以他们通常会修正PHP在验证过程中捕获的错误(与名称域无关)因此O\'riley
将在数据库中的土地,因为mysql_real_escape_string
将逃脱字符
课: 当处理形式,FIRST保存形式补充器使用数据的第二验证表单字段THIRD逸出用于处理的数据。进入数据库
或更好的是,使用PDO,并避免这=)。
评论欢迎。感谢所有!
你的方法有一个严重的错误。无论什么“数据”都不需要转义,而只需要SQL字符串。对于所有其他数据类型的转义是无用的,从而使您可以广泛开放注入。 – 2013-05-09 10:07:46
@YourCommonSense我不理解评论? – Shackrock 2013-05-09 17:35:16
不,这不是意向操作存储字符串为“O \'riley”;它只应该在查询中被转义,但不能以这种方式存储。我猜测PHP会通过Magic Quotes加入反斜杠,然后你再次逃脱以使它坚持下去。
这很奇怪。它在'php.ini'中绝对关闭 - 在WHM中显示相同。但是用'phpinfo()'将它显示为ON。我已经直接编辑了PHP.ini:'配置文件(php.ini)路径:\t/usr/local/lib' - 但它仍然显示为ON。这并不是如此,任何想法? – Shackrock 2012-02-15 01:42:27
可能有不同的.inis用于CLI,Apache和其他场景。检查它正在使用的'phpinfo()'。 – deceze 2012-02-15 01:50:59
似乎与那个目录中的一样......'加载的配置文件\t /usr/local/lib/php.ini'我已经验证了这在那里确实是关闭的。我在HTACCESS中设置了它,现在它在php info(local)中显示,但ON(主值)显示,这很奇怪。此外,它似乎仍然无法解决问题......并且它们正在用斜线插入到数据库中。 – Shackrock 2012-02-15 01:57:47
使用
var_dump(get_magic_quotes_gpc());
附近的某处实际使用发布的数据,看看魔术行情是真正关闭。
此外,一些奇怪的框架可能会为您添加所述报价,因此您的代码为addslashes
和其他类似escape_string
的函数。
好的...所以这返回false ....给我一个小时现在跑回来。这是在吹我的心! – Shackrock 2012-05-30 11:40:24
给一些更确切的答案 – 2012-06-04 06:50:46
我个人总是关闭魔术引号,因为它正在做一些我没有告诉它做的事情。如果您没有能力关闭它,请考虑将此代码包含在所有网页的顶部。
if (get_magic_quotes_gpc()) {
function strip_array($var) {
return is_array($var)? array_map("strip_array", $var):stripslashes($var);
}
$_POST = strip_array($_POST);
$_SESSION = strip_array($_SESSION);
$_GET = strip_array($_GET);
}
不是一个好的建议。 – 2012-06-04 06:50:05
要扩展@VIPINJAIN评论,如果你做了这样的事情,然后以后想要保护MySQL的帖子,将会有额外的斜线。例如,运行' teynon 2013-01-19 20:55:08
如果已禁用,并在get_magic_quotes_gpc返回1的情况下魔术引号和你不喜欢的东西@Michael节目和这个仍然发生时,魔术引号运行时可启用。
当执行数据库查询甚至写入文件时,魔术语句运行时会为字符串添加斜线。要在当前执行脚本禁用此功能,这样做:
if(function_exists('get_magic_quotes_runtime') && get_magic_quotes_runtime())
{
set_magic_quotes_runtime(false);
}
您还可以禁用这个configuration option through php.ini
为好,如果你能做到这一点。但是,如果您不能通过php.ini
永久禁用它,您可能需要在get_magic_quotes_runtime
和set_magic_quotes_runtime
之前添加@,因为PHP可能会通过E_DEPRECATED错误添加@如果error_reporting
被设置为记录此类错误(并且这会相当恼人)。
我会诚实地建议使用PDO。
PDO采用了准备和执行语句,这反过来又增加了安全性并消除了一些额外的头痛。
$pdo = new PDO();
$stm = $pdo->prepare('INSERT... (LastName) VALUES (:LastName)');
$stm->execute(array(':LastName' => "O'Rily"));
$stm->fetchAssoc(PDO::FETCH_ASSOC);
您不再需要担心删除转义斜杠以及确保基本的sql注入策略。
我很想去,但这是一个旧的代码库。尝试去取代一切将是疯狂的。 – Shackrock 2012-06-04 19:41:25
你可以做的一个想法是半覆盖现有的MySQL函数,如... '$ result = my_mysql_query($ mysql_resource,'INSERT INTO ...“); $ row = my_mysql_fetch_assoc($ result); function my_mysql_query($ mysql_resource,$ query){ \t return mysql_query($ mysql_resource,mysql_real_escape_string($ query,$ mysql_resource)); \t } function my_mysql_fetch_assoc($ resource){ \t $ result = mysql_fetch_assoc($ resource); \t return array_map(“strip_slashes”,$ result); }' – 2012-06-05 16:11:43
好的,这里是你需要做的。首先,根据该意见,从其他问题:
ISOLATE
您需要确定是什么原因造成的问题。它是服务器吗?它是否有一些隐藏的代码?什么?有些程序员可能包括这样的代码配置页上:
<?php if (isset($_POST))
foreach ($_POST as $key => $value) $_POST[$key] = addslashes($value);
?>
因此,这里有一些检查,看它是否是服务器。这是尽可能坚实的检查方式。创建一个新的页面。将其全部留空并添加以下代码:
<?php print_r($_POST); ?>
<form action="" method="POST">
<input type="text" name="test" value="O'riley" />
<input type="submit" name="submit" value="submit" />
</form>
将其保存并加载到浏览器中。点击提交。看看是否仍然添加斜杠。
如果它仍在添加它,则需要排除服务器/配置的故障。如果它是您付费的服务器,则需要告诉他们修复或推送它。如果它是你自己的服务器,那么你将需要做一些搞乱/谷歌搜索来弄清楚如何关闭魔术引号。
如果没有引号出现,那肯定会有一些代码在你的帖子变量中加斜线。但是,它可能不像上面的代码那么明显。您需要在您的代码上运行“addslashes”,“mysql_real_escape_string”和可能的“str_replace”搜索。如果您发现其中之一,则需要禁用它。但是请注意,这可能会破坏您的网站的其他正在发生此行为的部分。将数据存储在数据库中的其他选择是执行类似于上述代码的功能,但是可以在其上运行stripslashes。然后你可以稍后运行mysql_real_escape_string。 (有点不必要的开销。)
这可能是在您的httpd.conf或虚拟主机声明中启用了魔术引号。
确切的位置和文件将取决于操作系统和发行版。我会检查Apache配置文件的php_flag设置。
'php_flag magic_quotes_gpc On'也可以在.htaccess文件中设置。 – Eric 2012-06-05 08:18:02
只要用干净的数据插入到数据库之前,
function check_input($value)
{
if(get_magic_quotes_gpc())
{
$value = stripslashes($value);
}
//check if this function exists
if(function_exists("mysql_real_escape_string"))
{
$value = mysql_real_escape_string($value);
}
//for PHP version < 4.3.0 use addslashes
else
{
$value = addslashes($value);
}
return $value;
}
$cleandata = check_input($value);
$sql = "INSERT INTO `table_name` SET `field_name`='".$cleandata."'";
虽然获取数据并显示到它使用stripslashes($val)
你能从你的'php.ini'中显示魔术引号吗? – eggyal 2012-05-30 08:36:58