PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr

PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr (https://www.php-resource.de/forum/)
-   PHP Developer Forum (https://www.php-resource.de/forum/php-developer-forum/)
-   -   2 Logins, erbitte Feedback (https://www.php-resource.de/forum/php-developer-forum/82822-2-logins-erbitte-feedback.html)

clownish 02-04-2007 13:17

2 Logins, erbitte Feedback
 
Hallo Community,

Ich habe 2 Logins 'Scripte' geschrieben, im Grunde sind sie gleich, nur das das eine Sessions, das andere Cookies benutzt. Ich hätte gerne einfach etwas Feedback zu den Scripten weil ich mich noch nicht so lange mit PHP beschäftige und nicht wirklich einschätzen kann ob sie 'sicher' sind.
Eins von beiden soll später mal mit einem Blogscript benutzt werden, allerdings nur als Singeluserlogin und über https.

Also hier sind die beiden Scripte, ich wäre über Verbesserungsvorschläge sehr dankbar:

Mit Keksen:
PHP-Code:

<?php
    
//error_reporting(E_ALL);
    
   
require_once('config.php');
   
  function 
randomkeys($length)
  {
   
$pattern "123456789abcdefghijklmnopqrstuvwxyzQWERTZUIPASDFGHJKLYXCVBNM";
   for(
$i=0;$i<$length;$i++)
   {
     
$key .= $pattern{rand(0,59)};
   }
   return 
$key;
  }


     
mysql_connect(HOST,USER,PASS) && mysql_select_db(DB);
    
$result mysql_query('SELECT Name, Password, cookie FROM users WHERE ID = 1') OR die(mysql_error());
    
$row mysql_fetch_array($result);
    
    
$userpass $_POST['userpass'];
    
$username $_POST['username'];
    
mysql_free_result($result);
        
    if(isset(
$_COOKIE['login']) && $_COOKIE['login'] == MD5($row['cookie'].$row['Name'].$_SERVER['REMOTE_ADDR'])) 
    {
        echo 
'Logged In';
    } 
    else 
    {
                                
        if (
$username == $row['Name'] && MD5($userpass) == $row['Password'])
                {
                
ob_start();
                     
$atm randomkeys(32);
                    
$keks MD5($atm.$username.$_SERVER['REMOTE_ADDR']);
                    
setcookie('login'$keks);
                    
mysql_query("UPDATE users SET cookie = '".$atm."' WHERE id='1';"); 
                    echo 
'Logged In, Cookie set';
                
ob_end_flush();
                }
                else
                {
?>
Bitte loggen sie sich ein:<br><br>
                <form action="<?php echo $SCRIPT_NAME ?>" method="post">
                    <input type="text" name="username" /><br>
                    <input type="password" name="userpass" /><br>
                    <input type="submit" />                                
                </form>
<?php       
die;         
                }
        
           
        
    }
  
?> 
Hier gehts weiter

Und ohne Kekse:

PHP-Code:

<?php
   error_reporting
(E_ALL);
   
session_start();
    
   require_once(
'config.php');
   
  function 
randomkeys($length)
  {
   
$pattern "123456789abcdefghijklmnopqrstuvwxyzQWERTZUIPASDFGHJKLYXCVBNM";
   for(
$i=0;$i<$length;$i++)
   {
     
$key .= $pattern{rand(0,59)};
   }
   return 
$key;
  }


     
mysql_connect(HOST,USER,PASS) && mysql_select_db(DB);
    
$result mysql_query('SELECT Name, Password, cookie FROM users WHERE ID = 1') OR die(mysql_error());
    
$row mysql_fetch_array($result);
    
    
$userpass $_POST['userpass'];
    
$username $_POST['username'];
    
mysql_free_result($result);
        
    if(
$_SESSION['login'] == MD5($row['cookie'].$row['Name'].$_SERVER['REMOTE_ADDR'])) 
    {
        echo 
'Logged In';
    } 
    else 
    {
                                
        if (
$username == $row['Name'] && MD5($userpass) == $row['Password'])
                {
                
                     
$atm randomkeys(32);
                    
$sessiondata MD5($atm.$username.$_SERVER['REMOTE_ADDR']);
                    
$_SESSION['login'] = $sessiondata;
                    
mysql_query("UPDATE users SET cookie = '".$atm."' WHERE id='1';"); 
                    echo 
'Logged In, Cookie set';
                
                }
                else
                {
?>
Bitte loggen sie sich ein:<br><br>
                <form action="<?php echo $SCRIPT_NAME ?>" method="post">
                    <input type="text" name="username" /><br>
                    <input type="password" name="userpass" /><br>
                    <input type="submit" />                                
                </form>
<?php       
die;         
                }
        
           
        
    }
  
?> 
Hier gehts weiter

LG,
Fabian

ghostgambler 02-04-2007 13:50

Vielleicht solltest du dich besser an vorhandenen Logins orientieren anstatt zu versuchen bei Null anzufangen und dabei sowas zu produzieren...

Sorry, aber das ist für eine vernünftige Website praktisch unbrauchbar.
IP-Adresse kann wechseln (AOL-User), da funktioniert dein Login schon nicht.
Die user-ID ist fest-codiert, willst du damit erreichen, dass das Login nur für einen User funktioniert? Wenn ja, wieso dann überhaupt eine MySQL-Tabelle im Hintergrund? Da kann man die PW-Abfrage auch fest in den PHP-Code einbauen.
MD5 ist veraltet, SHA1 hat Vorrang
Was soll die Spielerei mit dem Output-Buffer? Braucht man für ein simples Login nicht, und wir haben es auch in einem komplexen Login nicht gebraucht - eigentlich braucht man das fast nie
randomkeys() ... uniqid+rand+md5, siehe Beschreibung?
{} <- diese Klammern haben beim Zugriff auf Array-Elemente nichts zu suchen
Du verwendest mysql_fetch_array, dabei würde es auch mysql_fetch_assoc tun
echo $SCRIPT_NAME; ist Trash


Orientier dich bitte nicht an vorchristlichen Skripten, sondern an aktuellen, modernen, in php5 geschriebenen Skripten - das von dir erinnert ein wenig an php3 (SCRIPT_NAME)

clownish 02-04-2007 14:04

Okay danke für das Feedback erstmal.
Ich werde das Script gleich nochmal neu schreiben. Die Tabelle brauche ich eh um Beiträge etc zu speichern, und so kann ich später das Passwort besser über ein Interface ändern.
Zu der IP: Wenn ich die nicht irgendwo mitgebe hätte doch jeder der den Cookie irgendwie klaut Zugriff oder?
Zitat:

Vielleicht solltest du dich besser an vorhandenen Logins orientieren anstatt zu versuchen bei Null anzufangen und dabei sowas zu produzieren...
Dann lerne ich es nie...

Zum Puffer... Irgendwie ging das mit dem Cookie sonst nicht, weil durch die Zufallsfunktion schon vorher der Header gesendet wird oder so (ja ich habe nicht viel Ahnung).

LG,
Fabian

wahsaga 02-04-2007 14:05

Zitat:

Original geschrieben von clownish
Zu der IP: Wenn ich die nicht irgendwo mitgebe hätte doch jeder der den Cookie irgendwie klaut Zugriff oder?
Wie gerade schon gesagt wurde: Wenn du die IP als Identifizierungsmerkmal nutzt, haben auch die "richtigen" Nutzer u.U. keinen Zugriff.

ghostgambler 02-04-2007 14:16

Zitat:

Original geschrieben von clownish
Dann lerne ich es nie...
Na irgendwoher wirst du das mit dem SKRIPT_NAME wohl haben, oder?
Wo auch immer du das her hast würde ich nicht wieder hingehen...


bzgl. Output-Buffer - Dann sortier deine Skripte so, dass die Header vor dem HTML-Output gesendet werden, dann brauchst du auch kein ob_*

clownish 02-04-2007 14:37

Vielen Dank für eure Hilfe.
Okay, hier also mein nächster Versuch:
PHP-Code:

<?php
   error_reporting
(E_ALL);
   
session_start();
    
   require_once(
'config.php');

     
mysql_connect(HOST,USER,PASS) && mysql_select_db(DB);
    
$result mysql_query('SELECT Name, Password, cookie FROM users WHERE ID = 1') OR die(mysql_error());
    
$row mysql_fetch_assoc($result);
    
    
$userpass $_POST['userpass'];
    
$username $_POST['username'];
    
    
mysql_free_result($result);
        
    if(
$_SESSION['login'] == sha1($row['cookie'].$row['Name'])) 
    {
        echo 
'Logged In';
    } 
    else 
    {
                                
        if (
$username == $row['Name'] && MD5($userpass) == $row['Password'])
                {
                
                     
$atm md5(uniqid (rand()));
                    
$sessiondata sha1($atm.$username);
                    
$_SESSION['login'] = $sessiondata;
                    
mysql_query("UPDATE users SET cookie = '".$atm."' WHERE id='1';"); 
                    echo 
'Logged In, Cookie set';
                
                }
                else
                {
?>
Bitte loggen sie sich ein:<br><br>
                <form action="<?php echo $_SERVER['REQUEST_URI'?>" method="post">
                    <input type="text" name="username" /><br>
                    <input type="password" name="userpass" /><br>
                    <input type="submit" />                                
                </form>
<?php       
die;         
                }
        
           
        
    }
  
?>

Das MD5 in der Datenbank kann ich momentan leider nicht ändern. Gibt es noch ein anderes Sicherheitsmerkmal so das ich Sessionklau irgenwie verhindern kann?

Lg,
Fabian

Ps: Das 'Scriptname' war mein Editor - (bluefish, linux).

Lennie 02-04-2007 15:17

So wie ich das verstehe willst du das script nur für dich und deine seite nutzen, dann ist es (sei denn du hast eine minütlich wechselnde ip, das kannst du ja mal bei seiten wie www.wieistmeineip.de testen) meiner meinung nach "besser"/sicherer mit der ip.
allerdings ist dann die nutzung deiner seite an anderen orten vllt. gefährdet. z.b. im urlaub, internetcaffee, freunden.

ich halte md5 ganz und garnicht für veraltet. ich habe in der php-resource eine umfrage gemacht in der nur 4 von 20 votes sha1 nutzen.

ps: in meinen login seiten habe ich eine timeabfrage, eine session ist maximal eine stunde gültig, danach muss man neu einloggen.

auserdem wird pro klick im acp die aktuelle zeit in der datenbank gespeichert, sollte zwischen einem klick mehr als 300 sek (5 minuten) vergangen sein, musss man sich auch neu einloggen.
ist eine weitere sicherheitsvariante die du in betracht ziehen könntest.

weitere varianten
- tancode (wie beim online banking)
- captcha (verhindert weitgehend bruteforce)
- orientierung
+ browser
+ betriebssystem
(ist eine nicht all zu sichere variante neben der ip.
bei einer abfrage bzw. einer einschränkung der session auf
diese merkmale des besitzers werden schon einmal die leute
ausgeschlossen die was anderes verwenden.)

ghostgambler 02-04-2007 15:28

Schon besser - nur das Speichern vom sha1-Hash in $_SESSION['login'] hat irgendwie keinen Sinn ... da kannst du auch einfach nur ein true reinschreiben spart Rechenzeit und ist genauso gut


Zitat:

Original geschrieben von Lennie
So wie ich das verstehe willst du das script nur für dich und deine seite nutzen, dann ist es (sei denn du hast eine minütlich wechselnde ip, das kannst du ja mal bei seiten wie www.wieistmeineip.de testen) meiner meinung nach "besser"/sicherer mit der ip.
Will heißen jedes Mal wenn man sich neu einloggt (beim DSL/ISDN) die IP im Code wieder ändern?
Find ich sehr umständlich...

Zitat:

ich halte md5 ganz und garnicht für veraltet. ich habe in der php-resource eine umfrage gemacht in der nur 4 von 20 votes sha1 nutzen.
Nur weil es jeder *piep* noch nutzt, heißt es nicht, dass es noch state-of-the-art ist, aber sha1 ist ja auch schon "geknackt", aber dazu kann sich jeder selbst auf Wikipedia und co eine Meinung bilden, ich werd fürs Tippen schließlich nicht bezahlt~

clownish 02-04-2007 15:42

Okay, vielen Dank für eure Hilfe...
Sollte mir jetzt allerdings jemand, wie auch immer, den Sessioncookie klauen hätte er vollen Zugriff. Wie kann ich Session-klau verhindern? Mal von Https abgesehen.

ghostgambler 02-04-2007 17:06

Zitat:

Original geschrieben von clownish
Okay, vielen Dank für eure Hilfe...
Sollte mir jetzt allerdings jemand, wie auch immer, den Sessioncookie klauen hätte er vollen Zugriff. Wie kann ich Session-klau verhindern? Mal von Https abgesehen.

z.B. einen Teil der IP verwenden+user_agent und das hashen und bei jedem Aufruf erneut erstellen und mit dem in der Session vergleichen

clownish 02-04-2007 17:39

Moment da komm ich nicht mit. Dann schließe ich doch wieder zb AOL benutzer aus? Also sie würden zumindest aus der jeweiligen Session 'rausfliegen' oder?

jahlives 02-04-2007 17:47

Zitat:

einen Teil der IP verwenden+user_agent
und nicht die ganz IP, damit du die AOLs nicht ausschliesst. Wobei sich für mich immer die Frage stellt ob das zuverlässig funzt, denn IP und User Agent kann man einfach spoofen (wobei das bei der IP etwas schwieriger ist, aber nicht desto trotz funzt).
Ein Problem hast du mit den Sessions ja eigentlich nur wenn sich jemand zwischen Server und Client hängen kann (Man in the Middle) und in diesem Falle kann der böse User ja eh fast jede Info bekommen.
Also drum die Frage: Lohnt sich der Aufwand überhaupt ? Sind denn deine Daten so schützenswert, dass du dich auf eine Technik verlassen musst, die im schlimmsten Fall "false positives" produziert ?

Gruss

tobi

clownish 02-04-2007 18:26

Oh hab ich überlesen. Dankeschön.
Wäre das dann so eine Lösung?
PHP-Code:

<?php
   error_reporting
(E_ALL);
   
session_start();
    
   require_once(
'config.php');

    
mysql_connect(HOST,USER,PASS) && mysql_select_db(DB);
    
$result mysql_query('SELECT Name, Password, cookie FROM users WHERE ID = 1') OR die(mysql_error());
    
$row mysql_fetch_assoc($result);
    
    
$currentip explode('.'$_SERVER['REMOTE_ADDR']);
    
$aolip $currentip[0].$currentip[1].$currentip[2];
    
    
$userpass $_POST['userpass'];
    
$username $_POST['username'];
    
    
mysql_free_result($result);
        
    if(!empty(
$_SESSION['login']) && $_SESSION['login'] <= $row['cookie'] + 60
    {
        if(
$_SESSION['data'] == sha1($_SERVER['HTTP_USER_AGENT'].$aolip))
        {
        
$_SESSION['login'] = time();
        }
    } 
    else 
    {
                                
        if (
$username == $row['Name'] && MD5($userpass) == $row['Password'])
                {
                
                 
$atm time();
                     
                    
$_SESSION['login'] = $atm;
                    
$_SESSION['data'] = sha1($_SERVER['HTTP_USER_AGENT'].$aolip);
                    
                    
mysql_query("UPDATE users SET cookie = '".$atm."' WHERE id='1';"); 
                    echo 
'Logged In, Cookie set'.$aolip;
                
                }
                else
                {
?>
Bitte loggen sie sich ein:<br><br>
                <form action="<?php echo $_SERVER['REQUEST_URI'?>" method="post">
                    <input type="text" name="username" /><br>
                    <input type="password" name="userpass" /><br>
                    <input type="submit" />                                
                </form>
<?php       
die;         
                }

    }
  
?>

LG,
Fabian

closure 02-04-2007 19:14

Zitat:

Original geschrieben von clownish
PHP-Code:

mysql_query("UPDATE users SET cookie = '".$atm."' WHERE id='1';"); 


hat nicht unbedingt mit dem thema zu tun aber du solltest hier nicht
1 als string übergeben, das führt nämlich dazu dass jeder eintrag
für den vergleich nach varchar gecasted wird, was bei großen tabellen
ordentlich an der performance zehrt.

du zeigst ja hier den willen, es besser zu machen was schon mal sehr
gut ist, aber lies dir auch nochmal jahlives' post durch und beatworte
für dich die frage ob sich der aufwand lohnt. wenn ja, dann kann man
da noch einiges schöner machen, was nicht nur mit sicherheit zu tun hat.

btw. ist require_once keine function, weshalb du die klammern dort weglassen solltest.

greets

clownish 02-04-2007 19:27

Hallo.

Zu dem Require_once, das habe ich so von http://de.php.net/manual/de/function.require-once.php übernommen, und da sind Klammern dabei.

Also ich hätte das Script schon gerne so sicher wie möglich, auch wenn das mit mehr Aufwand verbunden ist. Was kann ich denn noch schöner machen?

LG,
Fabian


Alle Zeitangaben in WEZ +2. Es ist jetzt 13:16 Uhr.

Powered by vBulletin® Version 3.8.2 (Deutsch)
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0
[c] ebiz-consult GmbH & Co. KG