Skip to content

πŸ›‘οΈ Sentinel: [MEDIUM] Fix control character injection in schemas#619

Open
seonghobae wants to merge 2 commits into
mainfrom
sentinel-fix-control-chars-schemas-16772809612572038082
Open

πŸ›‘οΈ Sentinel: [MEDIUM] Fix control character injection in schemas#619
seonghobae wants to merge 2 commits into
mainfrom
sentinel-fix-control-chars-schemas-16772809612572038082

Conversation

@seonghobae

Copy link
Copy Markdown
Collaborator

🚨 Severity: MEDIUM
πŸ’‘ Vulnerability: DiagramViewCreateIn, TableAnnotationUpsertIn, ApiKeyCreateIn λ“± μ—¬λŸ¬ Pydantic μŠ€ν‚€λ§ˆμ˜ λ¬Έμžμ—΄ ν•„λ“œκ°€ μ œμ–΄ 문자(Control characters)에 λŒ€ν•œ 검증 없이 길이 μ œν•œλ§Œ μ μš©λ˜μ–΄ μžˆμ—ˆμŠ΅λ‹ˆλ‹€.
🎯 Impact: μ•…μ˜μ μΈ μ‚¬μš©μžκ°€ 널 λ°”μ΄νŠΈ(\x00)λ‚˜ κ°œν–‰ 문자, νƒ­ λ“±μ˜ μ œμ–΄ 문자λ₯Ό μ‚½μž…ν•˜μ—¬ 둜그 μΈμ μ…˜, 터미널 μ΄μŠ€μΌ€μ΄ν”„ μ‘°μž‘ λ˜λŠ” μ‹œμŠ€ν…œμ˜ 예기치 μ•Šμ€ λ™μž‘μ„ μœ λ°œν•  수 μžˆμŠ΅λ‹ˆλ‹€.
πŸ”§ Fix: μ œμ–΄ λ¬Έμžκ°€ ν•„μš” μ—†λŠ” λ¬Έμžμ—΄ ν•„λ“œλ“€μ— λŒ€ν•΄ λͺ…μ‹œμ μœΌλ‘œ μ •κ·œν‘œν˜„μ‹ νŒ¨ν„΄(pattern=r"^[^\x00-\x1F\x7F]+$")을 μΆ”κ°€ν•˜μ—¬ ASCII μ œμ–΄ 문자의 μž…λ ₯을 μ—„κ²©νžˆ μ°¨λ‹¨ν–ˆμŠ΅λ‹ˆλ‹€.
βœ… Verification: backend/app/schemas.py의 νŒ¨ν„΄ μˆ˜μ • ν›„ uv run pytestλ₯Ό μ‹€ν–‰ν•˜μ—¬ κΈ°μ‘΄ ν…ŒμŠ€νŠΈ 톡과λ₯Ό ν™•μΈν•˜μ˜€μœΌλ©°, μ •κ·œμ‹μ— μ˜ν•œ μ œμ–΄ 문자 필터링 λ™μž‘μ„ 슀크립트둜 κ²€μ¦ν–ˆμŠ΅λ‹ˆλ‹€.


PR created automatically by Jules for task 16772809612572038082 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 22, 2026 02:08

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

Note

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Adds stricter validation to several Pydantic input schemas to block ASCII control characters in user-provided string fields (mitigating log/terminal injection vectors), and records the hardening guidance in the Sentinel notes.

Changes:

  • Added pattern=r"^[^\x00-\x1F\x7F]+$" to selected string fields in Pydantic request schemas.
  • Expanded .jules/sentinel.md with an extended entry describing the control-character hardening approach.

Reviewed changes

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

File Description
backend/app/schemas.py Adds regex-based validation to block ASCII control characters in multiple request schema string fields.
.jules/sentinel.md Documents the vulnerability pattern and the prevention guidance for consistent schema hardening.

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

