it-swarm.com.de

Was ist die beste Methode, um Benutzereingaben mit PHP zu bereinigen?

Gibt es irgendwo eine Catchall-Funktion, die gut für die Bereinigung der Benutzereingaben für SQL-Injection- und XSS-Angriffe geeignet ist und bestimmte Arten von HTML-Tags weiterhin zulässt?

1018
Brent

Es ist ein weit verbreitetes Missverständnis, dass Benutzereingaben gefiltert werden können. PHP hat sogar ein (jetzt veraltetes) "Feature", genannt "magische Anführungszeichen", das auf dieser Idee aufbaut. Das ist Unsinn. Vergessen Sie das Filtern (oder die Reinigung oder wie auch immer die Leute es nennen).

Was Sie tun sollten, um Probleme zu vermeiden, ist ziemlich einfach: Wenn Sie eine Zeichenfolge in einen Fremdcode einbetten, müssen Sie sie entsprechend den Regeln dieser Sprache deaktivieren. Wenn Sie beispielsweise eine Zeichenfolge in einige SQL-Adressen einbetten, die auf MySql abzielen, müssen Sie die Zeichenfolge mit der Funktion von MySql für diesen Zweck (mysqli_real_escape_string) umschreiben. (Oder im Fall von Datenbanken ist die Verwendung von vorbereiteten Anweisungen, wenn möglich, ein besserer Ansatz.)

Ein anderes Beispiel ist HTML: Wenn Sie Strings in HTML-Markup einbetten, müssen Sie es mit htmlspecialchars umleiten. Dies bedeutet, dass jede echo- oder print-Anweisung htmlspecialchars verwenden sollte.

Ein drittes Beispiel könnten Shell-Befehle sein: Wenn Sie Zeichenfolgen (wie Argumente) in externe Befehle einbetten und sie mit exec aufrufen, müssen Sie escapeshellcmd und escapeshellarg verwenden.

Und so weiter und so fort ...

Der Fall only, in dem Sie Daten aktiv filtern müssen, ist der Fall, wenn Sie vorformatierte Eingaben akzeptieren. Z.B. Wenn Sie Ihren Benutzern die Möglichkeit geben, HTML-Markup zu posten, möchten Sie diese auf der Website anzeigen. Sie sollten jedoch klug sein, dies um jeden Preis zu vermeiden, denn egal wie gut Sie es filtern, es wird immer eine potenzielle Sicherheitslücke sein.

1108
troelskn

Versuchen Sie nicht, die SQL-Injection durch Bereinigen der Eingabedaten zu verhindern.

Stattdessen erlauben keine Daten zur Erstellung Ihres SQL-Codes. Verwenden Sie Prepared Statements (d. H. Parameter in einer Vorlagenabfrage verwenden), die gebundene Variablen verwenden. Nur so kann gegen die SQL-Injection garantiert werden.

Bitte besuchen Sie meine Website http://bobby-tables.com/ , um weitere Informationen zur Verhinderung der SQL-Injektion zu erhalten.

191
Andy Lester

Nein. Sie können Daten nicht generisch filtern, ohne den Kontext zu definieren, für den sie bestimmt sind. Manchmal möchten Sie eine SQL-Abfrage als Eingabe verwenden, und manchmal möchten Sie HTML als Eingabe verwenden.

Sie müssen die Eingaben auf einer Positivliste filtern. Stellen Sie sicher, dass die Daten mit den Angaben Ihrer Erwartungen übereinstimmen. Sie müssen es dann vor der Verwendung entgehen, je nachdem, in welchem ​​Kontext Sie es verwenden.

Der Escape-Prozess von Daten für SQL - um die SQL-Injection zu verhindern - unterscheidet sich sehr vom Prozess der Escape-Daten von (X) HTML, um XSS zu verhindern.

73
Daniel Papasian

PHP verfügt jetzt über die neuen Nice-Filter_Input-Funktionen, die Sie zum Beispiel von der Suche nach dem ultimativen E-Mail-Regex befreien, da es jetzt einen integrierten FILTER_VALIDATE_EMAIL-Typ gibt

Meine eigene Filterklasse (verwendet Javascript, um fehlerhafte Felder hervorzuheben) kann entweder durch eine Ajax-Anforderung oder durch einen normalen Formularpost ausgelöst werden. (siehe Beispiel unten)

