Avatar billede roz Nybegynder
07. juli 2005 - 23:15 Der er 30 kommentarer og
1 løsning

Forbedring af sikkerhed i login system

Okay jeg har dette login system:

Login siden:

<?php
        session_start();
?>
<head>
<title> ..:: Admin-Login ::..</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body style="margin-top: 15px;">
<?php
include('config.php');

    $result = mysql_query("SELECT * FROM members");
if (mysql_num_rows($result) == 0) {
if (!isset($_POST['send'])) {

echo "
<span class=header>Opret admin konto:</span><br /><br />
<div style='width: 210px; border: 1px solid #797979;'>
  <table class=indhold>
  <tr>
    <td>
    <form action=".$_SERVER['PHP_SELF']."?page=opret method=post>
      Username:<br>
    </td>
  </tr>
  <tr>
    <td>
    <input type=text name=username size=30 maxlength=30><br>
    </td>
  </tr>
  <tr>
    <td>
    Password:<br>
    </td>
  </tr>
  <tr>
    <td>
    <input type=password name=password size=30 maxlength=30><br>
    </td>
  </tr>
  <tr>
    <td>
    Indtast Password igen:<br />
    </td>
  </tr>
  <tr>
    <td>
    <input type=password name=password2 size=30 maxlength=30><br>
    </td>
  </tr>
  <tr>
    <td align=center>
    <input type=submit name=send value=Opret>
    </form>
    </td>
  </tr>
  </table>
</div>
";
}

else {
switch($_GET['page']) {
case opret:

$username = $_POST['username'];
$password = $_POST['password'];
$password2 = $_POST['password2'];
if ($username == "" || $password == "" || $password2 == "") {
echo "Brugernavnet og passwordet skal indeholde mindst et tegn. <br />";
echo "<a href=admin.php>Tilbage</a>";
}
else {
if ($password == $password2) {

$kryptname = md5($username);
$kryptpass = md5($password);

include('config.php');

mysql_query("
INSERT INTO members
  (Password,
  Username)
VALUES
  ('$kryptpass',
  '$kryptname')
") or die(mysql_error());

echo "Admin kontoen er nu oprettet. <br />";
echo "<a href=admin.php>Login</a>";

}
else {
echo "De to passwords er ikke ens. <br />";
echo "<a href=admin.php>Tilbage</a>";

}
}
}
}}

else {

if (!isset($_POST['send'])) {
echo "
<span class=header>Login:</span><br /><br />
<div style='width: 210px; border: 1px solid #797979;'>
  <table class=indhold>
  <tr>
    <td>
    <form action=".$_SERVER['PHP_SELF']." method=post>
    </td>
  </tr>
  <tr>
    <td>
    Username:<br>
    </td>
  </tr>
  <tr>
    <td>
    <input type=text name=name size=30 maxlength=30><br>
    </td>
  </tr>
  <tr>
    <td>
    Password:<br>
    </td>
  </tr>
  <tr>
    <td>
    <input type=password name=pass size=30 maxlength=30><br>
    </td>
  </tr>
  <tr>
    <td align=center>
    <input type=submit name=send value=Login>
    </form>
    </td>
  </tr>
  </table>
</div>
";
}

else {
$password = $_POST['pass'];
$username = $_POST['name'];

if ($password == "" || $username == "") {

echo "Brugernavn og password skal være på mindst et tegn.<br />";
echo "<a href=admin.php>Tilbage</a>";
}

else
{

$kryptuser = md5($username);
$kryptpass = md5($password);

include('config.php');
$result = mysql_query("SELECT * FROM members WHERE Username = '$kryptuser'") or die(mysql_error());

if (mysql_num_rows($result) == 0) {
        echo "The username does not exist!<br />";
        echo "<a href=admin.php>Tilbage</a>";
    }
  else {
        while ($row = mysql_fetch_array($result)) {
            $check = $row["Password"];
        }
        if ($kryptpass == $check) {

            $_SESSION['username'] = $kryptuser;
            $_SESSION['password'] = $kryptpass;
        echo "<meta http-equiv=refresh content=0;URL=administrations_panel.php>";
        } else {
            echo "Login failed! Please try again.";
        }
    }}
}
}
?>

Og dette tjekker på hver side om sessionen stadig er korrekt:
<?php
session_start();
include('config.php');
$result = mysql_query("SELECT * FROM members WHERE Username = '".$_SESSION['username']."'");

while ($row = mysql_fetch_array($result)) {
$checkpass = $row["Password"];
$checkuser = $row["Username"];
}

if ((empty($result)) OR (empty($checkpass)) OR (empty($checkuser)) OR ($checkpass != $_SESSION['password']) OR ($checkuser != $_SESSION['username']) ) {
  session_destroy();
  echo "<meta http-equiv=refresh content=0;URL=admin.php>";
  exit;
}
else
{

echo "
//og så kommer sidens indhold
";
}
?>


Okay sagen er den at jeg gerne vil have sikkerheden helt i top her. Så de 105 point (hvad jeg havde tilbage) vil blive delt mellem alle dem der kan finde sikkerheds huller og komme med rette lser til disse. Jo flere du finder jo flere point får du :)
Avatar billede avminarm Juniormester
08. juli 2005 - 11:21 #1
du bør nok bruge htmlentities for at undgå sql injektion:

