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

SQL Injections

Yosh™

Mitglied
Tagchen,

wollte mal nen Thema ansprechen, was jedem das Genick brechen kann.

SQL Injections

Ich weiß, das man mit mysql/i mysql/i_real_escape_string nutzen kann, um Injections zu vermeiden, doch ich nutze in meinem Framework PDO.
Gelesen habe ich zwar das PDO SQL Injection sicher ist, doch stimmt das?

Wie kann ich mir 100%ig sicher sein, dass ich am Ende nicht meine Datenbanken gelöscht kriege durch solch eine SQL Injection?
Alles was mit $_POST und $_GET zutun hat, ist ja anfällig dafür.
Wie z.B. Inputs.
Bei einem Login Input "Email" kann ich zeichen wie "-" schlecht verbieten, da jede Mail ein solches Zeichen enthalten kann.
Im Internet finde ich auch nur relativ alte "Anleitungen" wie solch eine Injection funktioniert .

Was habt ihr für Tipps/Ratschläge/Vorsichtsmaßnahmen dagegen? Oder reicht es wirklich nur mit PDO zu arbeiten?

Mein Model für sämtliche SELECT/UPDATE/INSERT Abfragen schaut derzeit so aus:

PHP:
<?php

/**
* Created by PhpStorm.
* User: yoshii
* Date: 22.06.2015
* Time: 10:49
*/

namespace core\models;

use core\language;
use core\pdo;
use core\session;

class mainmodel
{

    protected $_dbase;
    protected $_bEntryExist = false;
    protected $_sCoreTable = "";
    public $aFields = array();

    public function __construct()
    {
        $oPdo = new pdo();
        if ($this->_sCoreTable != "") {
            $this->_getFields();
        }
        $this->_dbase = $oPdo->oDb;

    }

    public function save()
    {
        if ($this->_bEntryExist) {

            $index = 1;
            $sPrepareSql = sprintf('UPDATE %s SET ', $this->_sCoreTable);
            $aFieldValue = array();
            foreach (array_filter($this->aFields) as $key => $sField) {
                if ($key != "id") {
                    if ($index != count(array_filter($this->aFields))) {
                        $sPrepareSql .= sprintf('%s = ?,', $key);
                    } else {
                        $sPrepareSql .= sprintf('%s = ?', $key);
                    }
                    $aFieldValue[$index] = $sField;
                }
                ++$index;
            }
            $sPrepareSql .= sprintf(' WHERE id = "%s"', $this->aFields['id']);
            $oPdo = new pdo();
            $oStmt = $oPdo->oDb->prepare($sPrepareSql);
            $oStmt->execute(
                array_values($aFieldValue)
            );
            return $oStmt->execute();
        } else {

            $index = 1;

            $sPrepareSql = sprintf('INSERT INTO %s (', $this->_sCoreTable);
            foreach (array_filter($this->aFields) as $key => $sField) {
                if ($key != "id") {
                    if ($index != count(array_filter($this->aFields))) {
                        $sPrepareSql .= sprintf('%s,', $key);
                    } else {
                        $sPrepareSql .= sprintf('%s', $key);
                    }
                    $aFieldValue[$index] = $sField;
                }
                ++$index;
            }

            $sPrepareSql .= ') VALUES (';

            $index = 1;
            $aFieldValue = array();
            foreach (array_filter($this->aFields) as $key => $sField) {
                if ($key != "id") {
                    $aFieldValue[$index] = $sField;
                    if ($index != count(array_filter($this->aFields))) {
                        $sPrepareSql .= "?,";
                    } else {
                        $sPrepareSql .= "?";
                    }
                }
                $index++;
            }
            $sPrepareSql .= ')';
            $oPdo = new pdo();
            $oStmt = $oPdo->oDb->prepare($sPrepareSql);
            $oStmt->execute(
                array_values($aFieldValue)
            );
#            print_r($aFieldValue);
#            print_r($oStmt);
#            return $oStmt->execute();
        }
    }

    public function load($sSearch, $sKeyField = 'id', $sOrderBy = '', $throwException = false)
    {
        $this->_bEntryExist = true;
        $sPrepareQuery = "SELECT ";
        $index = 1;
        if ($sOrderBy == '') {
            $sOrderBy = $sKeyField;
        }
        foreach ($this->aFields as $key => $sField) {
            if ($index == count($this->aFields)) {
                $sPrepareQuery .= $key . " ";
            } else {
                $sPrepareQuery .= $key . ", ";
            }
            ++$index;
        }

        $sPrepareQuery .= sprintf('FROM %s WHERE %s = ? ORDER BY %s', $this->_sCoreTable, $sKeyField, $sOrderBy);
        $oPdo = new pdo();
        $oStmt = $oPdo->oDb->prepare($sPrepareQuery);
        $oStmt->execute(
            array(
                $sSearch
            )
        );

        #echo $sPrepareQuery;
        if ($oStmt->execute() && $oStmt->rowCount() > 0) {
            $oRes = $oStmt->fetch(\PDO::FETCH_ASSOC);

            foreach ($oRes as $key => $mValue) {
                $this->aFields[$key] = $mValue;
            }
            return true;
        } elseif ($throwException) {

            session::addErrorToDisplay(sprintf(language::lang('PDO_ERROR'), $sKeyField, $sSearch, $this->_sCoreTable));
        }
    }

    protected function _getFields()
    {
        $oPdo = new pdo();

        $oStmt = $oPdo->oDb->prepare('SELECT COLUMN_NAME
                          FROM INFORMATION_SCHEMA.COLUMNS
                          WHERE TABLE_SCHEMA=?
                          AND TABLE_NAME=?');

        $oStmt->execute(
            array(
                $oPdo->getDatabaseName(),
                $this->_sCoreTable
            )
        );

        while ($sField = $oStmt->fetch(\PDO::FETCH_ASSOC)) {
            $this->aFields[$sField['COLUMN_NAME']] = '';
        }

    }

    public function getCoreTable()
    {
        return $this->_sCoreTable;
    }

}

Schon mal Danke im voraus für eure Tipps und Hilfe.

MfG
 
Werbung:
Ohne deinen Quellcode jetzt gelesen zu haben, würde ich mal behaupten das du mit Prepared-Statements auf der sicheren Seite bist. Allerdings gibt es ja nicht nur normale SQL Injections, sondern auch Blind SQL Injections usw. Am besten du versuchst einfach mal selber eine SQL Injection in deinem Script zu finden, falls du eine finden solltest reicht es ja lediglich wenn du es in deiner Klasse änderst und nicht im ganzen Projekt. Nachhilfe zum Thema SQL Injections usw. kann ich dir gerne geben, allerdings nur über Teamspeak o.Ä.

Das Grundprinzip einer SQL Injection lässt sich einfach an einem Authentication Bypass zeigen. Nehmen wir an, es besteht ein stink normaler Login mit Benutzer und Passwort Abfrage.

Das SQL-Statement dahinter sieht wie folgt aus:
Code:
SELECT username, password FROM user WHERE username='$username' AND password='$password'

Die Variablen $username und $password werden aus der Form befüllt, sollte also klar sein. Wenn ich nun hin gehe und in beide Felder das hier reinschreibe
Code:
' OR '1'='1
und auf den "Login"-Button drücken, passiert folgendes mit unserem SQL-Statement:
Code:
SELECT username, password FROM user WHERE username='' OR '1'='1' AND password='' OR '1'='1'

Da logischerweise "1=1" immer TRUE ergibt, sind wir erfolgreich eingeloggt.
 
Zuletzt bearbeitet:
Werbung:
Zurück
Oben