/**
 *  Pork.FormValidator
 *  Validates arrays or properties by setting up simple arrays. 
 *  Note that some of the regexes are for dutch input!
 *  Example:
 * 
 *  $validations = array('name' => 'anything','email' => 'email','alias' => 'anything','pwd'=>'anything','gsm' => 'phone','birthdate' => 'date');
 *  $required = array('name', 'email', 'alias', 'pwd');
 *  $sanatize = array('alias');
 *
 *  $validator = new FormValidator($validations, $required, $sanatize);
 *                  
 *  if($validator->validate($_POST))
 *  {
 *      $_POST = $validator->sanatize($_POST);
 *      // now do your saving, $_POST has been sanatized.
 *      die($validator->getScript()."<script type='text/javascript'>alert('saved changes');</script>");
 *  }
 *  else
 *  {
 *      die($validator->getScript());
 *  }   
 *  
 * To validate just one element:
 * $validated = new FormValidator()->validate('[email protected]', 'email');
 * 
 * To sanatize just one element:
 * $sanatized = new FormValidator()->sanatize('<b>blah</b>', 'string');
 * 
 * @package pork
 * @author SchizoDuckie
 * @copyright SchizoDuckie 2008
 * @version 1.0
 * @access public
 */
class FormValidator
{
    public static $regexes = Array(
            'date' => "^[0-9]{1,2}[-/][0-9]{1,2}[-/][0-9]{4}\$",
            'amount' => "^[-]?[0-9]+\$",
            'number' => "^[-]?[0-9,]+\$",
            'alfanum' => "^[0-9a-zA-Z ,.-_\\s\?\!]+\$",
            'not_empty' => "[a-z0-9A-Z]+",
            'words' => "^[A-Za-z]+[A-Za-z \\s]*\$",
            'phone' => "^[0-9]{10,11}\$",
            'zipcode' => "^[1-9][0-9]{3}[a-zA-Z]{2}\$",
            'plate' => "^([0-9a-zA-Z]{2}[-]){2}[0-9a-zA-Z]{2}\$",
            'price' => "^[0-9.,]*(([.,][-])|([.,][0-9]{2}))?\$",
            '2digitopt' => "^\d+(\,\d{2})?\$",
            '2digitforce' => "^\d+\,\d\d\$",
            'anything' => "^[\d\D]{1,}\$"
    );
    private $validations, $sanatations, $mandatories, $errors, $corrects, $fields;


    public function __construct($validations=array(), $mandatories = array(), $sanatations = array())
    {
        $this->validations = $validations;
        $this->sanatations = $sanatations;
        $this->mandatories = $mandatories;
        $this->errors = array();
        $this->corrects = array();
    }

    /**
     * Validates an array of items (if needed) and returns true or false
     *
     */
    public function validate($items)
    {
        $this->fields = $items;
        $havefailures = false;
        foreach($items as $key=>$val)
        {
            if((strlen($val) == 0 || array_search($key, $this->validations) === false) && array_search($key, $this->mandatories) === false) 
            {
                $this->corrects[] = $key;
                continue;
            }
            $result = self::validateItem($val, $this->validations[$key]);
            if($result === false) {
                $havefailures = true;
                $this->addError($key, $this->validations[$key]);
            }
            else
            {
                $this->corrects[] = $key;
            }
        }

        return(!$havefailures);
    }

    /**
     *
     *  Adds unvalidated class to thos elements that are not validated. Removes them from classes that are.
     */
    public function getScript() {
        if(!empty($this->errors))
        {
            $errors = array();
            foreach($this->errors as $key=>$val) { $errors[] = "'INPUT[name={$key}]'"; }

            $output = '$$('.implode(',', $errors).').addClass("unvalidated");'; 
            $output .= "new FormValidator().showMessage();";
        }
        if(!empty($this->corrects))
        {
            $corrects = array();
            foreach($this->corrects as $key) { $corrects[] = "'INPUT[name={$key}]'"; }
            $output .= '$$('.implode(',', $corrects).').removeClass("unvalidated");';   
        }
        $output = "<script type='text/javascript'>{$output} </script>";
        return($output);
    }


