webForumDet fria alternativet

kryptering osv..säkerhetmässig hjlp behövs

PHP

25 svar · 1 379 visningar · startad av Tulork

Medlem sedan aug. 2004903 inlägg
Frågan#1

Jag har skrivit ihop ett litet login skript med en admin sida, allting är väldigt rått än så länge, men jag behöver lite hjälp med säkerheten, vill att ni påpekar vad jag kan göra bättre!

Framförallt vill jag skydda lösenorden, så en md5 kryptering hade varit super vid överföring utav lösenord osv..

så här ser koden ut idag.

index.php

<?php
session_start(); // Alltid överst på sidan

include "conn.php"; // Databasanslutningen

// Inloggning
if (isset($_POST['submit'])){

  $_POST = db_escape($_POST);
  
  $sql = "SELECT id FROM members
         WHERE user='{$_POST['user']}'
         AND pass='{$_POST['passwd']}'";
  $result = mysql_query($sql);
  
  // Hittades inte användarnamn och lösenord
  // skicka till formulär med felmeddelande
  if (mysql_num_rows($result) == 0){
    header("Location: index.php?badlogin=");
    exit;
  }
  
  // Sätt sessionen med unikt index
  $_SESSION['sess_id'] = mysql_result($result, 0, 'id');
  $_SESSION['sess_user'] = $_POST['user'];
  header("Location: admin.php");
  exit;
}

// Utloggning
if (isset($_GET['logout'])){
  session_unset();
  session_destroy();
  header("Location: index.php");
  exit;
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type"
  content="text/html; charset=iso-8859-1">
<title>Index</title>
</head>
<body>
<?php

// Om inte inloggad visa formulär, annars logga ut-länk
if (!isset($_SESSION['sess_user'])){

  echo "<h3>Logga in</h3>\n";
  
  // Visa felmeddelande vid felaktig inloggning
  if (isset($_GET['badlogin'])){
    echo "Fel användarnamn eller lösenord!<br>\n";
    echo "Försök igen!\n";
  }
  
?>
<form action="index.php" method="post">
Användarnamn:<br>
<input type="text" name="user"><br>
Lösenord:<br>
<input type="password" name="passwd"><br>
<input type="submit" name="submit" value="Logga in">
</form>

<?php

} else {

  echo "<a href=\"index.php?logout=\">Logga ut</a>\n";

}

?>
</body>
</html>

Admin.php

<?php
session_start(); // Alltid överst på sidan

// Kolla om inloggad = sessionen satt
if (!isset($_SESSION['sess_user'])){
  header("Location: index.php");
  exit;
}
?>

<html>
<head>
<!--
.style4{
	font-family: Verdana, Arial, Helvetica, sans-serif;
	font-size: 9px;
}
.style6{
	font-family: Verdana, Arial, Helvetica, sans-serif;
	font-size: 9px; font-weight:bold;
}
-->
</style>
</head>

<body>
<span class="style6">Administrations funktioner</span><br>

<span class="style4"><a href="welcome.php">Lägg till en användare</a><br>
<a href="remove.php">Ta bort en användare</a></span>
</body>
</html>

welcome.php

<?php
session_start(); // Alltid överst på sidan

// Kolla om inloggad = sessionen satt
if (!isset($_SESSION['sess_user'])){
  header("Location: index.php");
  exit;
}
?>
<?php
session_start(); // Alltid överst på sidan

include "conn.php"; // Databasanslutningen

if (isset($_POST['submit'])){

  $_POST = db_escape($_POST);

  // Tag bort eventuella blanksteg i början eller slutet
  foreach($_POST as $key => $val){
    $_POST[$key] = trim($val);
  }

  //Kolla efter tomma fält
  if (empty($_POST['user']) || empty($_POST['passwd']) ||
      empty($_POST['name']) || empty($_POST['email'])) {
    $reg_error[] = 0;
  }
  
  // Kolla om användarnamnet är upptaget
  $sql = "SELECT COUNT(*) FROM members WHERE user='{$_POST['user']}'";
  $result = mysql_query($sql);
  if (mysql_result($result, 0) > 0) {
    $reg_error[] = 1;
  }
  
  // Kolla om e-post kan tänkas vara ok
  if (!preg_match('/^[-A-Za-z0-9_.]+[@][A-Za-z0-9_-]+([.][A-Za-z0-9_-]+)*[.][A-Za-z]{2,6}$/', $_POST['email'])) {
    $reg_error[] = 2;    
  }

  // Kolla så att lösenorden stämmer överrens
  if ($_POST['passwd'] != $_POST['passwd2']) {
    $reg_error[] = 3;
  }
  
  // Inga fel? Spara och logga in samt skicka till välkomstsida
  if (!isset($reg_error)) {
    $sql = "INSERT INTO members(user, pass, name)
            VALUES('{$_POST['user']}', '{$_POST['passwd']}', '{$_POST['name']}')";
    mysql_query($sql);
    
    $_SESSION['sess_id'] = mysql_insert_id();
    $_SESSION['sess_user'] = $_POST['user'];
    header("Location: welcome.php");
    exit;     
  
  }

} else {

  // Sätt variabler för tomt formulär
  for ($i=0; $i<4; $i++) {
    $back[$i] = "";
  }

}

$error_list[0] = "Alla fält är inte infyllda";
$error_list[1] = "Användarnamnet är upptaget";
$error_list[2] = "Felaktig e-postadress";
$error_list[3] = "Lösenorden stämmer inte överrens";

?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type"
  content="text/html; charset=iso-8859-1">
<title>Registrera dig</title>
</head>
<body>
<h3>Registrera dig</h3>
<?php
if (isset($reg_error)){

  echo "Något blev fel:<br>\n";
  echo "<ul>\n";
  for ($i=0; $i<sizeof($reg_error); $i++) {
    echo "<li>{$error_list[$reg_error[$i]]}</li>\n";
  }
  echo "</ul>\n";
  
  $back[0] = stripslashes($_POST['user']);
  $back[2] = stripslashes($_POST['name']);
  $back[3] = stripslashes($_POST['email']);

}
?>
<form action="register.php" method="post">
<table cellspacing="3">

<tr>
<td>Användarnamn:</td>
<td><input type="text" name="user" value="<?=$back[0] ?>"></td>
</tr>

<tr>
<td>Lösenord:</td>
<td><input type="password" name="passwd" value=""></td>
</tr>

<tr>
<td>Repetera lösenord:</td>
<td><input type="password" name="passwd2" value=""></td>
</tr>

<tr>
<td>Ditt namn:</td>
<td><input type="text" name="name" value="<?=$back[2] ?>"></td>
</tr>

<tr>
<td>E-postadress</td>
<td><input type="text" name="email" value="<?=$back[3] ?>"></td>
</tr>

<tr>
<td colspan="2" align="center">
  <input type="submit" name="submit" value="Spara dina uppgifter">
</td>
</tr>

</table>
</form>

</body>
</html>

remove.php

<?php
session_start(); // Alltid överst på sidan

// Kolla om inloggad = sessionen satt
if (!isset($_SESSION['sess_user'])){
  header("Location: index.php");
  exit;
}
?>

<?php

include "conn.php";

// Performing SQL query
$query = 'SELECT * FROM members';
$result = mysql_query($query) or die('Query failed: ' . mysql_error());

// Printing results in HTML
echo "<table>\n";
echo "<p>ID User Pass Name<p>";
while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) {
   echo "\t<tr>\n";
   foreach ($line as $col_value) {
       echo "\t\t<td>$col_value</td>\n";
   }
   echo "\t</tr>\n";
}
echo "</table>\n";

