Allow to change the key of CSRF token in a session.

This commit is contained in:
Eitaro Fukamachi 2018-04-12 17:20:55 +09:00
parent 23c372594b
commit 9ae2c5df7c

View file

@ -11,23 +11,27 @@
:csrf-html-tag)) :csrf-html-tag))
(in-package :lack.middleware.csrf) (in-package :lack.middleware.csrf)
(defvar *csrf-token-key*)
(defparameter *lack-middleware-csrf* (defparameter *lack-middleware-csrf*
(lambda (app &key (block-app #'return-400) one-time) (lambda (app &key (block-app #'return-400) one-time
(csrf-token-key :csrf-token))
(lambda (env) (lambda (env)
(block nil (let ((*csrf-token-key* csrf-token-key))
(unless (danger-method-p (getf env :request-method)) (block nil
(return (funcall app env))) (unless (danger-method-p (getf env :request-method))
(return (funcall app env)))
(let ((session (getf env :lack.session))) (let ((session (getf env :lack.session)))
(unless session (unless session
(error ":lack.session is missing in ENV. Wrap this app up with lack.middleware.session")) (error ":lack.session is missing in ENV. Wrap this app up with lack.middleware.session"))
(if (valid-token-p env) (if (valid-token-p env)
(progn (progn
(when one-time (when one-time
(remhash :csrf-token session)) (remhash csrf-token-key session))
(funcall app env)) (funcall app env))
(funcall block-app env)))))) (funcall block-app env)))))))
"Middleware for easy CSRF protection") "Middleware for easy CSRF protection")
(defun return-400 (env) (defun return-400 (env)
@ -44,7 +48,7 @@
(defun valid-token-p (env) (defun valid-token-p (env)
(let ((req (make-request env)) (let ((req (make-request env))
(csrf-token (gethash :csrf-token (csrf-token (gethash *csrf-token-key*
(getf env :lack.session)))) (getf env :lack.session))))
(and csrf-token (and csrf-token
(let ((recieved-csrf-token (let ((recieved-csrf-token
@ -52,9 +56,9 @@
(string= csrf-token recieved-csrf-token))))) (string= csrf-token recieved-csrf-token)))))
(defun csrf-token (session) (defun csrf-token (session)
(unless (gethash :csrf-token session) (unless (gethash *csrf-token-key* session)
(setf (gethash :csrf-token session) (generate-random-id))) (setf (gethash *csrf-token-key* session) (generate-random-id)))
(gethash :csrf-token session)) (gethash *csrf-token-key* session))
(defun csrf-html-tag (session) (defun csrf-html-tag (session)
(format nil "<input type=\"hidden\" name=\"_csrf_token\" value=\"~A\">" (format nil "<input type=\"hidden\" name=\"_csrf_token\" value=\"~A\">"