php-resource



Zurück   PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr > Scripts > BRAINSTORMING PHP/SQL/HTML/JS/CSS
 

Login

 
eingeloggt bleiben
star Jetzt registrieren   star Passwort vergessen
 

 

 


BRAINSTORMING PHP/SQL/HTML/JS/CSS Ihr habt eine Idee, aber keinen genauen Ansatz? Diskutiert mit anderen Usern des Forums über eure Gedankengänge um evtl. hilfreiche Ideen zu bekommen!
Normale Fragen bitte weiterhin in die entsprechenden Foren!

Antwort
 
LinkBack Themen-Optionen Thema bewerten
  #1 (permalink)  
Alt 06-04-2008, 03:25
Londrag
 Registrierter Benutzer
Links : Onlinestatus : Londrag ist offline
Registriert seit: Jun 2004
Beiträge: 56
Londrag ist zur Zeit noch ein unbeschriebenes Blatt
Standard Mein remake des Login Systems von MrHappiness

Da das Login System von mrhappiness nun schon ein paar Jahre alt, und somit nicht mehr auf dem aktuellsten Stand ist, habe ich mich mal an einem remake versucht. Wollte ursprünglich nur ein paar Änderungen vornehmen, doch am Ende habe ich es von Grund auf neugeschrieben. Vorweg, ich bin PHP Anfänger (bzw. habe mich mal für ein paar Tagen vor mehr als 4 Jahren damit beschäftigt).

Könnt ihr mir helfen die grössten Sicherheitslücken zu stopfen? Sticht da was ins Auge was die Logik oder die Sicherheit angeht?
Ideen, Vorschläge und Kritik ist selbstverständlich willkommen.

Grundlegende Änderungen (plus meine Gedanken dazu):
- Als MySQL Schnittstelle wird nun PDO anstatt mysql_verwendet
- Anstatt md5 wird sha1 verwendet
- Passwörter werden zusätzlich mit einem Salt gespeichert
- Cookie Funktion für automatische Anmeldung hinzugefügt. (alle Informationen im Cookie werden mit sha1 gehasht und beinhalten einen Salt. Anstatt das gehashte Passwort im Cookie zuspeichern, wurde ein extra CookieSession Feld in der DB angelegt.)
- Logout Funktion keine seperate Datei mehr, sonder über $_GET['logout'] aufrufbar.

Habe versucht den Code ein bisschen zu dokumentieren, und falls der Codeschnipsel nicht von mir stammt habe ich die Quelle angegeben.

login.php
PHP-Code:
<?php
session_start
();

include_once(
'functions.inc.php');

$username $_POST['username'];
$password $_POST['password'];
$autologin $_POST['autologin'];
$cookieusername $_COOKIE['cookieusername'];
$cookiesession $_COOKIE['cookiesession'];

try {
    
//Open MySQL Connection with PDO
    
$dbh = new PDO('mysql:host='.$dbhost.';dbname='.$dbname.''$dbuser$dbpass);

    
//If logout is requested
    
if ($_GET['logout'] === "yes") {
        
logout();
        
$cookieusername NULL;
        
$cookiesession NULL;
        echo 
'Sie wurden erfolgreich ausgeloggt.<br />';
    }

    
//If logged in
    
if (IsLoggedIn() === true) {
        echo 
'Sie sind zurzeit eingeloggt.<br /><a href="?logout=yes">Logout</a>';
    }

    
//If Cookie was found and verified as true, login user
    
elseif (isset($cookieusername) && isset($cookiesession)) {
        
$UserID VerifyCookie($cookieusername$cookiesession);
        
//If cookie information incorrect, error message and logout user to delete cookie
        
if ($UserID === false) {
            
logout();
            echo 
'Automatische Anmeldung durch Cookie fehlgeschlagen.<br />
Sie werden nun ausgeloggt und die Cookies werden gelöscht</br />'
;
        }

        
//If cookie information okay, login user
        
else {
            
LoginUser($UserID$autologin);
            echo 
'Willkommen zurück. Sie wurden automatisch durch ihre Cookies eingeloggt.<br />';
        } 
    }

    
//Login, continue only if Username and Password are not empty
    
elseif (isset($_POST['login']) && $username !== "" && $password !== "") {    
        
$UserID VerifyUser($username$password);
        
//If login incorrect, error message
        
if ($UserID === false) {    
            echo 
'Anmeldung fehlgeschlagen.<br />';
        }

        
//If login okay, login user
        
else {
            
LoginUser($UserID$autologin);
            echo 
'Sie wurden erfolgreicht eingeloggt.<br />';

        }
    }

    
//If not logged in, display login form    
    
if (IsLoggedIn() === false) {
        echo 
'<form method="post" action="login.php">
              Username: <input type="text" name="username" id="username" /><br />
              Password: <input type="password" name="password" id="password" /><br />
              Angemeldet bleiben: <input type="checkbox" name="autologin" id="autologin" /><br />
              <input name="login" type="submit" value="Login">
              </form>'
;
    }

    
//Close MySQL Connection
    
$dbh NULL;
}

