WinFuture-Forum.de: ID aufruf + DB auslesen (PHP MySQL) - WinFuture-Forum.de

Zum Inhalt wechseln

Nachrichten zum Thema: Entwicklung
  • 2 Seiten +
  • 1
  • 2

ID aufruf + DB auslesen (PHP MySQL) Wie kann ich nach aufruf einer ID Daten aus einer DB auslesen?


#1 Mitglied ist offline   snwblnd 

  • Gruppe: aktive Mitglieder
  • Beiträge: 21
  • Beigetreten: 16. Juli 14
  • Reputation: 0

geschrieben 16. Juli 2014 - 21:16

Hat sich erledigt! :)

Das Script funktionierte tatsächlich endlich so wie es sollte!

<html> 
    <head> 
    <title>Deine Ergebniss für Max Mustermann</title> 
    </head> 
    <body> 

    <dl> 

    <?php 
    // Verbindung zum Datenbankserver 
    mysql_connect("host", "benutzer", "passwort") or die (mysql_error ()); 

    // Datenbank auswählen 
    mysql_select_db("datenbankname") or die(mysql_error()); 

    // Daten aus der Datenbank abrufen, wobei der Wert von id aus in der URL berücksichtigt wird 
    $strSQL = "SELECT * FROM search WHERE id=" . $_GET["id"]; 
    $rs = mysql_query($strSQL); 
     
    // Schleifendurchlauf durch $rs 
    while($row = mysql_fetch_array($rs)) { 

    // Schreibe die Daten der Person 
        echo "<dt>Name:</dt><dd>" . $row["VorUndNachName"] . " " . $row["Todestag"] . "</dd>"; 
        echo "<dt>Telefon:</dt><dd>" . $row["Geburtstag"] . "</dd>"; 
        echo "<dt>Geburtsdatum:</dt><dd>" . $row["Geburtsort"] . "</dd>"; 

    } 

    // Schließt die Datenbankverbindung 
    mysql_close(); 
    ?> 

    </dl> 
    <p><a href="index.php">Zurück zur Startseite</a></p> 

    </body> 

    </html>



Aufruf über namederdatei.php?id=1 für den Inhalt aus der search mit der ID 1

Ist das ganze auch nur im Ansatz sicher vor SQLi?

Dieser Beitrag wurde von snwblnd bearbeitet: 16. Juli 2014 - 21:41

0

Anzeige



#2 Mitglied ist offline   RalphS 

  • Gruppe: VIP Mitglieder
  • Beiträge: 8.895
  • Beigetreten: 20. Juli 07
  • Reputation: 1.126
  • Geschlecht:Männlich
  • Wohnort:Zuhause
  • Interessen:Ja

geschrieben 16. Juli 2014 - 21:58

Nein, das Script ist so eher ein... äh... Scheunentor.

Was meinst Du, was passiert, wenn einer /datei.php?id=1;%20drop%20database%20datenbankname; aufruft.

1. Parameter, die man nicht kennt (= alles was von außen reinkommt) IMMER prüfen. php hat da, iirc, Funktionen wie is_int() für. Ansonsten halt mit printf('%d', $paramenter).

2. In Abfragen um besagte Parameter *immer* - auch wenn es zB mit printf(%d...) nicht mehr nötig wäre - mit ' ' umschließen UND vor der Ausführung mit irgendeiner Escape-Funktion bedenken, die SQL-Elemente erkennt und rausfiltert. Schlußendlich sind das nur die ' ' , die man da codieren muß; DROP DATABASE tut nix, wenn das als String 'DROP DATABASE' übergeben wird. Immerhin sind Zahlwerte nur eine Option; Strings sind da die weitaus häufigere Alternative.

3. $_REQUEST Parameter haben im Code nur an genau EINER Stelle was verloren, und das ist dort, wo sie einer anderen Variable zugewiesen werden (mit Überprüfung per isset() oder dergleichen plus, falls zutreffend, einem Typen-Check). Es muß sichergestellt werden können, daß $intDatenbankID auch wirklich a) gesetzt und b) eine positive Ganzzahl ist und das geht nicht, wenn man diese Variable nicht hat.

Dieser Beitrag wurde von RalphS bearbeitet: 16. Juli 2014 - 22:05

"If you give a man a fish he is hungry again in an hour. If you teach him to catch a fish you do him a good turn."-- Anne Isabella Thackeray Ritchie

Eingefügtes Bild
Eingefügtes Bild
0

#3 Mitglied ist offline   snwblnd 

  • Gruppe: aktive Mitglieder
  • Beiträge: 21
  • Beigetreten: 16. Juli 14
  • Reputation: 0

