2010-03-08 9 views
19

Ich verwende Codeigniter-Framework.

wo sollte ich PHP-Eingabe - Controller oder Modell sanisieren?

+0

Was meinst du mit sanitize? – troelskn

+1

Betrachten Sie Phil Sturgeon's Antwort. Genau das möchte ich Sie fragen: Warum verwenden Sie nicht die nativen Sanitizing- und Validierungsfunktionen von CI? Und wenn du das tust, was brauchst du außerdem? Das würde zu genaueren Antworten bezüglich CI führen. – Boldewyn

Antwort

19

Ich war so lange wie möglich ein Freund der Zentralisierung der Sanitärversorgung, aber eine ausführliche Diskussion über SO (for example here) hat meine Meinung geändert. Auf jeden Fall eine Lektüre wert.

Ich lege Sie die folgende Praxis:

In einer zentralen Validierungsroutine, tue keine sanitären Einrichtungen, oder einfach nur „grobe“ Kontrollen (zum Beispiel für Datentyp) und Größe („$ _POST [“ category_name "] sollte nicht größer als 200 Bytes sein. ")

Eingehende Variablen als unsichere (z. B. $unsafe_id = $_POST["category_name"];) markieren.Speichern Sie sie in jedem Controller/Klasse/Konstrukt, den Sie dafür zur Verfügung haben.

Sanitize Daten wo es verwendet wird. Wenn eingehende Daten in einem exec Aufruf zum Beispiel verwendet wird, führen Sie die notwendigen sanitären Einrichtungen direkt vor dem Aufruf:

$safe_category_name = escapeshellargs($unsafe_category_name); 
    exec("external_binary -category_name '$safe_category_name'"); 

wenn die gleichen Daten dann in ein verwendet wird, sagen wir, mySQL Abfrage, sanieren sie wieder vor des Anrufs:

$safe_category_name = mysql_real_escape_string ($unsafe_category_name); 
mysql_query("SELECT * FROM items WHERE category_name = '$safe_category_name'"); 

(dies ist nur ein Beispiel, wenn ein Projekt von Grund auf neu, werden Sie PDO und vorbereitete Anweisungen verwenden, die den Aufwand für die Flucht eingehenden Daten in diesem Zusammenhang nimmt..)

wenn die gleichen Daten dann in einem we ausgegeben werden b Seite, machen wieder die sanitären Einrichtungen direkt vor dem Aufruf:

$safe_category_name = htmlspecialchars($unsafe_category_name); 
echo "<span>$safe_category_name</span>"; 

Diese Praxis

  • Baut einen Workflow, gibt es unsichere Variablen geht davon aus, dass mit dem ersten behandelt werden müssen, was dazu führt, ein sicherer Programmierstil IMO.

  • Verhindert unnötige Konvertierungen.

  • Hilft gegen die Illusion, dass es eine Ein-Klick-Methode gibt, um die Eingabe "sicher" zu machen. Es ist nicht. Hygiene hängt zu 100% vom Kontext ab.

+2

Noch einfacher, wenn es eine ID in Vanille PHP ist, kannst du einfach $ id = (int) $ _POST ['id'] verwenden, um es sicher zu machen. –

+0

@Phil die '$ id' sollte ein Beispiel für beliebige String-Daten sein. Ich habe die Variable geändert, da id normalerweise numerisch ist, du hast Recht. Prost. –

0

Ihre Anfrage geht an Controller in der Regel, sollten Sie tun, dass in einem Controller, Controller, sobald diese Daten bekommt und hygienisiert, die dann mit dem Modell mit sicheren Daten interagieren können.

-1

Ich würde es nur aus meiner Sicht tun. Es ist nicht notwendig, es für das Speichern in der Datenbank zu bereinigen. Es reicht aus, nur die sauberen Daten auszugeben. Sie müssen auch die Daten umgehen, um SQL-Injektionen zu verhindern.

+0

Ich dachte, dass Desinfizieren bedeutet, Daten zu filtern. Ich würde nie irgendwelche Daten filtern, die von den Benutzern zur Verfügung gestellt werden, um es in der DB zu speichern, da das Entkommen es genug ist. –

7

Controller sollten dünn sein.

Die PHP-Eingabe sollte im Modell für alles, was mit dem Modell zu tun ist, bereinigt werden. d. h., SQL-Injektion in das Modell verhindern.

Es sollte in der Ansicht für alles, was mit der endgültigen Ausgabe zu tun, aber bereinigt werden. d. h. XSS in der Ansicht verhindern.

Grundsätzlich sollte jede Sensibilisierung rechtzeitig erfolgen, damit keine schädlichen Daten entstehen.

+2

Können Sie herausfinden, warum Controller dünn sein sollten? Ich unterstelle nicht, dass es falsch ist oder so, ich bin nur neugierig. – rogeriopvl

+0

Es ist wiederverwendbar und ermöglicht es Ihnen, Komponententests einfacher zu schreiben. – Quentin

+2

@rogeriopvl, würde ich wegen des Konzepts der losen Kopplung sagen. Sie möchten, dass der Controller Entscheidungen nur auf Grundlage seines Zwecks trifft und nicht auf Annahmen darüber, was passieren wird, nachdem die Daten den Controller passiert haben. – Nicole

1

Der Controller ist wie der Anwendungs-Gatekeeper, also sollten Sie alle Eingaben validieren.

+0

Der Controller, das Modell und alle Anzeigen werden als index.php ausgeführt. Außerdem sollte durch Übung die gesamte Logik im Modell beibehalten werden. – Babiker

8

Die Desinfektion hängt davon ab, für welche Daten die Daten bereinigt werden.

Normalerweise gibt es zwei Arten von sanitization:

  • Datenbank Eingang
  • Front-End-Ausgabe

Im ersten Fall ist es SQL injection Angriffe zu verhindern, und die zweiten Cross-site scripting zu verhindern ist, Anschläge.

So Ihre Frage zu beantworten (in Bezug auf die oben genannten Angriffsvektoren), sollten Sie Ihre sanitization sein, wo Schwachstellen vorhanden sind, und genauer gesagt:

  • wo Sie SQL-Abfragen mit Variablen in sie zu schreiben (die Modelle)
  • , wo Sie jede Ausgabe (in der Regel HTML) (die Ansichten) schreiben

ich hoffe, das half.

0

Nach mir, soll eine Benutzereingabe in der Controller hygienisiert werden, da es eine obligatorische Passage für die Daten zwischen Ihrer Ansicht darstellt (der Ort, wo Sie Informationen für den Benutzer anzeigen und Sie Benutzer erhalten Eingabe) und Ihr Modell (wo Sie die Daten speichern).

Das Modell sollte immer als steckbare Komponente in Ihrem MVC Struktur in Betracht gezogen werden, was bedeutet, dass Sie könnte zum Beispiel das Modell wechseln (die Datenbank-Implementierung und/oder die Art und Weise Sie mit ihm interagieren) an einem bestimmten Punkt . Aus diesem Grund sollte die Benutzerdatenvalidierung nicht an die spezifische Implementierung einer Datenbank gebunden sein. Nur der Teil Desinfektion, der DB-spezifisch ist (falls vorhanden) sollte im Modell beibehalten werden.

Sagte dies, die endgültige Entscheidung liegt immer bei Ihnen. Denken Sie daran:

  • Eingang immer validiert sein muss, sollte
  • Entwurf konsistent sein. Wenn Sie sich entschließen, Benutzereingaben im Controller zu bereinigen, versuchen Sie es mit aways. Dies wird zu sauberer und einfacher zu verstehen Code

Hope dies hilft.

22

Alle diese Antworten beziehen sich auf PHP-Methoden im Allgemeinen, sind aber für CodeIgniter irrelevant.

POST-Daten

CodeIgniter reinigt Ihre Daten automatisch POST, wenn Sie $ this- verwenden> Input-> post ('item_name'), wenn Sie global_xss in config.php aktiviert haben. Wenn Sie nur für bestimmte Elemente wollen gereinigt werden, können Sie verwenden:

$this->input->post('item_name', TRUE); 

So oder so, die Sie von XSS-Angriffe und andere Fragen sind sicher.

SQL-Injection-

Alles wird in die Datenbank eingegeben wird entkam automatisch, wenn Sie Active (insert(), update(), usw.) verwenden oder verwenden Sie die query() Bindungen.

$this->db->query('INSERT INTO bla (?, ?)', array($foo, $bar)); 

Das ist alles mit so nicht mehr Faffing entkommen, was wo geht. Sie können einfach Code schreiben und die Sicherheit in den Händen des Frameworks belassen.

+0

Gute Antwort. +1 für das Aufzeigen der Kernfunktionen von CI. – Boldewyn

1

Ich würde es in den Controller setzen, der die Formularübergabe behandelt. Da Phil Sturgeon darauf hinweist, dass die Option global_xss in Ihrer Konfiguration aktiviert ist, wird CodeIgniter ohnehin eine gewisse Stufe der Desinfektion behandeln.

Als zusätzliche Sicherheitsstufe würde ich die form_validation-Bibliothek von CodeIgniter verwenden. Hier ist ein Beispiel-Controller für Sie:

function processForm() 
{ 

    // fields will need to be validated so load library 
    $this->load->library('form_validation'); 

    // field name, error message, validaiton rules 
    $this->form_validation->set_rules('first_name','Name','trim|required'); 

    if($this->form_validation->run() == FALSE) 
    { 
     // load form again showing errors 
    } else { 
     // update database or proceed to stage 2 
    } 

} 

Ich hoffe, das hilft! Cheers