【问题标题】:PHP placeholders [closed]PHP占位符[关闭]
【发布时间】:2012-10-10 15:31:53
【问题描述】:
$query = '
PREPARE statement FROM
"INSERT INTO games_new
(
    gamedate,
    hometeam,
    visitors,
    result,
    matchreport,
    battedfirst,
    fieldedfirst,
    battedfirstruns,
    battedfirstextras,
    battedfirsttotal,
    battedsecond,
    fieldedsecond,
    battedsecondruns,
    battedsecondextras,
    battedsecondtotal
)
VALUES
(
    ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?
)
"';
$result = mysql_query($query);
if (!$result) {die("Database access failed: " . mysql_error());}
$query =
'SET @gamedate = $_POST["gamedate"],' .
'@hometeam = $_POST["hometeam"],' .
'@visitors = $_POST["visitors"],' .
'@result = $_POST["result"],' .
'@matchreport = $_POST["matchreport"],' .
'@battedfirst = $_POST["battedfirst"],' .
'@fieldedfirst = $_POST["fieldedfirst"],' .
'@battedfirstruns = $_POST["battedfirstruns"],' .
'@battedfirstextras = $_POST["battedfirstextras"],' .
'@battedfirsttotal = $_POST["battedfirsttotal"],' .
'@battedsecond = $_POST["battedsecond"],' .
'@fieldedsecond = $_POST["fieldedsecond"],' .
'@battedsecondruns = $_POST["battedsecondruns"],' .
'@battedsecondextras = $_POST["battedsecondextras"],' .
'@battedsecondtotal = $_POST["battedsecondtotal"]'
;
$result = mysql_query($query);
if (!$result) {die("Database access failed: " . mysql_error());}
$query = '
EXECUTE statement USING
    @gamedate,
    @hometeam,
    @visitors,
    @result,
    @matchreport,
    @battedfirst,
    @fieldedfirst,
    @battedfirstruns,
    @battedfirstextras,
    @battedfirsttotal,
    @battedsecond,
    @fieldedsecond,
    @battedsecondruns,
    @battedsecondextras,
    @battedsecondtotal
';
$result = mysql_query($query);
if (!$result) {die("Database access failed: " . mysql_error());}
$query = 'DEALLOCATE PREPARE statement';
$result = mysql_query($query);
if (!$result) {die("Database access failed: " . mysql_error());}

我收到此语法错误:

数据库访问失败:您的 SQL 语法有错误;查看 与您的 MySQL 服务器版本相对应的手册 在 '["gamedate"],@hometeam = 附近使用的语法 $_POST["hometeam"],@visitors = $_POST["visitors"],@resu'

有什么想法吗?谢谢。

【问题讨论】:

  • 您仍然容易受到 sql 注入的攻击,因为您首先将 _POST 数据填充到您的 SET 查询中。通过完全错误地使用占位符,您绝对没有安全性。
  • 有什么想法吗?是的。您只需复制和编造一些东西,而无需查看手册。

标签: php mysql


【解决方案1】:

首先,了解单(')和双("quoted strings in php的区别。

其次,mysql_ 函数 aren't recommended 将不再使用。使用MySQLiPDO

所以你应该使用:

"SET @gamedate = '{$_POST['gamedate']}'"

而不是使用' 转义。或者更确切地说:

'SET @gamedate = "' . mysql_real_escape_string( $_POST['gamedate'], $conn) . '"'

或者你可以用正确的方式来做(例如使用PDO::prepare):

$sql = 'SET @gamedate = :gamedate';
$sth = $dbh->prepare($sql); // $dbh is instance of PDO
$sth->execute(array(':gamedate' => '...'));

【讨论】:

    【解决方案2】:

    为此用途:

    mysqli_prepare ( $link , $query );
    

    例子:

    $mysqli = new mysqli("localhost", "user", "pwd", "db");
    $stmt = mysqli_prepare($link, "INSERT INTO games_new
    ( gamedate, hometeam, visitors, result, matchreport, battedfirst, fieldedfirst, battedfirstruns, battedfirstextras, battedfirsttotal, battedsecond, fieldedsecond, battedsecondruns, battedsecondextras, battedsecondtotal )
    VALUES
    (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
    
    mysqli_stmt_bind_param($stmt, "ssssssssssssss",
        $_POST["hometeam"],
        $_POST["visitors"],
        $_POST["result"],
        $_POST["matchreport"],
        $_POST["battedfirst"],
        $_POST["fieldedfirst"],
        $_POST["battedfirstruns"],
        $_POST["battedfirstextras"],
        $_POST["battedfirsttotal"],
        $_POST["battedsecond"],
        $_POST["fieldedsecond"],
        $_POST["battedsecondruns"],
        $_POST["battedsecondextras"],
        $_POST["battedsecondtotal"]
    );
    
    mysqli_stmt_execute($stmt);
    mysqli_stmt_close($stmt);
    mysqli_close($link);
    

    【讨论】:

    • +1 表示mysqli。这是唯一安全的方法。命名占位符使用起来更容易一些,但这确实有效。
    • 这不是“唯一安全的方法”。 PDO 更好。
    • 我的意思是使用像 ? 这样的占位符,而不是专门的 mysqli
    • 我不明白为什么人们使用未命名的占位符。似乎它在要求错误。洞察力?
    • @Stephane MySQLi 不像 PDO 那样支持命名占位符。
    【解决方案3】:
    $query =
    'SET @gamedate = $_POST["gamedate"],' .
    

    因为这是在单引号中,所以 $_POST["gamedate"] 不会被评估。你应该这样做:

    $query =
    "SET @gamedate = {$_POST['gamedate']}," .
    

    但是,像这样直接使用 $_POST 参数最终通过 SQL 注入攻击您的网站。

    【讨论】:

    • 请不要“修复”这样的代码,这样会导致巨大的 SQL 注入漏洞。如果必须,请使用mysql_real_escape_string 来演示如何编写工作代码。
    • 因此注释,@tadman。这里的基本问题是单引号与双引号,不管SQL注入问题他都需要学习。
    • 如果你要修复它,至少修复它。 "SET @gamedate = {$_POST['gamedate']}," 甚至还没有接近工作 SQL。
    • 取决于$_POST 参数是什么。 SET @gamedate = 1; 在我的 MySQL 安装中执行得非常好。不安全,当然,但有效。
    • 这也是 FFS 的原因,我注意到他会以这种方式进行 SQL 注入。
    【解决方案4】:
    '@battedsecond = $_POST["battedsecond"],'
    

    由于您使用的是简单引号,因此您不能将变量直接放入字符串中。要么使用双引号,要么使用连接。

    "@battedsecond = {$_POST["battedsecond"]},"
    //OR
    '@battedsecond = '.$_POST["battedsecond"].','
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-24
      • 2013-08-03
      • 2016-05-28
      • 2021-06-13
      • 2016-06-11
      • 2014-12-21
      • 2013-01-11
      • 2016-12-20
      相关资源
      最近更新 更多