Login systeem MySQL extra beveiliging (sessions in SQL/cookie)

Gepost door Erik-Jan op 13-06-2011 23:00.

Hieronder staat een eenvoudig ogend login systeem met php en MySQL.

Er is echter wat onzichtbare extra beveiliging toegevoegd ten opzichte van wat normaal op de verschillende sites wordt gevonden.

Heeft er nog iemand ideeën om het geheel (nog) veiliger te maken en heeft iemand suggesties?

    Features:

[li]controle van browser, ip en poort en bij ieder bezoek aan een pagina en wisselende sessie-id en wisselende random code (tegen session hijacking)[/li]
[li](beperkte) bescherming tegen SQL-injection en file injection[/li]
[li]keuze uit sessiegegevens in MySQL-database of in cookie[/li]
[li]toegang op verschillende niveau's[/li]
[li]bescherming tegen verzenden van plain password[/li]
[li]gecodeerde gegevens in database, dus brute force nodig om username/password en andere gegevens achterhalen[/li]
[li]check voor https[/li]

    Potentiële nadelen

[li]Vrij zwaar bij veel gebruikers[/li]
[li]Over the top[/li]

    Getest met

[li]Apache/2.2.17 (Win32) mod_ssl/2.2.17 OpenSSL/0.9.8o PHP/5.3.4 mod_perl/2.0.4 Perl/v5.10.1[/li]
[li]MySQL client version: mysqlnd 5.0.7-dev - 091210 - $Revision: 304625 $[/li]

Bestanden van dit script

database.php

1
2
3
4
5
6
<?php

    mysql_connect ("localhost","login", "login") or exit(); 
    mysql_select_db("login") or exit(); 

?>

index.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
<?php
error_reporting(0);

/* OPTIONAL: HANDLE SECTIONS THROUGH MYSQL + CHECK IF HTTPS IS USED */

    include("sessions.php");
    
    //check if HTTPS IS USED
    //if ($_SERVER['SERVER_PORT'] != 443) { header('Location:https://www.abc.com/login/'); exit; } 

/* OPTIONAL: CLEAN UP LOGIN TABLE */
    
    //connect to database (not required if MySQL-sessions are used)
    require_once("database.php");
    
    //remove session_id which are no longer used from the login table
    $sql = " DELETE FROM `login` WHERE `session_id` NOT IN (SELECT `id` FROM `sessions`) ";
    mysql_query($sql) or die();

/* OPTIONAL: PROTECTION AGAINST CODE INJECTION */
    
    //list of valid pages
    $pages=array("/login/index.php", "/login/index.php?task=logout");
    if( !in_array(htmlspecialchars($_SERVER['REQUEST_URI']),$pages)) {
        
    //if the case reload clean page    
    header("Location:index.php");
    exit;

    }
        
/* LOGOUT SECTION */

if (isset($_GET['task']) AND ctype_alnum($_GET['task']) AND $_GET['task'] == 'logout')
{
    //start the session to be closed
    session_start();
    
    //destroy the session
    session_destroy();
}

/* START NEW SESSION */

    session_start();
    session_regenerate_id($delete_old_session = TRUE);

// VERIFY POSTED USERNAME AND PASSWORD USING CHALLENGE

if( isset($_POST['login']))
{
    $username=sha1(mysql_real_escape_string($_POST['username']));

    //create password including the challenge submitted
    $response=mysql_real_escape_string($_POST['response']);
    
    //check if username and password are valid
    $query = " SELECT `level`,`password` FROM `users` WHERE `user` = '".$username."'";
    $result = mysql_query("$query") or die();
    $row = mysql_fetch_assoc($result);
    
    if( mysql_num_rows($result) == 1 AND sha1($username.$row['password'].htmlspecialchars($_SESSION['challenge'])) == $_POST['response'] )
    {

    //clean username, password, respons and empty challenge session for security reasons
    $username=''; $row['password']=''; $response=''; $_SESSION['challenge']='';

    //write system details in session
    $_SESSION['system']=sha1($_SERVER['HTTP_USER_AGENT'].$_SERVER['REMOTE_ADDR'].$_SERVER['SERVER_PORT']);
    
    //write random code and system details in database
    $code=sha1(rand(1000,10000));
    $sql = "INSERT `login` SET `session_id` = '".session_id()."' , `code` = '".$code."' , `system` = ";
    $sql.= "SHA1('".$_SERVER['HTTP_USER_AGENT'].$_SERVER['REMOTE_ADDR'].$_SERVER['SERVER_PORT']."') , ";
    $sql.= " `level` = '".$row['level']."' ";
    $result = mysql_query("$sql") or die();
    
    //write random code in session
    $_SESSION['code']=$code;

    //go to next page    
    header("Location:index2.php");
    exit;
    
}

/* IF LOGIN IS NOT SUCCESSFUL */
    
else { echo "<br />Wrong username/password."; }

}


// CREATE CHALLENGE FOR PREVENTING SENDING PLAIN PASSWORD OVER HTTP CONNECTION
    $challenge=sha1(rand(1000,10000));
    $_SESSION['challenge']=$challenge;

?>

<script type="text/javascript" src="sha1.js"></script>

<script type="text/javascript">
<!--
function createResponse()
{
document.getElementById('response').value = hex_sha1 ( hex_sha1 ( document.getElementById('username').value ) + hex_sha1 (document.getElementById('password').value ) + document.getElementById('challenge').value ) ;
document.getElementById('password').value = "";
document.getElementById('challenge').value = "";
return true;
}
//-->
</script>

<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" name="login" onsubmit="return createResponse();">
<fieldset>
<legend>Log In</legend>
    <label>Username</label>
<input type="text" name="username" id="username"><br />
    <label>Password</label>
<input type="password" name="password" id="password"><br />
<input type="hidden" name="challenge" id="challenge" value="<?php echo $challenge; ?>">
<input type="hidden" name="response" id="response" value="">
<input name= "login" type="submit">
</fieldset>
</form>    

index2.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<?php
error_reporting(0);

/* OPTIONAL: HANDLE SECTIONS THROUGH MYSQL */

    include("sessions.php");
    
/* SESSION START */

    session_start();

/* CHECKS */

    //connect to database
    require_once("database.php");

    // check same brower, IP address and port and random code in both database and session
    $query = " SELECT `level` FROM `login` WHERE `session_id` = '".session_id()."' AND ";
    $query.= "`system` = SHA1('".$_SERVER['HTTP_USER_AGENT'].$_SERVER['REMOTE_ADDR'].$_SERVER['SERVER_PORT']."') AND ";
    $query.= "`code` = '".$_SESSION['code']."' AND ";
    $query.= "`system` = '".$_SESSION['system']."'";
    $result = mysql_query("$query") or die();

/* IF CHECKS SUCCESSFUL -> GENERATE NEW RANDOM CODE AND GENERATE NEW SESSION ID */

if( mysql_num_rows( $result ) == 1 ) 
{
    //put level in a variable
    $row = mysql_fetch_assoc($result);
    $level = $row['level'];
    
    //generate new random code
    $code=sha1(rand(1000,10000));
    
    //obtain old session id
    $session_id_old=session_id();
    
    //generate new session id and remove old session
    session_regenerate_id($delete_old_session = TRUE);
    
    //obtain new session id
    $session_id_new=session_id();
    
    //update table with random code and assing new session id
    $sql = "UPDATE `login` SET `code` = '".$code."' , `session_id` = '".$session_id_new."' WHERE `session_id` = '".$session_id_old."'";
    $result = mysql_query("$sql") or die();
    
    //write new random code in session
    $_SESSION['code']=$code;

/* IF CHECKS OK */    
    
    echo "Logged in!<br />";
    echo "Level: ".$level."<br />";
    echo "<a href=\"index.php?task=logout\">Log out</a>";

}

/* IF CHECKS NOT OK */    

else {

    //destroy session
    session_destroy();
    
    //go back to login page
    header("Location:index.php");
    exit;

}

?>

sessions.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<?php

    //connect to database
    require_once("database.php");

    //hash session id through sha1
    ini_set ('session.hash_function','1');
    
    //never double sessions
    ini_set ('session.gc_probability','100');
    ini_set ('session.gc_divisor','100');
    
    //session only for 5 minutes without refresh
    ini_set ('session.gc_maxlifetime','300');
    
    //OPTIONAL referer check
    //ini_set ('session.referer_check','https://www.abc.com/login/');

    
function _open() { }

function _close() { }

function _read($id)
{
    $sql = "SELECT `data` FROM `sessions` WHERE `id` = '$id'";
        if ($result = mysql_query($sql))
        {
            if (mysql_num_rows($result))
            {
                $record = mysql_fetch_assoc($result);
                return $record['data'];
            }
        }
return;
}

function _write($id, $data)
{
    $access = time();
    $sql = "REPLACE INTO `sessions` VALUES ('$id', '$access', '$data', CURRENT_TIMESTAMP)";
    return mysql_query($sql) or die();
}

function _destroy($id)
{
    $sql = "DELETE FROM `sessions` WHERE `id` = '$id' ";
    return mysql_query($sql) or die();
}

function _clean($max)
{
    $old = time() - $max;
    $sql = "DELETE FROM `sessions` WHERE `access` < '$old'";
    return mysql_query($sql) or die();
}

session_set_save_handler ('_open', '_close', '_read', '_write', '_destroy', '_clean');

?>

sha1.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
/*
 * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
 * in FIPS PUB 180-1
 * Version 2.1a Copyright Paul Johnston 2000 - 2002.
 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
 * Distributed under the BSD License
 * See http://pajhome.org.uk/crypt/md5 for details.
 */

/*
 * Configurable variables. You may need to tweak these to be compatible with
 * the server-side, but the defaults work in most cases.
 */
var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */

/*
 * These are the functions you'll usually want to call
 * They take string arguments and return either hex or base-64 encoded strings
 */
function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));}
function b64_sha1(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz));}
function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));}
function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));}
function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));}
function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));}

/*
 * Perform a simple self-test to see if the VM is working
 */
function sha1_vm_test()
{
  return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
}

/*
 * Calculate the SHA-1 of an array of big-endian words, and a bit length
 */
function core_sha1(x, len)
{
  /* append padding */
  x[len >> 5] |= 0x80 << (24 - len % 32);
  x[((len + 64 >> 9) << 4) + 15] = len;

  var w = Array(80);
  var a =  1732584193;
  var b = -271733879;
  var c = -1732584194;
  var d =  271733878;
  var e = -1009589776;

  for(var i = 0; i < x.length; i += 16)
  {
    var olda = a;
    var oldb = b;
    var oldc = c;
    var oldd = d;
    var olde = e;

    for(var j = 0; j < 80; j++)
    {
      if(j < 16) w[j] = x[i + j];
      else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
      var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
                       safe_add(safe_add(e, w[j]), sha1_kt(j)));
      e = d;
      d = c;
      c = rol(b, 30);
      b = a;
      a = t;
    }

    a = safe_add(a, olda);
    b = safe_add(b, oldb);
    c = safe_add(c, oldc);
    d = safe_add(d, oldd);
    e = safe_add(e, olde);
  }
  return Array(a, b, c, d, e);

}

/*
 * Perform the appropriate triplet combination function for the current
 * iteration
 */
function sha1_ft(t, b, c, d)
{
  if(t < 20) return (b & c) | ((~b) & d);
  if(t < 40) return b ^ c ^ d;
  if(t < 60) return (b & c) | (b & d) | (c & d);
  return b ^ c ^ d;
}

/*
 * Determine the appropriate additive constant for the current iteration
 */
function sha1_kt(t)
{
  return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :
         (t < 60) ? -1894007588 : -899497514;
}

/*
 * Calculate the HMAC-SHA1 of a key and some data
 */
