0

誰もが常にユーザー データについて心配していることを考えると (当然のことですが)、取得した外部配列を単純にループし、mysql_real_escape_string() を適用するだけで十分でしょうか。

これが悪い考えなのか、興味があります。

何かのようなもの:

関数 getExternalData($type='GET')
{
    $type = strtoupper($type);
    $data = $_$type;
    foreach($data as $key => $value)
    {
        $clean[$key] = mysql_real_escape_string($value);
    }
    $クリーンを返します。
}

これにより、すべてのデータがデータベースで安全に使用できるようになります。しかし、このようにすることの短所は何ですか?

4

6 に答える 6

2

主な短所は、入力を処理する必要がある場合です。たとえば、マークアップを解析するために、入力をエスケープ解除してから、再度エスケープすることを忘れないようにする必要があります。また、かなり効率が悪いです。クエリ プレースホルダーは、SQL インジェクションを防ぐ非常に優れた方法です。

サニタイズ自体 (SQL だけでなく) については、PHP 5.2 および 5.1 の PECL でデフォルトで利用可能なFilter 拡張機能を確認する必要があります。

于 2009-07-27T15:24:59.387 に答える
2

すべてのスーパーグローバル変数に適用するmysql_real_escape_stringと、それらを MySQL クエリで排他的に使用したい、または何に役立つか見当がつかないという印象を与えますmysql_real_escape_string

于 2009-07-27T15:22:56.443 に答える
1

検証とフィルタリングのロジックを一般化するのは悪い考えだと思います。それが結局のところ、魔法の引用の背後にある考え方であり、現在では広く非難されています.

それに加えて、フィールド入力の検証には通常、多くの特定のがらくたが含まれます。一般的なルールは、特にアプリのサイズと複雑さが増すにつれて、検証のかなり小さな部分であることが判明しました。

一般的な検証と特定の検証の両方を同じ場所で処理できるミニ フレームワークを考え出すことをお勧めします。このようなもの...

class BrokenRules extends Exception {
    protected $errors;
    function __construct($errors) {
        $this->errors = $errors;
    }
    function getErrors() {
        return $this->errors;
    }
}

class Foo {
    protected $db;
    function __construct(PDO $db) {
        $this->db = $db;
    }
    function loadNew() {
        return array('bar' => 'new foo', 'baz' => 5);
    }
    function loadById($id) {
        $stmt = $this->db->prepare('SELECT * FROM foo WHERE id = ?');
        $stmt->bindValue(1, $id, PDO::PARAM::INT);
        $stmt->execute();
        return $stmt->fetch();
    }
    function save($data) {
        return isset($data['id']) ? $this->update($data) : $this->insert($data);
    }
    protected function validateForInsert($data) {
        if ((int)$data['baz'] <= 3) $errors['baz'][] = 'Baz must be greater than 3';
        if (isset($errors)) throw new BrokenRules($errors);
    }
    protected function validateForUpdate($data) {
        // TODO: validateForUpdate
    }
    protected function insert($data) {
        $this->validateForInsert($data);
        $stmt = $this->db->prepare('INSERT INTO foo (x, y) VALUES (?, ?)');
        $stmt->bindValue(1, $data['bar'], PDO::PARAM_STR);
        $stmt->bindValue(2, $data['baz'], PDO::PARAM_INT);
        $stmt->execute();
        return $this->db->lastInsertId();
    }
    protected function update($data) {
        $this->validateForUpdate($data);
        $stmt = $this->db->prepare('UPDATE foo SET x = ?, y = ? WHERE id = ?');
        $stmt->bindValue(1, $data['bar'], PDO::PARAM_STR);
        $stmt->bindValue(2, $data['baz'], PDO::PARAM_INT);
        $stmt->bindValue(3, $data['id'], PDO::PARAM_INT);
        $stmt->execute();
        return $data['id'];
    }
}

try {
    $foo = new Foo($pdo);
    if ($_POST) {
        $id = $foo->save($_POST);
        redirect("edit_foo.php?id=$id");
    } else if (isset($_GET['id'])) {
        $data = $foo->loadById($_GET['id']);
    } else {
        $data = $foo->loadNew();
    }
} catch (BrokenRules $e) {
    $errors = $e->getErrors();
}

include 'templates/foo.php';
于 2009-07-27T18:24:52.677 に答える
1

短所:

他のタイプのユーザー入力があることを忘れている可能性があるため、それらを消去しないでください。
そしてもちろん、余分なループ。
また、DB クリーニングは、DL で DB にデータを入力する直前に、できるだけ最新に行う必要があると思います。
プレゼンテーション用データのクリーニングは、データのプレゼンテーションの直前に行う必要があります。

とはいえ、このアプローチを試すまでは、決してわかりません。通常、人々は自分で使用しないアプローチに反対する傾向があるためです (上記を参照してください :-) )

于 2009-07-27T15:11:44.063 に答える
1

データをサニタイズしようとしないでください。プレースホルダーでクエリを使用します。bobby-tables.comを参照

于 2009-07-27T15:17:10.777 に答える
0

実際にarray_map()を探していると思います。これにより、ループが不要になります。はい、これはリクエストをデータベースに対して安全にするために受け入れられます。

ただし、ここで$_SERVER['REQUEST_METHOD']を使用することをお勧めします。(この関数にパラメーターとして渡すために使用している場合を除きます。)

于 2009-07-27T15:13:44.903 に答える