// Free resultset
mysql_free_result($result);

if (isset ($_POST ['submit'])){
$delete = $_POST['delete'];
$sql = mysql_query("DELETE  FROM members WHERE id = '$delete'");
}
?>

<br><form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
<label for="delete"> Vilket id vill du ta bort</label>
<input type="text" name="delete" />
<input type="submit" name="submit" value="skicka"/>

</form>

conn.php är databaskopplingen.

Medlem sedan juni 20008 205 inlägg
#2

Vill du skydda lösenorden är SSL det enda raka.

Medlem sedan aug. 2004903 inlägg
#3

ok, men jag tror det blir md5..men jag vet inte riktigt hur md5() ska ligga, var de ska ligga osv...

Medlem sedan juni 20006 031 inlägg
#4

index.php
AND pass='{md5($_POST['passwd'])}'";

Kom ihåg att du måste lägga in lösenordet med md5 när det registreras också.

Sen ska du kontrollera alla fält så dom innehåller tillåtna tecken för att minska risken för sql injections.
Om servern inte har magic_quotes_gpc påslagen bör du även köra addslashes på indata och stripslashes på utdata.

/red
Att skaffa certifikat och köra ssl känns som överkurs om det inte handlar om mycket känslig information som lagras i databasen.

Medlem sedan juni 20014 290 inlägg
#5

Detta skyddar inte lösenordet vid överföring mellan webläsaren och webservern.

Antingen får du göra det mha javascript innan webläsaren skickar lösenordet eller använda SSL, SSL är att föredra.

Medlem sedan aug. 2004903 inlägg
#6

Pedda skrev:

index.php
AND pass='{md5($_POST['passwd'])}'";

Kom ihåg att du måste lägga in lösenordet med md5 när det registreras också.

Sen ska du kontrollera alla fält så dom innehåller tillåtna tecken för att minska risken för sql injections.
Om servern inte har magic_quotes_gpc påslagen bör du även köra addslashes på indata och stripslashes på utdata.

/red
Att skaffa certifikat och köra ssl känns som överkurs om det inte handlar om mycket känslig information som lagras i databasen.

testade lägga till det du skrev, fick som innan när jag provade

Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE, expecting T_STRING or T_VARIABLE or T_NUM_STRING in /usr/local/www/apache22/data/Grej/index.php on line 13

Medlem sedan juni 20008 205 inlägg
#7

