Skip to content

fix(security): address open CodeQL alerts (path-injection, url-redirection, stack-trace-exposure)#2884

Merged
vpetersson merged 2 commits into
masterfrom
fix-codeql-alerts
May 13, 2026
Merged

fix(security): address open CodeQL alerts (path-injection, url-redirection, stack-trace-exposure)#2884
vpetersson merged 2 commits into
masterfrom
fix-codeql-alerts

Conversation

@vpetersson
Copy link
Copy Markdown
Contributor

Summary

Closes the three currently-actionable CodeQL alerts on master HEAD:

  • Cannot set non existing web asset inactive #91 py/path-injection (src/anthias_server/app/views.py:393) — assets_upload now drops any src_ext that isn't a plain .<alnum> extension before it's joined onto assetdir, so a hostile Content-Disposition: filename= can't smuggle / or .. into the on-disk path. The random-UUID basename was already the safe component; this is defence-in-depth on the extension.
  • Add support for live streaming #90 py/url-redirection (src/anthias_server/app/views.py:1014) — login runs django.utils.http.url_has_allowed_host_and_scheme inline at the redirect() site so CodeQL sees the canonical Django sanitiser guarding the target. The now-only-internal _safe_login_next helper is removed because the check lives at the call site.
  • Screenly OSE MVP #77 py/stack-trace-exposure (src/anthias_server/api/views/v2.py:665) — DeviceSettingsViewV2.patch logs the failure via logger.exception and returns a generic 400 instead of interpolating the exception into the response body.

Other open alerts (not addressed in code)

  • Allow aborting currently shown asset via SIGUSR1 #92 py/csrf-protection-disabled (django_project/settings.py:121) — false positive: SameHostOriginCsrfMiddleware subclasses django.middleware.csrf.CsrfViewMiddleware. CodeQL doesn't follow class hierarchy; the existing NOSONAR comment already documents this for SonarQube's S4502. Will dismiss via gh code-scanning alert update once the rest land.
  • Manual for downloading the git repository doesn't work like expected #1Improve crash handling #10 point at paths (auth.py, lib/auth.py, server.py, static/js/moment.js, static/js/bootstrap-datepicker.js) that no longer exist after the React→Django (e9738288), src/ layout (133ec78f), and django.contrib.auth (8e2f38b1) refactors. They should auto-transition to fixed after the next master scan; any stragglers can be dismissed.

Test plan

  • uv run ruff check — green locally for the changed files.
  • CodeQL on the PR — py/path-injection, py/url-redirection, and py/stack-trace-exposure no longer flagged on these files.
  • Existing tests/test_login_view.py (off-host next rejection) and tests/test_template_views.py (HEIC/JPEG/video upload extension preservation) still pass.

🤖 Generated with Claude Code

…py/stack-trace-exposure

* `assets_upload` now drops any ``src_ext`` that isn't a plain
  ``.<alnum>`` extension before joining it onto ``assetdir``, so a
  hostile Content-Disposition filename can't smuggle ``/`` or ``..``
  into the destination path (py/path-injection on
  ``app/views.py``).
* `login` runs ``url_has_allowed_host_and_scheme`` inline at the
  ``redirect`` site so CodeQL sees the canonical Django sanitiser
  guarding the target (py/url-redirection on ``app/views.py``).
  The since-only-internal ``_safe_login_next`` helper is dropped
  because the check now lives at the call site.
* `DeviceSettingsViewV2.patch` logs the exception via
  ``logger.exception`` and returns a generic error string instead
  of interpolating the exception into the 400 body
  (py/stack-trace-exposure on ``api/views/v2.py``).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vpetersson vpetersson requested a review from a team as a code owner May 12, 2026 21:16
@vpetersson vpetersson requested a review from Copilot May 12, 2026 21:16
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses three actionable Python CodeQL alerts by tightening input handling in the upload path, hardening login redirects against open-redirect abuse, and avoiding exception detail leakage in an API response.

Changes:

  • Sanitize uploaded asset filename extensions to prevent path injection via Content-Disposition.
  • Inline url_has_allowed_host_and_scheme guarding at the login redirect() call site and remove the helper.
  • Replace API error interpolation with server-side exception logging and a generic client-facing error message.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
tests/test_login_view.py Updates test commentary to reflect the redirect check living in the view (behavior unchanged).
src/anthias_server/app/views.py Adds extension validation for uploads and inlines the safe-redirect allowlist logic in login.
src/anthias_server/api/views/v2.py Prevents stack-trace/detail exposure by logging exceptions server-side and returning a generic 400 error.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/anthias_server/app/views.py Outdated
…e regex

Copilot review on PR #2884 noticed that the original patch dropped any
``src_ext`` failing the ``\.<alnum>`` check without re-running the
MIME-subtype fallback. A file uploaded with a filename like ``foo.``
(``path.splitext`` → ``'.'``) would land extensionless even when the
``image/<subtype>`` mapping would have recovered a valid extension —
which means ``needs_image_normalisation`` returns False and a HEIC
upload bypasses the pipeline.

Lift the regex into ``_SAFE_EXT_RE`` and apply ``_safe_ext()`` to
each candidate as it's tried. The control flow stays the same
(short-circuit on the first accepted value), but a candidate that
fails the regex no longer wedges ``src_ext = ''`` past the MIME
fallback.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vpetersson vpetersson requested a review from Copilot May 12, 2026 21:22
@sonarqubecloud
Copy link
Copy Markdown

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@vpetersson vpetersson merged commit 465a33e into master May 13, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants