Skip to content

πŸ›‘οΈ Sentinel: [CRITICAL/HIGH] projectId 경둜 μ‘°μž‘(Path Traversal) 취약점 μˆ˜μ • - #696

Closed
seonghobae wants to merge 4 commits into
developfrom
fix-projectid-traversal-5899358760909572075
Closed

πŸ›‘οΈ Sentinel: [CRITICAL/HIGH] projectId 경둜 μ‘°μž‘(Path Traversal) 취약점 μˆ˜μ •#696
seonghobae wants to merge 4 commits into
developfrom
fix-projectid-traversal-5899358760909572075

Conversation

@seonghobae

Copy link
Copy Markdown
Collaborator

🚨 Severity: CRITICAL/HIGH
πŸ’‘ Vulnerability: API μš”μ²­μ—μ„œ μ „λ‹¬λ°›λŠ” projectIdκ°€ 경둜 μ‘°μž‘μ— μ·¨μ•½ν•œ μƒνƒœμ˜€μŠ΅λ‹ˆλ‹€. . μ΄λ‚˜ .., /, \ λ“±μ˜ 값을 톡해 νŒŒμΌμ‹œμŠ€ν…œ κ²½λ‘œμ— κ°œμž…ν•  수 μžˆλŠ” μœ„ν—˜μ΄ μžˆμ—ˆμŠ΅λ‹ˆλ‹€.
🎯 Impact: κ³΅κ²©μžκ°€ μž„μ˜μ˜ 경둜λ₯Ό μƒμ„±ν•˜μ—¬ μ„œλ²„ 파일 μ‹œμŠ€ν…œμ— μ ‘κ·Όν•˜κ±°λ‚˜ μ“°κΈ°λ₯Ό μˆ˜ν–‰ν•  κ°€λŠ₯성이 μ‘΄μž¬ν–ˆμŠ΅λ‹ˆλ‹€.
πŸ”§ Fix: services/analysis-engine/src/bandscope_analysis/api.py λ‚΄μ˜ validate_analysis_job_request에 λͺ…μ‹œμ μΈ 검증 λ‘œμ§μ„ μΆ”κ°€ν–ˆμŠ΅λ‹ˆλ‹€. projectIdκ°€ . λ˜λŠ” ..인 κ²½μš°λ‚˜ 디렉토리 κ΅¬λΆ„μž(/, \)λ₯Ό ν¬ν•¨ν•œ 경우 μ°¨λ‹¨ν•˜λ„λ‘ λ³€κ²½ν•˜μ˜€κ³ , μœ νš¨ν•œ μ‹λ³„μž(예: my..id)λŠ” ν†΅κ³Όν•˜λ„λ‘ μ²˜λ¦¬ν–ˆμŠ΅λ‹ˆλ‹€.
βœ… Verification: uv run pytest 및 quickcheck.sh ν…ŒμŠ€νŠΈλ₯Ό λͺ¨λ‘ ν†΅κ³Όν–ˆμŠ΅λ‹ˆλ‹€.


PR created automatically by Jules for task 5899358760909572075 started by @seonghobae

@google-labs-jules

Copy link
Copy Markdown

πŸ‘‹ 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.

Copilot AI review requested due to automatic review settings July 25, 2026 04:07

Copilot AI left a comment

Copy link
Copy Markdown

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 strengthens analysis-engine request validation by adding explicit projectId path-traversal guards in the Python API boundary, and extends unit coverage to ensure safe failures for traversal-like IDs while still allowing benign identifiers containing ...

Changes:

  • Added projectId validation to reject . / .. and any / or \ separators in validate_analysis_job_request.
  • Updated/expanded Python unit tests to confirm my..project remains valid and traversal-shaped projectId values are rejected.
  • Documented the validation approach in the Sentinel knowledge file.

Reviewed changes

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

File Description
services/analysis-engine/src/bandscope_analysis/api.py Adds projectId traversal checks and associated error/telemetry behavior.
services/analysis-engine/tests/test_api.py Updates an acceptance test to allow .. inside IDs and adds rejection cases for traversal-like IDs.
.jules/sentinel.md Captures the intended validation strategy for future reference.