geschrieben 16. Juli 2014 - 22:06

Verdammt! :(
Wie kann ich das mit meinem Code verhindern?
(Ok jetzt bettel ich doch um Hilfe/fertigen Code...)
Aber erstmal VIELEN Dank für deine ausführliche Antwort.
Leider übersteigt sie gänzlich meinen Horizont, darum die Bitte.
(So als Shinra Soldaten unter sich ;) )

P.S: Ich habe jetzt mal aus Interesse an eine URL
;%20drop%20database%20datenbankname; drangehangen und es kam eine leere Seite und sonst nur der zurück zu Startseite Link. Mehr nicht.
Ich habe auch sowohl meine LiveSearch als auch dieses Script mit ' getestet.
LiveSearch zeigt keine Ergebnisse und dieses Script dasselbe wie bei deinem Code.
Bin ich jetzt doch abgesichert?

Dieser Beitrag wurde von snwblnd bearbeitet: 16. Juli 2014 - 22:30

0

#4 Mitglied ist offline   RalphS 

  • Gruppe: VIP Mitglieder
  • Beiträge: 8.895
  • Beigetreten: 20. Juli 07
  • Reputation: 1.126
  • Geschlecht:Männlich
  • Wohnort:Zuhause
  • Interessen:Ja

geschrieben 16. Juli 2014 - 22:36

Naja, Du baust halt eine Variable für die ID...

// Id-Parameter bestimmen und sicherstellen, daß es eine ganze Zahl ist
$intDbId = (isset($_GET['id'])) ? printf('%d', $_GET['id'] ) : 0;
$intDbId = max(0,$intDbId); // Negative Werte brauchen wir wohl eher nicht



... möglichst weit oben. Ich hab jetzt die 0 als ungültige ID genommen - wenn die 0 bei Dir gültig ist, wäre auch -1 eine Idee. Wenn Du das schon vor dem connect() auswertest, könntest Du das davon gleich abhängig machen - falsche ID = keine Datenbankverbindung. Da würde wegen der falschen Eingabe eh nix bei rumkommen. Aber das nur nebenher.

Als Nächstes machen wir aus Deiner SQL-Abfrage sowas...

    $strSQL = "SELECT * FROM search WHERE id='" . $intDbId . "';"


wobei anzumerken ist, daß es sauberer wäre, wenn Du mit expliziten Spaltennamen arbeitest; wenn sich am Datenbankschema was ändert, bekommst Du so trotzdem nur die gewünschten Daten. Ganz streng genommen könnten wir uns auch die beiden ' ' um die id sparen - wir haben schon sichergestellt, daß das eine natürliche Zahl ist, die -technisch- eine gültige ID in der Datenbank sein *könnte*. Was anderes kann in intDbId nicht mehr stecken.

Mehr Glocken und Pfeifen (= bells and whistles) muß man da glaub ich nicht unbedingt dranhängen.


- Re: wenn Du das da dranhängst... kann es Dir durchaus passieren, daß der da einfach ungefragt ein DROP DATABASE an die Datenbank durchreicht. ... Da solltest Du vielleicht mal schauen, ob die jetzt noch da da ist. Keine Ahnung, ob und inwieweit php da bei Dir Semikola als Abfrage-Trennzeichen interpretiert (und so die Datenbank ein wenig schützt) oder nicht.

In jedem Fall ist es KEINE Absicherung. WENN PHP die ; gesondert behandeln sollte, baut man einfach ein \ davor und schwups gehts doch wieder zur Datenbank und Du stehst ohne Datenbank da (wegen dem DROP).

Dieser Beitrag wurde von RalphS bearbeitet: 16. Juli 2014 - 22:39

"If you give a man a fish he is hungry again in an hour. If you teach him to catch a fish you do him a good turn."-- Anne Isabella Thackeray Ritchie

Eingefügtes Bild
Eingefügtes Bild
1

#5 Mitglied ist offline   snwblnd 

  • Gruppe: aktive Mitglieder
  • Beiträge: 21
  • Beigetreten: 16. Juli 14
  • Reputation: 0

geschrieben 17. Juli 2014 - 08:58

Vielen vielen Dank für deine erneute ausführliche Antwort! :)
Meine Datenbank funktioniert nach wie vor wunderbar.
Kann es nicht sein das eine SQLi bei meiner MySQL Version nicht möglich ist auf diesen Wegen?
Eigentlich(!) ist nicht geplant am Schema etwas zu ändern, getreu dem Motto "Never touch a running system".
Und die 0 ist bei mir keine notwendige ID. Es fängt ganz normal bei 1 an. :)

Der aktuelle code:
<html> 
    <head> 
    <title>Deine Ergebniss für Max Mustermann</title> 
    </head> 
    <body> 

    <dl> 

    <?php 
     // Id-Parameter bestimmen und sicherstellen, daß es eine ganze Zahl ist
     $intDbId = (isset($_GET['id'])) ? printf('%d', $_GET['id'] ) : 0;
     $intDbId = max(0,$intDbId); // Negative Werte brauchen wir wohl eher nicht

    // Verbindung zum Datenbankserver 
    mysql_connect("host", "benutzer", "passwort") or die (mysql_error ()); 

    // Datenbank auswählen 
    mysql_select_db("datenbankname") or die(mysql_error()); 

    // Daten aus der Datenbank abrufen, wobei der Wert von id aus in der URL berücksichtigt wird 
    $strSQL = "SELECT * FROM search WHERE id='" . $intDbId . "';"
    $rs = mysql_query($strSQL); 
     
    // Schleifendurchlauf durch $rs 
    while($row = mysql_fetch_array($rs)) { 

     // Schreibe die Daten der Person 
        echo "Vor und Nachname: " . $row["VorUndNachName"] . "";
        echo "Geburtstag: " . $row["Geburtsdatum"] . "";
        echo "Geburtsort: " . $row["Geburtsort"] . "";

    } 

    // Schließt die Datenbankverbindung 
    mysql_close(); 
    ?> 

    </dl> 
    <p><a href="index.php">Zurück zur Startseite</a></p> 

    </body> 

    </html>




Jetzt funktioniert nur das Script nicht mehr. :(
Er zeigt also eine ganze weiße Seite.
Wohlmöglich weil er bei der Zeile
 $strSQL = "SELECT * FROM search WHERE id='" . $intDbId . "';"

kein Get mehr hat und daher auch keine id mehr abfragt?!

Greetz
0

#6 Mitglied ist offline   RalphS 

  • Gruppe: VIP Mitglieder
  • Beiträge: 8.895
  • Beigetreten: 20. Juli 07
  • Reputation: 1.126
  • Geschlecht:Männlich
  • Wohnort:Zuhause
  • Interessen:Ja

geschrieben 17. Juli 2014 - 09:28

Ups :blush: PHP möchte da sprintf. Also ein 's' vor das 'printf' und dann sollte das gehen.
"If you give a man a fish he is hungry again in an hour. If you teach him to catch a fish you do him a good turn."-- Anne Isabella Thackeray Ritchie

Eingefügtes Bild
Eingefügtes Bild
0

#7 Mitglied ist offline   snwblnd 

  • Gruppe: aktive Mitglieder
  • Beiträge: 21
  • Beigetreten: 16. Juli 14
  • Reputation: 0

geschrieben 17. Juli 2014 - 11:49

Wenn ich aus
$intDbId = (isset($_GET['id'])) ? printf('%d', $_GET['id'] ) : 0;

$intDbId = (isset($_GET['id'])) ? sprintf('%d', $_GET['id'] ) : 0;

mache zeige er wieder nichts an.

Entschuldige das ich so ein Anfänger bin und wegen einer wahrscheinlichen Kleinigkeit so "nerve".
Ich gelobe besserung und wenn das alles funktioniert,
werde ich alle Begriffe nachschauen was sie im einzelnen mache
damit solche Fragen der Vergangenheit angehören. :)

Dieser Beitrag wurde von snwblnd bearbeitet: 17. Juli 2014 - 12:28

0

#8 Mitglied ist offline   Holger_N 

  • Gruppe: aktive Mitglieder
  • Beiträge: 5.111
  • Beigetreten: 11. September 10
  • Reputation: 458
  • Geschlecht:Männlich

geschrieben 17. Juli 2014 - 20:21

Mein "Sicherheitskonzept" ist, bei allen möglichen übertragenen Werten mit Zahlen zu arbeiten. Das ist bei einer ID ja schonmal kein Problem. Wenn man dann einen übergebenen Wert hat, schreibe ich den mit:

$zu_verarbeitende_variable = intval($_GET['id']) ;

in die Variable und arbeite dann mit "$zu_verarbeitende_variable" die dann immer eine Zahl ist, weiter.

Das geht natürlich noch weiter aber das ist sozusagen Schritt 1. Da kommt dann noch das Abfangen von Fehlern usw. dazu.
Bauernregel: Regnets mächtig im April, passiert irgendwas, was sich auf April reimt.
1

#9 Mitglied ist offline   snwblnd 

  • Gruppe: aktive Mitglieder
  • Beiträge: 21
  • Beigetreten: 16. Juli 14
  • Reputation: 0

geschrieben 18. Juli 2014 - 21:27

Aber wo ist den der Fehler im Code von RalphS?
0

#10 Mitglied ist offline   RalphS 

  • Gruppe: VIP Mitglieder
  • Beiträge: 8.895
  • Beigetreten: 20. Juli 07
  • Reputation: 1.126
  • Geschlecht:Männlich
  • Wohnort:Zuhause
  • Interessen:Ja

geschrieben 18. Juli 2014 - 21:40

Wenn Du auf der Kommandozeile
\Pfad\zur\PHP-Installation\php-cgi.exe \Pfad\zur\PHP-Datei.php id=4
eingibst, was passiert denn da?

Außerdem hab ich natürlich nicht geschaut, ob der Datenbankbenutzer/PW hinhaut -ich hab Deine Datenbank ja nicht. Hatte da nur auf die Eingabe geachtet.

.... Du wirst Dir doch nicht die fragliche Datenbank gekillt haben, als Du diesen einen ungefilterten Befehl da abgeschickt hast? :huh:

Schau mal in MySQL nach (mit welchem Frontend auch immer) ob die Datenbank überhaupt noch da ist und deren Inhalt auch.


Und, klar, wie weiter oben (glaub ich) schon irgendwo erwähnt gibt es natürlich auch Funktionen bei PHP, die auf einen spezifischen Typen prüfen. Ich bevorzuge einfach die *printf-Variante, weil die mehr oder weniger immer gleich ist, egal worauf man prüft. Wie immer gibt es mehrere Möglichkeiten das zu kriegen, was man wollte. :)


RE: Fehler, hm, bei wir war's ausführbar (hab mit 5.4 geschaut).

Dieser Beitrag wurde von RalphS bearbeitet: 18. Juli 2014 - 21:44

"If you give a man a fish he is hungry again in an hour. If you teach him to catch a fish you do him a good turn."-- Anne Isabella Thackeray Ritchie

Eingefügtes Bild
Eingefügtes Bild
0

#11 Mitglied ist offline   snwblnd 

  • Gruppe: aktive Mitglieder
  • Beiträge: 21
  • Beigetreten: 16. Juli 14
  • Reputation: 0

geschrieben 19. Juli 2014 - 09:48

Also ich kann nichts per Komandozeile ausführen weil es auf dem Webspace liegt.
Ich könnte natürlich XAMMP o.ä. herunterladen und es lokal testen.

Die Datenbank ist komplett unangetastet und läuft, der Inhalt ist noch komplett da. :)
Laut phpinfo nutzt mein Anbieter: PHP Version 5.3.10-1ubuntu3.13

Ich werde es nachher dennoch einmal lokal testen, vielleicht ergibt sich ja was.

Vielen Dank für eure Mühe bisher! :)


EDIT: Da ich nicht untätig sein wollte,
hab ich geschaut ob mir mit E_ALL etwas auswirft.
Hat er aber nicht. Weiße Seite.
Also war mein Mittel zum Weg (falls einer den Beitrag je benötigen wird)

<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);
include("DieDateiMitFehler.php");
?>


Und er zeigte mir daraufhin ein

Zitat

Parse error: syntax error, unexpected T_VARIABLE in test.php on line 25


$rs = mysql_query($strSQL);


ist was er beanstandet.

Hoffe das hilft?

Dieser Beitrag wurde von snwblnd bearbeitet: 19. Juli 2014 - 10:25

0

#12 Mitglied ist offline   RalphS 

  • Gruppe: VIP Mitglieder
  • Beiträge: 8.895
  • Beigetreten: 20. Juli 07
  • Reputation: 1.126
  • Geschlecht:Männlich
  • Wohnort:Zuhause
  • Interessen:Ja

geschrieben 19. Juli 2014 - 11:02

Jau, in der Zeile drüber fehlt das termininierende Semikolon. Das was da steht, ist Teil der SQL-Abfrage.
"If you give a man a fish he is hungry again in an hour. If you teach him to catch a fish you do him a good turn."-- Anne Isabella Thackeray Ritchie

Eingefügtes Bild
Eingefügtes Bild
0

#13 Mitglied ist offline   snwblnd 

  • Gruppe: aktive Mitglieder
  • Beiträge: 21
  • Beigetreten: 16. Juli 14
  • Reputation: 0

geschrieben 19. Juli 2014 - 11:14

Beitrag anzeigenZitat (RalphS: 19. Juli 2014 - 11:02)

Jau, in der Zeile drüber fehlt das termininierende Semikolon. Das was da steht, ist Teil der SQL-Abfrage.


Das dachte ich mir auch schon.

Aus
$strSQL = "SELECT * FROM search WHERE id='" . $intDbId . "';"


wurde

$strSQL = "SELECT * FROM search WHERE id='" . $intDbId . "';";


brachte aber keine Verbesserung. Ich verzweifele langsam.
0

#14 Mitglied ist offline   snwblnd 

  • Gruppe: aktive Mitglieder
  • Beiträge: 21
  • Beigetreten: 16. Juli 14
  • Reputation: 0

geschrieben 19. Juli 2014 - 11:21

Der aktuelle Code

<html> 
    <head> 
    <title>Deine Ergebniss für Max Mustermann</title> 
    </head> 
    <body> 

    <dl> 

    <?php 
     // Melde alle Fehler
     error_reporting(E_ALL);

     // Id-Parameter bestimmen und sicherstellen, daß es eine ganze Zahl ist
     $intDbId = (isset($_GET['id'])) ? sprintf('%d', $_GET['id'] ) : 0;
     $intDbId = max(0,$intDbId); // Negative Werte brauchen wir wohl eher nicht

    // Verbindung zum Datenbankserver 
    mysql_connect("host", "user", "passwort") or die (mysql_error ()); 

    // Datenbank auswählen 
    mysql_select_db("search") or die(mysql_error()); 

    // Daten aus der Datenbank abrufen, wobei der Wert von id aus in der URL berücksichtigt wird 
    $strSQL = "SELECT * FROM search WHERE id='" . $intDbId . "';";
    $rs = mysql_query($strSQL); 
     
    // Schleifendurchlauf durch $rs 
    while($row = mysql_fetch_array($rs)) { 

    // Schreibe die Daten der Person 
        echo "Vor und Nachname: " . $row["VorUndNachName"] . "";
        echo "Geburtstag: " . $row["Geburtsdatum"] . "";
        echo "Geburtsort: " . $row["Geburtsort"] . "";

    } 

    // Schließt die Datenbankverbindung 
    mysql_close(); 
    ?> 

    </dl> 
    <p><a href="index.php">Zurück zur Startseite</a></p> 

    </body> 

    </html>


Zitat

Access denied for user 'korrekterbenutzername'@'%' to database 'search'


Langsam versteht ich garnichts mehr! Die Daten sind definitiv korrekt!

Dieser Beitrag wurde von snwblnd bearbeitet: 19. Juli 2014 - 11:22

0

#15 Mitglied ist offline   RalphS 

  • Gruppe: VIP Mitglieder
  • Beiträge: 8.895
  • Beigetreten: 20. Juli 07
  • Reputation: 1.126
  • Geschlecht:Männlich
  • Wohnort:Zuhause
  • Interessen:Ja

geschrieben 19. Juli 2014 - 11:39

Immer noch derselbe Fehler? Hab jetzt mal testweise eine kompatible Datenbank angelegt und bei mir geht es (php 5.5.14).

(Wobei anzumerken ist, daß "VorundNachname" schlechter Stil ist und das ZWEI Spalten sein müßten - eine für Vorname, eine für Nachname. Aber das hat mit dem Problem an sich erstmal nix zu tun.)




EDIT. Schau unbedingt mal bei MySQL vorbei, ob... oh? :unsure:

- Schau überhaupt erstmal nach, ob die Datenbank jetzt "search" heißt oder "datenbankname" und ob das die richtige Datenbank ist, zu der Du verbindest.

- Und dann schaust Du nach, ob diese Datenbank existiert oder nicht
mysql -uBENUTZERNAME -pPASSWORT
USE DATENBANKNAME



und was deren Schema ist
describe TABELLENNAME
würde mich auch mal interessieren. Möglicherweise paßt das Script einfach nicht zur Datenbank.

Dieser Beitrag wurde von RalphS bearbeitet: 19. Juli 2014 - 11:46

"If you give a man a fish he is hungry again in an hour. If you teach him to catch a fish you do him a good turn."-- Anne Isabella Thackeray Ritchie

Eingefügtes Bild
Eingefügtes Bild
0

Thema verteilen:


  • 2 Seiten +
  • 1
  • 2

1 Besucher lesen dieses Thema
Mitglieder: 0, Gäste: 1, unsichtbare Mitglieder: 0