Skip to content

Commit fc60dc1

Browse files
committed
feat(a2): implement preflight
1 parent 3e6e499 commit fc60dc1

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed

a2/resources.php

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,96 @@
120120
*/
121121
function preflight(&$request, &$response, &$db, &$pdo)
122122
{
123+
$is_new_sessionid_required = false;
124+
$sessionid = $request->cookie("sessionid");
125+
126+
// Check if sessionid is in cookies
127+
if ($sessionid) {
128+
$get_web_session_info_by_sessionid = $db->get_web_session_info_by_sessionid;
129+
$get_web_session_info_by_sessionid->execute(array('sessionid' => $sessionid));
130+
$web_session = $get_web_session_info_by_sessionid->fetch();
131+
132+
// Check if sessionid exists in db and is not expired
133+
if ($web_session && new DateTime() < date_create_from_format(DateTimeInterface::ISO8601, $web_session["expires"])) {
134+
$csrf_token = $request->token("csrf_token");
135+
136+
// Check if csrf_token exists and if it is valid, update expires
137+
if ($csrf_token && $csrf_token === $web_session["metadata"]) {
138+
$expires = new DateTime("+30 minutes");
139+
$expires = $expires->format(DateTimeInterface::ISO8601);
140+
141+
$result = $db->update_web_session_info_by_sessionid->execute(array(
142+
'expires' => $expires,
143+
'sessionid' => $sessionid
144+
));
145+
146+
if (!$result) {
147+
$response->set_http_code(500);
148+
$response->failure("Failed to load.");
149+
log_to_console("Cannot update web session in database.");
150+
151+
return false;
152+
}
153+
154+
log_to_console("Updated web session!");
155+
} else {
156+
// This is possible CSRF, void session, reject request and log client IP
157+
$expires = new DateTime("-30 minutes");
158+
$expires = $expires->format(DateTimeInterface::ISO8601);
159+
160+
$result = $db->update_web_session_info_by_sessionid->execute(array(
161+
'expires' => $expires,
162+
'sessionid' => $sessionid
163+
));
164+
165+
if (!$result) {
166+
$response->set_http_code(500);
167+
$response->failure("Failed to load.");
168+
log_to_console("Cannot void web session in database.");
169+
170+
return false;
171+
}
172+
173+
$response->set_http_code(403);
174+
$response->failure("Request Failed");
175+
log_to_console("Possible CSRF from " . $request->client_ip() . "!");
176+
177+
return false;
178+
}
179+
} else {
180+
$is_new_sessionid_required = true;
181+
}
182+
} else {
183+
$is_new_sessionid_required = true;
184+
}
185+
186+
if ($is_new_sessionid_required) {
187+
// Create new sessionid and csrf_token
188+
$sessionid = trim(get_GUID(), '{}');
189+
$expires = new DateTime("+30 minutes");
190+
$expires = $expires->format(DateTimeInterface::ISO8601);
191+
$csrf_token = trim(get_GUID(), '{}');
192+
193+
$result = $db->create_web_session_info->execute(array(
194+
'sessionid' => $sessionid,
195+
'expires' => $expires,
196+
'metadata' => $csrf_token
197+
));
198+
199+
if (!$result) {
200+
$response->set_http_code(500);
201+
$response->failure("Failed to load.");
202+
log_to_console("Cannot create web session in database.");
203+
204+
return false;
205+
}
206+
207+
$response->add_cookie("sessionid", $sessionid);
208+
$response->set_token("csrf_token", $csrf_token);
209+
210+
log_to_console("New web session created.");
211+
}
212+
123213
$response->set_http_code(200);
124214
$response->success("Request OK");
125215
log_to_console("OK");
@@ -343,3 +433,18 @@ function logout(&$request, &$response, &$db, &$pdo)
343433

344434
return true;
345435
}
436+
437+
// http://guid.us/GUID/PHP
438+
function get_GUID()
439+
{
440+
$charid = strtoupper(md5(uniqid(rand(), true)));
441+
$hyphen = chr(45); // "-"
442+
$uuid = chr(123) // "{"
443+
. substr($charid, 0, 8) . $hyphen
444+
. substr($charid, 8, 4) . $hyphen
445+
. substr($charid, 12, 4) . $hyphen
446+
. substr($charid, 16, 4) . $hyphen
447+
. substr($charid, 20, 12)
448+
. chr(125); // "}"
449+
return $uuid;
450+
}

a2/server.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ public function __call($method, $arguments)
5454
// create PDO prepared statements
5555
$db = new stdObject();
5656

57+
// preflight
58+
$db->get_web_session_info_by_sessionid = $pdo->prepare("SELECT * FROM web_session WHERE sessionid = :sessionid");
59+
$db->update_web_session_info_by_sessionid = $pdo->prepare("UPDATE web_session SET expires = :expires WHERE sessionid = :sessionid");
60+
$db->create_web_session_info = $pdo->prepare("INSERT INTO web_session (sessionid, expires, metadata) VALUES (:sessionid, :expires, :metadata)");
61+
5762
// signup
5863
$db->create_user = $pdo->prepare("INSERT INTO user (username, passwd, email, valid, modified) VALUES (:username, :passwd, :email, TRUE, :modified)");
5964
$db->create_login_info = $pdo->prepare("INSERT INTO user_login (username, salt, challenge, expires) VALUES (:username, :salt, NULL, NULL)");

0 commit comments

Comments
 (0)