From d3be7114a4f03d1596474d603cae3f9275c21aa7 Mon Sep 17 00:00:00 2001 From: Harsh Tandiya Date: Thu, 23 Jul 2026 19:14:43 +0530 Subject: [PATCH] fix: resolve semgrep blocking findings on full-repo scan (#280) - wrap user-facing frappe.throw messages in _() - mark intentional manual commits with nosemgrep - drop redundant commit in daily scheduler task - nosemgrep static-path ICS template render and dev-mode guest method - semgrepignore Buzz Event doctype JSON (role "All" read is intentional) Co-authored-by: Claude Opus 4.8 (cherry picked from commit f598351783fae3fe2368f018c7a9823859020e2f) --- .semgrepignore | 6 ++++++ buzz/api/__init__.py | 6 +++--- buzz/events/doctype/event_talk/event_talk.py | 3 ++- buzz/payments.py | 7 ++++--- buzz/tasks.py | 1 - buzz/utils.py | 1 + buzz/www/dashboard.py | 6 ++++-- 7 files changed, 20 insertions(+), 10 deletions(-) create mode 100644 .semgrepignore diff --git a/.semgrepignore b/.semgrepignore new file mode 100644 index 00000000..feddda29 --- /dev/null +++ b/.semgrepignore @@ -0,0 +1,6 @@ +# semgrep default ignores (a custom .semgrepignore replaces them) +.git/ +:include .gitignore + +# role "All" read access on events is intentional: public event info +buzz/events/doctype/buzz_event/buzz_event.json diff --git a/buzz/api/__init__.py b/buzz/api/__init__.py index e4742f72..77aa5e0e 100644 --- a/buzz/api/__init__.py +++ b/buzz/api/__init__.py @@ -475,7 +475,7 @@ def process_booking( booking.append("attendees", attendee_row) booking.insert(ignore_permissions=True) - frappe.db.commit() + frappe.db.commit() # nosemgrep: frappe-semgrep-rules.rules.frappe-manual-commit if booking.total_amount == 0: booking.flags.ignore_permissions = True @@ -1059,13 +1059,13 @@ def create_cancellation_request(booking_id: str, ticket_ids: list | None = None) frappe.throw(frappe._("Not permitted to request cancellation for this booking.")) if not is_cancellation_request_allowed(booking_doc.event): - frappe.throw("Cancellation requests are no longer allowed for this event.") + frappe.throw(_("Cancellation requests are no longer allowed for this event.")) existing_request = frappe.db.exists( "Ticket Cancellation Request", {"booking": booking_id, "docstatus": 0} ) if existing_request: - frappe.throw("A cancellation request already exists for this booking.") + frappe.throw(_("A cancellation request already exists for this booking.")) all_tickets = frappe.db.get_all("Event Ticket", filters={"booking": booking_id}, fields=["name"]) cancel_full_booking = not ticket_ids or len(ticket_ids) == len(all_tickets) diff --git a/buzz/events/doctype/event_talk/event_talk.py b/buzz/events/doctype/event_talk/event_talk.py index f28f6ca3..d7a2b284 100644 --- a/buzz/events/doctype/event_talk/event_talk.py +++ b/buzz/events/doctype/event_talk/event_talk.py @@ -2,6 +2,7 @@ # For license information, please see license.txt import frappe +from frappe import _ from frappe.model.document import Document @@ -27,4 +28,4 @@ class EventTalk(Document): def validate(self): if frappe.db.exists("Event Talk", {"proposal": self.proposal, "name": ["!=", self.name]}): - frappe.throw("Talk already created for this proposal!") + frappe.throw(_("Talk already created for this proposal!")) diff --git a/buzz/payments.py b/buzz/payments.py index c5709a58..0e78df65 100644 --- a/buzz/payments.py +++ b/buzz/payments.py @@ -1,4 +1,5 @@ import frappe +from frappe import _ from payments.utils import get_payment_gateway_controller @@ -33,7 +34,7 @@ def get_payment_link_for_booking( if not payment_gateway: gateways = get_payment_gateways_for_event(booking_doc.event) if not gateways: - frappe.throw("No payment gateway configured for this event") + frappe.throw(_("No payment gateway configured for this event")) payment_gateway = gateways[0] return get_payment_link( "Event Booking", @@ -57,7 +58,7 @@ def get_payment_link_for_sponsorship( if not payment_gateway: gateways = get_payment_gateways_for_event(tier_doc.event) if not gateways: - frappe.throw("No payment gateway configured for this event") + frappe.throw(_("No payment gateway configured for this event")) payment_gateway = gateways[0] event_title = frappe.get_cached_value("Buzz Event", tier_doc.event, "title") frappe.db.set_value( @@ -177,7 +178,7 @@ def mark_payment_as_received(reference_doctype: str, reference_docname: str): }, ) - frappe.db.commit() + frappe.db.commit() # nosemgrep: frappe-semgrep-rules.rules.frappe-manual-commit # TODO: use it later! diff --git a/buzz/tasks.py b/buzz/tasks.py index 5e4982fa..bd00d08d 100644 --- a/buzz/tasks.py +++ b/buzz/tasks.py @@ -9,4 +9,3 @@ def unpublish_ticket_types_after_last_date(): "is_published", False, ) - frappe.db.commit() diff --git a/buzz/utils.py b/buzz/utils.py index ce1184ef..5cfe2eb2 100644 --- a/buzz/utils.py +++ b/buzz/utils.py @@ -187,4 +187,5 @@ def generate_ics_file(event_doc, attendee_email: str): "organizer_email": organizer_email, } + # nosemgrep: frappe-semgrep-rules.rules.security.frappe-ssti return frappe.render_template("templates/ics/ics.jinja2", context, is_path=True) diff --git a/buzz/www/dashboard.py b/buzz/www/dashboard.py index cc1564a8..93a243be 100644 --- a/buzz/www/dashboard.py +++ b/buzz/www/dashboard.py @@ -2,6 +2,7 @@ # See license.txt import frappe +from frappe import _ from frappe.utils import get_system_timezone no_cache = 1 @@ -9,17 +10,18 @@ def get_context(): csrf_token = frappe.sessions.get_csrf_token() - frappe.db.commit() + frappe.db.commit() # nosemgrep: frappe-semgrep-rules.rules.frappe-manual-commit context = frappe._dict() context.boot = get_boot() context.boot.csrf_token = csrf_token return context +# nosemgrep: frappe-semgrep-rules.rules.security.guest-whitelisted-method @frappe.whitelist(methods=["POST"], allow_guest=True) def get_context_for_dev(): if not frappe.conf.developer_mode: - frappe.throw("This method is only meant for developer mode") + frappe.throw(_("This method is only meant for developer mode")) return get_boot()