1<?php 2 /* Copyright (c) by Hugo Leisink <hugo@leisink.net> 3 * This file is part of the Banshee PHP framework 4 * https://www.banshee-php.org/ 5 * 6 * Licensed under The MIT License 7 */ 8 9 class prevent_CSRF { 10 const TOKEN_KEY = "banshee_csrf"; 11 12 private $page = null; 13 private $user = null; 14 private $output = null; 15 16 /* Constructor 17 * 18 * INPUT: object page, object user, object output 19 * OUTPUT: - 20 * ERROR: - 21 */ 22 public function __construct($page, $user, $output) { 23 $this->page = $page; 24 $this->user = $user; 25 $this->output = $output; 26 } 27 28 /* Prevent CSRF attack 29 * 30 * INPUT: - 31 * OUTPUT: - 32 * ERROR: - 33 */ 34 public function execute() { 35 if ($this->page->module == "setup") { 36 return false; 37 } 38 39 if (isset($_SESSION[self::TOKEN_KEY]) == false) { 40 $_SESSION[self::TOKEN_KEY] = random_string(32); 41 } 42 43 $token = hash("sha256", $_SESSION[self::TOKEN_KEY].$this->user->username); 44 45 $this->output->add_javascript("banshee/prevent_csrf.js"); 46 $this->output->run_javascript("prevent_csrf('".self::TOKEN_KEY."', '".$token."')"); 47 48 if (($_SERVER["REQUEST_METHOD"] != "POST") || $this->page->ajax_request) { 49 return; 50 } 51 52 if ($_POST[self::TOKEN_KEY] == $token) { 53 return; 54 } 55 56 /* CSRF attack detected 57 */ 58 if (isset($_SERVER["HTTP_ORIGIN"])) { 59 $referer = $_SERVER["HTTP_ORIGIN"]; 60 } else if (isset($_SERVER["HTTP_REFERER"])) { 61 $referer = $_SERVER["HTTP_REFERER"]; 62 } else { 63 $referer = "previous visited website"; 64 } 65 66 $message = "CSRF attempt via %s blocked"; 67 $this->output->add_system_warning($message, $referer); 68 $this->user->log_action($message, $referer); 69 $this->user->logout(); 70 71 $_SERVER["REQUEST_METHOD"] = "GET"; 72 $_GET = array(); 73 $_POST = array(); 74 } 75 } 76?> 77