File TODO changed (mode: 100644) (index 59dfe3d..a503461) |
... |
... |
e-mail to him. Or I may comment on LWN or "PEP 474". |
7 |
7 |
Find a way to distribute this code and a way to support it in rg. |
Find a way to distribute this code and a way to support it in rg. |
8 |
8 |
Probably I will allow only one plan (Friends) till they all create |
Probably I will allow only one plan (Friends) till they all create |
9 |
9 |
accounts. After this, I will remove this plan? |
accounts. After this, I will remove this plan? |
|
10 |
|
[ ] CSRF for logout. Seems is not so easy because I need to generate a token |
|
11 |
|
all the time to embed it in the logout link. Another possibility |
|
12 |
|
is to have a form on the logout page. But some people probably will |
|
13 |
|
assume that pressing the logout link is enough and will not press |
|
14 |
|
the logout _button_. A signed token is enough, if I prepare it special |
|
15 |
|
for logout. It is important to work only there. And, I can embed it in |
|
16 |
|
the link. |
|
17 |
|
Anyway, I can link all tokens with the forms and I can store them in |
|
18 |
|
db when they are used, so we cannot use them anymore. This way I do not |
|
19 |
|
have to save them in database at generation time. |
|
20 |
|
What is the problem with the token?! Double post? And using same token |
|
21 |
|
for two forms? |
|
22 |
|
[ ] If email is not confirmed, do not send e-mail! |
|
23 |
|
[ ] Now, we gen generate tokens without storing in database, and store tokens |
|
24 |
|
in db only after they are used. In rg_token_valid, we will check if it |
|
25 |
|
was already used, after we check the signing. |
|
26 |
|
generate_token |
|
27 |
|
user post form |
|
28 |
|
we insert it in db => ok |
|
29 |
|
user post it again |
|
30 |
|
we insert it in db => get error! |
|
31 |
|
this means was already used it |
|
32 |
|
abort |
|
33 |
|
continue work |
|
34 |
|
What I have to change: |
|
35 |
|
- rg_token_get must return a signed token. Maybe we add the form id to |
|
36 |
|
the equation. |
|
37 |
|
- rg_token_valid: we insert it in db as used, return FALSE if we get |
|
38 |
|
an error. We need to know if db failed or we could not |
|
39 |
|
insert because of already present key |
|
40 |
|
- get rid of tokens.used field. What about expiration? |
|
41 |
|
|
10 |
42 |
[ ] |
[ ] |
11 |
43 |
|
|
12 |
44 |
== BEFORE NEXT RELEASE == |
== BEFORE NEXT RELEASE == |
|
45 |
|
[ ] Check cache socket is protected agains other users. |
13 |
46 |
[ ] Ce se intimpla daca un atacator seteaza un cookie pe .com, de exemplu. |
[ ] Ce se intimpla daca un atacator seteaza un cookie pe .com, de exemplu. |
14 |
47 |
El se va trimite si pe rocketgit.com. Deci, daca user-ul viziteaza site-ul |
El se va trimite si pe rocketgit.com. Deci, daca user-ul viziteaza site-ul |
15 |
48 |
atacatorului, se seteaza acest cookie, care apoi va fi trimis catre rg.com. |
atacatorului, se seteaza acest cookie, care apoi va fi trimis catre rg.com. |
File inc/token.inc.php changed (mode: 100644) (index 1b8f04b..ecf6f7e) |
... |
... |
function rg_token_valid($db, $rg) |
138 |
138 |
$rand = substr($rg['token'], 0, 16); |
$rand = substr($rg['token'], 0, 16); |
139 |
139 |
$search = $rand . $ua_hash; |
$search = $rand . $ua_hash; |
140 |
140 |
$params = array("sid" => $rg['sid'], "token" => $search); |
$params = array("sid" => $rg['sid'], "token" => $search); |
141 |
|
$sql = "SELECT 1 AS junk FROM tokens" |
|
|
141 |
|
$sql = "UPDATE tokens SET used = 1" |
142 |
142 |
. " WHERE token = @@token@@" |
. " WHERE token = @@token@@" |
143 |
|
. " AND sid = @@sid@@"; |
|
|
143 |
|
. " AND sid = @@sid@@" |
|
144 |
|
. " AND used = 0"; |
144 |
145 |
$res = rg_sql_query_params($db, $sql, $params); |
$res = rg_sql_query_params($db, $sql, $params); |
145 |
146 |
if ($res === FALSE) { |
if ($res === FALSE) { |
146 |
147 |
rg_token_set_error("cannot get token (" . rg_sql_error() . ")"); |
rg_token_set_error("cannot get token (" . rg_sql_error() . ")"); |
147 |
148 |
break; |
break; |
148 |
149 |
} |
} |
149 |
150 |
|
|
150 |
|
$rows = rg_sql_num_rows($res); |
|
|
151 |
|
$rows = rg_sql_affected_rows($res); |
151 |
152 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
152 |
153 |
if ($rows == 0) |
if ($rows == 0) |
153 |
154 |
break; |
break; |
|
... |
... |
function rg_token_insert($db, $sid, $token) |
199 |
200 |
|
|
200 |
201 |
/* |
/* |
201 |
202 |
* Returns a token to be used on a form/url |
* Returns a token to be used on a form/url |
202 |
|
* We generate only one per session. |
|
|
203 |
|
* We generate only one per form, but multiple per session. |
203 |
204 |
*/ |
*/ |
204 |
205 |
$rg_token = FALSE; |
$rg_token = FALSE; |
205 |
206 |
function rg_token_get($db, $rg) |
function rg_token_get($db, $rg) |
File tests/token.php changed (mode: 100644) (index f384d12..2fac7ce) |
... |
... |
rg_log_set_file("token.log"); |
14 |
14 |
$rg_no_db = TRUE; |
$rg_no_db = TRUE; |
15 |
15 |
require_once("common.php"); |
require_once("common.php"); |
16 |
16 |
|
|
17 |
|
$sid = "session1"; |
|
18 |
|
$token = rg_token_get($db, $sid, "user-agent1"); |
|
|
17 |
|
$a = array("ua" => "user-agent1", "sid" => "session1"); |
|
18 |
|
$token = rg_token_get($db, $a); |
19 |
19 |
if ($token === FALSE) { |
if ($token === FALSE) { |
20 |
20 |
rg_log("Generating a token should not fail (" . rg_token_error() . ")!"); |
rg_log("Generating a token should not fail (" . rg_token_error() . ")!"); |
21 |
21 |
exit(1); |
exit(1); |
22 |
22 |
} |
} |
23 |
23 |
rg_log("Correct token: $token"); |
rg_log("Correct token: $token"); |
24 |
24 |
|
|
25 |
|
$a = array("sid" => $sid, "token" => $token); |
|
|
25 |
|
$a['token'] = $token; |
26 |
26 |
$r = rg_token_valid($db, $a); |
$r = rg_token_valid($db, $a); |
27 |
27 |
if ($r === FALSE) { |
if ($r === FALSE) { |
28 |
28 |
rg_log("Validating a correct token must work (" . rg_token_error() . ")!"); |
rg_log("Validating a correct token must work (" . rg_token_error() . ")!"); |
29 |
29 |
exit(1); |
exit(1); |
30 |
30 |
} |
} |
31 |
31 |
|
|
32 |
|
$r = rg_token_delete($db, $sid, $token); |
|
|
32 |
|
$r = rg_token_delete($db, $a['sid'], $a['token']); |
33 |
33 |
if ($r['ok'] != 1) { |
if ($r['ok'] != 1) { |
34 |
34 |
rg_log("We should be able to delete a token!"); |
rg_log("We should be able to delete a token!"); |
35 |
35 |
exit(1); |
exit(1); |
36 |
36 |
} |
} |
37 |
37 |
|
|
38 |
|
$a = array("sid" => $sid, "token" => $token); |
|
39 |
38 |
$r = rg_token_valid($db, $a); |
$r = rg_token_valid($db, $a); |
40 |
39 |
if ($r !== FALSE) { |
if ($r !== FALSE) { |
41 |
40 |
rg_log("Token should not be available after delete!"); |
rg_log("Token should not be available after delete!"); |
|
... |
... |
if ($r !== FALSE) { |
45 |
44 |
|
|
46 |
45 |
rg_log("Now, test pre-login sessions..."); |
rg_log("Now, test pre-login sessions..."); |
47 |
46 |
$rg_token = FALSE; /* we must remove it from memory */ |
$rg_token = FALSE; /* we must remove it from memory */ |
48 |
|
$sid = "Xsession2"; |
|
49 |
|
$token = rg_token_get($db, $sid, "user-agent1"); |
|
|
47 |
|
$a = array("ua" => "user-agent1", "sid" => "Xsession2"); |
|
48 |
|
$token = rg_token_get($db, $a); |
50 |
49 |
if ($token === FALSE) { |
if ($token === FALSE) { |
51 |
50 |
rg_log("Generating a token should not fail (" . rg_token_error() . ")!"); |
rg_log("Generating a token should not fail (" . rg_token_error() . ")!"); |
52 |
51 |
exit(1); |
exit(1); |
53 |
52 |
} |
} |
54 |
53 |
rg_log("Correct token: $token"); |
rg_log("Correct token: $token"); |
|
54 |
|
$a['token'] = $token; |
55 |
55 |
|
|
56 |
|
$copy = "y" . substr($token, 1); |
|
57 |
|
$a = array("sid" => $sid, "token" => $token); |
|
58 |
|
$r = rg_token_valid($db, $a); |
|
|
56 |
|
$copy = $a; |
|
57 |
|
$copy['token'] = "y" . substr($a['token'], 1); |
|
58 |
|
$r = rg_token_valid($db, $copy); |
59 |
59 |
if ($r !== FALSE) { |
if ($r !== FALSE) { |
60 |
60 |
rg_log("An altered token must return error!"); |
rg_log("An altered token must return error!"); |
61 |
61 |
exit(1); |
exit(1); |
62 |
62 |
} |
} |
63 |
63 |
|
|
64 |
|
$a = array("sid" => $sid, "token" => $token); |
|
65 |
64 |
$r = rg_token_valid($db, $a); |
$r = rg_token_valid($db, $a); |
66 |
65 |
if ($r === FALSE) { |
if ($r === FALSE) { |
67 |
66 |
rg_log("Validating a correct token must work (" . rg_token_error() . ")!"); |
rg_log("Validating a correct token must work (" . rg_token_error() . ")!"); |
68 |
67 |
exit(1); |
exit(1); |
69 |
68 |
} |
} |
70 |
69 |
|
|
71 |
|
echo "token: OK!\n"; |
|
|
70 |
|
|
|
71 |
|
rg_log("Testing double posting..."); |
|
72 |
|
$rg_token = FALSE; /* we must remove it from memory */ |
|
73 |
|
$a = array("ua" => "user-agent3", |
|
74 |
|
"sid" => "session_double"); |
|
75 |
|
$token = rg_token_get($db, $a); |
|
76 |
|
if ($token === FALSE) { |
|
77 |
|
rg_log("Generating a token should not fail (" . rg_token_error() . ")!"); |
|
78 |
|
exit(1); |
|
79 |
|
} |
|
80 |
|
$a['token'] = $token; |
|
81 |
|
|
|
82 |
|
$r = rg_token_valid($db, $a); |
|
83 |
|
if ($r === FALSE) { |
|
84 |
|
rg_log("Calling 'valid' first time must work!"); |
|
85 |
|
exit(1); |
|
86 |
|
} |
|
87 |
|
$r = rg_token_valid($db, $a); |
|
88 |
|
if ($r !== FALSE) { |
|
89 |
|
rg_log("Calling 'valid' second time must NOT work!"); |
|
90 |
|
exit(1); |
|
91 |
|
} |
|
92 |
|
|
|
93 |
|
rg_log("OK!"); |
72 |
94 |
?> |
?> |