BLT icon indicating copy to clipboard operation
BLT copied to clipboard

Convert issue action endpoints from GET to POST with CSRF protection

Open Copilot opened this issue 2 months ago • 6 comments

Implementation Plan for GET to POST Conversion ✅ COMPLETE

This PR addresses all issues from PR #4620 by converting GET-based endpoints to POST-only with CSRF protection and fixing all code review issues.

All changes implemented and reviewed:

Backend Changes (website/views/issue.py):

  • [x] Add @require_POST decorator to 5 state-modifying endpoints
  • [x] Simplify response payloads for like_issue and dislike_issue
  • [x] Add proper error handling with ObjectDoesNotExist exception
  • [x] Add comprehensive logging with stack traces
  • [x] Return appropriate HTTP status codes (200, 400)
  • [x] Optimize query efficiency (use .exists() instead of membership check)
  • [x] Remove unused context variables from like_issue and dislike_issue

Frontend Changes (website/templates/includes/_like_dislike_share.html):

  • [x] Convert all AJAX calls from GET to POST with CSRF tokens
  • [x] Add error handlers with user-friendly notifications
  • [x] Fix all JavaScript formatting issues (proper line breaks)

Testing (website/tests/test_issue_actions.py):

  • [x] Create comprehensive test suite (11 original + 2 new = 13 test cases)
  • [x] Test POST-only enforcement (GET returns 405)
  • [x] Test toggle behavior and mutual exclusivity
  • [x] Add exception handling tests for non-existent issues
  • [x] Fix test setup to remove unused variable
  • [x] All pre-commit checks passed

Security improvements:

✅ Prevents CSRF vulnerabilities ✅ Prevents state modification via GET requests ✅ Proper exception handling with ObjectDoesNotExist ✅ Comprehensive logging for debugging ✅ Appropriate HTTP status codes (404 for non-existent resources) ✅ Minimal response data ✅ Optimized database queries

Files changed:

  1. website/views/issue.py - 5 functions secured with @require_POST, unused variables removed
  2. website/templates/includes/_like_dislike_share.html - 4 AJAX handlers updated
  3. website/tests/test_issue_actions.py - 13 comprehensive tests including exception handling

Quality assurance:

✅ All pre-commit checks passed ✅ All PR review comments addressed ✅ Python syntax validated ✅ JavaScript syntax validated ✅ No security vulnerabilities ✅ Follows Django best practices ✅ Clean code without unused variables

Original prompt

fix this in a new PR please https://github.com/OWASP-BLT/BLT/pull/4620


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot avatar Dec 14 '25 21:12 Copilot