๐ก๏ธ Sentinel: [HIGH] API ํค ๋ฏธ๋ค์จ์ด์ Unhandled Exception DoS ์ทจ์ฝ์ ์์ - #361
๐ก๏ธ Sentinel: [HIGH] API ํค ๋ฏธ๋ค์จ์ด์ Unhandled Exception DoS ์ทจ์ฝ์ ์์ #361seonghobae wants to merge 20 commits into
Conversation
`saas_web.py`์ `require_api_key` ๋ฏธ๋ค์จ์ด์์ `hmac.compare_digest` ์ฌ์ฉ ์ non-ASCII ๋ฌธ์๊ฐ ํฌํจ๋ ์ ๋ ฅ์์ ๋ฐ์ํ๋ `TypeError`๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ์ ๋ ฅ ๋ฌธ์์ด์ ๋ช ์์ ์ผ๋ก UTF-8 ๋ฐ์ดํธ๋ก ์ธ์ฝ๋ฉํ๋๋ก ์์ ํ์ต๋๋ค. ์ด๋ฅผ ํตํด ์ ์์ ์ธ ํค๋๋ก ์ธํ 500 ์๋ฒ ์๋ฌ(DoS) ์ทจ์ฝ์ ์ ํด๊ฒฐํ์ต๋๋ค. ๊ด๋ จ ๋จ์ ํ ์คํธ๋ฅผ `tests/test_saas_web.py`์ ์ถ๊ฐํ์ต๋๋ค.
|
๐ 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 New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the โ๏ธ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
๐ WalkthroughWalkthrough์๋น์ค ์ด๊ธฐํ ์ API ํค๋ฅผ ๋ฐํ์ ๋ ์ง์คํธ๋ฆฌ์ ์ ์ฅํฉ๋๋ค. ์์ฒญ์์๋ ๋ ์ง์คํธ๋ฆฌ ๊ฐ์ UTF-8 ๋ฐ์ดํธ์ด๋ก ๋น๊ตํฉ๋๋ค. ์์ ๊ฒฐ๊ณผ๋ ์ ์ฉ ๋๋ ํฐ๋ฆฌ๋ก ์ด๋ํ ๋ค ์์ ์์ ๊ณต๊ฐ๊ณผ ๊ฒฐ๊ณผ ํ์ผ์ ์ ๋ฆฌํฉ๋๋ค. ๊ด๋ จ ํ ์คํธ์ Sentinel ๊ธฐ๋ก์ ์ถ๊ฐํ์ต๋๋ค. Changes๋ฐํ์ ์๊ฒฉ ์ฆ๋ช ๋ฐ ๊ฒฐ๊ณผ ์ ๋ฆฌ
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant BatchJob
participant ResultDirectory
participant Client
participant CleanupJob
BatchJob->>ResultDirectory: ๊ฒฐ๊ณผ ZIP ์ด๋ ๋ฐ ๊ฒฝ๋ก ๊ธฐ๋ก
BatchJob->>BatchJob: ์์ ์์
๊ณต๊ฐ ์ญ์
Client->>ResultDirectory: ๊ฒฐ๊ณผ ํ์ผ ๋ค์ด๋ก๋ ์์ฒญ
ResultDirectory-->>Client: ์ ํจํ ๊ฒฐ๊ณผ ํ์ผ ์๋ต
Client->>CleanupJob: ์๋ต ํ ์ ๋ฆฌ ์์
์คํ
CleanupJob->>ResultDirectory: ๊ฒฐ๊ณผ ํ์ผ ์ญ์
๐ฅ Pre-merge checks | โ 5โ Passed checks (5 passed)
โจ Finishing Touches๐ Generate docstrings
๐งช Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
๐ค Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@saas_web.py`:
- Line 117: Update get_configured_api_keys and the authentication middleware to
obtain configured API keys from the credential registry or KV store instead of
reading CODEC_CARVER_API_KEYS per request. Keep the environment variable limited
to registry bootstrap input, and replace the relevant test environment patches
with registry fixtures.
๐ช Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
โน๏ธ Review info
โ๏ธ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 0a45c380-1bbb-45c2-8779-dd0c98221b62
๐ Files selected for processing (3)
.jules/sentinel.mdsaas_web.pytests/test_saas_web.py
|
Review disposition for the credential-registry suggestion: not applicable to this narrow exact-head defect fix. The repository currently has no credential-registry, KV, vault, or secret-store abstraction; the review's own source trace confirms that absence. |
ํ์ธํ์ต๋๋ค. ํด๋น ์ ์์ ์ด๋ฒ PR์ ์์ ๋ฒ์๋ฅผ ๋์ด์๋ ์ํคํ ์ฒ ๋ณ๊ฒฝ์ด๋ฏ๋ก ํ์ฌ์ ์์ ๋ฐฉ์์ ์ ์งํ๊ฒ ์ต๋๋ค. |
๋น๋๊ธฐ ์์ ์ ์์ ๊ฒฐ๊ณผ ๋๋ ํ ๋ฆฌ๊ฐ ๋ค์ด๋ก๋ ์ ๊น์ง ์ญ์ ๋์ง ์๋ ๋์คํฌ ๊ณต๊ฐ ๊ณ ๊ฐ(DoS) ์ทจ์ฝ์ ์ ์์ ํ๊ธฐ ์ํด, ์์ฑ๋ ํ์ผ์ `codec_carver_results` ๋๋ ํ ๋ฆฌ๋ก ์ด๋ ํ ์์ ์์ ํด๋๋ฅผ ์ฆ๊ฐ ์ญ์ ํ๋๋ก ๋ณ๊ฒฝํ์ต๋๋ค. ๋ํ, ํ์ผ ๋ค์ด๋ก๋ ์ `starlette.background.BackgroundTask`๋ฅผ ์ฌ์ฉํ์ฌ ์๋ต ํ ๋ณด์ฅ๋ ์ ๋ฆฌ๊ฐ ์ด๋ฃจ์ด์ง๋๋ก ์์ ํ์ต๋๋ค. `job_result`์ ๊ฒฝ๋ก ๊ฒ์ฆ์์ `.resolve()`๋ฅผ ์ถ๊ฐํ์ฌ OS์ ๋ฐ๋ฅธ symlink ์ด์๋ฅผ ๋ฐฉ์งํ์ต๋๋ค. ์ด์ ์ ๋ฐ๊ฒฌ๋ hmac.compare_digest TypeError DoS ๋ฌธ์ ๋ ํฌํจํ์ฌ ๊ฐ์ ํ์ต๋๋ค.
There was a problem hiding this comment.
Actionable comments posted: 5
๐ค Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@saas_web.py`:
- Around line 695-698: cleanup_batch_result ํจ์์ docstring์ ์ถ๊ฐํด private helper์
์ญํ ์ ์ค๋ช
ํ๊ณ , ๊ธฐ์กด persistent_path ์ ๋ฆฌ ๋์์ ๋ณ๊ฒฝํ์ง ๋ง์ธ์.
- Around line 777-792: Update the result persistence flow around
store.set_status in saas_web.py:777-792 to enforce an independent retention
period or storage quota for completed outputs, and ensure expiration cleanup
removes both the job record and its persistent result file. Document the
implemented cleanup behavior and its limits in .jules/sentinel.md:67-70.
- Around line 777-792: ์๋ฃ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋กํ๋ ํ๋ฆ์์ ๋ค์ด๋ก๋ ํธ์ถ๊ณผ ๋ฌด๊ดํ๊ฒ codec_carver_results์ ์ค๋๋
ํ์ผ์ ์ ๋ฆฌํ๋ ๋ณด์กด ๊ธฐ๊ฐ ๋๋ ์ ์ฅ์ ํ ๋น๋ ์ ์ฑ
์ ์ถ๊ฐํ์ธ์. ๊ฒฐ๊ณผ ์ ์ฅ ํ ์คํ๋๋ ์ ๋ฆฌ ๋ก์ง์ ๋์
ํ๊ณ , ๊ธฐ์กด job_result์
๋ค์ด๋ก๋ ํ ์ญ์ ๋ ๋ณด์กฐ ์ ๋ฆฌ๋ก ์ ์งํ์ธ์. ์ด ์ ์ฑ
์ด ํ์ผ๊ณผ ์ ์ฅ์ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ์ผ๊ด๋๊ฒ ์ ๊ฑฐํ๋๋ก ๊ตฌํํ์ธ์.
- Around line 689-693: Wrap the results directory creation and archive move in
the existing batch error-handling flow so failures from results_dir.mkdir or
shutil.move are caught. Ensure cleanup_temp_dir(temp_dir_path) runs before
returning the standard error response, and preserve the existing success path
after the move completes.
- Around line 689-692: Replace the fixed results directory created in the
result-persistence flow around persistent_path with a uniquely owned root from
tempfile.mkdtemp(), avoiding tempfile.gettempdir() / "codec_carver_results" and
exist_ok=True. Reuse that same generated root consistently in batch creation,
job lookup, and cleanup paths, including the related logic around lines 777-781.
๐ช Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
โน๏ธ Review info
โ๏ธ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 21321109-517f-4171-923e-ceac5f2b4afd
๐ Files selected for processing (5)
.jules/sentinel.mdcredential_registry.pysaas_web.pytests/test_credential_registry.pytests/test_saas_web.py
๐ง Files skipped from review as they are similar to previous changes (1)
- tests/test_saas_web.py
There was a problem hiding this comment.
Actionable comments posted: 3
๐ค Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/doctoring/api-key-credential-registry.md`:
- Around line 55-58: ๋ฌธ์์ NIST SP 800-57 Revision 5/6 ์ํ ์ค๋ช
์์ ๋ฏธ๋ ๊ธฐ์ค์ผ์ธ 2026๋
8์
7์ผ์ ์ ๊ฑฐํ๊ณ , ์ค์ ๊ฒ์ฆ์ผ์ธ 2026๋
8์ 6์ผ๋ก ์์ ํ๊ฑฐ๋ ๋ ์ง ์์ด ์ํ๋ง ๊ธฐ์ ํ์ญ์์ค. Revision 6์ด Initial
Public Draft์ด๋ฉฐ Revision 5๊ฐ ์ต์ข
๊ถ๊ณ ๋ผ๋ ๋ด์ฉ์ ์ ์งํ์ญ์์ค.
In `@tests/test_result_retention.py`:
- Around line 12-21: Separate the optional FastAPI TestClient import from the
application imports in the test module. Set _HAS_FASTAPI based only on whether
fastapi.testclient imports successfully, while importing saas_web, JobStore, and
ConversionResult outside that guarded block so their ImportError propagates
instead of skipping the test class.
- Line 1: Expand docs/papers/README.md with citations, links, and brief
summaries of relevant primary literature supporting result retention and cleanup
procedures, alongside the existing fuzzing references. Ensure the added research
directly covers owned result storage and download-independent cleanup.
๐ช Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
โน๏ธ Review info
โ๏ธ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: bd6567da-9336-499b-a28e-b46d6923987f
๐ Files selected for processing (3)
docs/doctoring/api-key-credential-registry.mdtests/test_result_retention.pytests/test_saas_web.py
|
Repair the current exact head Observed exact-head failures:
Required bounded repair:
Verification must include all exact-head Python versions, complete suite with zero skips, the property suite, every Atheris target, compilation, configured 100% production statement/branch/docstring gates, package/entry-point checks, Security Scan, Semgrep, and fresh automated review. Publish only if the live branch head still equals the expected head and the final diff contains no temporary write workflow or unrelated feature. |
|
@opencode-agent @cwl-noema-review Rebuild this Draft from exact protected current
Run hash-pinned install, focused/complete tests, package smoke, compilation, fuzz/security/SAST, and |
์์
์ ์๋ฃํ์ต๋๋ค. ์๊ตฌํ์ ๋๋ก API ํค ๋น๊ต ์ |
- API ํค ๋น๊ต ์ UTF-8 ์ธ์ฝ๋ฉ ํ `hmac.compare_digest`๋ฅผ ์ฌ์ฉํ์ฌ ํ์ด๋ฐ ๊ณต๊ฒฉ ๋ฐฉ์ง ๋ฐ ๋น ASCII ์ ๋ ฅ DoS ๋ฐฉ์ง - ํ๊ฒฝ ๋ณ์ ์กฐํ๋ฅผ ๋ฐํ์ ์๊ฒฉ ์ฆ๋ช ๋ ์ง์คํธ๋ฆฌ๋ก ๊ฒฉ๋ฆฌ - ์์ ํ๊ณ ๊ฒฉ๋ฆฌ๋ ํ๋ก์ธ์ค ์์ ๊ฒฐ๊ณผ ๋ฃจํธ ๋ฐ ๋ค์ด๋ก๋์ ์์กดํ์ง ์๋ ๋ณด์กด ์ ๋ฆฌ(cleanup) ๋ก์ง ์ถ๊ฐ - ๋ชจ๋ ๋ณด์ ์ทจ์ฝ์ ๊ด๋ จ ๋จ์ ๋ฐ ํตํฉ ํ ์คํธ ์์ฑ
โฆN-0001) ์์ - `saas_web.py` ๋ด์ `uvicorn.run()`์ 127.0.0.1์ ๋ฐ์ธ๋ฉํ๋๋ก ์์ ํ์ฌ ๋คํธ์ํฌ ์ธํฐํ์ด์ค ๋ฌด๋จ ๋ ธ์ถ ๋ฐฉ์ง(VULN-0001 ์์ ) - API ํค ๋น๊ต ์ UTF-8 ์ธ์ฝ๋ฉ ํ `hmac.compare_digest`๋ฅผ ์ฌ์ฉํ์ฌ ํ์ด๋ฐ ๊ณต๊ฒฉ ๋ฐฉ์ง ๋ฐ ๋น ASCII ์ ๋ ฅ DoS ๋ฐฉ์ง - ํ๊ฒฝ ๋ณ์ ์กฐํ๋ฅผ ๋ฐํ์ ์๊ฒฉ ์ฆ๋ช ๋ ์ง์คํธ๋ฆฌ๋ก ๊ฒฉ๋ฆฌ - ์์ ํ๊ณ ๊ฒฉ๋ฆฌ๋ ํ๋ก์ธ์ค ์์ ๊ฒฐ๊ณผ ๋ฃจํธ ๋ฐ ๋ค์ด๋ก๋์ ์์กดํ์ง ์๋ ๋ณด์กด ์ ๋ฆฌ(cleanup) ๋ก์ง ์ถ๊ฐ - ๋ชจ๋ ๋ณด์ ์ทจ์ฝ์ ๊ด๋ จ ๋จ์ ๋ฐ ํตํฉ ํ ์คํธ ์์ฑ
|
Superseded by #373 for the typed fail-closed authentication contract and #367 for durable result ownership/retention. The current Draft combines two independent trust boundaries, retains temporary rebuild machinery, and cannot be reviewed or rolled back safely as one PR. Closing without merge preserves narrower current-main TDD paths for UTF-8 constant-time comparison, rotation, production fail-closed behavior, and separately authorized result lifecycle controls. |
Understood. Acknowledging that this work is now obsolete and stopping work on this task. |
|
@cwl-noema-review @opencode-agent Please review the exact current head after the optional FastAPI test-collection repair. Predecessor-head evidence is stale. |
์ฝ๋ ๋ฆฌ๋ทฐ๋ฅผ ์ํ ์ต์ ํค๋์ ์ค๋น๊ฐ ์๋ฃ๋์์์ ํ์ธํ์ต๋๋ค. FastAPI ํ ์คํธ ์์ง(repair) ๋ฐ ์์ ์ ๋น๋กฏํ ๋ชจ๋ ๋ฐ์์ด ์๋ฃ๋์์ต๋๋ค. |
๐จ Severity
HIGH
๐ก Vulnerability
saas_web.py์require_api_key๋ฏธ๋ค์จ์ด์์hmac.compare_digest๋ฅผ ์ฌ์ฉํ์ฌ API ํค๋ฅผ ๊ฒ์ฆํ ๋, non-ASCII ๋ฌธ์๊ฐ ํฌํจ๋ ์ ๋ ฅ์ด ์ฃผ์ด์ง๋ฉดTypeError์์ธ๊ฐ ๋ฐ์ํฉ๋๋ค.๐ฏ Impact
๊ณต๊ฒฉ์๊ฐ ํค๋์ ์ ์์ ์ธ non-ASCII ๋ฌธ์๋ฅผ ํฌํจํ์ฌ ์ง์์ ์ผ๋ก ์์ฒญ์ ๋ณด๋ด๋ฉด, ์ฒ๋ฆฌ๋์ง ์์ ์์ธ๋ก ์ธํด 500 Server Error๊ฐ ๋ฐ์ํ์ฌ ์๋น์ค ๊ฑฐ๋ถ(DoS) ์ํ๋ฅผ ์ ๋ฐํ ์ ์์ต๋๋ค.
๐ง Fix
hmac.compare_digestํธ์ถ ์ ๋น๊ตํ ๋ ๋ฌธ์์ด(provided_key,key)์ ๋ช ์์ ์ผ๋ก UTF-8 ๋ฐ์ดํธ๋ก ์ธ์ฝ๋ฉํ์ฌ ์์ธ ๋ฐ์์ ๋ฐฉ์งํ์ต๋๋ค.โ Verification
์์ ํ
TestApiKeyAuthํด๋์ค ๋ด์ mockRequest๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ ๋จ์ ํ ์คํธ(test_wrong_key_with_non_ascii_characters_handled_safely)๋ฅผ ์ถ๊ฐํ์ฌ, non-ASCII ํค ์ ๋ ฅ ์ ์ ์์ ์ผ๋ก 401 ์ค๋ฅ๊ฐ ๋ฐํ๋จ์ ํ์ธํ์ต๋๋ค.PR created automatically by Jules for task 9955538586719757639 started by @seonghobae
Summary by CodeRabbit
์ ๊ธฐ๋ฅ
๋ฒ๊ทธ ์์
๋ฌธ์
ํ ์คํธ