diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4929840..dad22de 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,13 @@ All notable changes to ExaFS will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [1.2.1] - 2026-01-30
+
+### Fixed
+- Fixed nested `
+
+
+
{% endif %}
{% if rule.comment %}
@@ -111,19 +108,13 @@
-
+
+
+
{% if rule.community.id in allowed_communities %}
-
+
+
+
{% endif %}
{% endif %}
{% if rule.comment %}
@@ -162,12 +153,9 @@
-
+
+
+
{% endif %}
{% if rule.comment %}
diff --git a/flowapp/views/rules.py b/flowapp/views/rules.py
index d746271..7318159 100644
--- a/flowapp/views/rules.py
+++ b/flowapp/views/rules.py
@@ -3,6 +3,8 @@
from collections import namedtuple
from flask import Blueprint, current_app, flash, redirect, render_template, request, session, url_for
+from flask_wtf.csrf import validate_csrf
+from wtforms import ValidationError
from flowapp import constants, db
from flowapp.auth import (
@@ -148,7 +150,7 @@ def reactivate_rule(rule_type, rule_id):
)
-@rules.route("/delete//", methods=["POST"])
+@rules.route("/delete//", methods=["GET"])
@auth_required
@user_or_admin_required
def delete_rule(rule_type, rule_id):
@@ -157,6 +159,13 @@ def delete_rule(rule_type, rule_id):
:param rule_type: integer - type of rule to be deleted
:param rule_id: integer - rule id
"""
+ # Validate CSRF token from query parameter
+ try:
+ validate_csrf(request.args.get("csrf_token", ""))
+ except ValidationError:
+ flash("CSRF token missing or invalid.", "alert-danger")
+ return redirect(url_for("dashboard.index"))
+
# Convert the integer rule_type to RuleTypes enum
enum_rule_type = RuleTypes(rule_type)
@@ -205,13 +214,20 @@ def delete_rule(rule_type, rule_id):
)
-@rules.route("/delete_and_whitelist//", methods=["POST"])
+@rules.route("/delete_and_whitelist//", methods=["GET"])
@auth_required
@user_or_admin_required
def delete_and_whitelist(rule_type, rule_id):
"""
Delete an RTBH rule and create a whitelist entry from it.
"""
+ # Validate CSRF token from query parameter
+ try:
+ validate_csrf(request.args.get("csrf_token", ""))
+ except ValidationError:
+ flash("CSRF token missing or invalid.", "alert-danger")
+ return redirect(url_for("dashboard.index"))
+
if rule_type != RuleTypes.RTBH.value:
flash("Only RTBH rules can be converted to whitelists", "alert-warning")
return redirect(url_for("index"))
diff --git a/flowapp/views/whitelist.py b/flowapp/views/whitelist.py
index 400aa94..ba565b3 100644
--- a/flowapp/views/whitelist.py
+++ b/flowapp/views/whitelist.py
@@ -1,5 +1,7 @@
from datetime import datetime, timedelta
from flask import Blueprint, current_app, flash, redirect, render_template, request, session, url_for
+from flask_wtf.csrf import validate_csrf
+from wtforms import ValidationError
from flowapp.auth import (
auth_required,
@@ -100,7 +102,7 @@ def reactivate(wl_id):
)
-@whitelist.route("/delete/", methods=["POST"])
+@whitelist.route("/delete/", methods=["GET"])
@auth_required
@user_or_admin_required
def delete(wl_id):
@@ -108,6 +110,13 @@ def delete(wl_id):
Delete whitelist
:param wl_id: integer - id of the whitelist
"""
+ # Validate CSRF token from query parameter
+ try:
+ validate_csrf(request.args.get("csrf_token", ""))
+ except ValidationError:
+ flash("CSRF token missing or invalid.", "alert-danger")
+ return redirect(url_for("dashboard.index"))
+
# Check if user can modify this whitelist
if check_user_can_modify_rule(wl_id, "whitelist"):
messages = delete_whitelist(wl_id)