$password = htmlentities($_POST['pass']);
$username = htmlentities($_POST['name']);
Avatar billede avminarm Juniormester
08. juli 2005 - 11:23 #2
evt også trim() for at undgå blanke felter i start/slut
Avatar billede roz Nybegynder
08. juli 2005 - 11:41 #3
Okay tak skal du have :)¨

Men hvordan bruges trim()?
Avatar billede avminarm Juniormester
08. juli 2005 - 11:47 #4
sådan: htmlentities(trim($_POST['pass'])); og naturligvis også på name
Avatar billede roz Nybegynder
08. juli 2005 - 11:58 #5
Okay mange tak.. :)

Du får selvfølgelig point men ser lige om der er andre der kan finde noget også.
Avatar billede avminarm Juniormester
08. juli 2005 - 12:10 #6
en side bemærkning som intet har med sikkerheden men din html er ikke helt i top - det er ikke god skik at skrive:

<input type=text name=username size=30 maxlength=30>

du bør bruge: "" f.eks: <input type="text" name="username" size="30" maxlength="30">

du kan så bere echo med '' omkring så slipper du for at skulle skrive \"text\"
Avatar billede avminarm Juniormester
08. juli 2005 - 12:11 #7
hmmm - når jeg skriver echo med '' omkring ligner det jo alm "gåseøjne" ;o) - jeg mener sådan her: echo '<input type="text" name="username" size="30" maxlength="30">';
Avatar billede avminarm Juniormester
08. juli 2005 - 12:15 #8
kiggede lige lidt mere - lad være med at gemme password i en session:            $_SESSION['password'] = $kryptpass;

- gem hellere f.eks bruger id. og hvis brugernavn er unik er den jo lig med bruger id. Du har ikke noget at bruge password til efter succesfuld login.

I stedet for password så kan du gemme session_id() og tjekke op på om det er den korrekte id der kører.
Avatar billede roz Nybegynder
08. juli 2005 - 12:19 #9
Okay kan du ikke forklare lidt mere om det der session_id()? For så tror jeg jeg vil droppe det der med at tjekke efter brugernavn og password på hver side.
Avatar billede roz Nybegynder
08. juli 2005 - 12:22 #10
Altså prøv og forklar grundigt hvordan jeg skulle bruge sessions. Hvad jeg skulle gemme i dem og hvad jeg skulle tjekke :)
Avatar billede avminarm Juniormester
08. juli 2005 - 12:33 #11
jo ;o)

Men du skal ved første login altid tjekke efter navn+pass - efter login succes sætter du jo to sessions en på name og en på session id:

$_SESSION['username'] = $kryptuser;
$_SESSION['id'] = session_id();


<?php
//Vi starter sessions
session_start();

//Hvis ikke sessions er sat, bliver man sendt til logind.php
if(!isset($_SESSION['username']) || ($_SESSION['id'] != session_id())) {
header("Location:logind.php");
exit;
}
?>

du kan måske have glæde af denne artikel: http://www.showsource.dk/artikler/vis_artikel.php?id=1042998056 på samme side har "sukos aka steffen" lavet et par login scripts som du måske kan have glæde af at "pille" i :-)
Avatar billede avminarm Juniormester
08. juli 2005 - 12:34 #12
hov glemte lige at skrive at denne lille fil stump er alt hvad du behøve på dine beskyttede sider:
<?php
//Vi starter sessions
session_start();

//Hvis ikke sessions er sat, bliver man sendt til logind.php
if(!isset($_SESSION['username']) || ($_SESSION['id'] != session_id())) {
header("Location:logind.php");
exit;
}
?>
Avatar billede roz Nybegynder
08. juli 2005 - 12:54 #13
Okay mange tak :) Virker fint. Venter lige lidt endnu.. Og ser om der er nogen der kan finde mere.
Avatar billede avminarm Juniormester
08. juli 2005 - 13:27 #14
ok ;o)
Avatar billede ksoren Nybegynder
08. juli 2005 - 14:33 #15
htmlentities er normalt ikke den anvendte metode til at forhindre sql injektion..

<?php
# Hvis magic quotes er aktiveret,
# vil alle apostroffer automatisk blive escaped ved submit

$gpc = get_magic_quotes_gpc();

# Under normale omstændigheder, vil name og pass altid være sat,
# men det skader ikke at kontrollere. Returner en tom streng ved false

$password = isset($_POST['pass']) ? $_POST['pass'] : "";
$username = isset($_POST['name']) ? $_POST['name'] : "";

