-2

我在下面编写了这个函数来返回可以在 PDO 语句中使用的 $_POST 全局值。如果这是一个好方法,我只是想要建议。我知道“内爆”部分可能不是很灵活,但我想知道如何改进。非常感谢任何有关逻辑和改进功能的帮助。谢谢。

/**
 * This function loops through the $_POST global and returns parameters that can be used in
 * a PDO statement directly. Note : For this function to work properly the 
 * PDO::ATTR_EMULATE_PREPARES should be set to "false"
 * like so "$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false)".
 * @param  Array $exclude This is an array of keys in $_POST that you want the function to ignore
 * @return Array The function returns an array that can be used as parameters for the PDO statement
 */
function get_params($exclude = array()) {
    $keys = array();
    $values = array();
    $placeholder_keys = array();
    $params = array();

    foreach ($_POST as $key => $value) {
        if(!in_array($key, $exclude)) {
            $keys[]             = $key;
            $placeholder_keys[] = ":" . $key;
            if(is_array($value)){
                $value = implode(",", $value);
            }
            $values[] = $value;
        }
    }

    $comma_sep_keys = implode(",", $keys);
    $comma_sep_placeholder_keys = implode(",", $placeholder_keys);

    $params['keys'] = $keys;
    $params['values'] = $values;
    $params['placeholder_keys'] = $placeholder_keys;
    $params['comma_sep_keys'] = $comma_sep_keys;
    $params['comma_sep_placeholder_keys'] = $comma_sep_placeholder_keys;

    return $params;
}
4

2 回答 2

4

你根本没有对钥匙进行消毒。如果数组元素是:

array(
    "foo = ''; DROP TABLE users; --" => 'baz'
)

这让您对 SQL 注入敞开大门。您将占位,但作为回报,您盲目地将未清理的键连接到查询中。

您还将数组值内爆到单个字符串中;"foo,bar,baz"当它们最初是一个数组时,你真的想将它们作为单个值插入吗?

于 2013-06-09T13:15:25.437 回答
1

如果不清楚(因为这是我想到的第一件事),请扩展一点以防万一,您的用户可以将表单更改为:

<input name = "foo = ''; DROP TABLE users; --" value = 'baz'>

此外,您很容易受到 XSS 攻击。如果有人输入这个值怎么办:

<SCRIPT SRC=http://ha.ckers.org/xss.js></SCRIPT>

然后,进入可以读取该用户输入的页面的每个人(最重要的是,您)将加载该xss.js. 这是非常危险的,我建议制定严格的消毒规则。编辑:通常您应该使用htmlentities(),但仅在输出数据时使用它们,这可以在 SO 的这个问题中了解到。但是,如果您接受 html,那么HTML Purifier是一个很好的库。

于 2013-06-09T13:35:00.223 回答