Avatar billede snigeren Nybegynder
04. marts 2010 - 12:37 Der er 16 kommentarer og
1 løsning

guide til at gøre egen php scripting sikkert

Jeg har tidligere lavet en hjemmeside i php og mysql som blev hacket,.. Hvad kan jeg gøre for at sikre det ikke sker igen?

Håber nogen kan hjælpe.
Avatar billede preppydude Nybegynder
04. marts 2010 - 12:45 #1
Du kan lade være med at lave noget ala:

<?php
$side = $_GET["page"];
include("minesider/$side.php");

$brugernavn = $_POST["brugernavn"];
$kodeord = $_POST["kodeord"];
$rigtig = (mysql_num_rows(@mysql_query("SELECT id FROM users WHERE username='$brugernavn' AND password='$kodeord'"))>0);

// osv..
?>

De fleste måder man kan "hacke" en PHP side på er baseret på programmørens dumheder, som vist i nogle simple eksempler ovenover.

Så det bedste tip er nok, at du skal tænke dig om når du laver noget. Slår du noget op i en database baseret på et ID i querystring, så kan du jo fx smidde en (int)$_GET["id"] i stedet for $_GET["id"] osv.
Avatar billede repox Seniormester
04. marts 2010 - 12:45 #2
Der er ikke nogen universel opskrift udover devisen 'stol aldrig på dine brugere'.
Som udgangspunkt skal du i princippet tænke dig at den værst tænkelige bruger kunne kigge forbi udelukkende med det formål at ødelægge dit website.

Valider dit brugerinput - det er det vigtigste.
Avatar billede snigeren Nybegynder
04. marts 2010 - 13:19 #3
login.php ser f.eks. sådan her ud:

<?PHP
include("../db.php");
   
// Get a connection to the database
$cxn = @ConnectToDb($dbServer, $dbUser, $dbPass, $dbName);


session_start();
$username = $_POST['username'];
$password = md5($_POST['password']);

$query = "select * from users where username='$username' and password='$password'";

$result = mysql_query($query);

if (mysql_num_rows($result) != 1) {
$error = "Bad Login";
    include "login.html";

} else {
    $_SESSION['username'] = "$username";
    echo "<script>parent.location='index.php'</script>";
    //include "index.php";
}

?>




og min login.html ser således ud:

<form name="login" method="post" action="login.php">
<table border="0" width="225" align="center">
    <tr>
        <td width="219">
            <p align="center" class="style2">Login</p>
        </td>
    </tr>
    <tr>
        <td width="219">
            <table border="0" width="220" align="center">
                <tr>
                    <td width="71"><span style="font-size:10pt;">Username:</span></td>
                    <td width="139"><input type="text" name="username"></td>
                </tr>
                <tr>
                    <td width="71"><span style="font-size:10pt;">Password:</span></td>
                    <td width="139"><input type="password" name="password"></td>
                </tr>
                <tr>
                    <td width="71"> </td>
                        <td width="139">
                            <p align="right"><input type="submit" name="submit" value="Submit"></p>
                        </td>
                </tr>
            </table>
        </td>
    </tr>
    <tr>
        <td width="219"> </td>
    </tr>
</table>
</form>


Det kan måske f.eks. være her problemet er?
Hvordan kan jeg sikre at der KUN bliver brugt tal og bogstaver i tekst felterne? så man ikke kan skrive ;' og den slags forbudte tegn?

Hvis der er andre dumheder vil jeg hellere end gerne vide dem! =)
Avatar billede preppydude Nybegynder
04. marts 2010 - 13:21 #4
Ja, addslashes() er en god funkton at bruge når du laver query's baseret på user input. :)
Avatar billede repox Seniormester
04. marts 2010 - 13:26 #5
Tegnene bør som sådan ikke være forbudte - du skal bare tag højde for at nogen kan finde på at bruge dem. Jeg ville eksempelvis ikke kunne det samme kodeord i dit system, som jeg bruger her på eksperten.dk, hvis jeg ikke måtte bruge 'forbudte' tegn.

Du kan tage højde for at folk vil bruge dem ved at anvende mysql_real_escape_string():
$username = mysql_real_escape_string($_POST['username']);
$password = md5($_POST['password']);


Der er ingen grund til at gøre det på $password, for der hasher du alligevel.
Avatar billede repox Seniormester
04. marts 2010 - 13:30 #6
#4
mysql_real_escape_string tager højde for flere ting i forbindelse med SQL injection end addslashes gør. addslashes tager kun højde for quotes og NULL byte.

Ikke om jeg fatter hvorfor folk bliver ved med at foreslå addslashes til at sikre sig mod SQL injection - mysql_real_escape_string har da også sine mangler, men den er da væsentligt sikrere end addslashes.

Den bedste sikkerhed opnås vha, prepared statements.
Avatar billede preppydude Nybegynder
04. marts 2010 - 13:33 #7
@repox:
Jeg har ikke lavet hjemmesider siden jeg var 14-15 år pga. manglende udfordring, så jeg kendte faktisk ikke til mysql_real_escape_string. Nu kender jeg den. Tak for det.

.. og så skal du vidst have lidt sukker, eller hvad?
Avatar billede repox Seniormester
04. marts 2010 - 13:55 #8
#7
Udvidenhed er en dårlig undskyldning for at komme med dårlige råd.

Nu kan jeg selvfølgelig sidde og gætte på din alder, men det er ikke relevant; mysql_escape_string() (den primitive udgave af mysql_real_escape_string) har alle dage været til, så længe vi snakker kommunikation mellem PHP og MySQL. Så i virkeligheden anser jeg det ikke som mangel på erfaring at du anbefaler addslashes, men bare ren uvidenhed! 'Manglende udfordring'...

Der har været lige så lang vej for mig selv, som der har været for dig, at opnå den portion erfaring man har gjort sig.
Forskellen på dig og mig er tilsyneladende blot at jeg har lært af mine fejl.

Dine stikpiller kan du i øvrigt holde for dig selv - dem er der ikke nogen her der er interesseret i; heller ikke jeg.
Har du andre kommentarer til min personlighed kan du sende dem som PM eller gøre kort proces og anvende 'Anmeld misbrug' i stedet for at genere andre med dem.
Avatar billede snigeren Nybegynder
04. marts 2010 - 15:00 #9
@repox:
dvs. jeg skal bruge mysql_real_escape_string() på alle queries til databasen også selvom man ikke kan indtaste noget i tekst felt eller er det kun når det har med tekst felter(input fra bruger) at gøre?

og det er så ikke nødvendigt at gøre noget ved selve tekst felterne?
Avatar billede repox Seniormester
04. marts 2010 - 15:09 #10
#9
Data som brugeren har indflydelse på skal du naturligvis altid være opmærksom på.
Har du statisk data (altså data, som du selv definerer) er det din egen opgave at sikre at der ikke er noget i som ikke skal være der.

Fuldstændig som i det eksempel jeg gav dig - brugernavnet har kun brugeren direkte indflydelse på. Men kodeordet har du allerede foruddefineret at det skal MD5 hashes hvilket så giver dig en streng du kender det mulige indhold af, så den behøver du ikke køre igennem mysql_real_escape_string.

#1 kom også med nogle ret gode eksempler på hvad man IKKE skal gøre.
JEg vil anbefale dig at prøvet at google på "SQL injection".
Avatar billede snigeren Nybegynder
04. marts 2010 - 15:23 #11
ok

lige to ting du sikkert også kan svare på =)

1. inde på selve admin siden når man nu har sikret(så meget man nu kan) mod injections and what not. Er det så i teorien nødvendigt at sikre admin felterne? for man kan jo ikke komme derind eller?
Jeg vil nu sikre dem alligevel men i teorien? =)

2. hvordan vil du lave en kontakt knap der åbner direkte link til en email klient, hvor robotter ikke bare lige kan hapse emailadressen der sendes til? vil helst undgå at lave en form der så bliver sendt med email script... derfor direkte til email klienten.
Avatar billede repox Seniormester
04. marts 2010 - 21:57 #12
1. Jo, jeg vil mene du skal tage lige så meget højde for det der; for hvad nu hvis en eller anden alligevel får adgang til systemet, på trods af dine forsøg på at skabe et sikkert fundament? Det er også en god vane at have - at validere sine brugeres input.

2. Altså, hvis det ikke må læses ud fra noget i teksten, kunne man jo lave en Location header. Pseudokode:
sendemail.php

<?php
  include("dbconnect.php");

  $userId = (int)$_GET["userId"];

  $sql = "SELECT email FROM users WHERE userId=".$userId." LIMIT 1";
  $result = mysql_query($sql);

  if( mysql_num_rows($result) == 0)
  {
    header("Location: email_not_found.php");
    exit;
  }

  $email = mysql_result($result, 0, "email");
  header("Location: mailto: ".$email);
  exit;
?>


Så når du klikker på linket
<a href="sendemail.php?userId=345">Send e-mail</a>
vil den hente den mailadresse ud tilknyttet userId 345. Ser du linket i en browser, vil den sandsynligvis forsøge at åbne dit foretrukne mailprogram for dig.
Avatar billede snigeren Nybegynder
04. marts 2010 - 23:56 #13
ja ok det er self. et forsøg værd.. well i første omgang vil jeg sige tak for hjælpen. du kan jo lige smide et svar så får du de velfortjente point =)
Avatar billede repox Seniormester
05. marts 2010 - 08:35 #14
Jeg deler gerne med preppydude; han kom med eksempler på hvordan du ikke skal gøre.
Avatar billede snigeren Nybegynder
05. marts 2010 - 11:32 #15
Fint med mig, hvis preppydude smider et svar snart får 20 og han 10 =)

Har også efter jeres lille battle været inde og læse om de to og kan se det er ret nemt at snyde addslashes hvis man ved hvordan...

Anyways er jeg kommet et stykke videre og takker jer. =)
Avatar billede snigeren Nybegynder
05. marts 2010 - 16:50 #16
lige en ting til ;)

i følgende:

if($action=="gem")
    {
    $gruppe = mysql_real_escape_string($_POST['gruppe']);
    $sql = "insert into items_grupper (gruppe) values ('$gruppe')";
    $result = mysql_query($sql) or die(mysql_error());
    }

I php tager den vel altid ting liniert så hvis jeg definerer $gruppe med mysql_real_escape....  er det vel den $gruppe den bruger som value ikke? den kan vel aldrig finde på at bruge den værdi den fik sendt fra formen vel?

dumt spørgsmål i know men vil bare være 100% =)
Avatar billede repox Seniormester
15. marts 2010 - 10:29 #17
Nå, det var da en gammel tråd... :/

Lineært er et besynderligt ord at benytte, men jeg tror jeg forstår hvad du mener.

Med lidt sundt fornuft kan du med rimelighed antage at dine udtryk evalueres fra venstre mod højre. Så jo, din opfattelse er korrekt.
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