if(!$gpc){
    # gpc ikke aktiv
    # sørg for at sql injektion ikke er muligt
    $password = addslashes($password);
    $username = addslashes($username);
}

# og normalt vil man nok smide passwordet med ind i sqlsætningen:

$result = mysql_query("SELECT * FROM members WHERE Username = '$username' AND Password = '$password'");

if(mysql_num_rows($result) == 1)){
    // username og password OK
}

?>


--

Hvis htmlentites overhovedet skal have en effekt, skal der en extra parameter på:

htmlentities("nu også med 'apostroffer'", ENT_QUOTES);

ellers bliver apostroffer ikke konverteret
Avatar billede ksoren Nybegynder
08. juli 2005 - 14:38 #16
Et par ekstra forbedringer kunne være:

1) gemme en hash af passwordet i databasen

2) ved login: gem brugerens ip, og kontroller denne ikke ændrer sig undervejs. Det kan forhindre session hijacking
Avatar billede roz Nybegynder
08. juli 2005 - 16:13 #17
Okay så htmlentities'ne skal altså bruges sådan: $password = htmlentities(trim($_POST['pass']), ENT_QUOTES);

Det andet prøver jeg lige om lidt.
Avatar billede roz Nybegynder
08. juli 2005 - 16:18 #18
Så er det med at bruge Password i MySQL sætningen også ændret. Det gjorde også koden lidt kortere da jeg så kunne fjerne password tjekket nedenunder.

Det med magiv quotes ved jeg ikke helt hvordan jeg skal bruge... Kan du forklare det lidt bedre?
Avatar billede roz Nybegynder
08. juli 2005 - 16:20 #19
Det med at gemme hash af passwordet i databasen ved jeg heller ikke helt hvordan jeg gør.

Og det andet med at gemme brugerens ip: Hvad er bedst? Blot at gemme ip'en i sessionen eller i databasen?
Avatar billede avminarm Juniormester
08. juli 2005 - 18:31 #20
ksoren>> du har ret med hensyn til htmlentities - jeg blander det sammren med noget jeg roder med i forbindelse med et forum i øjeblikket - tak ;o)
Avatar billede roz Nybegynder
09. juli 2005 - 00:00 #21
ksoren kunne du uddybe følgende ting? :)

Det med magiv quotes ved jeg ikke helt hvordan jeg skal bruge... Kan du forklare det lidt bedre?

Det med at gemme hash af passwordet i databasen ved jeg heller ikke helt hvordan jeg gør.

Og det andet med at gemme brugerens ip: Hvad er bedst? Blot at gemme ip'en i sessionen eller i databasen?
Avatar billede Slettet bruger
09. juli 2005 - 17:33 #22
Avatar billede roz Nybegynder
09. juli 2005 - 17:43 #23
Læste den lige igennem.. Men forstår stadig ikke helt hvordan jeg skal bruge dem i mit tilfælde?
Avatar billede avminarm Juniormester
10. juli 2005 - 08:57 #24
du kan faktisk bruge det ksoren har lavet:

if(!$gpc){
    # gpc ikke aktiv
    # sørg for at sql injektion ikke er muligt
    $password = addslashes($password);
    $username = addslashes($username);
} else {
    $password = $password;
    $username = $username;

}
Avatar billede roz Nybegynder
10. juli 2005 - 10:05 #25
Hvornår skulle jeg bruge dette i min kode? :)
Avatar billede roz Nybegynder
10. juli 2005 - 11:11 #26
Efter at jeg har hentet variablerne og kørt htmlentities på dem og alt det?
Avatar billede avminarm Juniormester
10. juli 2005 - 22:44 #27
glem htmlentities - de gir ikke mening her ;o9 - det var mig der vrøvlede!

du bruger det når brugeren logger sig på - inden du tjekker efter i databasen.
Avatar billede roz Nybegynder
11. juli 2005 - 01:02 #28
Okay tak igen :)

Kun et spørgsmål tilbage:
Og det andet med at gemme brugerens ip: Hvad er bedst? Blot at gemme ip'en i sessionen eller i databasen?
Avatar billede avminarm Juniormester
12. juli 2005 - 08:45 #29
jeg ville gemme IP i en session. Det kan være "farligt" at filtrere brugere på IP da ikke alle har statisk IP og derfor vil den være forskellig hver gang de logger på nettet.

Ved at gemme IP i en session (en session ophører når browser vinduet lukkes) kan du tjekke at brugerens IP ikke ændrer sig under vejs - altså samme IP = samme bruger
Avatar billede roz Nybegynder
12. juli 2005 - 11:32 #30
Mange tak. :D
Giver lige ksoren tid indtil i aften til at lægge et svar. Ellers får du alle pointene.
Avatar billede roz Nybegynder
12. juli 2005 - 23:58 #31
Så får du bare pointene :) Mange tak for hjælpen alle sammen :)
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