2009-07-27 5 views
0

Wenn man bedenkt, dass sich jeder immer Sorgen um Benutzerdaten macht (und das zu Recht), würde es ausreichen, einfach jedes externe Array zu durchlaufen, wenn Sie es erhalten, und mysql_real_escape_string() anzuwenden.Looping durch GET, POST und COOKIE zu Sanitize?

Ich bin gespannt, ob das eine schlechte Idee ist.

Etwas wie:

 
function getExternalData($type='GET') 
{ 
    $type = strtoupper($type); 
    $data = $_$type; 
    foreach($data as $key => $value) 
    { 
     $clean[$key] = mysql_real_escape_string($value); 
    } 
    return $clean; 
} 

Das ist alles, dass die Daten sicher machen würde, in Datenbanken zu verwenden. Aber, was sind die Nachteile, es auf diese Weise zu tun?

+0

http://stackoverflow.com/questions/129677/whats-the-best-method-for-sanitizing-user-input-with-php/130323#130323 – troelskn

Antwort

2

Der Hauptkonsens ist, wenn Sie die Eingabe verarbeiten müssen, um zum Beispiel Markup zu analysieren, müssen Sie die Eingabe unescape, dann vergessen Sie nicht, es erneut zu entkommen. Außerdem ist es ziemlich ineffizient. Platzhalter für Abfragen sind eine sehr gute Möglichkeit, die SQL-Injektion zu verhindern.

Zur Desinfektion selbst (nicht nur für SQL) sollten Sie einen Blick auf die Filter extension werfen, die standardmäßig in PHP 5.2 und in PECL für 5.1 verfügbar ist.

1

Nachteile:

Sie könnten es vergessen andere Arten von Benutzereingaben sind und so, sie nicht reinigen.
Und natürlich, die überschüssigen Schleifen.
Und ich denke DB Reinigung sollte so spät wie möglich getan werden, kurz bevor Sie die Daten in die DB in Ihrem DL eingeben.
Reinigungs Daten für die Präsentation sollte kurz vor Vorlage der Daten durchgeführt werden, usw.

Das heißt, bis Sie versuchen, diesen Ansatz, werden Sie nie wissen, wie die Leute usualy mit Ansätzen anderer Meinung zu sein neigen sie selbst nicht verwenden (siehe oben :-))

0

ich glaube, du bist wirklich auf der Suche nach array_map(). Dies beseitigt die Notwendigkeit einer Schleife. Und ja, das ist akzeptabel, um Anfragen für die Datenbank zu sichern.

Eine Sache jedoch, möchten Sie vielleicht $_SERVER['REQUEST_METHOD'] hier verwenden. (es sei denn, Sie verwenden es als Parameter für diese Funktion.)

1

Versuchen Sie nicht, Daten zu bereinigen. Verwenden Sie Abfragen mit Platzhaltern. Siehe bobby-tables.com

2

Anwendung mysql_real_escape_string auf allen superglobalen Variablen vermitteln den Eindruck, dass entweder Sie wollen, dass sie verwenden ausschließlich in MySQL-Abfragen oder dass Sie keine Ahnung haben, was mysql_real_escape_string gut ist.

1

Ich denke, es ist eine schlechte Idee, Validierung und Filterlogik zu verallgemeinern. Das war die Idee hinter Zauberzitaten, die jetzt allgemein verurteilt wird.

Abgesehen davon beinhaltet die Validierung von Feldeingaben normalerweise eine Menge spezifischen Mülls. Generische Regeln erweisen sich als eher kleiner Teil der Validierung, insbesondere wenn die Größe und Komplexität von Apps zunimmt.

Es wäre eine bessere Idee, ein Mini-Framework zu entwickeln, mit dem Sie sowohl die generische als auch die spezifische Validierung am selben Ort durchführen können. So etwas wie dies ...

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';