function core_hmac_sha1(key, data)
{
  var bkey = str2binb(key);
  if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz);

  var ipad = Array(16), opad = Array(16);
  for(var i = 0; i < 16; i++)
  {
    ipad[i] = bkey[i] ^ 0x36363636;
    opad[i] = bkey[i] ^ 0x5C5C5C5C;
  }

  var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
  return core_sha1(opad.concat(hash), 512 + 160);
}

/*
 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
 * to work around bugs in some JS interpreters.
 */
function safe_add(x, y)
{
  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
}

/*
 * Bitwise rotate a 32-bit number to the left.
 */
function rol(num, cnt)
{
  return (num << cnt) | (num >>> (32 - cnt));
}

/*
 * Convert an 8-bit or 16-bit string to an array of big-endian words
 * In 8-bit function, characters >255 have their hi-byte silently ignored.
 */
function str2binb(str)
{
  var bin = Array();
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < str.length * chrsz; i += chrsz)
    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32);
  return bin;
}

/*
 * Convert an array of big-endian words to a string
 */
function binb2str(bin)
{
  var str = "";
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < bin.length * 32; i += chrsz)
    str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask);
  return str;
}

/*
 * Convert an array of big-endian words to a hex string.
 */
function binb2hex(binarray)
{
  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i++)
  {
    str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
           hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8  )) & 0xF);
  }
  return str;
}

/*
 * Convert an array of big-endian words to a base-64 string
 */
function binb2b64(binarray)
{
  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i += 3)
  {
    var triplet = (((binarray[i   >> 2] >> 8 * (3 -  i   %4)) & 0xFF) << 16)
                | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 )
                |  ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);
    for(var j = 0; j < 4; j++)
    {
      if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
    }
  }
  return str;
}

Commentaar

