【问题标题】:Php-MySql Security approach while INSERT’ing INTO MySql & fetching from MySql to screen插入 MySql 并从 MySql 获取屏幕时的 PHP-MySql 安全方法
【发布时间】:2013-04-01 10:16:09
【问题描述】:

我在插入 MySql 时的方法

我想我在 *.com 中读到“如果您需要转义或类似操作,请及时执行”,因此在验证页面中我验证了用户输入(空或不检查、长度检查和结构检查(例如:邮件结构、自定义标签结构);我使用$_POST[''] 变量作为输入。在验证过程中,即使在自定义错误打印部分,我的错误消息也不包括消息文本中的任何$_POST[''] 值。
作为临时说明:我在 php-MySql 交互期间使用准备好的语句和参数化查询。如果输入得到验证;就在插入 MySql 之前,我 从输入中剥离标签,因为除了自定义结构化标签之外,我不允许任何 html 标签。 (例如**bold text** === <strong>bold text</strong>)然后我将用户输入插入MySql db。

从 MySql 获取并将输出打印到屏幕时的我的方法

我只应用 htmlspecialchars() 命令从 MySql db 打印到屏幕

我的问题

我不确定自己。我的方法有什么明显或隐藏的弱点吗?提前感谢 php 大师的宝贵 cmets。 BR

更新

在插入 MySql 数据库期间我不会剥离标签。具体原因请参考下方ÁlvaroG.Vicario的cmets。 BR。

【问题讨论】:

  • 如果您的输入不是 HTML,请不要去除 HTML 标签。你只是在破坏用户数据。
  • @ÁlvaroG.Vicario 如果用户输入一些javascript或smilar恶意代码怎么办?然后我将接受这些输入到 mysql db。但由于我将在打印到屏幕时使用 htmlspecialchars,因此恶意代码不会是危险的。所以剥离标签没有任何好处。我理解正确吗?你能举一个例子,我需要在 INSERT INTO 期间剥离标签吗?谢谢,BR
  • 如果它没有好处,那将是无害的。我的意思是,您实际上可以打破用户关心的输入内容。请不要这样做。
  • 好的,谢谢,我会根据您的 cmets 更新我的问题。 BR。

标签: php mysql security prepared-statement parameterized


【解决方案1】:

到目前为止的讨论都是关于防止 SQL 注入和持久性跨站点脚本。听起来你走在正确的轨道上。

  • 使用预准备语句是对抗 SQL 注入的“最佳实践”。
  • htmlspecialchars() 是防止 XSS 的良好开端,但您必须在适合您输出数据的位置的编码方案中转义数据。 OWASP 有一个全面的页面讨论这个问题:XSS (Cross Site Scripting) Prevention Cheat Sheet。简短的回答:确保您使用的是“the escape syntax for the part of the HTML document you're putting untrusted data into.

【讨论】:

    【解决方案2】:

    我在 trial.php 中尝试了下面的代码

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
    <html xmlns="http://www.w3.org/1999/xhtml" lang="tr"> 
    <head> 
    <title>trial</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
    <meta http-equiv="Content-Language" content="tr" /> 
    <meta name="Description" content="trial page." /> 
    <meta name="Robots" content="noindex, nofollow" />
    </head>
    <body>
    <?php
    $str1 = '<script>alert(\'inside of input with quote\')</script>';
    $str2 = '<script>alert("inside of input with quote")</script>';
    $str3 = "<script>alert(\"inside of input with quote\")</script>";
    $str4 = '<script>alert("outside of form")</script>';
    ?>
    <form method="post" action="">
        <fieldset>
            <legend>alert attempts inside form inputs</legend>
            <label for="input1">label 1:</label><br />
            <input type="text" value="<?php echo htmlspecialchars($str1) ; ?>" name="input1" id="input1" /><br /><br />
    
            <legend>attempt 2</legend>
            <label for="input2">label 2:</label><br />
            <input type="text" value="<?php echo htmlspecialchars($str2) ; ?>" name="input2" id="input2" /><br /><br />
    
            <label for="input3">Label 3:</label><br />
            <input type="text" value="<?php echo htmlspecialchars($str3) ; ?>" name="input3" id="input3" />
        </fieldset>
    </form>    
    <?php echo htmlspecialchars($str4) ; ?>
    </body>
    </html>
    

    trial.php 的结果

    1. 用户关心的输入没有中断,因此用户数据没有中断 损坏
    2. 我清楚地看到了用户在屏幕上输入的内容
    3. 脚本警报不起作用

    INSERT'ing INTO MySQL & 从 MySQL 获取并将输出打印到屏幕时产生的过程

    1. 使用准备好的语句和参数查询 php-MySQL 交互。在 INSERT’ing INTO MySQl db 时,这种方法已经防止了 SQL 注入,因此无需额外的转义。像strip_tags() 这样的额外努力会破坏用户真正关心的输入,就像htmlspecialchars()htmlentities() 也会这样做。
    2. 同时使用准备好的语句和参数查询 从 MySQL 数据库中获取
    3. 在屏幕上打印用户输入的数据时,使用 htmlspecialchars() 所以用户真正关心的打字不会 break 和可能的恶意特殊字符将被转换为 它们对应的 HTML 实体

    【讨论】: