Avatar billede kimox Nybegynder
15. februar 2011 - 16:26 Der er 10 kommentarer og
1 løsning

Hjælp til SQL injection

Hej Eksperter.

Jeg genåbner lige et tidligere spørgsmål da den anden tog lidt "overhånd" :-) - http://www.eksperten.dk/spm/931674

- Men mit spørgsmål er som følgende:

Jeg har en side som har været uheldig at blive hacket/leget med, og dette skal jeg have ændret på. Derfor skal jeg have stoppet for SQL injection. - jeg har prøvet at læse på det, men sidder stadig fast.

Jeg har derfor fundet denne function:

      function mysql_escape_mimic($str) {

$search=array("\\","\0","\n","\r","\x1a","'",'"');
$replace=array("\\\\","\\0","\\n","\\r","\Z","\'",'\"');
return str_replace($search,$replace,$str);

}

Hvordan bruges den?

sådan?:
<?
      function mysql_escape_mimic($sql2) {

$search=array("\\","\0","\n","\r","\x1a","'",'"');
$replace=array("\\\\","\\0","\\n","\\r","\Z","\'",'\"');
return str_replace($search,$replace,$str);

}

require "db.php";
$id = $_GET['id'];
$sql2 = mysql_query ("SELECT * FROM nyhed WHERE id = $id");
while($row = mysql_fetch_array($sql2))
{
$oversk = nl2br($row['oversk']);
$tekst = $row['tekst'];
$dato = $row['dato'];
?>   


______________________

og derudover har jeg fundet denne string:

$id= mysql_real_escape_string($_GET[id]);
$navn= mysql_real_escape_string($_POST[navn]);

den bruger jeg på alle sider hvor jeg har GET og POST?? - når nu at $id indenholder tal, er det så stadig real_escape_sting jeg skal bruge? eller en anden?


Håber i kan hjælpe så jeg kan komme ud over mine problemer, samt lære noget nyt.

- Jeg vil gerne bede om i bruger eksempler, da jeg forstår mere ved dette.
Avatar billede keysersoze Guru
15. februar 2011 - 19:38 #1
Som også skrevet i det oprindelige indlæg - prepared statements; http://php.net/manual/en/pdo.prepared-statements.php
Avatar billede showsource Seniormester
15. februar 2011 - 20:55 #2
Og den simple, nogenlunde brugbare løsning:

function safe_sql($var) {

$var = trim($var);

  if (get_magic_quotes_gpc()) {
      $var = stripslashes($var);
  }

  if (!is_numeric($var)) {
      $var = "'" . mysql_real_escape_string($var) . "'";
  }

  return $var;
}

$sql2 = mysql_query ("SELECT * FROM nyhed WHERE id = ".safe_sql($_GET{"id"]);
Avatar billede repox Seniormester
16. februar 2011 - 11:30 #3
Hvis du har muligheden for det, vil jeg også anbefale dig at kigge på muligheden som #1 referer til.
Jeg ville dog bruge MySQLi i stedet - http://php.net/mysqli - ikke fordi det er mere rigtigt end at anvende PDO, men du kan opnå det samme.

Prepared statements har den fordel at du ikke behøver selv at tænke over om du får escaped de rigtige ting.

Et eksempel på prepared statements med MySQLi:
<?php

  $mysqli = new mysqli("localhost", "user", "password", "database");
  $sql = "SELECT * FROM table WHERE id=?";
  $stmt = $mysqli->prepare($sql);
  $stmt->bind_param("i", $_GET["id"]);
  $stmt->execute();

  $stmt->bind_result($col1, $col2);

  while ($stmt->fetch())
    echo $col1." - ".$col2;

  $stmt->close();

?>


Eksemplet er måske ikke så selvforklarende og man skal måske lige lure dokumentationen af, men på den måde sikrer du dig at tingene bliver escaped korrekt og når det er nødvendigt. Det er mere sikkert end at anvende mysql_real_escape_string().
Avatar billede kimox Nybegynder
16. februar 2011 - 15:49 #4
showsource, okay det ser ikke alt for svært ud ..

repox, kan jeg få dig til at smide det sammen med hvordan det ser ud idag, så jeg bedre kan se sammenhænget i det..

require "db.php";
$id = $_GET['id'];
$sql2 = mysql_query ("SELECT * FROM nyhed WHERE id = $id");
while($row = mysql_fetch_array($sql2))
{
$oversk = nl2br($row['oversk']);
$tekst = $row['tekst'];
$dato = $row['dato'];
?>

$mysqli = new mysqli("localhost", "user", "password", "database"); - skal vel bare placeres i min db.php?

- samt hvis i har lyst så har jeg endnu et spørgsmål kørende, det henvender sig lidt til dette: http://www.eksperten.dk/spm/931725
Avatar billede kimox Nybegynder
16. februar 2011 - 16:42 #5
kan man ikke få lov til at gøre sådan?

$laung = safe_sql($_GET["laung"]);
$tekst = $row['tekst_'. $laung .''];
Avatar billede kimox Nybegynder
16. februar 2011 - 16:59 #6
eller er det ikke nødvendigt? har det kun noget at sige når GET og POST er en del af sql? som her: $sql2 = mysql_query ("SELECT * FROM nyhed WHERE id = $id");


eller skal jeg også gøre det her f.eks.:
$laung = $_GET["laung"];
$tekst = $row['tekst_'. $laung .''];
$sql_cus = mysql_query("SELECT * FROM customers WHERE id = 1");

??
Avatar billede showsource Seniormester
16. februar 2011 - 21:03 #7
den safe_sql() funktion bruger du når kald til db afvikles.
Altså inde i en query.

Et tal ( integer ) bør ikke have '' omkring sig i en query.
'' fortæller det er en streng og ikke et tal. Omend mysql godt kan "håndtere" det alligevel.

safe_sql() fjerner først "tom luft", mellemrum/linieskift
Så tjekkes om php har forsøgt at escape farlige tegn, og hvis det er tilfældet, så fjern escaping.

dernæst tjekkes om det er et tal som bruges, og hvis ikke, så sæt
' til start
dernæst bruge mysql_real_escape_string() på input, og afslut med '

Hvis f.eks. GET er Hvadnu?
vil det blive til
'Hvadnu?'
eller hva'nu? => 'hva\'nu?'

Hvis GET er 931710 vil der ikke være brugt ' omkring
Avatar billede kimox Nybegynder
17. februar 2011 - 12:27 #8
super ! det ser ud til at virke som det skal !.

smide et svar showsource og Repox
Avatar billede showsource Seniormester
19. februar 2011 - 14:11 #9
Ok
Men repox's forslag er bestemt det bedste!
Avatar billede showsource Seniormester
19. februar 2011 - 14:11 #10
Nåh.....
Avatar billede kimox Nybegynder
21. april 2011 - 22:14 #11
-lukket-
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester