Conversation
- Add permissions: contents: read to CI and static workflows - Use sandboxed Django template Engine for mailing templates (SSTI) - Sanitize file paths in fix_success_story_images command (path injection) - Validate redirect URL path in MediaMigrationView (open redirect) - Use textContent instead of innerHTML in font demo (DOM XSS) - Validate image src URLs in sponsor application form (DOM XSS) - Validate select value is relative URL in event detail (DOM XSS) - Dismiss SHA1 alert as won't-fix (PyCon API requirement) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
apps/sponsors/management/commands/create_pycon_vouchers_for_sponsors.py
Dismissed
Show dismissed
Hide dismissed
Use Django storage API (ContentFile + ImageField.save) instead of raw file I/O to eliminate path injection taint chain. Dismiss remaining alerts as false positives — data originates from server-rendered Django templates, not user input. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This pull request implements security fixes to address 15 of 16 CodeQL security alerts, covering SSTI, XSS, path traversal, and open redirect vulnerabilities. The changes include GitHub Actions permission hardening, sandboxed template rendering for email templates, input sanitization for file paths and URLs, and DOM XSS mitigations in JavaScript code.
Changes:
- Added least-privilege
permissions: contents: readto CI and static GitHub workflows - Implemented sandboxed Django
Enginefor email template rendering to prevent SSTI attacks - Added path sanitization in management commands and redirect views to prevent path traversal
- Implemented client-side URL validation to prevent DOM-based XSS and open redirect vulnerabilities
- Updated noqa comment for SHA1 usage to document it as an external API requirement
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
.github/workflows/ci.yml |
Added read-only permissions for least-privilege security |
.github/workflows/static.yml |
Added read-only permissions for least-privilege security |
static/js/sponsors/applicationForm.js |
Added isSafeImageSrc() validation for image sources |
static/fonts/demo/demo.js |
Replaced innerHTML with textContent to prevent XSS |
apps/events/templates/events/event_detail.html |
Added URL validation for date range selector |
apps/pages/management/commands/fix_success_story_images.py |
Added path traversal protections for file operations |
pydotorg/views.py |
Added path sanitization in MediaMigrationView redirect |
apps/mailing/models.py |
Implemented sandboxed Engine for template rendering |
apps/mailing/forms.py |
Updated to use sandboxed engine for validation |
apps/sponsors/management/commands/create_pycon_vouchers_for_sponsors.py |
Updated noqa comment for SHA1 usage |
Comments suppressed due to low confidence (1)
apps/pages/management/commands/fix_success_story_images.py:43
- The path traversal protection has a subtle flaw. Line 43 uses
Path(parsed_name).nameafter already extracting.namefromPurePosixPathon line 42. Since.namealready returns just the filename component without directory parts, callingPath().nameagain is redundant but harmless. However, ifparsed_namecontains path separators for some reason (which shouldn't happen after.name), the second.namecall could potentially allow them through on Windows due to different path separator handling between PurePosixPath and Path.
Consider simplifying to just use filename = PurePosixPath(urlparse(url).path).name and remove the redundant second Path wrapper, or document why both are necessary for defense-in-depth.
def find_image_paths(self, page):
content = page.content.raw
paths = set(re.findall(r"(/files/success.*)\b", content))
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b61b5e4186
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- Use permissions: {} per Hugo's suggestion (cherry-picker pattern)
- Fix protocol-relative URL bypass (//evil.com) in event detail and
isSafeImageSrc
- Use PurePosixPath + part filtering for robust path traversal
prevention in MediaMigrationView
- var -> let in JS
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
permissions: contents: readto CI and static workflows (least-privilege)Enginefor mailing email templates to mitigate SSTIfix_success_story_imagesmanagement command (path traversal)MediaMigrationViewto prevent open redirectinnerHTMLwithtextContentin font demo script (DOM XSS)isSafeImageSrc()validation for sponsor application form image sources (DOM XSS)Resolves 15 of 16 open CodeQL alerts; 1 dismissed as external API requirement.
Test plan
🤖 Generated with Claude Code