    /**
     *
     * Sanatizes an array of items according to the $this->sanatations
     * sanatations will be standard of type string, but can also be specified.
     * For ease of use, this syntax is accepted:
     * $sanatations = array('fieldname', 'otherfieldname'=>'float');
     */
    public function sanatize($items)
    {
        foreach($items as $key=>$val)
        {
            if(array_search($key, $this->sanatations) === false && !array_key_exists($key, $this->sanatations)) continue;
            $items[$key] = self::sanatizeItem($val, $this->validations[$key]);
        }
        return($items);
    }


    /**
     *
     * Adds an error to the errors array.
     */ 
    private function addError($field, $type='string')
    {
        $this->errors[$field] = $type;
    }

    /**
     *
     * Sanatize a single var according to $type.
     * Allows for static calling to allow simple sanatization
     */
    public static function sanatizeItem($var, $type)
    {
        $flags = NULL;
        switch($type)
        {
            case 'url':
                $filter = FILTER_SANITIZE_URL;
            break;
            case 'int':
                $filter = FILTER_SANITIZE_NUMBER_INT;
            break;
            case 'float':
                $filter = FILTER_SANITIZE_NUMBER_FLOAT;
                $flags = FILTER_FLAG_ALLOW_FRACTION | FILTER_FLAG_ALLOW_THOUSAND;
            break;
            case 'email':
                $var = substr($var, 0, 254);
                $filter = FILTER_SANITIZE_EMAIL;
            break;
            case 'string':
            default:
                $filter = FILTER_SANITIZE_STRING;
                $flags = FILTER_FLAG_NO_ENCODE_QUOTES;
            break;

        }
        $output = filter_var($var, $filter, $flags);        
        return($output);
    }

    /** 
     *
     * Validates a single var according to $type.
     * Allows for static calling to allow simple validation.
     *
     */
    public static function validateItem($var, $type)
    {
        if(array_key_exists($type, self::$regexes))
        {
            $returnval =  filter_var($var, FILTER_VALIDATE_REGEXP, array("options"=> array("regexp"=>'!'.self::$regexes[$type].'!i'))) !== false;
            return($returnval);
        }
        $filter = false;
        switch($type)
        {
            case 'email':
                $var = substr($var, 0, 254);
                $filter = FILTER_VALIDATE_EMAIL;    
            break;
            case 'int':
                $filter = FILTER_VALIDATE_INT;
            break;
            case 'boolean':
                $filter = FILTER_VALIDATE_BOOLEAN;
            break;
            case 'ip':
                $filter = FILTER_VALIDATE_IP;
            break;
            case 'url':
                $filter = FILTER_VALIDATE_URL;
            break;
        }
        return ($filter === false) ? false : filter_var($var, $filter) !== false ? true : false;
    }       



}

Denken Sie jedoch daran, dass Sie Ihre SQL-Abfrage auch abhängig von der Art der verwendeten Datenbank verwenden müssen (mysql_real_escape_string () ist beispielsweise für einen SQL-Server unbrauchbar). Wahrscheinlich möchten Sie dies auf Ihrer entsprechenden Anwendungsebene wie ein ORM automatisch behandeln. Auch, wie oben erwähnt: Für die Ausgabe in HTML verwenden Sie die anderen PHP-spezifischen Funktionen wie htmlspecialchars;)

Um wirklich HTML-Eingaben mit ähnlich entfernten Klassen und/oder Tags zuzulassen, müssen Sie eines der dedizierten xss-Validierungspakete verwenden. SCHREIBEN SIE NICHT IHRE EIGENEN REGEXES IN PARSE HTML!

46
SchizoDuckie

Nein, da ist kein.

Zunächst einmal ist die SQL-Injection ein Problem bei der Eingabefilterung und bei XSS handelt es sich um eine Ausgabe, bei der es um eins geht - Sie müssen also diese beiden Vorgänge nicht einmal gleichzeitig im Code-Lebenszyklus ausführen.

