相关疑难解决方法(0)

如何在PHP中阻止SQL注入?

如果插入用户输入而不修改SQL查询,则应用程序容易受到SQL注入的攻击,如下例所示:

$unsafe_variable = $_POST['user_input']; 

mysql_query("INSERT INTO `table` (`column`) VALUES ('$unsafe_variable')");
Run Code Online (Sandbox Code Playgroud)

这是因为用户可以输入类似的内容value'); DROP TABLE table;--,查询变为:

INSERT INTO `table` (`column`) VALUES('value'); DROP TABLE table;--')
Run Code Online (Sandbox Code Playgroud)

可以采取哪些措施来防止这种情况发生?

php mysql sql security sql-injection

2776
推荐指数
28
解决办法
166万
查看次数

SQL的扩展占位符,例如WHERE id IN(??)

赏金更新:马克已经得到了很好的答案.改编:=进入:,下面.但是,除了DBIx之外,我还在寻找类似的方案.我只对与任何东西兼容感兴趣.


我需要建议我在参数化SQL语句中为"扩展"占位符选择的语法.因为构建一些构造(IN子句)让我烦恼,我决定使用一些自动扩展为普通的语法快捷方式?占位符.
我喜欢他们.但我想打包它以便分发,并且问我自己是否容易理解.

基本上我的新占位符是??和:?(枚举参数)和:&和:,(:|以及::(对于命名占位符)具有以下用例:

-> db("  SELECT * FROM all WHERE id IN (??)  ", [$a, $b, $c, $d, $e])
Run Code Online (Sandbox Code Playgroud)

该??扩展到?,?,?,?,?,...依赖于的$ args数到我的分贝()FUNC.这个很清楚,它的语法已经标准化了.Perls DBIx :: Simple也使用它.所以我很确定这是一个可以接受的想法.

-> db("  SELECT :? FROM any WHERE id>0   ",  ["title", "frog", "id"]);
// Note: not actually parameterized attr, needs cleanup regex
Run Code Online (Sandbox Code Playgroud)

承认它.我只喜欢笑脸.基本上这个:?占位符将关联$ args扩展为普通列名.它实际上抛弃了任何$ args值.它实际上对于INSERT和??有时是有用的,有时对于IN子句也是有用的.但是在这里我已经想知道这种新语法是否合理,或者只是用词不当,因为它混合了:和?字符.但不知何故,它似​​乎很好地匹配语法方案.

-> db("  UPDATE some SET :, WHERE :& AND (:|) …
Run Code Online (Sandbox Code Playgroud)

php sql

10
推荐指数
1
解决办法
2327
查看次数

用PDO和预处理语句替换mysql_*函数

我总是做简单的连接mysql_connect,mysql_pconnect:

$db = mysql_pconnect('*host*', '*user*', '*pass*');

if (!$db) {
    echo("<strong>Error:</strong> Could not connect to the database!");
    exit;
}

mysql_select_db('*database*');
Run Code Online (Sandbox Code Playgroud)

虽然使用这个我一直使用的简单的方法,使查询之前逃脱的任何数据,不管是INSERT,SELECT,UPDATE或者DELETE通过使用mysql_real_escape_string

$name = $_POST['name'];

$name = mysql_real_escape_string($name);

$sql = mysql_query("SELECT * FROM `users` WHERE (`name` = '$name')") or die(mysql_error());
Run Code Online (Sandbox Code Playgroud)

现在我明白这在某种程度上是安全的!

它逃脱了危险的人物; 但是,它仍然容易受到其他可能包含安全字符的攻击,但可能对显示数据或在某些情况下恶意修改或删除数据有害.

所以,我搜索了一下,发现了PDO,MySQLi和准备好的语句.是的,我可能会迟到,但我已经阅读了很多很多教程(tizag,W3C,博客,谷歌搜索),没有一个人提到这些.看起来很奇怪为什么,因为只是逃避用户输入真的不安全而且至少可以说是不好的做法.是的,我知道你可以使用Regex解决它,但是,我很确定这还不够吗?

据我所知,当用户输入给出变量时,使用PDO /预处理语句是一种更安全的方式来存储和检索数据库中的数据.唯一的麻烦是,切换(特别是在我的方式/先前编码的习惯非常困难之后)有点困难.

现在我明白使用PDO连接到我的数据库我会使用

$hostname = '*host*';
$username = '*user*';
$password = '*pass*';
$database = '*database*'

$dbh = new PDO("mysql:host=$hostname;dbname=$database", $username, $password);

if ($dbh) {
    echo …
Run Code Online (Sandbox Code Playgroud)

php mysql database pdo prepared-statement

10
推荐指数
3
解决办法
2961
查看次数

PDO Prepared语句的语法错误

我刚刚开始准备语句的工作,我的第几个例子摸索出伟大的,但现在我运行到一个SQL语法,我不明白.我有一个执行INSERT的函数,带有一个关联数组的参数,其中数组的键是字段,数组的值是要插入的值.例如:

$arr = array("field1" => "value1",
             "field2" => "value2");

$this->insert("table", $arr);
Run Code Online (Sandbox Code Playgroud)

会执行:

INSERT INTO table ('field1', 'field2') VALUES ('value1', 'value2')
Run Code Online (Sandbox Code Playgroud)

但是,在尝试执行此操作时,我收到以下错误:

PDOException:SQLSTATE [42000]:语法错误或访问冲突:1064 SQL语法中有错误; 检查与MySQL服务器版本对应的手册,以便在''post_title','post_body'附近使用正确的语法.)VALUES('Testing!','1 2 3!')'在第1行

这是我的功能:

    /**
     * insert()
     * 
     * Performs an insert query
     * 
     * @param  string $table   The table to be inserted into
     * @param  array  $fields  An associative array of the fields to be inserted
     *                         and their respective values
     * @return void
     *
     */
    function insert($table, $fields) {
        if (empty($table) || empty($fields)) { …
Run Code Online (Sandbox Code Playgroud)

php pdo prepared-statement

4
推荐指数
1
解决办法
1020
查看次数

标签 统计

php ×4

mysql ×2

pdo ×2

prepared-statement ×2

sql ×2

database ×1

security ×1

sql-injection ×1