Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
**Vulnerability:** User-provided string fields (like project and connection names) lacked strict validation against control characters, only relying on length constraints.
**Learning:** This could potentially lead to Log Injection (CRLF injection), Null Byte Injection, or terminal escape injection if these strings are subsequently logged or rendered directly.
**Prevention:** Use explicit regex validation `pattern=r'^[^\x00-\x1F\x7F]+$'` on Pydantic string fields to strictly reject control characters.
## 2025-02-18 - Hardening Remaining Pydantic String Fields Against Control Characters\n**Vulnerability:** User-provided string fields for diagram views and API keys lacked strict validation against control characters.\n**Learning:** Incomplete application of the strict regex pattern left some inputs vulnerable to log injection and similar risks.\n**Prevention:** Apply the regex validation `pattern=r'^[^\x00-\x1F\x7F]+$'` universally across all Pydantic string fields that do not explicitly require multiline inputs.
8 changes: 6 additions & 2 deletions backend/app/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,9 @@ class IndexRedundancyOut(BaseModel):
class DiagramViewCreateIn(BaseModel):
"""Request body for saving an ERD canvas view."""

name: str = Field(min_length=1, max_length=200)
name: str = Field(
min_length=1, max_length=200, pattern=r"^[^\x00-\x1F\x7F]+$"
)
# Opaque client layout (node positions, hidden tables, viewport). The API
# bounds the serialized size in the endpoint to prevent abuse.
layout_json: dict
Expand Down Expand Up @@ -302,7 +304,9 @@ class DbmlConvertOut(BaseModel):
class ApiKeyCreateIn(BaseModel):
"""Request body for creating an API key."""

key_name: str = Field(min_length=1, max_length=128)
key_name: str = Field(
min_length=1, max_length=128, pattern=r"^[^\x00-\x1F\x7F]+$"
)


class ApiKeyOut(BaseModel):
Expand Down
Loading