catch(
PDOException $e) {
    echo 
$e->getMessage();
}    
?>
functions.inc.php
PHP-Code:
<?php
//Database login information
$dbhost "HOSTNAME";
$dbname "DATABASE NAME";
$dbuser "USERNAME";
$dbpass "PASSWORD"


//Disbaling Magic Quotes, code from http://de.php.net/manual/de/security.magicquotes.php#76387
if (get_magic_quotes_gpc()) {
    function 
stripslashes_deep($value)
    {
        
$value is_array($value) ?
                    
array_map('stripslashes_deep'$value) :
                    
stripslashes($value);

        return 
$value;
    }

    
$_POST array_map('stripslashes_deep'$_POST);
    
$_GET array_map('stripslashes_deep'$_GET);
    
$_COOKIE array_map('stripslashes_deep'$_COOKIE);
    
$_REQUEST array_map('stripslashes_deep'$_REQUEST);
}

//Check if logged in
function IsLoggedIn() {
    global 
$dbh;
    
    
$sql='SELECT session FROM users WHERE session="'.session_id().'"';
    
$row=$dbh->query($sql)->fetch();
    
    if (
session_id() === $row['session']) {
        return 
true;
    }
    
    else {
        return 
false;
    }
}

//Veryfing POST_Username and POST_Password
function VerifyUser($username$password) {
    global 
$dbh;
    
    
$sql 'SELECT UserID, password, salt FROM users WHERE username = :username';
    
$stmt $dbh->prepare($sql);
    
$stmt->bindParam(':username'$usernamePDO::PARAM_STR40);
    
$stmt->execute();
    
$row $stmt->fetch();
    
    if (
$row['password'] === sha1($password.$row[salt]))    {
        return 
$row[UserID];
    }
    
    else {
        return 
false;
    }
}

//Logging in User
function LoginUser($UserID$autologin) {
    global 
$dbh;
    
    
$sql='UPDATE users SET session="'.session_id().'" WHERE UserID = "'.$UserID.'"';
    
$dbh->exec($sql);
    
    
//Set a Cookie and Update DB with CookieSession
    
if ($autologin == true) {
        
        
$sql 'SELECT username, salt FROM users WHERE UserID = "'.$UserID.'"';
        
$row $dbh->query($sql)->fetch();
        
        
$cookiesalt sha1(GenerateSalt());
        
$usernamesalt sha1($row['username'].$row['salt']);
        
        
setcookie("cookieusername"$usernamesalttime() + 31536000"/");
        
setcookie("cookiesession"$cookiesalttime() + 31536000"/");
    
        
$sql 'UPDATE users SET cookiesession="'.$cookiesalt.'" WHERE UserID = "'.$UserID.'"';
        
$dbh->exec($sql);
        }
}

//Creating Salt with 40 characters, code from http://wiki.jumba.com.au/wiki/PHP_Generate_random_password
function GenerateSalt() {
    
$characters "01234567890abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_!?-+";
    
$i 0;
    
$salt "";
    while (
$i <= 40) {
        
$salt .= $characters{mt_rand(0,strlen($characters))};
        
$i++;
    }
    return 
$salt;
}

