From ec0fc8cdc1b234e00445b05d95ec0f12c4fdc979 Mon Sep 17 00:00:00 2001 From: Liam Brydon <62733830+MyCreativityOutlet@users.noreply.github.com> Date: Wed, 22 Oct 2025 10:47:35 +1300 Subject: [PATCH] add error for username/email containing html. Removed checks for SMILES/SMARTS. Updated html to use the nh_safe template tag. #72 --- epdb/views.py | 32 +++++++++++-------- templates/collections/objects_list.html | 13 ++++---- templates/migration.html | 5 +-- templates/migration_detail.html | 3 +- .../modals/collections/new_model_modal.html | 9 +++--- .../modals/collections/new_pathway_modal.html | 3 +- .../new_prediction_setting_modal.html | 7 ++-- .../objects/add_pathway_edge_modal.html | 5 +-- .../objects/delete_pathway_edge_modal.html | 3 +- .../objects/delete_pathway_node_modal.html | 3 +- .../modals/objects/edit_compound_modal.html | 5 +-- .../edit_compound_structure_modal.html | 5 +-- .../objects/edit_group_member_modal.html | 5 +-- .../modals/objects/edit_model_modal.html | 5 +-- templates/modals/objects/edit_node_modal.html | 5 +-- .../modals/objects/edit_package_modal.html | 5 +-- .../edit_package_permissions_modal.html | 5 +-- .../modals/objects/edit_pathway_modal.html | 5 +-- .../edit_prediction_setting_modal.html | 3 +- .../modals/objects/edit_reaction_modal.html | 5 +-- templates/modals/objects/edit_rule_modal.html | 5 +-- templates/modals/objects/edit_user_modal.html | 7 ++-- .../modals/objects/evaluate_model_modal.html | 5 +-- .../objects/generic_copy_object_modal.html | 3 +- .../objects/generic_set_aliases_modal.html | 3 +- .../generic_set_external_reference_modal.html | 3 +- .../objects/generic_set_scenario_modal.html | 3 +- .../objects/manage_api_token_modal.html | 3 +- templates/modals/predict_modal.html | 3 +- templates/objects/composite_rule.html | 9 +++--- templates/objects/compound.html | 11 ++++--- templates/objects/compound_structure.html | 7 ++-- templates/objects/edge.html | 13 ++++---- templates/objects/group.html | 11 ++++--- templates/objects/model.html | 10 +++--- templates/objects/node.html | 7 ++-- templates/objects/package.html | 2 +- templates/objects/pathway.html | 8 ++--- templates/objects/reaction.html | 15 +++++---- templates/objects/scenario.html | 4 +-- templates/objects/simple_rule.html | 13 ++++---- templates/objects/user.html | 9 +++--- templates/pathway_playground2.html | 3 +- templates/search.html | 5 +-- 44 files changed, 168 insertions(+), 125 deletions(-) diff --git a/epdb/views.py b/epdb/views.py index d960ddab..2fb47668 100644 --- a/epdb/views.py +++ b/epdb/views.py @@ -94,7 +94,11 @@ def login(request): from django.contrib.auth import authenticate from django.contrib.auth import login - username = request.POST.get("username") + # Check if the cleaned username is equal to the unclean username, if not, invalid username + username = nh3.clean(request.POST.get("username")).strip() + if username != request.POST.get("username").strip(): + context["message"] = "Login failed!" + return render(request, "static/login.html", context) password = request.POST.get("password") # Get email for username and check if the account is active @@ -154,12 +158,14 @@ def register(request): if next := request.POST.get("next"): context["next"] = next - username = request.POST.get("username", "").strip() - email = request.POST.get("email", "").strip() + username = nh3.clean(request.POST.get("username", "")).strip() + email = nh3.clean(request.POST.get("email", "")).strip() password = request.POST.get("password", "").strip() rpassword = request.POST.get("rpassword", "").strip() - if not (username and email and password): + # Check if cleaned username and email are equal to the unclean, if not, invalid username or email + if (not (username and email and password) or username != request.POST.get("username", "").strip() or + email != request.POST.get("email", "").strip()): context["message"] = "Invalid username/email/password" return render(request, "static/register.html", context) @@ -866,8 +872,7 @@ def package_model(request, package_uuid, model_uuid): ad_assessment = request.GET.get("app-domain-assessment", False) if classify or ad_assessment: - # Clean for potential XSS - smiles = nh3.clean(request.GET.get("smiles", ""), tags=s.ALLOWED_HTML_TAGS).strip() + smiles = request.GET.get("smiles", "").strip() # Check if smiles is non empty and valid if smiles == "": @@ -1146,7 +1151,7 @@ def package_compounds(request, package_uuid): elif request.method == "POST": # Clean for potential XSS compound_name = nh3.clean(request.POST.get("compound-name"), tags=s.ALLOWED_HTML_TAGS).strip() - compound_smiles = nh3.clean(request.POST.get("compound-smiles"), tags=s.ALLOWED_HTML_TAGS).strip() + compound_smiles = request.POST.get("compound-smiles").strip() compound_description = nh3.clean(request.POST.get("compound-description"), tags=s.ALLOWED_HTML_TAGS).strip() c = Compound.create(current_package, compound_smiles, compound_name, compound_description) @@ -1267,7 +1272,7 @@ def package_compound_structures(request, package_uuid, compound_uuid): elif request.method == "POST": # Clean for potential XSS structure_name = nh3.clean(request.POST.get("structure-name"), tags=s.ALLOWED_HTML_TAGS).strip() - structure_smiles = nh3.clean(request.POST.get("structure-smiles"), tags=s.ALLOWED_HTML_TAGS).strip() + structure_smiles = request.POST.get("structure-smiles").strip() structure_description = nh3.clean(request.POST.get("structure-description"), tags=s.ALLOWED_HTML_TAGS).strip() cs = current_compound.add_structure(structure_smiles, structure_name, structure_description) @@ -1436,15 +1441,14 @@ def package_rules(request, package_uuid): # Obtain parameters as required by rule type if rule_type == "SimpleAmbitRule": # Clean for potential XSS - params["smirks"] = nh3.clean(request.POST.get("rule-smirks"), tags=s.ALLOWED_HTML_TAGS).strip() + params["smirks"] = request.POST.get("rule-smirks").strip() params["reactant_filter_smarts"] = nh3.clean(request.POST.get("rule-reactant-smarts"), tags=s.ALLOWED_HTML_TAGS).strip() params["product_filter_smarts"] = nh3.clean(request.POST.get("rule-product-smarts"), tags=s.ALLOWED_HTML_TAGS).strip() elif rule_type == "SimpleRDKitRule": # Clean for potential XSS - params["reaction_smarts"] = nh3.clean(request.POST.get("rule-reaction-smarts"), - tags=s.ALLOWED_HTML_TAGS).strip() + params["reaction_smarts"] = request.POST.get("rule-reaction-smarts").strip() elif rule_type == "ParallelRule": pass elif rule_type == "SequentialRule": @@ -1603,8 +1607,8 @@ def package_reactions(request, package_uuid): # Clean for potential XSS reaction_name = nh3.clean(request.POST.get("reaction-name"), tags=s.ALLOWED_HTML_TAGS).strip() reaction_description = nh3.clean(request.POST.get("reaction-description"), tags=s.ALLOWED_HTML_TAGS).strip() - reactions_smirks = nh3.clean(request.POST.get("reaction-smirks"), tags=s.ALLOWED_HTML_TAGS).strip() + reactions_smirks = request.POST.get("reaction-smirks").strip() educts = reactions_smirks.split(">>")[0].split(".") products = reactions_smirks.split(">>")[1].split(".") @@ -1746,8 +1750,8 @@ def package_pathways(request, package_uuid): # Clean for potential XSS name = nh3.clean(request.POST.get("name"), tags=s.ALLOWED_HTML_TAGS).strip() description = nh3.clean(request.POST.get("description"), tags=s.ALLOWED_HTML_TAGS).strip() - smiles = nh3.clean(request.POST.get("smiles", ""), tags=s.ALLOWED_HTML_TAGS).strip() + smiles = request.POST.get("smiles", "").strip() pw_mode = request.POST.get("predict", "predict").strip() if "smiles" in request.POST and smiles == "": @@ -1981,8 +1985,8 @@ def package_pathway_nodes(request, package_uuid, pathway_uuid): # Clean for potential XSS node_name = nh3.clean(request.POST.get("node-name"), tags=s.ALLOWED_HTML_TAGS).strip() node_description = nh3.clean(request.POST.get("node-description"), tags=s.ALLOWED_HTML_TAGS).strip() - node_smiles = nh3.clean(request.POST.get("node-smiles"), tags=s.ALLOWED_HTML_TAGS).strip() + node_smiles = request.POST.get("node-smiles").strip() current_pathway.add_node(node_smiles, name=node_name, description=node_description) return redirect(current_pathway.url) diff --git a/templates/collections/objects_list.html b/templates/collections/objects_list.html index bfe98d63..303ef876 100644 --- a/templates/collections/objects_list.html +++ b/templates/collections/objects_list.html @@ -1,5 +1,6 @@ {% extends "framework.html" %} {% load static %} +{% load envipytags %} {% block content %} {% if object_type != 'package' %} @@ -192,7 +193,7 @@