Grundregeln des Daumens

  • Binden Sie für SQL-Abfragen Parameter (wie bei PDO) oder verwenden Sie eine Treiber-native Escape-Funktion für Abfragevariablen (wie mysql_real_escape_string()).
  • Verwenden Sie strip_tags(), um unerwünschtes HTML herauszufiltern
  • Entkommen Sie alle anderen Ausgaben mit htmlspecialchars() und achten Sie hier auf den 2. und 3. Parameter.
40
Peter Bailey

Um das XSS-Problem zu beheben, werfen Sie einen Blick auf HTML Purifier . Es ist ziemlich konfigurierbar und hat eine ordentliche Erfolgsbilanz.

Vergewissern Sie sich bei den SQL-Injection-Angriffen, dass Sie die Benutzereingaben überprüfen und dann über mysql_real_escape_string () ausführen. Die Funktion kann jedoch nicht alle Injektionsangriffe abwehren. Daher ist es wichtig, dass Sie die Daten überprüfen, bevor Sie sie in Ihre Abfragezeichenfolge ablegen.

Eine bessere Lösung ist die Verwendung vorbereiteter Anweisungen. Die PDO-Bibliothek und die mysqli-Erweiterung unterstützen diese.

21
jasonbar

Mit PHP 5.2 wurde die Funktion filter_var eingeführt.

Es unterstützt eine Vielzahl von SANITIZE-, VALIDATE-Filtern.

http://php.net/manual/de/function.filter-var.php

19
dangel

Ein Trick, der in bestimmten Situationen hilfreich sein kann, in denen Sie eine Seite wie /mypage?id=53 verwenden und die ID in einer WHERE-Klausel verwenden, besteht darin, sicherzustellen, dass id auf jeden Fall eine Ganzzahl ist, wie folgt:

if (isset($_GET['id'])) {
  $id = $_GET['id'];
  settype($id, 'integer');
  $result = mysql_query("SELECT * FROM mytable WHERE id = '$id'");
  # now use the result
}

Aber das schließt natürlich nur einen bestimmten Angriff aus, also lesen Sie alle anderen Antworten. (Und ja, ich weiß, dass der obige Code nicht großartig ist, aber er zeigt die spezifische Verteidigung.)

15
Hamish Downer

Was Sie hier beschreiben, ist zwei getrennte Punkte: 

  1. Desinfektion/Filterung von Benutzereingabedaten.
  2. Ausgabe kann entkommen.

1) Benutzereingaben sollten immer als schlecht angenommen werden.

Das Verwenden von vorbereiteten Anweisungen oder/und das Filtern mit mysql_real_escape_string ist auf jeden Fall ein Muss . PHP hat auch filter_input eingebaut, was ein guter Anfang ist.

2) Dies ist ein umfangreiches Thema und hängt vom Kontext der ausgegebenen Daten ab. Für HTML gibt es Lösungen wie htmlpurifier da draußen. Als Faustregel, entgehen Sie immer alles, was Sie ausgeben.

Beide Ausgaben sind viel zu groß, um in einem einzigen Beitrag behandelt zu werden, aber es gibt viele Beiträge, die detaillierter beschrieben werden:

Ausgabe von Methoden PHP

Sicherere PHP -Ausgabe

10
Andrew