//Verify Cookie
function VerifyCookie($cookieusername$cookiesession) {
    global 
$dbh;
    
    
$sql 'SELECT UserID, username, salt, cookiesession FROM users WHERE cookiesession = :cookiesession';
    
$stmt $dbh->prepare($sql);
    
$stmt->bindParam(':cookiesession'$cookiesessionPDO::PARAM_STR40);
    
$stmt->execute();
    
$row $stmt->fetch();
    
    if (
$cookiesession === $row['cookiesession'] && $cookieusername === sha1($row['username'].$row['salt']))    {
        return 
$row[UserID];
    }
    
    else {
        return 
false;
    }
}

//Logout Users, delete cookie and set session & cookiesession field in DB to NULL
function Logout() {
    global 
$dbh;
    
    
setcookie("cookieusername"""time() - 31536000"/");
    
setcookie("cookiesession"""time() - 31536000"/");
    
    
$dbh->exec('UPDATE users SET session="'.NULL.'", cookiesession = "'.NULL.'" WHERE session = "'.session_id().'"');
}

?>

Hier die dazugehörige SQL Struktur (inkl. 3 Test Users, admin, test, test2 - Username und Passwort jeweils gleich)
Code:
CREATE TABLE `users` (
  `UserID` int(11) unsigned NOT NULL auto_increment,
  `username` varchar(40) NOT NULL,
  `password` varchar(40) NOT NULL,
  `salt` varchar(40) NOT NULL,
  `session` varchar(32) default NULL,
  `cookiesession` varchar(40) default NULL,
  `email` varchar(255) NOT NULL,
  PRIMARY KEY  (`UserID`),
  UNIQUE KEY `username` (`username`,`email`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
Code:
INSERT INTO `users` (`UserID`, `username`, `password`, `salt`, `session`, `cookiesession`, `email`) VALUES 
(1, 'admin', '67440a4fc2736f883108ae1c69dab0606222e0cb', 
'FUgRO;1txF,Q;,2qyyR0.yHPOPVTfzegVAIR?ZKc', '', '', 'admin@admin.com'),
(2, 'test', '4307bbda209f29f932e8f0a05baf7dc8f8a3015b', 
'!tWcGU1GyHW68N-4LcZdHg9XhW!FR,KdzgY6nORV', '', '', 'test@test.de'),
(3, 'test2', '79475350f67f95b32f18a3dfb071af4cc6f20f96', 
'ER0E6tiP0vNMoz0aOLt6hU2wYE,V!Bg6eEQf7iz;', '', '', 'test2@test2.de');
UserID // Selbsterklärend
username // Selbsterklärend
password // sha1 ($EingabeDesUsers.$Salt)
salt //Zufällig generierter 40 Stelliger String
session // aktuelle session_id()
cookiesession // sha1 (Zufällig generierter 40 Stelliger String)
email // Selbsterklärend


Freundliche Grüsse
Londrag

Geändert von Londrag (06-04-2008 um 22:20 Uhr)
Mit Zitat antworten
  #2 (permalink)  
Alt 06-04-2008, 21:01
frodenius
 Registrierter Benutzer
Links : Onlinestatus : frodenius ist offline
Registriert seit: Sep 2006
Ort: Germany, Frankfurt/Main
Beiträge: 156
frodenius ist zur Zeit noch ein unbeschriebenes Blatt
Standard

bitte code umbrechen.
schaut ganz gut aus.
__________________
blllubb
Mit Zitat antworten
  #3 (permalink)  
Alt 06-04-2008, 21:05
asp2php
 Banned
Links : Onlinestatus : asp2php ist offline
Registriert seit: Feb 2004
Beiträge: 11.745
asp2php ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Tssss ... Es gibt eine Klasse von äh ... Haxe, die auf dem TUT von Happy aufbaut.

Heut' zu Tage, wenn du schon abkupferst, dann lieber richtig und zwar mit PHP5 OOP, dann wird sich vielleicht jemand dafür interessieren, aber so bestimmt nicht.

Nachtrag: global? Igit!

Geändert von asp2php (06-04-2008 um 21:10 Uhr)
Mit Zitat antworten
  #4 (permalink)  
Alt 06-04-2008, 21:29
Londrag
 Registrierter Benutzer
Links : Onlinestatus : Londrag ist offline
Registriert seit: Jun 2004
Beiträge: 56
Londrag ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat:
Original geschrieben von frodenius
bitte code umbrechen.
schaut ganz gut aus.
Sorry, benutze eine 1920x1200er Auflösung, daher fällt es mir nicht immer auf. Code war eigentlich Gebrochen, nur jedes Mal wenn ich den Beitrag editere werden die URL wieder automatisch verlinkt.

Zitat:
Original geschrieben von asp2php
Tssss ... Es gibt eine Klasse von äh ... Haxe, die auf dem TUT von Happy aufbaut.

Heut' zu Tage, wenn du schon abkupferst, dann lieber richtig und zwar mit PHP5 OOP, dann wird sich vielleicht jemand dafür interessieren, aber so bestimmt nicht.

Nachtrag: global? Igit!

Schade eigentlich, dachtedass ich auf einem gutem Weg sei. Ich habe es ja in erster Linie nicht für Andere geschrieben, sondern für mich.
Wie gesagt, ich bin Anfänger und es ist nur ein kleines Hobby. Habe gerade die letzten 2 Wochen damit verbracht mich auf den aktuelleren Stand zu bringen und mich mit PDO auseinander gesetzt.

Um OOP zulernen wird es wohl noch länger dauern. Aber es kann ja nicht schaden den Code mal hier hin zu stellen und euch zu fragen wie es mit der Sicherheit aussieht.
Mit Zitat antworten
  #5 (permalink)  
Alt 06-04-2008, 21:53
lennart
 PHP Junior
Links : Onlinestatus : lennart ist offline
Registriert seit: May 2007
Ort: Hamburg
Beiträge: 565
lennart ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat:
Original geschrieben von asp2php
Heut' zu Tage, wenn du schon abkupferst, dann lieber richtig und zwar mit PHP5 OOP, [...]
Ich würde nicht sagen, dass OOP ein Qualitätsmerkmal ist. Das wird von vielen einfach sehr überschätzt denke ich.

Drupal z.b. hat sich AFAIK ganz bewusst gegen OOP entschieden.
Mit Zitat antworten
  #6 (permalink)  
Alt 06-04-2008, 22:13
asp2php
 Banned
Links : Onlinestatus : asp2php ist offline
Registriert seit: Feb 2004
Beiträge: 11.745
asp2php ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Es muss nicht alles OOP sein, aber gerade dieser Vorgang (~Usermanagement) ist dafür ganz geeignet.
Mit Zitat antworten
  #7 (permalink)  
Alt 06-04-2008, 22:26
Londrag
 Registrierter Benutzer
Links : Onlinestatus : Londrag ist offline
Registriert seit: Jun 2004
Beiträge: 56
Londrag ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Ist global einfach unschön oder besteht dadurch ein Sicherheitsrisiko?
Mit Zitat antworten
  #8 (permalink)  
Alt 06-04-2008, 23:09
asp2php
 Banned
Links : Onlinestatus : asp2php ist offline
Registriert seit: Feb 2004
Beiträge: 11.745
asp2php ist zur Zeit noch ein unbeschriebenes Blatt
Standard

global braucht niemand, früher nicht, jetzt auch nicht, ich weiss nicht welcher Idiot auf die Idee kam, dies überhaupt zu ermöglichen; ich spreche nicht nur wegen PHP sondern in alle Programmiersprache. Eine Funktion/Procedure/Klasse muss in sich gekapselt sein, dass alle externe Daten immer via Parameter übergeben müssen, quasi als Bedingung. Denn nur somit ist die Wiederverwendbarkeit gewährleistet, d.h. du kannst sie in beliebige Projekte übenehmen und sofort verwenden.
Mit Zitat antworten
  #9 (permalink)  
Alt 06-04-2008, 23:53
PHP-Desaster
 PHP Expert
Links : Onlinestatus : PHP-Desaster ist offline
Registriert seit: Mar 2006
Beiträge: 3.105
PHP-Desaster befindet sich auf einem aufstrebenden Ast
Standard

OffTopic:
Zitat:
Ich würde nicht sagen, dass OOP ein Qualitätsmerkmal ist. Das wird von vielen einfach sehr überschätzt denke ich.

Drupal z.b. hat sich AFAIK ganz bewusst gegen OOP entschieden.
Das sehe ich ganz anders. Eine Klasse ist genau das richtige, um zusammenhängende Funktionen und Aufgaben gemeinsam zu kapseln. Warum Drupal sich dagegen entschieden hat, ist mir beim besten Willen nicht klar!
Mit Zitat antworten
  #10 (permalink)  
Alt 06-04-2008, 23:58
Londrag
 Registrierter Benutzer
Links : Onlinestatus : Londrag ist offline
Registriert seit: Jun 2004
Beiträge: 56
Londrag ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Okay verstehe, danke für die Aufklärung. Man muss ja aber nicht jeden einzelnen Codeschnipsel der in der Welt rumfliegt wieder verwenden können, manche sind halt einfach auf ein bestimmtes Script fixiert Und $dbh bezieht sich ja auf das PDO __construct, was in diesem Script so oder so Voraussetzung ist.
Mit Zitat antworten
  #11 (permalink)  
Alt 17-04-2008, 21:36
Lennie
 PHP Senior
Links : Onlinestatus : Lennie ist offline
Registriert seit: May 2006
Beiträge: 1.013
Lennie ist zur Zeit noch ein unbeschriebenes Blatt
Standard

hier wird doch wohl nicht ernsthaft über Drupal geredet oder? Finde überhaupt nichts gutes an diesem System.
__________________
Webdesign und Webentwicklung - Plunix.de
Mit Zitat antworten
  #12 (permalink)  
Alt 17-04-2008, 21:40
PHP-Desaster
 PHP Expert
Links : Onlinestatus : PHP-Desaster ist offline
Registriert seit: Mar 2006
Beiträge: 3.105
PHP-Desaster befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
hier wird doch wohl nicht ernsthaft über Drupal geredet oder? Finde überhaupt nichts gutes an diesem System.
Diese Meinung ist sicherlich subjektiv, sehe ich aber genau so wie du.
Mit Zitat antworten
  #13 (permalink)  
Alt 16-02-2009, 20:58
kesandal
 Newbie
Links : Onlinestatus : kesandal ist offline
Registriert seit: Jun 2006
Beiträge: 1
kesandal ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat:
Original geschrieben von asp2php
Tssss ... Es gibt eine Klasse von äh ... Haxe, die auf dem TUT von Happy aufbaut.

Heut' zu Tage, wenn du schon abkupferst, dann lieber richtig und zwar mit PHP5 OOP, dann wird sich vielleicht jemand dafür interessieren, aber so bestimmt nicht.

Nachtrag: global? Igit!
Kann mir bitte jemand sagen wo ich diese Klasse finde?
Suche mich schon dumm und dämlich

Merci
kesandal
Mit Zitat antworten
Antwort

Lesezeichen


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 

Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an


PHP News

ebiz-trader 7.5.0 mit PHP7 Unterstützung veröffentlicht
ebiz-trader 7.5.0 mit PHP7 Unterstützung veröffentlichtDie bekannte Marktplatzsoftware ebiz-trader ist in der Version 7.5.0 veröffentlicht worden.

28.05.2018 | Berni

Wissensbestand in Unternehmen
Wissensbestand in UnternehmenLebenslanges Lernen und Weiterbilden sichert Wissensbestand in Unternehmen

25.05.2018 | Berni


 

Aktuelle PHP Scripte

PHP Server Monitor

PHP Server Monitor ist ein Skript, das prüft, ob Ihre Websites und Server betriebsbereit sind.

11.09.2018 Berni | Kategorie: PHP/ Security
PHP WEB STATISTIK ansehen PHP WEB STATISTIK

Die PHP Web Statistik bietet Ihnen ein einfach zu konfigurierendes Script zur Aufzeichnung und grafischen und textuellen Auswertung der Besuchern Ihrer Webseite. Folgende zeitlichen Module sind verfügbar: Jahr, Monat, Tag, Wochentag, Stunde Folgende son

28.08.2018 phpwebstat | Kategorie: PHP/ Counter
Affilinator - Affilinet XML Produktlisten Skript

Die Affilinator Affilinet XML Edition ist ein vollautomatisches Skript zum einlesen und darstellen der Affili.net (Partnerprogramm Netzwerk) Produktlisten und Produktdaten. Im Grunde gibt der Webmaster seine Affilinet PartnerID ein und hat dann unmittelb

27.08.2018 freefrank@ | Kategorie: PHP/ Partnerprogramme
 Alle PHP Scripte anzeigen

Alle Zeitangaben in WEZ +2. Es ist jetzt 05:14 Uhr.