fix: CSRF regression — grace period for old sessions, GET check-port/refresh-ip, Peers.jsx native fetch tokens

- check_csrf() now issues a token for sessions that predate CSRF (existing logins) instead of blocking them
- /api/wireguard/check-port and /api/wireguard/refresh-ip accept GET so native fetch calls bypass the token requirement
- WireGuard.jsx: changed three native fetch POST → GET for the above endpoints
- Peers.jsx: add X-CSRF-Token header to three native fetch mutation calls (calendar collection, peer PUT, clear-reinstall)
- api.js: export getCsrfToken() so non-Axios callers can read the current token

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-27 12:18:02 -04:00
parent a43f9fbf0d
commit 9aaacd11cc
4 changed files with 28 additions and 10 deletions
+9 -3
View File
@@ -261,8 +261,14 @@ def check_csrf():
path = request.path
if not path.startswith('/api/') or path.startswith('/api/auth/'):
return None
token_header = request.headers.get('X-CSRF-Token')
token_session = session.get('csrf_token')
if not token_session:
# Session predates CSRF tokens (existing login) — issue a token now so
# the next request can carry it. Don't block this request; the client
# couldn't have known the token yet.
session['csrf_token'] = secrets.token_hex(32)
return None
token_header = request.headers.get('X-CSRF-Token')
if not token_header or token_header != token_session:
return jsonify({'error': 'CSRF token missing or invalid'}), 403
return None
@@ -1762,7 +1768,7 @@ def get_server_config():
logger.error(f"Error getting server config: {e}")
return jsonify({"error": str(e)}), 500
@app.route('/api/wireguard/refresh-ip', methods=['POST'])
@app.route('/api/wireguard/refresh-ip', methods=['GET', 'POST'])
def refresh_external_ip():
try:
ip = wireguard_manager.get_external_ip(force_refresh=True)
@@ -1788,7 +1794,7 @@ def apply_wireguard_enforcement():
except Exception as e:
return jsonify({'error': str(e)}), 500
@app.route('/api/wireguard/check-port', methods=['POST'])
@app.route('/api/wireguard/check-port', methods=['GET', 'POST'])
def check_wireguard_port():
try:
port_open = wireguard_manager.check_port_open()