Methoden zur Bereinigung von Benutzereingaben mit PHP:

  • Verwenden Sie moderne Versionen von MySQL und PHP.

  • Zeichensatz explizit setzen:

    • $ mysqli-> set_charset ("utf8");
      Handbuch
    • $ pdo = new PDO ('mysql: Host = localhost; dbname = testdb; charset = UTF8', $ user, $ password);
      Handbuch
    • $ pdo-> exec ("set names utf8");
      Handbuch
    • $ pdo = new PDO (
       "mysql: Host = $ host; dbname = $ db", $ user, $ pass, 
       array (
       PDO :: ATTR_ERRMODE => PDO :: ERRMODE_EXCEPTION, 
      PDO :: MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8" 
      ) 
      );
      Handbuch
    • mysql_set_charset ('utf8')
      [veraltet in PHP 5.5.0, entfernt in PHP 7.0.0].
  • Verwenden Sie sichere Zeichensätze:

    • Wählen Sie utf8, latin1, ascii .. aus. Verwenden Sie keine anfälligen Zeichensätze big5, cp932, gb2312, gbk, sjis.
  • Räumliche Funktion verwenden:

    • MySQLi vorbereitete Anweisungen:
      $ stmt = $ mysqli-> prepare ('SELECT * FROM test WHERE name =? LIMIT 1'); 
      $ param = "'OR 1 = 1/*";
      $ stmt-> bind_param ('s', $ param);
      $ stmt-> execute ();
    • PDO :: quote () - setzt (falls erforderlich) Anführungszeichen um die Eingabezeichenfolge und entfernt Sonderzeichen innerhalb der Eingabezeichenfolge. Dabei wird ein für den zugrunde liegenden Treiber geeigneter Anführungsstil verwendet:

      $ pdo = new PDO ('mysql: Host = localhost; dbname = testdb; charset = UTF8', $ user, $ password);explizit den Zeichensatz festlegen
      $ pdo-> setAttribute (PDO :: ATTR_EMULATE_PREPARES, false);deaktivieren Sie die Emulation vorbereiteter Anweisungen, um einen Rückfall auf die Emulation von Anweisungen zu verhindern, die MySQL nicht direkt vorbereiten kann (um Injektionen zu verhindern).
      $ var = $ pdo-> quote ("'OR 1 = 1/*");entgeht nicht nur dem Literal, sondern zitiert es auch (in Anführungszeichen) $ stmt = $ pdo-> query ("SELECT * FROM test WHERE name = $ var LIMIT 1");

    • Vorbereitete Anweisungen für PDO : vs Die vorbereiteten Anweisungen von MySQLi unterstützen mehr Datenbanktreiber und benannte Parameter: 

      $ pdo = new PDO ('mysql: Host = localhost; dbname = testdb; charset = UTF8', $ user, $ password);explizit den Zeichensatz festlegen
      $ pdo-> setAttribute (PDO :: ATTR_EMULATE_PREPARES, false);deaktivieren Sie die Emulation vorbereiteter Anweisungen, um einen Rückfall auf die Emulation von Anweisungen zu verhindern, die MySQL nicht direkt vorbereiten kann (um Injektionen zu verhindern). $ stmt = $ pdo-> vorbereiten ('SELECT * FROM test WHERE name =? LIMIT 1'); $ stmt-> ausführen (["'OR 1 = 1/*"]) );

    •  mysql_real_escape_string [veraltet in PHP 5.5.0, entfernt in PHP 7.0.0].
    • mysqli_real_escape_string Entfernt Sonderzeichen in einer Zeichenfolge zur Verwendung in einer SQL-Anweisung unter Berücksichtigung des aktuellen Zeichensatzes der Verbindung. Es wird jedoch empfohlen, Prepared Statements zu verwenden, da es sich nicht einfach um Strings mit Escapezeichen handelt. Eine Anweisung enthält einen vollständigen Abfrage-Ausführungsplan, einschließlich der verwendeten Tabellen und Indizes. Dies ist eine optimierte Methode.
    • Verwenden Sie einfache Anführungszeichen ('') für Ihre Variablen in Ihrer Abfrage.
  • Überprüfen Sie, ob die Variable enthält, was Sie erwarten:

    • Wenn Sie eine Ganzzahl erwarten, verwenden Sie:
      ctype_digit - Auf numerische Zeichen prüfen;
      $ value = (int) $ value;
      $ value = intval ($ value);
      $ var = filter_var ('0755', FILTER_VALIDATE_INT, $ options);
    • Für Strings verwenden Sie:
      is_string () - Finden Sie heraus, ob der Typ einer Variablen ein String ist

      Verwenden Sie Filter Function filter_var () - filtert eine Variable mit einem angegebenen Filter:
      $ email = filter_var ($ email, FILTER_SANITIZE_EMAIL);
      $ newstr = filter_var ($ str, FILTER_SANITIZE_STRING);
      mehr vordefinierte Filter
    • filter_input () - Ruft eine bestimmte externe Variable nach Namen ab und filtert sie optional:
      $ search_html = filter_input (INPUT_GET, 'search', FILTER_SANITIZE_SPECIAL_CHARS);
    • preg_match () - Führt einen regulären Ausdruck aus;
    • Schreiben Sie Ihre eigene Validierungsfunktion.
8
Mark Martin

Wenn Sie PostgreSQL verwenden, können die Eingaben von PHP mit pg_escape_string () maskiert werden.

 $username = pg_escape_string($_POST['username']);

Aus der Dokumentation ( http://php.net/manual/es/function.pg-escape-string.php ):

mit pg_escape_string () wird eine Zeichenfolge zum Abfragen der Datenbank ausgegeben. Es gibt eine Escape-Zeichenfolge im PostgreSQL-Format ohne Anführungszeichen zurück.

6
Alejandro Silva

Der einfachste Weg, Fehler bei der Bereinigung von Eingaben zu vermeiden und Daten zu umgehen, ist die Verwendung eines PHP - Frameworks wie Symfony , Nette usw. oder eines Teils dieses Frameworks (Templating Engine, Datenbankschicht, ORM).

Templating Engine wie Twig oder Latte hat standardmäßig eine Escape-Ausgabe - Sie müssen die Lösung nicht manuell lösen, wenn Sie Ihre Ausgabe je nach Kontext (HTML- oder Javascript-Teil der Webseite) ordnungsgemäß entschlüsselt haben.

Das Framework reinigt die Eingabe automatisch und Sie sollten die Variablen $ _POST, $ _GET oder $ _SESSION nicht direkt verwenden, sondern über Mechanismen wie Routing, Sitzungsbehandlung usw.

Und für Datenbank- (Modell) -Schichten gibt es ORM-Frameworks wie Doctrine oder Wrapper um PDO wie Nette Database.

Mehr darüber erfahren Sie hier - Was ist ein Software-Framework?

5
Ondřej Šotek

Es gibt keine Catchall-Funktion, da mehrere Probleme angesprochen werden müssen.

  1. SQL Injection - Heutzutage sollte generell jedes PHP Projekt vorbereitete Anweisungen über PHP Data Objects (PDO) als bewährte Methode, Vermeidung eines Fehlers in einem Streuzitat sowie eine umfassende Lösung gegen Injection. Dies ist auch die flexibelste und sicherste Möglichkeit, auf Ihre Datenbank zuzugreifen.

    In (Das einzig richtige) PDO-Tutorial finden Sie so ziemlich alles, was Sie über PDO wissen müssen. (Ein herzliches Dankeschön an den besten SO Mitwirkenden, @YourCommonSense, für diese großartige Ressource zu diesem Thema.)

  2. XSS - Daten bereinigen auf dem Weg in ...

    • HTML Purifier gibt es schon lange und es wird immer noch aktiv aktualisiert. Sie können es verwenden, um böswillige Eingaben zu bereinigen und gleichzeitig eine großzügige und konfigurierbare Whitelist mit Tags zuzulassen. Funktioniert gut mit vielen WYSIWYG-Editoren, kann aber in einigen Anwendungsfällen sehr schwer sein.

    • In anderen Fällen, in denen wir überhaupt kein HTML/Javascript akzeptieren möchten, fand ich diese einfache Funktion nützlich (und hat mehrere Prüfungen gegen XSS bestanden):

      /* Prevent XSS input */ function sanitizeXSS () { $_GET = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING); $_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING); $_REQUEST = (array)$_POST + (array)$_GET + (array)$_REQUEST; }

  3. XSS - Daten auf dem Weg nach draußen bereinigen ... Wenn Sie nicht garantieren, dass die Daten ordnungsgemäß bereinigt wurden, bevor Sie sie Ihrer Datenbank hinzufügen, müssen Sie dies tun Wenn Sie es bereinigen, bevor Sie es Ihrem Benutzer anzeigen, können wir diese nützlichen PHP Funktionen nutzen:

    • Wenn Sie echo oder print aufrufen, um vom Benutzer angegebene Werte anzuzeigen, verwenden Sie htmlspecialchars , sofern die Daten nicht ordnungsgemäß sicher und sicher bereinigt wurden darf HTML anzeigen.
    • json_encode ist eine sichere Möglichkeit, benutzerdefinierte Werte von PHP bis Javascript bereitzustellen
  4. Rufen Sie externe Shell-Befehle mit exec() oder system() auf? Funktionen, oder an den backtick Operator? Wenn ja, zusätzlich zu SQL Injection & XSS Sie Möglicherweise gibt es ein zusätzliches Anliegen, Benutzer, die böswillige Befehle auf Ihrem Server ausführen. Sie müssen escapeshellcmd verwenden, wenn Sie den gesamten Befehl OR escapeshellarg , um einzelnen Argumenten zu entgehen.