13-06-2011 23:04
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
CREATE TABLE `login` (
  `id` smallint(6) NOT NULL AUTO_INCREMENT,
  `session_id` varchar(50) NOT NULL,
  `code` varchar(40) NOT NULL,
  `system` varchar(40) NOT NULL,
  `level` smallint(6) NOT NULL,
  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;


CREATE TABLE `sessions` (
  `id` varchar(40) NOT NULL,
  `access` int(10) unsigned DEFAULT NULL,
  `data` text,
  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;


CREATE TABLE `users` (
  `id` smallint(6) NOT NULL AUTO_INCREMENT,
  `user` varchar(40) NOT NULL,
  `password` varchar(40) NOT NULL,
  `level` smallint(6) NOT NULL,
  UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;

INSERT INTO `users` (`id`, `user`, `password`, `level`) VALUES
(4, SHA1('user'), SHA1('password'), 1),
(7, SHA1('moderator'), SHA1('password'), 2),
(8, SHA1('admin'), SHA1('password'), 3);
13-06-2011 23:14

En dat met al die beveiligingsmaatregelen toch nog PHP_SELF in de form action gebruiken :')

http://www.scriptorama.nl/security/tips-veiligere-site-phpself

13-06-2011 23:24

Je hebt helemaal gelijk; dit heb ik over het hoofd gezien.

Regel 114 van index.php kan dus als volgt gewijzigd worden:

1
<form action="index.php" method="post" name="login" onsubmit="return createResponse();">

Of je kunt één van de opties van de website hierboven van Roland F. gebruiken.

14-06-2011 09:18
14-06-2011 09:56

Ja, maar wat zou dat aan bovenstaand script toevoegen?

14-06-2011 23:38

Daarin wordt uitgelegd waarom session_destroy() niet zo zinnig is.

14-06-2011 23:42

O ja, en in http://www.pfz.nl/wiki/mysql-foutafhandeling-in-php/ wordt uitgelegd waarom je beter geen "or die() " kunt gebruiken...

15-06-2011 13:07
1
$sql = " DELETE FROM `login` WHERE `session_id` NOT IN (SELECT `id` FROM `sessions`) ";

dan lijkt het alsof session_id een foreign_key naar de tabel sessions is.
Maar was dat zo, dan had dat record in de tabel login nooit het deleten uit de tabel sessions kunnen overleven....

1
2
CREATE TABLE `login` (
  `id` smallint(6) NOT NULL AUTO_INCREMENT,

dus na 32000 logins is de koek op....'
gebruik liever een INT

20-06-2011 18:50

Ik heb het niet geprobeerd, dus negeer me als ik het mis heb:

Stel nou dat ik een website met meerdere (i)frames gebruik.
Wanneer de eerste pagina geladen wordt, krijg ik een session-id goed voor 1 nieuwe pagina. Omdat er echter meerdere iframes in de pagina zitten, gaat mijn browser met die ene sessie-id meerdere pagina's opvragen. Loop ik nou voor een deel mijn sessie mis omdat bij het eerste verzoek van een van de iframes mijn sessie-id veranderd wordt?

20-06-2011 21:35

Stel nou dat ik een website met meerdere (i)frames gebruik.
Wanneer de eerste pagina geladen wordt, krijg ik een session-id goed voor 1 nieuwe pagina. Omdat er echter meerdere iframes in de pagina zitten, gaat mijn browser met die ene sessie-id meerdere pagina's opvragen. Loop ik nou voor een deel mijn sessie mis omdat bij het eerste verzoek van een van de iframes mijn sessie-id veranderd wordt?

Frames zijn uit de tijd, maar het probleem doet zich ook voor bij bijvoorbeeld AJAX-calls.
Een quote van uit de documentatie van FuelPHP http://fuelphp.com/docs/classes/session/advanced.html#footer

When talking about sessions, session cookies, and their behaviour, it is important to understand how they work and what the possibilities and limitations are.

This is especially true when it comes to concurrency. For web-based application, you will have concurrency if you use multiple asynchronous ajax calls on your webpages, or if you allow a browser to have multiple windows open to the same application (which, lets face it, is something you can't prevent).

Something else you need to know is that by default, the session class will rotate (or regenerate) the session id on a regular basis, to prevent session hijacking due to session id fixation (someone stealing your session cookie and use it to take over your session). You can control the rotation time using a configuration setting, or even disable it, but from a security point of view that is a bad idea. Take these two together, and you have a potential disaster on your hands!

An illustration:
- you request a page, the session cookie containing ID-A is sent to the server.
- your page sends two ajax requests. the session cookie containing ID-A is again sent to the server with each request.
- ajax request 1 finishes, and rotates the ID. A cookie with ID-B is sent to the browser.
- now ajax request 2 finishes. Because it sent the same cookie, it also decides to rotate, this time to ID-C.
(you will get a different ID, because session IDs are generated using a randomized algorithm)
Now we have a problem. The session class tries to update the stored session with key ID-A to ID-C, but it can't find that session. Remember, it had been updated from ID-A to ID-B by the first ajax call! So it decides the session is invalid, create a new and empty session, and return that cookie to the browser. Now your valid cookie is overwritten by the new and empty session cookie. Result: you have lost the session.

This is an issue that most frameworks have not solved. Enter Fuel!

Fuel's session class contains two mechanisms to detect and mitigate this problem. Every session key store contains two session IDs: the current ID and the previous ID. If a request comes in just after the session id has been rotated, the correct session can be located using the previous session id stored in the key store. And it case of a session id mismatch which could not be recovered using the previous id, no updated cookie will be sent back to the browser. The result is that you lose the session data of that request, but you don't lose the session itself.

Quoted from http://fuelphp.com/docs/classes/session/advanced.html#footer

24-06-2011 15:16

Is dit script makkelijk aan te passen, ik wil de username niet encrypten omdat ik op deze manier geen lijst met users kan weergeven ?

06-07-2011 09:51

Ik krijg een error:

De pagina verwijst niet op een juiste manier door
Firefox heeft vastgesteld dat de server het verzoek voor dit adres doorverwijst op een manier die nooit zal eindigen.

Wat is hier het probleem van

07-08-2011 00:42

@Mark
Je kunt de volgende regels vrij eenvoudig als volgt aanpassen:
index.php
regel 52:

1
$username=mysql_real_escape_string($_POST['username']);

regel 106:

1
document.getElementById('response').value = hex_sha1 ( document.getElementById('username').value + hex_sha1 (document.getElementById('password').value ) + document.getElementById('challenge').value ) ;

Door bovenstaande aanpassingen kun je de usernames als plain text in de database opslaan.

@Arjen
Het probleem zit in regel 20 t/m 30 van index.php. Als je die beveiliging tijdelijk uitzet, zul je de foutmelding niet krijgen.

@Iedereen
Ten opzichte van de beginpost moet dus regel 114 van index.php worden aangepast (zie mijn post van 13-06-2011) en in alle pagina's "or die()" verwijderd worden als je dat nodig vindt (persoonlijk vind ik dat het maar valt te bezien of je de rest van je pagina wil laden als je login script ergens vastloopt). Als je wilt dat de sessies bewaard blijven kun je session_destroy dus uitschakelen, maar als je die gegevens niet wilt bewaren (zoals nu het geval is), hoef je niets aan te passen aan mijn script (anders 2x session_destroy verwijderen uit index.php en index2.php en wellicht ook regel 16 t/m 18 van index.php niet gebruiken).

01-09-2011 22:59

Hoi,

Is het normaal dat ik geen inlog form te zien krijg? In plaats van in directory 'login' heb ik mijn files in 'secure' geplaatst, maar ik heb wel de regel 23 uit index.php aangepast, ttz, login vervangen door secure.

Iemand enig idee? Ik krijg overigens ook geen error, totaal geen inlog form.

Groeten
Pieter

10-09-2011 22:13

Ik wordt altijd getriggerd om een kleine inspectie te doen als iemand roept dat iets veilig is ;-) Alleen helaas, zo heel veilig is dit loginsysteem niet.

Er zit in index.php op regel 75 en in index2.php op regel 19 een SQL injectie zwakheid ($_SERVER['HTTP_USER_AGENT'] direct zonder omzetting in SQL query gebruiken).

In index.php op regel 115 zit een Cross Site Scripting zwakheid ($_SERVER['PHP_SELF'] zonder omzetting in HTML gebruiken).

Ook zou je SSL moeten afdwingen wanneer dit geconfigureerd is.

Wellicht zitten er nog meer zwakheden in het script, het vinden van de rest laat ik aan jullie over ;-)

07-10-2011 17:58

error_reporting(E_ALL); met een (0); uitstaande kunnen we het allemaal wel..

07-10-2011 18:02

@ivo p waarom een int gebruiken en waarom geen mediumint ? met een mediumint kun je wellicht veel meer aanmeldingen krijgen.. en daarbij zijn de bytes van een mediumint ook nog meter dan een normale int ;)

28-10-2011 16:56

Het lukt mij niet om het script te installeren.
Ik krijg alleen een lege pagina!

weet iemand een oplossing?

n9iels

10-04-2012 20:28

Goede avond

het wil maar niet lukken om dit script werkend te krijgen. waarschijnlijk ligt het aan mijn ontbrekende kennis.

ik heb 1 index.php pagina waarin de pagina's van mijn website worden geladen.
Is het de bedoeling dat ik

1
include_once 'login\index.php';

toevoeg aan pagina? (als ik dit doe blijft de pagina leeg)

als ik naar localhost/login/index.php ga kan ik inloggen. en word dan door glinkt naar index2.php.
is het de bedoeling dat ik de code van localhost/index.php in dit bestand zet.

zou iemand een korte uitleg kunnen geven hoe je dit script kunt toevoegen:)

wat ik eigelijk hoop te kunnen is dat als iemand naar naar de site surft altijd een inlog scherm tezien krijgt tot hij/zij inlogd.

alvast bedankt!

15-05-2012 09:17

Ik heb een user toegevoegd met test, test maar als ik wil inloggen krijg ik wrong username/password

Inloggen wachtwoord vergeten? Aanmelden