Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,8 @@
**Vulnerability:** XSS risk due to modifying the DOM using `.innerHTML` with potentially dynamic or unescaped translated values in `static/js/app.js`.
**Learning:** `innerHTML` exposes a risk of executing unescaped input or malformed HTML translations. Instead of clearing nodes with `.innerHTML = ""` or creating nested HTML structures via strings, safer programmatic node manipulation should be utilized.
**Prevention:** Use `.textContent` for assigning simple text to elements. Use programmatic DOM creation methods like `document.createElement` and `node.appendChild` instead of injecting raw HTML strings into `.innerHTML`. To clear an element, loop through and use `removeChild` on its children (e.g. `while (el.firstChild) el.removeChild(el.firstChild);`).

## 2024-10-24 - [Login CSRF on Authentication Endpoints]
**Vulnerability:** The `@csrf_exempt` decorator was applied to `demo_login` and `demo_portal_login` endpoints in `apps/auth_app/views.py`.
**Learning:** Bypassing CSRF checks on authentication boundaries (like login, invite accept, password reset) allows an attacker to perform Login CSRF attacks, potentially forcing a victim's browser to log into an attacker-controlled account and exposing their activity. Since the frontend forms already include `{% csrf_token %}`, the exemption was unnecessary and dangerous.
**Prevention:** Avoid using `@csrf_exempt` on authentication boundaries unless strictly required by an external callback. Always ensure forms in login templates include `{% csrf_token %}` and rely on Django's built-in CSRF protection.
3 changes: 0 additions & 3 deletions apps/auth_app/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from django.core.cache import cache
from django.http import HttpResponse, HttpResponseNotAllowed
from django.shortcuts import redirect, render
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
from django.utils import timezone
from django.utils import translation
Expand Down Expand Up @@ -340,7 +339,6 @@ def azure_callback(request):
return _set_language_cookie(response, lang_code)


@csrf_exempt
@require_POST
@ratelimit(key="ip", rate="10/m", method=["POST"], block=True)
def demo_login(request, role):
Expand Down Expand Up @@ -383,7 +381,6 @@ def demo_login(request, role):
return _set_language_cookie(response, lang_code)


@csrf_exempt
@require_POST
@ratelimit(key="ip", rate="10/m", method=["POST"], block=True)
def demo_portal_login(request, record_id):
Expand Down