Comment thread backend/app/schemas.py
Comment on lines +193 to +197
name: str = Field(
min_length=1,
max_length=200,
pattern=r"^[^\x00-\x1F\x7F]+$",
)
Comment thread backend/app/schemas.py
Comment on lines +221 to +230
schema_name: str = Field(
min_length=1,
max_length=255,
pattern=r"^[^\x00-\x1F\x7F]+$",
)
relation_name: str = Field(
min_length=1,
max_length=255,
pattern=r"^[^\x00-\x1F\x7F]+$",
)
Comment thread backend/app/schemas.py
Comment on lines +317 to +321
key_name: str = Field(
min_length=1,
max_length=128,
pattern=r"^[^\x00-\x1F\x7F]+$",
)
Comment thread backend/app/schemas.py Outdated
Comment thread backend/app/schemas.py Outdated
Comment thread backend/app/schemas.py Outdated
Comment thread backend/app/schemas.py Outdated
Comment thread backend/app/schemas.py
Comment on lines +193 to +197
name: str = Field(
min_length=1,
max_length=200,
pattern=r"^[^\x00-\x1F\x7F]+$",
)
@seonghobae

Copy link
Copy Markdown
Collaborator Author

@copilot Fix the code for all comments in this review thread.

When a review comment includes a suggested change, apply the suggestion exactly.

Do not make changes beyond what is described in the linked review thread.

Copilot AI review requested due to automatic review settings July 22, 2026 03:04

Copilot AI commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

@copilot Fix the code for all comments in this review thread.

When a review comment includes a suggested c...

Addressed all feedback in commit refactor(schemas): extract NO_ASCII_CONTROL_CHARS_PATTERN constant, extend to C1 controls:

  • Extracted constant: Defined NO_ASCII_CONTROL_CHARS_PATTERN at module level (after imports) and replaced all 6 duplicate regex literals with it.
  • Extended to C1 controls: Updated pattern from ^[^\x00-\x1F\x7F]+$ to ^[^\x00-\x1F\x7F-\x9F]+$, now blocking C0 (\x00–\x1F), DEL (\x7F), and C1 (\x80–\x9F) control characters.
  • Pydantic version: Confirmed pydantic>=2.13.4 (v2) is in use β€” pattern= is the correct parameter name, no change needed.

19 existing tests continue to pass.

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

Comment thread backend/app/schemas.py
Comment on lines +9 to +11
# Rejects ASCII C0 controls (\x00–\x1F), DEL (\x7F), and C1 controls
# (\x80–\x9F) to prevent log/terminal injection in user-supplied strings.
NO_ASCII_CONTROL_CHARS_PATTERN = r"^[^\x00-\x1F\x7F-\x9F]+$"
Comment thread backend/app/schemas.py
Comment on lines +197 to +201
name: str = Field(
min_length=1,
max_length=200,
pattern=NO_ASCII_CONTROL_CHARS_PATTERN,
)
Comment thread backend/app/schemas.py
Comment on lines +225 to +234
schema_name: str = Field(
min_length=1,
max_length=255,
pattern=NO_ASCII_CONTROL_CHARS_PATTERN,
)
relation_name: str = Field(
min_length=1,
max_length=255,
pattern=NO_ASCII_CONTROL_CHARS_PATTERN,
)
Comment thread backend/app/schemas.py
Comment on lines +321 to +325
key_name: str = Field(
min_length=1,
max_length=128,
pattern=NO_ASCII_CONTROL_CHARS_PATTERN,
)
Comment thread .jules/sentinel.md
Comment on lines 4 to +8
**Prevention:** Use explicit regex validation `pattern=r'^[^\x00-\x1F\x7F]+$'` on Pydantic string fields to strictly reject control characters.
## 2025-02-18 - Hardening Pydantic String Fields Against Control Characters (Extended)
**Vulnerability:** Several Pydantic string fields such as schema names, relation names, and diagram view names were missing strict validation against ASCII control characters, only relying on length constraints.
**Learning:** Incomplete validation across schemas can lead to log injection, terminal manipulation, or unintended backend behaviors if these fields are logged or processed.
**Prevention:** Consistently apply the explicit regex validation `pattern=r"^[^\x00-\x1F\x7F]+$"` on all relevant Pydantic string fields, except for fields like bodies or raw scripts that legitimately require newlines and tabs.
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.

3 participants