Jag och oskob diskuterade hashning av lösenord innan de skickas över nätet i en annan tråd, och där kom vi fram till att det faktiskt inte höjer säkerheten på applikationen nämnvärt. Har man att göra med någon som paketsniffar kommer de ändå kunna använda hashen de sniffar upp för att logga in.

Medlem sedan aug. 2004903 inlägg
#8

jo jag inser det, och har själv testat sniffa upp lösen med och utan md5..inte så stor skillnad, men det är åt den kunden jag utvecklar detta till jag vill göra det åt..även om det inte hjälper, så är det en sak man laggt extra tid på, låter bra med kryptering och det skadar inte koden, dessutom visar man att man laggt ner tid och sådant, vilket kan löna sig vid framtida jobb..

Medlem sedan juni 20006 031 inlägg
#9

Tulork - Ser ingen orsak till att du får parse error. Ligger funktion db_escape i conn.php?

Spango och GunnarD - Självklart är det bättre att köra SSL. Beror ju helt på hur publik inloggningen är om det är någon överhängande risk för sniffare.

Medlem sedan aug. 2004903 inlägg
#10

Pedda skrev:

Tulork - Ser ingen orsak till att du får parse error. Ligger funktion db_escape i conn.php?

Spango och GunnarD - Självklart är det bättre att köra SSL. Beror ju helt på hur publik inloggningen är om det är någon överhängande risk för sniffare.

aa det gör den


function db_escape ($post)
{
   if (is_string($post)) {
     if (get_magic_quotes_gpc()) {
        $post = stripslashes($post);
     }
     return mysql_real_escape_string($post);
   }
   
   foreach ($post as $key => $val) {
      $post[$key] = db_escape($val);
   }
   
   return $post;
}
Medlem sedan juni 20014 290 inlägg
#11

Pedda skrev:

Spango och GunnarD - Självklart är det bättre att köra SSL. Beror ju helt på hur publik inloggningen är om det är någon överhängande risk för sniffare.

Bara så att du är medveten om att om du genererar MD5 hash i php innan du lägger in lösenordet i databasen eller när du kontrollerar lösenordet mot ett som redan finns så transporteras lösenordet i klartext mellan webläsaren och webservern.

Så det skyddar mot att någon kan läsa lösenorden från databasen men skyddar inte mot sniffning av lösenorden eller att lösenorden lagras i klartext i ex. en proxy på vägen.

Medlem sedan aug. 2004903 inlägg
#12

men hur får jag rätt på md5 nu då, får fortfarande det felmeddelandet..har testat på massa olika sätt.

Medlem sedan juni 20006 031 inlägg
#13

Testade koden till index.php fast utan att köra include på conn.php och det funkade.
När får du felkoden? Kontrollera även conn.php

Medlem sedan aug. 2004903 inlägg
#14

får felet på line 13 i index..dvs där md5 är skrivet..samma fel får jag även på registrerings sidan...

Medlem sedan juni 20006 031 inlägg
#15

Testa att ta bort ' i sql-satsen

$sql = "SELECT id FROM members
         WHERE user={$_POST['user']}
         AND pass={md5($_POST['passwd'])}";
Medlem sedan juni 20008 205 inlägg
#16

Tulork skrev:

även om det inte hjälper, så är det en sak man laggt extra tid på, låter bra med kryptering och det skadar inte koden, dessutom visar man att man laggt ner tid och sådant, vilket kan löna sig vid framtida jobb..

Som potentiell kund skulle jag nog snarare känna mig en aning tveksam över att anlita någon som lägger ner tid på att göra något som inte löser problemet, men men.

Medlem sedan aug. 2004903 inlägg
#17

nej, det löser inte problemet, och det är lätt att hitta informationen om man vet vart man ska leta..men md5 är bättre än ingenting i mina ögon då det skyddar åt ena hållet och det är dessutom inte något som tar så speciellt lång tid eller är krångligt..det är bara det att det spökar lite för mig nu av någon anledning...att använda ssh är både dyrt och knepigt.

Medlem sedan juni 20034 013 inlägg
#18

Att använda ssl är inte dyrt, det finns gratis precis som det mesta annat. Att använda det är heller inte knepigt, man bara gör allt som vanligt. Däremot behöver det ju installeras på servern och konfigureras, men när det är fixat behöver man inte göra något mer.

Medlem sedan aug. 2004903 inlägg
#19

det är just server confen jag e orolig för..men vi släpper shh så länge, vill få igång md5 först o testa lite random hakkning på det... igår sniffa jag upp lösen o användare från en inloggning...5min tog det att hitta...om man vet vart man ska leta. vill kolla lite på md5 igen, va ett tag sen jag gjorde det sist.

Medlem sedan juni 20034 013 inlägg
#20

Du kommer kunna sniffa upp lösen och användare lika snabbt om du kör MD5. Som redan nämnts några gånger ingår det inte i MD5:s arbetsuppgifter utan det är SSL:s funktionalitet du efterlyser.

272 ms totalt · 4 externa anrop · v20260731065814-full.a51de22e
126 ms — deklarationer (db)
0 ms — hämta statistik (cache)
143 ms — hämta tråd, inlägg och bilagor (db)
125 ms — ändringar (db)