SQL Injektion und Cross Site Scripting verhindern?

4 Antworten

Vom Fragesteller als hilfreich ausgezeichnet

nutz gleich PDO und prepare statements und übergibt die variablen seperat mit platzhaltern und assoziativen arrays . das modul macht das nötige für dich .

fals du davon was nciht verstehst einfach mit google mal suchen nach den begriffen .

Hier ien gutes tutorial was es erklärt (ist deutsch)

https://code.tutsplus.com/de/tutorials/why-you-should-be-using-phps-pdo-for-database-access--net-12059

zum thema XSS musst du dich einlesen , da fällt mir pauschal nix zu ein , den da gibts vieles zu breachten .

gfdsgsdgsdg 
Fragesteller
 11.07.2022, 00:45

Kannst du mir vielleicht sagen welche Angriffsmöglichkeiten du hier hättest ?

Also ich habe dasselbe wie oben mit PDO gemacht und Prepared Statements.

Ein Teil ist um Etwas Auszulesen mit SELECT * FROM ... und der zweite Teil um in die Datenbank einzufügen.

<?php
//Datenbank Informationen
    $server = 'localhost';
    $user = 'root';
    $psw = null;
    $dbName = 'Test';
//Verbinden mit Datenbank ($server $user $psw $dbName )
try {
   $conn = new PDO('mysql:host='.$server.';dbname='.$dbName.'', $user, $psw);
}catch (PDOException $e) {
   print "Error!: " . $e->getMessage() . "<br/>";
   die();
}




// In Datenbank lesen 
$sql = "SELECT * FROM messages";
//Prepared Statement
$Abfrage = $conn -> prepare($sql);
//Abfrage lesen auführen
$Abfrage -> execute();
$result = $Abfrage -> fetchAll();
//Antwort von der Datenbank in das Objekt result
//Nacheinander anzeigen
foreach ($result as $i) {
    echo "<p class='". $i["user"]."'>".
         $i["message"] ." <br>". 
         $i["date"] .    "</p>";
}




// In Datenbank Schreiben
$username = "Alice";
$message = $_GET['message'];

$sql = 'INSERT INTO messages SET
user = "' . $username . '",
message = "' . $message . '"';
//Prepared Statement
$Abfrage = $conn -> prepare($sql);
//Abfrage Schreiben auführen
$Abfrage -> execute();




//Verbindung mit Datenbank beenden
$conn = null;


0
TechPech1984  11.07.2022, 01:02
@gfdsgsdgsdg

hier

so macht man es richtig

<?php
//Datenbank Informationen
   $server = 'localhost';
   $user = 'root';
   $psw = null;
   $dbName = 'Test';
//Verbinden mit Datenbank ($server $user $psw $dbName )
try {
   $conn = new PDO('mysql:host='.$server.';dbname='.$dbName.';charset=utf8', $user, $psw);
   $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
   $conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
   // In Datenbank lesen 
   $sql = "SELECT * FROM messages";
   //Prepared Statement
   $Abfrage = $conn->prepare($sql);
   //Abfrage lesen auführen
   $Abfrage -> execute();
   $result = $Abfrage->fetchAll(PDO::FETCH_ASSOC);
   //Antwort von der Datenbank in das Objekt result
   //Nacheinander anzeigen
   foreach ($result as $i) {
      echo "<p class='". $i["user"]."'>".
         $i["message"] ." <br>". 
         $i["date"] .   "</p>";
   }
   // In Datenbank Schreiben
   $username = "Alice";
   $message = $_GET['message'];
   // platzhalter mit doppelpunkt vorran für folgende namen im array , siehe $sqlvars
   $sql = "INSERT INTO messages (user,message) VALUES (:username,:message) ";
   // variablen für platzhalter als array mit "namen" 
   $sqlvars = array("username"  => $username,
                    "message"   => $message );
   //Prepared Statement
   $Abfrage = $conn->prepare($sql);
   //Abfrage Schreiben ausführen , $variablenarray übergeben , maskiert automatisch alle werte .
   $Abfrage->execute($sqlvars);

}catch (PDOException $e) {
  print "Error!: " . $e->getMessage() . "<br/>";
  exit;
}
1
TechPech1984  11.07.2022, 01:08
@gfdsgsdgsdg

zu dein angriffmöglichkeiten gehört natürlich dann das XSS , weil wenn die $message javascript enthält wird das bei anzeige ausgeführt . also muss du noch mal nachgucken im netz wie man sowas entfernt aus der message .

1
gfdsgsdgsdg 
Fragesteller
 11.07.2022, 01:14
@TechPech1984

Danke , Also ist das was du bearbeitet hast dann auch wirklich SQL Injection sicher oder könnte man selbst das noch irgendwie knacken ?