4
webaholik

Ich wollte das nur beim Thema Escapeing hinzufügen. Wenn Sie php DOMDocument verwenden, um Ihre HTML-Ausgabe zu erstellen, wird es automatisch im richtigen Kontext angezeigt. Ein Attribut (value = "") und der innere Text eines <span> sind nicht gleich . Um gegen XSS sicher zu sein, lesen Sie dies: OWASP XSS Prevention Cheat Sheet

2
user138720

Sie bereinigen niemals Eingaben.

Sie desinfizieren immer die Ausgabe.

Die Transformationen, die Sie auf Daten anwenden, um sie für die Aufnahme in eine SQL-Anweisung sicher zu machen, unterscheiden sich grundlegend von denen, die Sie für die Aufnahme in HTML beantragen. Sie unterscheiden sich vollständig von denen, die Sie für die Aufnahme in Javascript beantragen Sie unterscheiden sich grundlegend von denen, die Sie für die Aufnahme in CSS beantragen, und unterscheiden sich vollständig von denen, die Sie für die Aufnahme in eine E-Mail beantragen.

Bestimmen Sie auf jeden Fall validate input - entscheiden Sie, ob Sie es zur weiteren Verarbeitung akzeptieren oder dem Benutzer mitteilen, dass es nicht akzeptabel ist. Nehmen Sie jedoch keine Änderungen an der Darstellung der Daten vor, bis das Land PHP verlassen wird.

Vor langer Zeit hat jemand versucht, einen One-Size-Fits-All-Mechanismus für das Entweichen von Daten zu erfinden, und wir endeten mit " magic_quotes ", bei dem nicht für alle Ausgabeziele Daten korrekt entschlüsselt wurden Arbeit.

1
symcbean

Ich kann sehen, wie PHP-Filter Sonderzeichen bereinigen.

mögen:

    $a=fliter_var($_POST['a'],FILTER_SANITIZE_SPECIAL_CHARS);

Ich denke jedoch, dass es besser sein könnte, wenn man sich den C-Code ansieht, filtert er nur die "'\ <> & und\0, so dass ich sehen kann, dass dies eine gute Möglichkeit ist, zu bereinigen. Allerdings kann der Quellcode geändert werden Wenn Sie diese anderen Zeichen wie/{} []. `einfügen, wird diese Funktion in der Zeile encode (enc ['']) verstärkt:

    void php_filter_special_chars(PHP_INPUT_FILTER_PARAM_DECL)
{
unsigned char enc[256] = {0};

php_filter_strip(value, flags);

/* encodes ' " < > & \0 to numerical entities */
enc['\''] = enc['"'] = enc['<'] = enc['>'] = enc['&'] = enc[0] = 1;

/* if strip low is not set, then we encode them as &#xx; */
memset(enc, 1, 32);

if (flags & FILTER_FLAG_ENCODE_HIGH) {
    memset(enc + 127, 1, sizeof(enc) - 127);
}

php_filter_encode_html(value, enc);
}
0
drtechno

Vertrauen Sie niemals Benutzerdaten.

function clean_input($data) {
  $data = trim($data);
  $data = stripslashes($data);
  $data = htmlspecialchars($data);
  return $data;
}

Die Funktion trim() entfernt Leerzeichen und andere vordefinierte Zeichen von beiden Seiten einer Zeichenfolge.

Die Funktion stripslashes() entfernt Backslashes

Die Funktion htmlspecialchars() konvertiert einige vordefinierte Zeichen in HTML-Entitäten.

Die vordefinierten Zeichen sind:

& (ampersand) becomes &amp;
" (double quote) becomes &quot;
' (single quote) becomes &#039;
< (less than) becomes &lt;
> (greater than) becomes &gt;
0
Erik Thiart

Es gibt die Filtererweiterung ( How to-Link , manual ), die mit allen GPC-Variablen ziemlich gut funktioniert. Es ist zwar keine magische Sache, aber Sie müssen es trotzdem benutzen.

0
Till