πŸ’‘ Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 279 to +283
if not isinstance(project_id, str) or not project_id.strip():
raise ValueError("Invalid analysis job request: invalid field 'projectId'")
if project_id in {".", ".."} or "/" in project_id or "\\" in project_id:
logger.warning("Security: path traversal detected in projectId")
raise ValueError("Invalid analysis job request: path traversal detected in 'projectId'")
Comment on lines +311 to +325
(
{
"sourceKind": "local_audio",
"projectId": "..",
"sourceLabel": "Late Night Set",
"roleFocus": [],
"localSource": {
"sourcePath": "/tmp/a.wav",
"fileName": "a.wav",
"extension": "wav",
"fileSizeBytes": 1024000,
},
},
"path traversal detected in 'projectId'",
),
Comment thread .jules/sentinel.md
Comment on lines +31 to +34
## 2025-10-24 - Project ID path traversal guard validation approach
**Vulnerability:** Any project identifier that can reach a filesystem path join must be treated as untrusted.
**Learning:** Checking for substrings like `..` can erroneously block legitimate inputs like `my..id`.
**Prevention:** When validating identifiers like `projectId`, reject exact matches for `.` and `..`, and block any path separators (`/` and `\`), rather than blocking any string containing `..`.
Copilot AI review requested due to automatic review settings July 25, 2026 04:15

Copilot AI left a comment

Copy link
Copy Markdown

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 5 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

services/analysis-engine/tests/test_api.py:315

  • The new projectId traversal guard also rejects the exact value ".", but the test matrix only covers ".." and path separators. Add a failing case for projectId=="." so the behavior is explicitly regression-tested.
        (
            {
                "sourceKind": "local_audio",
                "projectId": "..",
                "sourceLabel": "Late Night Set",

Copilot AI review requested due to automatic review settings July 25, 2026 04:28

Copilot AI left a comment

Copy link
Copy Markdown

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 4 out of 6 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

services/analysis-engine/src/bandscope_analysis/api.py:283

  • The path-traversal guard checks the raw project_id value, but the earlier validation only uses project_id.strip() for emptiness. That means inputs like " .. " bypass the {'.','..'} check (and may later be normalized/trimmed elsewhere), weakening the intended protection. Strip once and validate against the stripped value.
    if not isinstance(project_id, str) or not project_id.strip():
        raise ValueError("Invalid analysis job request: invalid field 'projectId'")
    if project_id in {".", ".."} or "/" in project_id or "\\" in project_id:
        logger.warning("Security: path traversal detected in projectId")
        raise ValueError("Invalid analysis job request: path traversal detected in 'projectId'")

Comment on lines +311 to +325
(
{
"sourceKind": "local_audio",
"projectId": "..",
"sourceLabel": "Late Night Set",
"roleFocus": [],
"localSource": {
"sourcePath": "/tmp/a.wav",
"fileName": "a.wav",
"extension": "wav",
"fileSizeBytes": 1024000,
},
},
"path traversal detected in 'projectId'",
),
Comment on lines 14 to 18
"numpy>=1.26",
"setuptools>=83.0.0",
"soundfile>=0.13.1",
"urllib3>=2.7.0",
"urllib3>=2.7.0",
"yt-dlp>=2026.6.9",
@seonghobae
seonghobae enabled auto-merge (squash) July 29, 2026 13:51
@seonghobae
seonghobae disabled auto-merge July 29, 2026 14:00

Copy link
Copy Markdown
Collaborator Author

Superseded by #713 for the base-branch security remediation, and its projectId guard is carried forward there with the Copilot review findings addressed.

Specifically, #713 (services/analysis-engine/src/bandscope_analysis/api.py):

  • Closes the whitespace bypass flagged in the Copilot threads here (" .. " passed the exact {".",".."} comparison but a downstream trim would normalize it back to a .. segment). The guard now also rejects any leading/trailing whitespace (project_id != project_id.strip()), and tests cover " .. ", " . ", " project-1 ".
  • Adds the missing . case and locks the intended-allowed dotted identifiers (my..project, a.b.c) in a dedicated accepts test.
  • Keeps the dependency remediation separate (the yt-dlp/setuptools/brace-expansion/postcss CVE bumps live in fix(security): remediate base-branch supply-chain findings blocking all open PRsΒ #713's focused base-fix commit as a uv constraint rather than a direct setuptools runtime dependency), avoiding the mixed-scope concern raised here.

Auto-merge disabled here to avoid landing the un-hardened guard ahead of #713. This PR can be closed once #713 merges; leaving it open for now so nothing is lost if #713's review path stalls.


Generated by Claude Code

@google-labs-jules

Copy link
Copy Markdown

Superseded by #713 for the base-branch security remediation, and its projectId guard is carried forward there with the Copilot review findings addressed.

Specifically, #713 (services/analysis-engine/src/bandscope_analysis/api.py):

  • Closes the whitespace bypass flagged in the Copilot threads here (" .. " passed the exact {".",".."} comparison but a downstream trim would normalize it back to a .. segment). The guard now also rejects any leading/trailing whitespace (project_id != project_id.strip()), and tests cover " .. ", " . ", " project-1 ".
  • Adds the missing . case and locks the intended-allowed dotted identifiers (my..project, a.b.c) in a dedicated accepts test.
  • Keeps the dependency remediation separate (the yt-dlp/setuptools/brace-expansion/postcss CVE bumps live in fix(security): remediate base-branch supply-chain findings blocking all open PRsΒ #713's focused base-fix commit as a uv constraint rather than a direct setuptools runtime dependency), avoiding the mixed-scope concern raised here.

Auto-merge disabled here to avoid landing the un-hardened guard ahead of #713. This PR can be closed once #713 merges; leaving it open for now so nothing is lost if #713's review path stalls.


Generated by Claude Code

Understood. Acknowledging that this work is superseded by #713 and stopping work on this task.

@seonghobae

Copy link
Copy Markdown
Collaborator Author

Closing as closed-duplicate/superseded (path-traversal cluster) by autonomous product-completion loop.

Winner / disposition target: #727

Unique value from this cluster is consolidated there (projectId path guard + npm HIGH CVE pins + Foote novelty kernel sign). Remaining micro-duplicates do not land additional commercial readiness.

@seonghobae

Copy link
Copy Markdown
Collaborator Author

closed-closed-duplicate/superseded (path-traversal cluster) β†’ #727

@seonghobae seonghobae closed this Jul 31, 2026
@google-labs-jules

Copy link
Copy Markdown

Closing as closed-duplicate/superseded (path-traversal cluster) by autonomous product-completion loop.

Winner / disposition target: #727

Unique value from this cluster is consolidated there (projectId path guard + npm HIGH CVE pins + Foote novelty kernel sign). Remaining micro-duplicates do not land additional commercial readiness.

Understood. Acknowledging that this work is closed as a duplicate and superseded by #727, and stopping work on this task.

@google-labs-jules

Copy link
Copy Markdown

closed-closed-duplicate/superseded (path-traversal cluster) β†’ #727

Acknowledged.

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