Skip to content

[Bug]: Contact form ContactRequest model has no input validation — empty or oversized submissions accepted #290

Description

@vipul674

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

  1. 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": ""}'
  1. Observe: HTTP 200 is returned, and Resend receives an email with blank fields.
  2. 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)')"'"}'
  1. 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()

Activity

  1. vipul674 commented on Jul 6, 2026

    @vipul674
    ContributorAuthor

    @Aashikhandelwal05 I would like to work on this issue under GSSoC 2026. Please assign it to me.

  2. aaniya22 commented on Jul 7, 2026

    @aaniya22
    Contributor

    pls assign this to me under gssoc

  3. Aashikhandelwal05 commented on Jul 19, 2026

    @Aashikhandelwal05
    Owner

    Hey @vipul674! Assigning this to you under GSSoC '26
    Reference in PR: Closes #290. Ask questions here if stuck!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions