Skip to content

🛡️ Sentinel: [CRITICAL] Fix broken security check in SafeStaticFiles#90

Merged
socialawy merged 1 commit into
mainfrom
sentinel/fix-safestaticfiles-lower-bug-1220491930769183854
May 13, 2026
Merged

🛡️ Sentinel: [CRITICAL] Fix broken security check in SafeStaticFiles#90
socialawy merged 1 commit into
mainfrom
sentinel/fix-safestaticfiles-lower-bug-1220491930769183854

Conversation

@socialawy-dev
Copy link
Copy Markdown
Collaborator

🚨 Severity: CRITICAL
💡 Vulnerability: The custom SafeStaticFiles middleware intended to block access to sensitive files used an invalid method call (Path(path).lower()), causing an AttributeError on static file requests. This caused all static file serving to fail with 500 errors, and represented a malformed security check.
🎯 Impact: Broke static file serving and represented a risk of bypass if exceptions were ever swallowed.
🔧 Fix: Normalized the path string to lowercase before instantiating the Path object (Path(str(path).lower())).
Verification: Verified by querying the endpoint and confirming a proper 404 response instead of a 500 internal server error.


PR created automatically by Jules for task 1220491930769183854 started by @socialawy

Co-authored-by: socialawy <24765060+socialawy@users.noreply.github.com>
@google-labs-jules
Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request fixes a runtime error in the SafeStaticFiles middleware caused by an invalid method call on a Path object and documents the incident in the security sentinel log. The review feedback points out that the explicit string conversion is redundant since the input variable is already a string. Additionally, a security improvement was suggested for the path validation logic, noting that the current check for .env files only inspects the final component of the path and could be bypassed if .env is used as a directory name.

async def get_response(self, path: str, scope) -> Response:
# Normalize path for check
p = Path(path).lower()
p = Path(str(path).lower())
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-high high

The path parameter is already a string according to the type hint, so the str(path) conversion is redundant. You can simplify this to Path(path.lower()).

Additionally, while fixing this crash, note that the security check on line 28 for .env using p.name.startswith(".env") only protects the resource if it is the final component of the path. If a directory named .env exists, a request like .env/secrets would bypass this check because p.name would be secrets. Consider updating the logic to check if any component in p.parts starts with .env, similar to how the 00_config and .git directories are handled.

Suggested change
p = Path(str(path).lower())
p = Path(path.lower())

Comment thread .jules/sentinel.md
## 2025-02-23 - Broken Security Check in SafeStaticFiles
**Vulnerability:** The custom `SafeStaticFiles` middleware in `src/audioformation/server/app.py` intended to block access to sensitive directories (like `00_CONFIG` and `.git`). However, it used `p = Path(path).lower()`, which raises an `AttributeError` because `pathlib.Path` objects lack a `.lower()` method. This effectively broke static file serving entirely (causing 500 errors) and represented a malformed security check. If such errors were ever 'swallowed' without raising an HTTP exception, it could result in 'failing open' and allowing access to sensitive files.
**Learning:** Security checks that rely on path manipulation or normalization must be carefully tested for runtime exceptions. An unhandled exception in a security gate can either block legitimate traffic (Denial of Service) or, if caught improperly elsewhere, fail open. Always normalize the string representation of paths before converting them to `Path` objects.
**Prevention:** Thoroughly test security middleware endpoints for both valid and invalid access attempts. Ensure that path string normalizations like `.lower()` are applied directly to the string before instantiating `Path(str(path).lower())`.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The str() conversion is redundant here as path is already a string. It is better to suggest Path(path.lower()) in the prevention guide to avoid propagating redundant type conversions in security documentation.

Suggested change
**Prevention:** Thoroughly test security middleware endpoints for both valid and invalid access attempts. Ensure that path string normalizations like `.lower()` are applied directly to the string before instantiating `Path(str(path).lower())`.
**Prevention:** Thoroughly test security middleware endpoints for both valid and invalid access attempts. Ensure that path string normalizations like `.lower()` are applied directly to the string before instantiating `Path(path.lower())`.

@socialawy socialawy merged commit ac23b55 into main May 13, 2026
5 checks passed
@socialawy socialawy deleted the sentinel/fix-safestaticfiles-lower-bug-1220491930769183854 branch May 13, 2026 19:05
This was referenced May 13, 2026
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