Skip to content

Commit

Permalink
fix: rename all instances of csrf into xsrf
Browse files Browse the repository at this point in the history
  • Loading branch information
CorentinDeBoisset committed Jan 14, 2024
1 parent 85031b6 commit fd22151
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 23 deletions.
2 changes: 1 addition & 1 deletion pyneutrino/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def get_config():
config = {
"SESSION_COOKIE_SAMESITE": "Strict",
"SECRET_KEY": "secret-key",
"CSRF_TOKEN_SALT": "csrf-salt",
"XSRF_TOKEN_SALT": "xsrf-salt",
"SQLALCHEMY_DATABASE_URI": "postgresql://neutrino:[email protected]:5432/neutrino",
"REDIS_URI": "redis://localhost:6379",
}
Expand Down
4 changes: 2 additions & 2 deletions pyneutrino/hooks/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from flask import Flask
from .csrf import CsrfBp
from .xsrf import XsrfBp

# These are dummy blueprints, to register global hooks using
# the @bp.before_app_request and @bp.after_app_request decorators


def register(app: Flask):
app.register_blueprint(CsrfBp)
app.register_blueprint(XsrfBp)
36 changes: 18 additions & 18 deletions pyneutrino/hooks/csrf.py → pyneutrino/hooks/xsrf.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,48 @@
from itsdangerous.serializer import BadSignature
from itsdangerous.url_safe import URLSafeSerializer

CsrfBp = Blueprint("csrf", __name__)
XsrfBp = Blueprint("xsrf", __name__)

# This module implements CSRF protection
# This module implements XSRF protection
# See more information here:
# * https://angular.io/guide/http-security-xsrf-protection
# * https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html


def check_token(header_value: str, expected_value: str):
"""Checks the validity of a given CSRF token.
"""Checks the validity of a given XSRF token.
This function must be called within a request context,
the SECRET_KEY and CSRF_TOKEN_SALT configuration keys must be set on the current Flask app.
the SECRET_KEY and XSRF_TOKEN_SALT configuration keys must be set on the current Flask app.
:param header_value: The value of the CSRF token sent by the user in a header.
:param header_value: The value of the XSRF token sent by the user in a header.
:param expected_value: The used to serialize the token
"""
if current_app.config.get("DISABLE_CSRF", False):
if current_app.config.get("DISABLE_XSRF", False):
return

s = URLSafeSerializer(current_app.config["SECRET_KEY"])

try:
value = s.loads(header_value, current_app.config["CSRF_TOKEN_SALT"])
value = s.loads(header_value, current_app.config["XSRF_TOKEN_SALT"])
except BadSignature:
session.clear()
raise Unauthorized("Invalid CSRF Token")
raise Unauthorized("Invalid XSRF Token")

if value != expected_value:
session.clear()
raise Unauthorized("Invalid CSRF Token")
raise Unauthorized("Invalid XSRF Token")


@CsrfBp.before_app_request
def check_csrf_token():
if current_app.config.get("DISABLE_CSRF", False):
@XsrfBp.before_app_request
def check_xsrf_token():
if current_app.config.get("DISABLE_XSRF", False):
return

# Skip CSRF token validation on non-mutating requests
# Skip XSRF token validation on non-mutating requests
if request.method in ("GET", "HEAD"):
return

# Skip CSRF token validation if there is no session
# Skip XSRF token validation if there is no session
if "user_id" not in session and "session_id" not in session:
return

Expand All @@ -56,18 +56,18 @@ def check_csrf_token():
xsrf_token_header = request.headers.get("X-XSRF-TOKEN", default=None)
if xsrf_token_header is None:
session.clear()
raise Unauthorized("A CSRF token must be sent in the X-XSRF-TOKEN header")
raise Unauthorized("A XSRF token must be sent in the X-XSRF-TOKEN header")

check_token(xsrf_token_header, session["session_id"])


@CsrfBp.after_app_request
@XsrfBp.after_app_request
def generate_csr_token(res: Response):
if "user_id" in session and "session_id" in session:
# If there is a session, we ensure there is a CSRF Token in the Cookie
# If there is a session, we ensure there is a XSRF Token in the Cookie
if "XSRF-TOKEN" not in request.cookies:
s = URLSafeSerializer(current_app.config["SECRET_KEY"])
token = s.dumps(session["session_id"], current_app.config["CSRF_TOKEN_SALT"])
token = s.dumps(session["session_id"], current_app.config["XSRF_TOKEN_SALT"])
res.set_cookie("XSRF-TOKEN", value=str(token), samesite="Strict")
else:
# If there is no session, we ensure the cookie is cleaned up
Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def app(alembic_runner):
{
"TESTING": True,
"SQLALCHEMY_DATABASE_URI": SQLALCHEMY_DATABASE_URI,
"DISABLE_CSRF": True,
"DISABLE_XSRF": True,
}
)

Expand Down
2 changes: 1 addition & 1 deletion tests/test_xsrf.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,4 @@ def test_invalid_xsrf(alembic_runner):
# Test a post request without the token
res = client.post("/api/auth/session/logout")
assert res.status_code == 401
assert res.json["description"] == "A CSRF token must be sent in the X-XSRF-TOKEN header"
assert res.json["description"] == "A XSRF token must be sent in the X-XSRF-TOKEN header"

0 comments on commit fd22151

Please sign in to comment.