• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Tags von globaler Variable entfernen.

nookie

I did it all for the nookie
Hallo liebe Community,

ich habe mir ein kleines Script zum Abfangen von XSS, MySQLi, usw. Attacken gebaut. Funktioniert auch eig. aber NUR wenn ich das ganze in einer Funktion abarbeite und dann nach einem Wahrheitswert prüfe. Es soll folgendes OHNE Funktion passieren. "<script>alert(xss);</script>" wird z.B. eingetippt und der entsprechende User wird auf Seite XY weitergeleitet bzw. ein Error wird ausgegeben. Funktioniert aber irgendwie nicht.

Beispiel: index.php?site=<script>alert(xss);</script>

PHP:
$site = $_GET['site'];

if(isset($site)) {
        $request = strtolower(urldecode($_SERVER['QUERY_STRING']));
        $disallow = array("union","select","from","where","into","and","/*","*/","<",">","ascii",
                          "substring","script","alert","xss","root","telnet",
                          "cmd","passwd","exec","fopen","fwrite","javascript",
                          "mysql","perl","perl","chdir","root","phpinfo",
                          "system","shell_exec","table");
   
        $check = str_replace($disallow, "*",$request);
        if($request != $check) { return true;  error_message("Hackangriff."); }
}

Funktion zum ausgeben von Error:
PHP:
function error_message($text) {
   die('<!DOCTYPE html>
         <html>
         <head>
         <title></title>
         </head>
         <body>
         <span color="red">' . $text . '</span>
         </body>
         </html>');
}
 
Zuletzt bearbeitet:
Werbung:
Ich will deinen Bemühungen ja nicht die Luft raus lassen aber hast du mal daran gedacht deine Zeit lieber damit zu verbringen vorhandene Lücken zu schließen?
Will ja nicht sagen, dass ich damals nicht auch so etwas gebaut habe weil ich es nicht besser wusste. Würde nur lieber mit dir darüber reden warum du es für nötig hältst deine Bemühungen, in anderen Teilen deines Codes weniger auf Sicherheit zu achten, fortzusetzen.

Ich gebe gerne Tipps wie du effektiv verhindern kannst Sicherheitslücken einzubauen. Die einzigen Angriffsvektoren um die du dir bei MySQL Injections und XSS Angriffen sorgen machen musst sind $_GET, $_POST und $_FILES. und die abzusichern ist nicht all zu schwer.

lg

Ps: Falls du deine Bemühungen trotzdem weiterführen willst ist dein Stichwort, mit welchem du dich auf Google über das Thema schlau machen kannst, "WAF".
 
Also will ein kleines CMS schreiben, haben den Login schon fertig geschrieben und da auch drauf geachtet das kein Login Bypass usw. möglich ist. Bruteforce Attackn verhindert durch Login attempts. usw. Ich will meine Bemühungen trotzdem weiterführen einfach um es mal gemacht zu haben, auch wenn ich es danach besser weiß. :) Danke für deine Antwort.
 
Werbung:
Musste gerade mal googeln was bei den 3 Buchstaben "WAF" raus kommt und es tut mir leid. Google spuckt da ja totalen schwachsinn aus :-D

Ich meine natürlich "Web Application Firewall" ^^
 
Ja ich bin schon auf die "Web Application Firewall" gekommen, alles andere hätte auch keinen Sinn ergeben. :) Trotzdem dankeschön. Damit habe ich mich noch nie beschäftigt auch wenn ich mich schon mit einigen Sicherhietslücken auseinander gesetzt habe.

EDIT: Aber diese Firewall beinhaltet doch eig. genau das was ich gerade schreiben will? Also könnte ich es bei mir das ganze ausbauen?
 
Zuletzt bearbeitet:
Wenn du wirklich dieses extra bisschen an Sicherheit haben willst, solltest du eines der vorhandenne Produkte benutzen anstadt das Rad neu zu erfinden. Musst dich aber anständig mit den verschiedenen Produkten auseinander setzen da die meisten einfach nur beschissen sind. :-D
 
Werbung:
Ja, ich will das Rad ja ned neu erfinden. Es für mich einfach darum, das ich es einfach mal gemacht habe und nicht vorhandene Produkte benutze ohne zuwissen wie der Code genau arbeitet und strukturiert ist. Ich hab mich jetzt über die WAF schon ein bisschen schlau gemacht und diverse Produkte gefunden, die ich natürlich auch ausprobieren werde aber im Endeffekt möchte ich es gern selber schreiben.
 
Ok, ich würde dir gerne einen Stein in den weg legen. Nehmen wir einmal an du baust dein CMS und das rüstest du mit einer art WAF aus die z.b. die URL auf "böse" wörter überprüft. Was passiert, wenn aus irgendeinem grund eines der wörter auf normalem wege in der URL auftauchen sollte wie z.b. das überaus seltenne Wort "and". Auch andere der Wörter die du dort hast könnten ganz schnell in der URL landen.

