diff --git a/src/Pluf/Middleware/Csrf.php b/src/Pluf/Middleware/Csrf.php new file mode 100644 index 0000000..a898d42 --- /dev/null +++ b/src/Pluf/Middleware/Csrf.php @@ -0,0 +1,121 @@ +method != 'POST') { + return false; + } + $cookie_name = Pluf::f('session_cookie_id', 'sessionid'); + if (!isset($request->COOKIE[$cookie_name])) { + // no session, nothing to do + return false; + } + try { + $data = Pluf_Middleware_Session::_decodeData($request->COOKIE[$cookie_name]); + } catch (Exception $e) { + // no valid session + return false; + } + if (!isset($data['Pluf_Session_key'])) { + // no session key + return false; + } + $token = self::makeToken($data['Pluf_Session_key']); + if (!isset($request->POST['csrfmiddlewaretoken'])) { + return new Pluf_HTTP_Response_Forbidden($request); + } + if ($request->POST['csrfmiddlewaretoken'] != $token) { + return new Pluf_HTTP_Response_Forbidden($request); + } + return false; + } + + /** + * Process the response of a view. + * + * If we find a POST form, add the token to it. + * + * @param Pluf_HTTP_Request The request + * @param Pluf_HTTP_Response The response + * @return Pluf_HTTP_Response The response + */ + function process_response($request, $response) + { + $cookie_name = Pluf::f('session_cookie_id', 'sessionid'); + if (!isset($request->COOKIE[$cookie_name])) { + // no session, nothing to do + return $response; + } + try { + $data = Pluf_Middleware_Session::_decodeData($request->COOKIE[$cookie_name]); + } catch (Exception $e) { + // no valid session + return $response; + } + if (!isset($data['Pluf_Session_key'])) { + // no session key + return $response; + } + $ok = false; + $cts = array('text/html', 'application/xhtml+xml'); + foreach ($cts as $ct) { + if (false !== strripos($response->headers['Content-Type'], $ct)) { + $ok = true; + break; + } + } + if (!$ok) { + return $response; + } + $token = self::makeToken($data['Pluf_Session_key']); + $extra = '
'; + $response->content = preg_replace('/(]*\bmethod=(\'|"|)POST(\'|"|)\b[^>]*>)/i', '$1'.$extra, $response->content); + return $response; + } +} \ No newline at end of file