Hi daar,
Eigenlijk het volgende; ik heb gekozen om een eigen session handler te gebruiken i.c.m. een database. Heb hier t internet enige tijd op nagezocht en een beetje de puzzelstukjes aan elkaar verbonden. Heb daarmee de volgende class gemaakt.
init() functie is de constructor die door mijn framework wordt aangeroepen
Dit spreekt denk ik wel voor zich, maar als er iets onduidelijk is hoor ik het graag.
Het komt er in feite op neer dat ik de sessie aan een 'fingerprint' wil koppelen. Zodat als er -hoe dan ook- een sessie gestolen wordt (dmv cookie stelen oid) diegene daar niks mee kan.
Dit werkt nu een beetje, de query in mijn read() functie heeft dat al als voorwaarde. Alleen als ik de sessie cookie van de ene browser kopieër naar de andere browser, denkt de site wél dat dat mijn session_id is.
Korter gezegd: hij pakt niet de sessie data uit mijn database, maar php denkt wel dat session_id() de gestolen cookie is.
Ook worden wel updates doorgevoerd aan de sessie, in mijn geval de "last_access" veld, wordt wel elke keer geupdate.
Als 'oplossing' wilde ik in mijn read() functie de fingerprint uit de database halen, en in mijn init() vergelijken met de echte fingerprint(). Als deze niet overeenkomen, de sessie vernietigen. Hier zitten alleen een paar haken en ogen aan.
De eerste is dat het eigenlijk helemaal niet werkt:
Iemand een wél idee hoe ik dit fatsoenlijk werkend kan oplossen?
Eigenlijk het volgende; ik heb gekozen om een eigen session handler te gebruiken i.c.m. een database. Heb hier t internet enige tijd op nagezocht en een beetje de puzzelstukjes aan elkaar verbonden. Heb daarmee de volgende class gemaakt.
init() functie is de constructor die door mijn framework wordt aangeroepen
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
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
| class session { public $core; private $sess_print; public function init() { session_set_save_handler ( array(&$this, 'open'), array(&$this, 'close'), array(&$this, 'read'), array(&$this, 'write'), array(&$this, 'destroy'), array(&$this, 'gc') ); session_start(); /* Werkt niet, omdat er bij het eerste bezoek nog geen sessie in de database staat Dus hij destroyt hem altijd > gevolg is dat er nooit een sessie komt */ if( $this->fingerprint() != $this->sess_print) { //session_destroy(); //even uitgecomment, omdat t toch niet werkt } } private function fingerprint() { $print = @$_SERVER['HTTP_USER_AGENT'].'ennogwatzooi'; return sha1($print); } public function get($key) { if( isset($_SESSION[$key]) ) { return $_SESSION[$key]; } else { return false; } } public function delete_cookie() { setcookie(session_name(), '', -99999); } public function open($path, $name) { return true; } public function close() { return true; } public function read($sid) { $query = $this->core->db->prepare( " SELECT id, data, fingerprint, last_access FROM sessions WHERE id = :sess_id AND fingerprint = :print LIMIT 1 "); $query->bindParam(':sess_id', $sid, PDO::PARAM_INT); $query->bindParam(':print', $this->fingerprint(), PDO::PARAM_STR); $query->execute(); if( $query->rowCount() == 1 ) { $f = $query->fetch(PDO::FETCH_ASSOC); /* fingerprint in een variable zetten zodat we in de init() kunnen controleren of die overeenkomt */ $this->sess_print = $f['fingerprint']; return $f['data']; } else { return false; } } public function write($sid, $data) { $query = $this->core->db->prepare( " INSERT INTO sessions SET id = :sess_id, data = :sess_data, last_access = UNIX_TIMESTAMP(), fingerprint = :print, ip = :ip ON DUPLICATE KEY UPDATE last_access = UNIX_TIMESTAMP() "); $query->bindParam(':sess_id', $sid, PDO::PARAM_STR); $query->bindParam(':sess_data', $data, PDO::PARAM_STR); $query->bindParam(':print', $this->fingerprint(), PDO::PARAM_STR); $query->bindParam(':ip', $_SERVER['REMOTE_ADDR'], PDO::PARAM_STR); return $query->execute(); } public function destroy($sid) { $query = $this->core->db->prepare( " DELETE FROM sessions WHERE id = :sess_id LIMIT 1 "); $query->bindParam(':sess_id', $sid, PDO::PARAM_STR); return $query->execute(); } public function gc($lifetime) { $time = time() - $lifetime; $query = $this->core->db->prepare( " DELETE FROM sessions WHERE last_access < :time LIMIT 1 "); $query->bindParam(':time', $time, PDO::PARAM_INT); return $query->execute(); } } |
Dit spreekt denk ik wel voor zich, maar als er iets onduidelijk is hoor ik het graag.
Het komt er in feite op neer dat ik de sessie aan een 'fingerprint' wil koppelen. Zodat als er -hoe dan ook- een sessie gestolen wordt (dmv cookie stelen oid) diegene daar niks mee kan.
Dit werkt nu een beetje, de query in mijn read() functie heeft dat al als voorwaarde. Alleen als ik de sessie cookie van de ene browser kopieër naar de andere browser, denkt de site wél dat dat mijn session_id is.
Korter gezegd: hij pakt niet de sessie data uit mijn database, maar php denkt wel dat session_id() de gestolen cookie is.
Ook worden wel updates doorgevoerd aan de sessie, in mijn geval de "last_access" veld, wordt wel elke keer geupdate.
Als 'oplossing' wilde ik in mijn read() functie de fingerprint uit de database halen, en in mijn init() vergelijken met de echte fingerprint(). Als deze niet overeenkomen, de sessie vernietigen. Hier zitten alleen een paar haken en ogen aan.
De eerste is dat het eigenlijk helemaal niet werkt:
De tweede is dat als dit zou werken, de sessie voor de 'echte' gebruiker ook verloren gaat, waardoor hij/zij een nieuwe sessie krijgt (cq opnieuw moet inloggen).Werkt niet, omdat er bij het eerste bezoek nog geen sessie in de database staat
Dus hij destroyt hem altijd > gevolg is dat er nooit een sessie komt
Iemand een wél idee hoe ik dit fatsoenlijk werkend kan oplossen?