Ich konnte das Problem damals nicht lösen. Würde mich aber freuen wenn du ne lösung findest und sie uns mitteilst. :)

lg
 
Naja, ich würde diesen Stein einfach umgehen. Ich baue ja das CMS und rüste es mit einer Art "WAF" aus, also bestimme ich ja auch was auf normalem Wege in der URL landet. Ich weiß aber worauf du hinaus willst und werde mich auch in Zukunft mal mit diesem Problem beschäftigen. Also evtl. morgen oder gleich noch.

Wenn ich eine Lösung finden sollte, werde ich Sie euch natürlich mitteilen.
 
Werbung:
Naja du kannst natürlich entscheiden wie du deine URLs aussehen lassen willst. Hat aber durchaus Vorteile, wenn du z.b. solche URLs hast
Code:
http://www.example.com/artikel/234/Eine+tolle+beschreibung+fuer+einen+artikel
Stelle mich übrigens gerne bereit dein Produkt ein wenig zu testen, wenn es fertig ist.
 
Ja, das ganze kann ich ja mit einer .htaccess - Datei so aussehen lassen. Danke, sehr gerne.
Ich bin immer noch am ueberlegen wie ich dein Problem lösen kann. :(
 
Nehmen wir mal an du willst auch irgendwann einen WYSIWYG editor in dein CMS einbauen. Einem Admin also z.b. erlauben HTML code in seinen artikeln zu verwenden so das er mehr Freiheit hat das Design des Artikels, welchen er schreibt, zu beeinflussen.
Ich genieße es in den CMS die ich benutze sehr, das ich HTML benutzen darf. Macht alles so viel einfacher.
Natürlich abgesehen von der von dir wahrscheinlich auch geplanten XSS überprüfung auf deiner seite... :)

Hier mal ein beispiel wie ich heutzurage dafür sorge, dass auf meinen Seiten kein schabernack angestellt werden kann.

PHP:
// setup
$oRequest = System::getRequest();
$oDb = System::getDb();

// ich will den text aus $_POST['titel'] haben und will keinen HTML Code
$sTitle = $oRequest->post('title', null, 'text');

// die user id brauche ich auch... die steht im $_GET
// die brauchen wir zwar nicht weil wir die in ner session gespeichert haben aber hier will ich ja nur was zeigen
// weiter unten würde man die ID natürlich nicht einfach so eintragen ohne sie vorher zu überprüfen...
$iId = $oRequest->get('id', null, 'integer');

// und nehmen wir mal an ich will auch HTML code für den content eines artikels haben
$sContent = $oRequest->post('content', null, 'html');

// in den ersten beiden variablen habe ich nun auf keinen fall XSS code... html nehme ich so wie es kommt also wird auch kein normaler user dieses script ausdführen dürfen

// das ganze nun in der datenbank speichern
$oDb->query("INSERT INTO `tabelle` (`title`, `content`, `user_id`) VALUES ('%s', '%s', '%d')", $sTitle, $sContent, $iId);

im hintergrund sieht das ganze ungefähr so aus

PHP:
// datenbank sicherheit
class DB extends something {
    /* ... */
    public function query($sQuery) {
        if (func_num_args() > 1) {
            $aArgs = func_get_args();
            array_shift($aArgs);
            foreach ($aArgs as &$mArg) {
                $mArg = $this->escape($mArg);
            }
            $sQuery = vsprintf($sQuery, $aArgs);
        }
        /* hier sicher mit $sQuery arbeiten */
    }
    /* ... */
    public function escape ($mValue) {
        // die mysql escape funktion ist hier nur ein beispiel. es kann auch jede andere funktion verwendet werden
        return mysql_real_escape_string($mValue);
    }
    /* ... */
}

und hier der Request teil... sieht ungefähr so aus

PHP:
class Request extends something {
    /* ... */
    public function getVar($aInput, $sKey, $mDefault, $sType) {
        if (!isset($aInput[$sKey])) {
            return $mDefault;
        }
     
        switch ($sType) {
            case 'int':
            case 'integer':
                $mValue = (int)$aInput[$sKey];
                break;
            case 'text':
                // weiß gerade aus dem kopf nicht ob das gegen xss reicht... habs so lange nicht mehr schreiben müssen :-D
                $mValue = htmlentities($aInput[$sKey], ENT_QUOTES);
                break;
            case 'html':
            default:
                $mValue = $aInput[$sKey];
        }
     
        return $mValue;
    }
    /* ... */
    public function post ($sKey, $mDefault, $sType) {
        return $this->getVar($_POST, $sKey, $mDefault, $sType);
    }
    /* ... */
}

Bin immer noch überzeugt das so eine herangehensweise flexibler ist als jede WAF die ich bis jetzt gesehen habe ^^
 
Zuletzt bearbeitet von einem Moderator:
Werbung:
Mag schon sein das diese herangehensweise flexibler ist, das will ich auch garnicht bestreiten. Da du mich letztens auf die "WAF" gebracht hast, beschäftige ich imom auch eher damit als mit meinem eigentlichem kleinen CMS, was ich eh nur zu Testzwecken geschrieben habe. ^^

