Summary
The ContactRequest Pydantic model in backend/app/main.py (lines 1413-1417) defines four string fields (name, email, subject, message) with NO validation constraints. All fields accept:
- Empty strings
- Whitespace-only strings
- Excessively long strings (no
max_length)
- Invalid email formats
This allows submissions with blank or meaningless data that generate broken emails.
Steps to reproduce
- Send a POST to
/api/contact with empty fields:
curl -X POST http://localhost:8000/api/contact \
-H "Content-Type: application/json" \
-d '{"name": "", "email": "", "subject": "", "message": ""}'
- Observe: HTTP 200 is returned, and Resend receives an email with blank fields.
- Send a POST with an extremely long message:
curl -X POST http://localhost:8000/api/contact \
-H "Content-Type: application/json" \
-d '{"name": "A", "email": "a@b.com", "subject": "Test", "message": "'"$(python -c 'print("A"*50000)')"'"}'
- Observe: The oversized message is accepted and forwarded to Resend.
Expected behavior
The ContactRequest model should enforce:
min_length / min_length with strip() on name, subject, and message to prevent blank submissions
max_length on all fields to prevent abuse (e.g., name ≤ 100, subject ≤ 200, message ≤ 5000)
- Email format validation via
EmailStr or a regex pattern
Invalid input should return HTTP 422 with a clear error message.
Actual behavior
ContactRequest has no field validators or constraints:
class ContactRequest(BaseModel):
name: str
email: str
subject: str
message: str
Any string value is accepted, including empty strings, whitespace-only, and strings hundreds of thousands of characters long.
Suggested fix
Add Pydantic field validators and constraints:
from pydantic import Field, field_validator
class ContactRequest(BaseModel):
name: str = Field(min_length=1, max_length=100)
email: str = Field(max_length=254)
subject: str = Field(min_length=1, max_length=200)
message: str = Field(min_length=1, max_length=5000)
@field_validator("name", "subject", "message")
@classmethod
def not_blank(cls, v: str) -> str:
if not v.strip():
raise ValueError("must not be blank")
return v.strip()
@field_validator("email")
@classmethod
def valid_email(cls, v: str) -> str:
if not re.match(r"^[^@\s]+@[^@\s]+\.[^@\s]+$", v):
raise ValueError("invalid email format")
return v.lower().strip()
Summary
The
ContactRequestPydantic model inbackend/app/main.py(lines 1413-1417) defines four string fields (name,email,subject,message) with NO validation constraints. All fields accept:max_length)This allows submissions with blank or meaningless data that generate broken emails.
Steps to reproduce
/api/contactwith empty fields:Expected behavior
The
ContactRequestmodel should enforce:min_length/min_lengthwithstrip()on name, subject, and message to prevent blank submissionsmax_lengthon all fields to prevent abuse (e.g., name ≤ 100, subject ≤ 200, message ≤ 5000)EmailStror a regex patternInvalid input should return HTTP 422 with a clear error message.
Actual behavior
ContactRequesthas no field validators or constraints:Any string value is accepted, including empty strings, whitespace-only, and strings hundreds of thousands of characters long.
Suggested fix
Add Pydantic field validators and constraints: