diff --git a/application/controllers/Station.php b/application/controllers/Station.php index 8ef8e3e46..7b89a8ff9 100644 --- a/application/controllers/Station.php +++ b/application/controllers/Station.php @@ -66,21 +66,16 @@ class Station extends CI_Controller $data['oqrs'] = $this->input->post('oqrs'); $data['oqrsemail'] = $this->input->post('oqrsemail'); $data['oqrstext'] = $this->input->post('oqrstext'); - $csrf_token = bin2hex(random_bytes(32)); - $this->session->set_userdata('csrf_station_create', $csrf_token); - $data['csrf_token'] = $csrf_token; + $data['csrf_token'] = $this->paths->csrf_generate('csrf_station_create'); $this->load->view('interface_assets/header', $data); $this->load->view('station_profile/create', $data); $this->load->view('interface_assets/footer'); } else { - $submitted = $this->input->post('csrf_token', TRUE); - $stored = $this->session->userdata('csrf_station_create'); - if (empty($submitted) || empty($stored) || !hash_equals($stored, $submitted)) { + if (!$this->paths->csrf_verify('csrf_station_create')) { $this->session->set_flashdata('error', __("Invalid security token")); redirect('station/create'); return; } - $this->session->set_userdata('csrf_station_create', bin2hex(random_bytes(32))); $this->stations->add(); redirect('stationsetup'); } @@ -96,21 +91,16 @@ class Station extends CI_Controller $this->form_validation->set_rules('dxcc', 'DXCC', 'required'); $this->form_validation->set_rules('gridsquare', 'Locator', 'callback_check_locator'); if ($this->form_validation->run() == FALSE) { - $csrf_token = bin2hex(random_bytes(32)); - $this->session->set_userdata('csrf_station_edit', $csrf_token); - $data['csrf_token'] = $csrf_token; + $data['csrf_token'] = $this->paths->csrf_generate('csrf_station_edit'); $this->load->view('interface_assets/header', $data); $this->load->view('station_profile/edit', $data); $this->load->view('interface_assets/footer'); } else { - $submitted = $this->input->post('csrf_token', TRUE); - $stored = $this->session->userdata('csrf_station_edit'); - if (empty($submitted) || empty($stored) || !hash_equals($stored, $submitted)) { + if (!$this->paths->csrf_verify('csrf_station_edit')) { $this->session->set_flashdata('error', __("Invalid security token")); redirect('station/edit/' . $id); return; } - $this->session->set_userdata('csrf_station_edit', bin2hex(random_bytes(32))); if ($this->stations->edit()) { $data['notice'] = __("Station Location") . $this->security->xss_clean($this->input->post('station_profile_name', true)) . " Updated"; diff --git a/application/controllers/User.php b/application/controllers/User.php index 19dd7e356..a7b870da5 100644 --- a/application/controllers/User.php +++ b/application/controllers/User.php @@ -1088,9 +1088,7 @@ class User extends CI_Controller { if ($this->form_validation->run() == FALSE) { - $csrf_token = bin2hex(random_bytes(32)); - $this->session->set_userdata('csrf_user_delete', $csrf_token); - $data->csrf_token = $csrf_token; + $data->csrf_token = $this->paths->csrf_generate('csrf_user_delete'); $this->load->view('interface_assets/header', $data); $this->load->view('user/delete'); @@ -1098,14 +1096,11 @@ class User extends CI_Controller { } else { - $submitted = $this->input->post('csrf_token', TRUE); - $stored = $this->session->userdata('csrf_user_delete'); - if (empty($submitted) || empty($stored) || !hash_equals($stored, $submitted)) { + if (!$this->paths->csrf_verify('csrf_user_delete')) { $this->session->set_flashdata('error', __("Invalid security token")); redirect('user'); return; } - $this->session->set_userdata('csrf_user_delete', bin2hex(random_bytes(32))); if($this->user_model->delete($data->user_id)) { diff --git a/application/libraries/Paths.php b/application/libraries/Paths.php index 1b86af470..6c5b3e6f3 100644 --- a/application/libraries/Paths.php +++ b/application/libraries/Paths.php @@ -33,6 +33,32 @@ class Paths return $datadir . "/" . $path; } + /** + * Generate a CSRF token, store it in the session under $key, and return it + * for injection into view data. + */ + function csrf_generate($key) { + $CI = &get_instance(); + $token = bin2hex(random_bytes(32)); + $CI->session->set_userdata($key, $token); + return $token; + } + + /** + * Verify the submitted csrf_token POST field against the session value for + * $key. Rotates the token on success. Returns true on success, false on failure. + */ + function csrf_verify($key) { + $CI = &get_instance(); + $submitted = $CI->input->post('csrf_token', TRUE); + $stored = $CI->session->userdata($key); + if (empty($submitted) || empty($stored) || !hash_equals($stored, $submitted)) { + return false; + } + $CI->session->set_userdata($key, bin2hex(random_bytes(32))); + return true; + } + function cache_buster($filepath) { // make sure $filepath starts with a slash if (substr($filepath, 0, 1) !== '/') $filepath = '/' . $filepath;