PHP:
// weiß gerade aus dem kopf nicht ob das gegen xss reicht... habs so lange nicht mehr schreiben müssen :-D
                $mValue = htmlentities($$aInput[$sKey], ENT_QUOTES);

Reicht schon, ich benutze persönlich aber lieber "htmlspecialchars". Die Funktion ist identisch, nur das "htmlentities" wirklich alle Zeichen die eine HTML-Code-Entsprechung haben umwandelt.

Ich benutze auch gern einen kleinen Scanner um zutesten ob ich wirklich noch Sicherheitslücken in meinem Code habe.
 
Zuletzt bearbeitet:
Eine Frage nochmal Slibbo, wäre es nicht hilfreich mit prepared-statements zu arbeiten?
 
Grundsätzlich ist PDO (und damit einhergehend prepared Statements) vor zu ziehen, dies erspart das eigene escapen von Werten für Querys und der Wechsel auf ein eine andere DB (z.B. PostgreSQL ist auch einfacher.


Gesendet von meinem iPhone mit Tapatalk
 
Werbung:
Es kommt ganz drauf an was du für ansprüche an dich selbst und deinen Code stellst.

Ich halte meine Ansprüche für hoch genug, dass ich es mir erlauben kann auf prepared statements zu verzichten und mir selbst (imho) dadurch mehr komfort und schnelleren code zu gewährleisten. Es ist aber keinenfalls so viel schneller das es einen wirklichen unterschied machen würde.

Wie CPCoder schon erwähnte macht es den wechsel der Datenbank ein wenig einfacher. Heißt aber nicht das es am ende viel einfacher ist. Für meine Zwecke ist es aber unsinnig daran zu denken das andere vllt ein anderes Datenbankformat bevorzugen. Wenn du eine Anwendung schreibst solltest du dir vorher klar machen welche ansprüche du an deine Datenbank hast und dementsprechend auch schon die richtige verwenden.

tldr; Wenn du schon sehr gut Programmieren kannst macht es kaum einen unterschied. Wenn nicht sind Prepared Statements ein guter Anfang.
 
Es kommt ganz drauf an was du für ansprüche an dich selbst und deinen Code stellst.

Ich halte meine Ansprüche für hoch genug, dass ich es mir erlauben kann auf prepared statements zu verzichten und mir selbst (imho) dadurch mehr komfort und schnelleren code zu gewährleisten. Es ist aber keinenfalls so viel schneller das es einen wirklichen unterschied machen würde.

Hmm, könntest du das näher erläutern?

Als Frontend-Entwickler, der mit Models und Datenbanken wenig am Hut hat, benutze ich, sofern ich tatsächlich mal in die Verlegenheit komme, grundsätzlich PDO. Weil ich irgendwann mal gelernt habe, dass diese Schnittstelle auch Gründen der Sicherheit zu bevorzugen sei.
 
Wie schon gesagt ist es besser in PHP PDO zu verwenden, wenn man es nicht besser weiß. Und die Vorteile meiner MEthode gegenüber PDO sind auch eher überschaubar.

An Stellen an denen man z.b. mehrere INSERTS hintereinander oder ein SELECT bei dem man so etwas wie "WHERE x IN (y, y, y, y)" verwenden will kommt die Klasse sehr schnell an ihre Grenzen.

Prepared statements scheinen außerdem dafür prädestiniert zu sein, mehrere der gleichen querys hintereinander abzusenden. Allerdings sollte dieser Fall garnicht auftreten wenn man seinen Query vorher gut schreibt.

Ich hoffe das reicht ertsmal. Wenn ich morgen wieder nüchtern bin gebe ich gerne mehr einsicht.

Frohe Ostern :)
 
Werbung:
Naja so überragend sind meine Kenntnisse in PHP nun auch nicht, aber ich versuche mich zu verbessern. Eine Frage am Rande, ist es möglich im Konstruktor ein Konfig zu laden und die Daten dann zu übergeben?

Inetwa so.

config.php
Code:
$mysql_hostname = 'localhost';
$mysql_username = 'root';
$mysql_password = '';
$mysql_database = 'test';

db class
Code:
class database {
   
    private $hostname;
    private $username;
    private $password;
    private $database;
    private $port;
    private $mysqli;
   
    public function __construct($config) {
        $this->hostname = $config['hostname'];
        $this->username = $config['username'];
        $this->password = $config['password'];
        $this->database =  $config['database'];
       
        if($this->port == NULL) {
            $this->port = ini_get('mysqli.default_port');   
        }
       
        $this->mysqli = new mysqli($this->hostname, $this->username, $this->password, $this->database, $this->port);
       
        if($this->mysqli->connect_error) {
            die('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);   
        }
       
        $this->mysqli->set_charset('utf-8');
    }
}
 
Was spricht gegen das gute alte

Code:
new MeinMySqlWrapper($sHost, $sDbName, $sUser, $sPassword, $iPort);

? :)
 
Zurück
Oben