Und für das XSS müsste doch das hier ausreichen ?

echo htmlspecialchars(stripslashes(trial($_[GET["message"])));

Oder ist nur oberflächlich/grob

0
TechPech1984  11.07.2022, 01:14
@gfdsgsdgsdg

ausserdem brauchst du noch session , da du nur message empfangen solltest was auch von deinem php gesendet wurde und nicht irgendwer mit GET an die url hängt . den dann spämmt dich irgendwer voll

also z.b.

in der form.php

<?php
session_start();
$_SESSION["message"] = "ok";
.
.
?>

und in deinem INSERT dann

<?php
session_start();
if (!isset($_SESSION['message'])) {exit;}
.
.
?>
1
gfdsgsdgsdg 
Fragesteller
 11.07.2022, 01:20
@TechPech1984

Danke aber ich glaube das mit dem spammen über die URL funktioniert hier nicht da ich das mit Ajax mache.

Der vordere Teil sieht so aus, sieht vielleicht für dich ein wenig dumm programmiert (Im Html Dokument mit Script Tags) aus aber das ist kein Ernst gemeintes Projekt und kann man schnell bearbeiten.

<script>
    $('#absendeFormular').submit(function(event){
    event.preventDefault();
    $.ajax({
        type:"GET",
        url:"assets/PHP/sendMessage.php",
        data: $(this).serialize(),
        success: function (data) {
            console.log(data)
          }
    });
    $('#absendeFormular')[0].reset();
    });
    </script>

<script>
 setInterval(() => {
    $(document).ready(function(event){
    $.ajax({
        type:"GET",
        url:"assets/PHP/aktualisieren.php",
        data: $(this).serialize(),
        success: function (data) {
            $('#ChatBereich').html(data)
          }
    });
    });
}, 500);
    </script>
0
TechPech1984  11.07.2022, 01:22
@gfdsgsdgsdg

das ist egal , ich kann ein GET auch selber mit AJAX von irgendwo machen , mach ich mir meine eigene webseite .

solltest eh lieber per POST machen . und wie gesagt , nur das $_SESSION verhindert das andere seiten das ausnutzen .

1
TechPech1984  11.07.2022, 01:23
@gfdsgsdgsdg

deswegen auch deine anderen seiten immer als php mit session_start() damit du weisst welcher user da von deinem server kommt . also auch wenn du dort javascript lädst zum verschicken, wichtig, der user soll schon eine session haben , die wird dann im header mitgeschickt auch beim ajax.

1
gfdsgsdgsdg 
Fragesteller
 11.07.2022, 01:24
@TechPech1984

Achso, dann nehme ich lieber POST.

GET soll ein kleines bisschen Performanter sein und es hat nicht in der URL gestört wie normalerweise deswegen hab ich mich schnell dafür entschieden.

..../&message=......................................

würde nicht schön aussehen

0
TechPech1984  11.07.2022, 01:25
@gfdsgsdgsdg

kannst auch get machen , das ist nicht schlimm , aber halt doof weil alte browser bei urls mit 255 zeichen früher aufgehört haben .

1
gfdsgsdgsdg 
Fragesteller
 11.07.2022, 01:34
@TechPech1984
echo htmlspecialchars(stripslashes(trial($_[GET["message"])));

Hab mich verschrieben, meinte *trim

ja geht , kannst dir auch eine funktion daraus machen wie hier beschrieben
function xss($string) {
  return htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
}

also so und dann

$message = xss($_POST['message']);

Das ist dann aufjedenfall übersichtlicher

0
TechPech1984  11.07.2022, 01:41
@gfdsgsdgsdg

ah wenn du gelesen hast , ist das immer kompliziert wenn man das bei der eingabe schon macht .

bei der ausgabe wäre fast leichter , oder eben einen wirklichen filter bauen .

musst du gucken , den wenn etwas erstmal merkwürdig in einer datenbank steht kann das auch nerfen :) da eben alle zeichen dann umgeformt werden und die daten schlecht anders genutzt werden können .

ggf ein filter bauen der ['message'] mit script tags nicht erlaubt . und dann nur die tags maskieren .

z.b. hier ganz nett gemacht

https://gist.github.com/mbijon/1098477/4e245ab3844ddbd0e7c6f9fdf360501517e121cf

1
SQL Injektion und Cross Site Scripting verhindern?

Verwende PDO mit prepared Statements. Damit bist Du auf der sicheren Seite.

Alex

gfdsgsdgsdg 
Fragesteller
 11.07.2022, 00:47

Kannst du mir vielleicht sagen welche Angriffsmöglichkeiten du hier hättest ?

Also ich habe dasselbe wie oben mit PDO gemacht und Prepared Statements.

Ein Teil ist um Etwas Auszulesen mit SELECT * FROM ... und der zweite Teil um in die Datenbank einzufügen.

<?php
//Datenbank Informationen
    $server = 'localhost';
    $user = 'root';
    $psw = null;
    $dbName = 'Test';
//Verbinden mit Datenbank ($server $user $psw $dbName )
try {
   $conn = new PDO('mysql:host='.$server.';dbname='.$dbName.'', $user, $psw);
}catch (PDOException $e) {
   print "Error!: " . $e->getMessage() . "<br/>";
   die();
}




// In Datenbank lesen 
$sql = "SELECT * FROM messages";
//Prepared Statement
$Abfrage = $conn -> prepare($sql);
//Abfrage lesen auführen
$Abfrage -> execute();
$result = $Abfrage -> fetchAll();
//Antwort von der Datenbank in das Objekt result
//Nacheinander anzeigen
foreach ($result as $i) {
    echo "<p class='". $i["user"]."'>".
         $i["message"] ." <br>". 
         $i["date"] .    "</p>";
}




// In Datenbank Schreiben
$username = "Alice";
$message = $_GET['message'];

$sql = 'INSERT INTO messages SET
user = "' . $username . '",
message = "' . $message . '"';
//Prepared Statement
$Abfrage = $conn -> prepare($sql);
//Abfrage Schreiben auführen
$Abfrage -> execute();




//Verbindung mit Datenbank beenden
$conn = null;
0
EinAlexander  11.07.2022, 09:34
@gfdsgsdgsdg
$message = $_GET['message'];

Usereingaben sollten nicht ungefiltert ineinander Datenbank übernommen werden. Besser ist

$message = htmlspecialchars($_GET['message']);

der insert lautet dann

$sql = 'INSERT INTO messages SET
user = :user,
message = :message";

//Prepared Statement
$Abfrage = $conn -> prepare($sql);
//Abfrage Schreiben auführen
$Abfrage -> execute(array(user => $user, message => $message));

1
gfdsgsdgsdg 
Fragesteller
 11.07.2022, 13:23
@EinAlexander

Danke, und mehr Schwachstellen fallen dir nicht auf du dir den überarbeiteten Code Anschaust ?

<?php
//Datenbank Informationen
   $server = 'localhost';
   $user = 'root';
   $psw = null;
   $dbName = 'Test';
//Verbinden mit Datenbank ($server $user $psw $dbName )
try {
   $conn = new PDO('mysql:host='.$server.';dbname='.$dbName.';charset=utf8', $user, $psw);
   $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
   $conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
   // In Datenbank lesen 
   $sql = "SELECT * FROM messages";
   //Prepared Statement
   $Abfrage = $conn->prepare($sql);
   //Abfrage lesen auführen
   $Abfrage -> execute();
   $result = $Abfrage->fetchAll(PDO::FETCH_ASSOC);
   //Antwort von der Datenbank in das Objekt result
   //Nacheinander anzeigen
   foreach ($result as $i) {
      echo "<p class='". $i["user"]."'>".
         $i["message"] ." <br>". 
         $i["date"] .   "</p>";
   }
   // In Datenbank Schreiben
   $username = "Alice";
//cross site scripting filtern
   $message = htmlspecialchars(stripslashes(trim($_POST['message'])));

   // platzhalter mit doppelpunkt vorran für folgende namen im array , siehe $sqlvars
   $sql = "INSERT INTO messages (user,message) VALUES (:username,:message) ";
   // variablen für platzhalter als array mit "namen" 
   $sqlvars = array("username"  => $username,
                    "message"   => $message );
   //Prepared Statement
   $Abfrage = $conn->prepare($sql);
   //Abfrage Schreiben ausführen , $variablenarray übergeben , maskiert automatisch alle werte .
   $Abfrage->execute($sqlvars);

}catch (PDOException $e) {
  print "Error!: " . $e->getMessage() . "<br/>";
  exit;
}
0

1. Der DB ordentliche Zugangsdaten geben.

2. Wenn möglich keinen root-Zugang benutzen.

3. Prepared Statements für das SQL benutzen.

4. Input validieren.

5. Input escapen.

Kurzum: Alles.

Woher ich das weiß:Studium / Ausbildung – Informatikstudium
gfdsgsdgsdg 
Fragesteller
 10.07.2022, 17:59
Der DB ordentliche Zugangsdaten geben.

Ja klar, das ist nur Lokal mit Xampp

4. Input validieren.

5. Input escapen.

Das hab ich nicht so genau verstanden, hast du vielleicht ein Beispiel ?

Und ist es dann 100% sicher vor SQL INJ. und XSS wenn ich diese 5 Punkte erledige oder gibt es da noch mehr ?

0
triopasi  10.07.2022, 18:23
@gfdsgsdgsdg

Aktuell darf da jeder alles reinwerfen.. Aich HTML, JavaScript oder sonstwas.. das ist nicht so gut.

Wenn ich mir deinen Code so ansehe nein, du wirst wahrscheinlich in jeder Datei Sicherheitslücken einbauen. Aber zum üben am Anfang ist das i.O.

1
gfdsgsdgsdg 
Fragesteller
 11.07.2022, 00:47
@triopasi

Kannst du mir vielleicht sagen welche Angriffsmöglichkeiten du hier hättest ?

Also ich habe dasselbe wie oben mit PDO gemacht und Prepared Statements.

Ein Teil ist um Etwas Auszulesen mit SELECT * FROM ... und der zweite Teil um in die Datenbank einzufügen.


<?php
//Datenbank Informationen
    $server = 'localhost';
    $user = 'root';
    $psw = null;
    $dbName = 'Test';
//Verbinden mit Datenbank ($server $user $psw $dbName )
try {
   $conn = new PDO('mysql:host='.$server.';dbname='.$dbName.'', $user, $psw);
}catch (PDOException $e) {
   print "Error!: " . $e->getMessage() . "<br/>";
   die();
}




// In Datenbank lesen 
$sql = "SELECT * FROM messages";
//Prepared Statement
$Abfrage = $conn -> prepare($sql);
//Abfrage lesen auführen
$Abfrage -> execute();
$result = $Abfrage -> fetchAll();
//Antwort von der Datenbank in das Objekt result
//Nacheinander anzeigen
foreach ($result as $i) {
    echo "<p class='". $i["user"]."'>".
         $i["message"] ." <br>". 
         $i["date"] .    "</p>";
}




// In Datenbank Schreiben
$username = "Alice";
$message = $_GET['message'];

$sql = 'INSERT INTO messages SET
user = "' . $username . '",
message = "' . $message . '"';
//Prepared Statement
$Abfrage = $conn -> prepare($sql);
//Abfrage Schreiben auführen
$Abfrage -> execute();




//Verbindung mit Datenbank beenden
$conn = null;
0
triopasi  11.07.2022, 07:51
@gfdsgsdgsdg

Du benutzt keine prepared Statements. Du hast 1-zu-1 die selben Probleme wie in der ursprünglichen Frage. Alle davon sind noch da.

1
gfdsgsdgsdg 
Fragesteller
 11.07.2022, 13:24
@triopasi

Ok danke, wie sieht es deiner Meinung nach jetzt überarbeitet aus ?
Könnte man so veröffentlichen oder immernoch Angreifbar ?

<?php
//Datenbank Informationen
   $server = 'localhost';
   $user = 'root';
   $psw = null;
   $dbName = 'Test';
//Verbinden mit Datenbank ($server $user $psw $dbName )
try {
   $conn = new PDO('mysql:host='.$server.';dbname='.$dbName.';charset=utf8', $user, $psw);
   $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
   $conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
   // In Datenbank lesen 
   $sql = "SELECT * FROM messages";
   //Prepared Statement
   $Abfrage = $conn->prepare($sql);
   //Abfrage lesen auführen
   $Abfrage -> execute();
   $result = $Abfrage->fetchAll(PDO::FETCH_ASSOC);
   //Antwort von der Datenbank in das Objekt result
   //Nacheinander anzeigen
   foreach ($result as $i) {
      echo "<p class='". $i["user"]."'>".
         $i["message"] ." <br>". 
         $i["date"] .   "</p>";
   }
   // In Datenbank Schreiben
   $username = "Alice";
//cross site scripting filtern
   $message = htmlspecialchars(stripslashes(trim($_POST['message'])));

   // platzhalter mit doppelpunkt vorran für folgende namen im array , siehe $sqlvars
   $sql = "INSERT INTO messages (user,message) VALUES (:username,:message) ";
   // variablen für platzhalter als array mit "namen" 
   $sqlvars = array("username"  => $username,
                    "message"   => $message );
   //Prepared Statement
   $Abfrage = $conn->prepare($sql);
   //Abfrage Schreiben ausführen , $variablenarray übergeben , maskiert automatisch alle werte .
   $Abfrage->execute($sqlvars);

}catch (PDOException $e) {
  print "Error!: " . $e->getMessage() . "<br/>";
  exit;
}
1

Ich würde eher ein Framework nehmen, welches bereits SQL Injections verhindern kann. Z.B. ein ORM Framework.

Woher ich das weiß:Studium / Ausbildung – Informatik studiert und mit PCs & Technik beschäftigt