我正在逃避从php表单收到的所有字符串参数,如下所示:
$usr_name = mysql_real_escape_string($_REQUEST['usr_name']);
Run Code Online (Sandbox Code Playgroud)
避免SQL注入的一些问题.但是当我从函数中恢复我的字符串时,我什么都没有结果.
另外,我在PHP日志中不断收到这个奇怪的警告:
PHP Warning: mysql_real_escape_string() [<a href='function.mysql-real-escape-string'>function.mysql-real-escape-string</a>]: A link to the server could not be established in /hermes/bosweb/web279/b2798/ipw.bankingforms/public_html/formAckResponse_controller.php on line 39
Run Code Online (Sandbox Code Playgroud)
主机使用:PHP版本4.4.7
在ruby中ActiveRecord不提供动态绑定更新和插入sqls,当然我可以使用原始sql,但是需要维护连接,所以我想知道是否有更简单的方法来逃避更新或插入sql之前执行下面的代码:
ActiveRecord::Base.connection.insert(sql)
Run Code Online (Sandbox Code Playgroud)
我想我可以用gsub编写代码,但我知道是否有一个现成的方法来做到这一点.
我对某些事感到非常困惑,并且想知道是否有人可以解释.
在PHP中我验证用户输入所以htmlentitiies,mysql_real_escape_string在插入数据库之前使用,而不是在所有内容上,因为我喜欢使用正则表达式,尽管我发现它们很难处理.现在显然我将使用mysql_real_escape_string,因为数据进入数据库但不确定我是否应该使用htmlentities()仅在从数据库获取数据并将其显示在网页上时这样做才能改变由人输入的数据是不保留它的原始形式,如果我想稍后使用该数据用于其他东西,可能会导致问题.
例如,我有一个带有3个字段名称,主题和消息的留言簿.现在显然字段可以包含任何像js标签中的恶意代码基本上什么,现在让我困惑的是让我说我是一个恶意的人,我决定使用js标签和一些恶性js代码并提交表单,现在基本上我有恶意我的数据库中无用的数据.现在通过使用htmlentities将恶意代码输出到网页(留言簿)这不是问题,因为htmlentities已将其转换为安全等价物,但同时我在数据库中有无用的恶意代码,我宁愿不拥有.
所以在说完这一切之后我的问题是我应该接受这样一个事实,即数据库中的某些数据可能是恶意的,无用的数据,只要我在输出中使用htmlentities一切都会好的,或者我应该做其他事情吗?
我读了很多书,说过在接收数据时过滤数据并在输出数据时将其转义,因此保留了原始表单但是他们只提供了一些示例,例如确保字段只是使用已经内置到php中的函数的int但我从未找到过任何关于确保类似于留言簿的内容,您希望用户输入他们想要的任何内容,还有除了mysql_real_escape_string()之外如何过滤这些数据以确保它不会破坏数据库查询?
请有人请最终为我解决这个困惑并告诉我应该做什么以及最佳做法是什么?
感谢任何可以解释的人.
干杯!
我阅读本教程关于在DB中存储图像.在本教程中,作者在插入之前转义二进制数据中的特殊字符:http://www.phpriot.com/articles/images-in-mysql/7 (addslashes尽管使用虽然mysql_real_escape_string更好 - 但这是另一个问题).
关键是,在显示时,他只显示存储的数据:http://www.phpriot.com/articles/images-in-mysql/8
我的问题:
1)我们是否需要转义特殊字符,即使对于二进制字段类型(blob)?
2)如果是这样,那么,为了正确显示图像,我们不需要再次"取消"字符吗?(如果是这样,最好的方法是什么.关于效率的任何评论?对于大图像:转义和转移可能是一个很大的开销?).
或者我对转义的理解是完全错误的(转义只会影响查询,而不会影响插入/存储的最终数据?).
谢谢
J.P
所以在我写的这个程序中,我实际上是使用表单从用户那里获取SQL查询.然后我继续在我的数据库上运行该查询.
我知道不要"信任"用户输入,所以我想对输入进行清理.我正在尝试使用mysql_real_escape_string但是没有成功使它工作.
根据输入,这是我正在尝试的内容:
select * from Actor;
//"query" is the input string:
$clean_string = mysql_real_escape_string($query, $db_connection);
$rs = mysql_query($clean_string, $db_connection);
if (!$rs)
{
echo "Invalid input!";
}
Run Code Online (Sandbox Code Playgroud)
这总是给我的
"输入无效!"
错误.
当我取出clean_string部分并运行mysql_query查询时,
"输入无效"
消息未输出.相反,当我这样做时:
$rs = mysql_query($query, $db_connection);
if (!$rs)
{
echo "Invalid input!";
}
Run Code Online (Sandbox Code Playgroud)
它不输出
"输入无效".
但是,我需要使用该mysql_real_escape_string功能.我究竟做错了什么?
更新:
鉴于
select * from Actor;作为输入,我发现以下.
使用echo语句我发现在清理之前,字符串保存了值:
select * from Actor;
这是正确的.但是,在清理后它会保留不正确的值select *\r\nfrom Actor;,因此会显示错误消息.为什么
mysql_real_escape_string这样做?
我从来没有在之前打开魔术引号的环境中编程.现在我正在开展一个项目.这就是我一直在设置用户接受的数据情况:
$first_name = $_POST['first_name']
if(!get_magic_quotes_gpc()) {
$first_name = mysql_real_escape_string($first_name);
}
Run Code Online (Sandbox Code Playgroud)
通过这种过滤,当启用魔术引号时,我仍然可以打开SQL注入攻击吗?
我真的只关心任何会破坏我的查询的SQL注入......其他区域的其他白名单,htmlspecialchar()-ing等.
看一些类似的SO问题似乎建议改为检查魔术引号,如果它打开则在数据上运行'stripslashes',然后总是运行转义函数.我有点担心这样做,因为网站中的所有现有代码都假定它已经开启.
谢谢!
我正在使用zend框架开发一个Web应用程序.对于select语句,我使用了以下方法.
例如:
public function getData($name)
{
$sql = "SELECT * from customer where Customer_Name = '$name'";
return $this->objDB->getAdapter()->fetchAll ($sql);
}
Run Code Online (Sandbox Code Playgroud)
这很好用.但是,如果我将客户名称发送为:colvin's place,则查询失败.我知道这是因为单引号.
之前我用过addslashes PHP函数.但我发现这不是一个很好的方法.这次我使用mysql_real_escape_stringPHP函数.
问题在于警告说.
Warning</b>: mysql_real_escape_string() [<a href='function.mysql-real-escape-string'>function.mysql-real-escape-string</a>]: Access denied for user 'ODBC'@'localhost' (using password: NO)
这是因为该mysql_real_escape_string函数需要连接到打开的数据库mysql_connect.我的问题是如何在*Zend_DB*类中使用它.我总是需要使用自定义选择查询.如果可以,请欣赏您的其他建议.
谢谢
我让用户输入他们的名字,如:O'riley.
在我将这些数据输入MySQL DB之前,我运行了mysql_real_escape_string.
问题是,当我选择此数据进行显示并稍后使用时,它会显示为:O\'riley.
显然,这是预期的操作.我想知道的是,如果有一点可以肯定我可以将它存储在数据库中(仍然安全地逃避可能的恶意代码),这样我就不必strip_slashes()在输出上使用每次我在整个网络中调用数据应用程序吗?或者,我在这里错过了一些东西吗?
谢谢.
更新 请参阅Deceze答案中的评论.
好吧,我还是不太懂.我一直在阅读,为了正确地逃避你的MySQL查询,你需要使用mysqli_prepare()和mysqli_bind_param().
我尝试使用这个设置,坦率地说,它有点笨拙.当我不需要再次引用变量时,我会通过引用传递变量,并且只需要更多行代码来完成相同的任务.
我想我只是不知道它们之间的区别:
<?php
$sql = new \MySQLi(...);
$result = $sql->query('
UPDATE `table`
SET
`field` = "'.$sql->real_escape_string($_REQUEST[$field]).'";
');
?>
Run Code Online (Sandbox Code Playgroud)
和
<?php
$sql = new \MySQLi(...);
$stmt = $sql->prepare('
UPDATE `table`
SET
`field` = ?;
');
$value = $_REQUEST[$field];
$stmt->bind_param('s', $value);
$stmt->execute();
$result = $stmt->get_result();
unset($value);
?>
Run Code Online (Sandbox Code Playgroud)
除了更多的代码.
我的意思是,他们是否实现了这一点,以便人们在发送查询之前不会忘记转义值?还是以某种方式更快?
或者当我打算重复使用相同的查询时(因为mysqli_stmt可以重复使用)并在其他情况下使用传统方法,我应该使用此方法吗?
php mysql mysqli mysql-real-escape-string prepared-statement
这被标记为重复,但我不认为这是一个公平的判断.这个问题再一次被简单地回答了......但这不是正确的答案.如果从实际的帖子表单中使用"重复"答案,则它不起作用.它被拒绝就像所有其他尝试一样.我实际上已多次使用该答案,它几乎出现在每个SQL注入备忘单上.请将此标记为重复标记.
这个问题纯粹是为了理解,而不是用于访问其他网站.我多次读过MySQL转义不足以保护自己免受SQL注入.因此,我设置了多个测试页面来尝试SQL注入.我成功了一些,但从未使用过该mysql_real_escape_string()功能.
我已经研究并尝试过许多来自备忘单的例子,但不能破解这个,所以我觉得它足够安全或足够安全.有人能举个例子吗?也许是为什么这个登录是不安全的原因和一个绕过登录和/或改变表的示例输入?
我打算也使用MySQLi.在这个例子中,我使用MySQL来询问与MySQLi相比这可能导致SQL注入问题的位置(另一个声明,但我从未见过证明).
这是某人有机会证明不安全感,而不仅仅是说它是不安全的.
if (isset($_POST['aun'])) {
$username = mysql_real_escape_string($_POST['aun']);
$checkadminlogin = mysql_query("SELECT * FROM admin WHERE un='$username'");
$uncreds = mysql_fetch_assoc($checkadminlogin);
$pass = mysql_real_escape_string($_POST['apwd']);
//Line to get key for encrypting input password, used below as $keyinfo['op_value'];
$salt = $keyinfo['op_value'];
$fpass = sha1($pass . $salt);
if ($fpass == $uncreds['pwd']) {
echo 'Congrats, you logged in. Or hacked your way in. Whatever';
}
}
Run Code Online (Sandbox Code Playgroud)
另外在旁注,你不能只是替换所有特殊字符以防止任何注射吗?
php ×9
mysql ×6
mysqli ×2
activerecord ×1
binary-data ×1
magic-quotes ×1
ruby ×1
security ×1
stripslashes ×1
validation ×1
zend-db ×1