HIGH email injectionfastapibasic auth

Email Injection in Fastapi with Basic Auth

Email Injection in Fastapi with Basic Auth — how this specific combination creates or exposes the vulnerability

Email Injection occurs when user-controlled input is placed into email headers or body values without proper validation, enabling attackers to inject additional headers, forge sender or recipient addresses, or manipulate mail server behavior. In Fastapi applications that handle user registration, password resets, or notifications, email fields such as to, from, reply-to, or message body content are common injection targets. When Basic Auth is used, the API typically requires a username and password in the Authorization header, but this does not inherently protect email workflows; authentication confirms identity, not the safety of email content derived from user input or internal data.

Combining Basic Auth with email functionality can inadvertently expose injection risks if the implementation treats authenticated requests as trusted. For example, an authenticated user may submit a profile update that includes an email address used later in transactional messages. If the application directly embeds this email value into SMTP headers or templates without sanitization or strict validation, attackers can inject newline characters (\r\n) to append forged headers such as Cc:, Bcc:, or additional From: lines. Some mail servers or libraries may process these injected lines, leading to header smuggling, unintended recipients, or email spoofing. Even when Fastapi enforces Basic Auth via middleware or dependencies, the email generation layer must still validate and encode user-provided or derived email data to prevent injection.

An OpenAPI specification that models an email-sending endpoint may define a JSON body with an email property but omit strict format constraints, allowing values like [email protected]\r\nCc: [email protected] to be accepted. During scanning, middleBrick checks input validation and data exposure to detect whether email fields are constrained and whether runtime behavior reflects unsafe handling. Because Basic Auth secures the endpoint but not the content derived from it, developers must implement output encoding and strict schema validation to ensure that email headers remain intact and that authenticated sessions do not bypass safe email construction practices.

Basic Auth-Specific Remediation in Fastapi — concrete code fixes

To remediate Email Injection in Fastapi while using Basic Auth, focus on strict input validation, safe header construction, and secure handling of email values. Use a structured Pydantic model to enforce email format and reject values containing newline characters or other control characters. When constructing SMTP messages, avoid string concatenation for headers; use dedicated email libraries that handle encoding and line folding safely. Below is a minimal, secure Fastapi example that combines HTTP Basic Auth with validated email handling.

from fastapi import Fastapi, Depends, HTTPException, status
from fastapi.security import HTTPBasic, HTTPBasicCredentials
from pydantic import BaseModel, EmailStr, validator
import re
import smtplib
from email.message import EmailMessage

app = Fastapi()
security = HTTPBasic()

# Simple hardcoded user store for demonstration
USERS = {"alice": "wonderland"}

def verify_auth(credentials: HTTPBasicCredentials = Depends(security)):
    if credentials.username not in USERS or USERS[credentials.username] != credentials.password:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid credentials",
            headers={"WWW-Authenticate": "Basic"},
        )
    return credentials.username

class EmailRequest(BaseModel):
    to: EmailStr
    subject: str
    body: str

    # Reject newlines to prevent header injection
    @validator("subject", "body", pre=True, always=True)
    def reject_newlines(cls, v):
        if isinstance(v, str) and ("\n" in v or "\r" in v):
            raise ValueError("Newline characters not allowed")
        return v

@app.post("/send-notification")
def send_notification(
    req: EmailRequest,
    username: str = Depends(verify_auth)
):
    msg = EmailMessage()
    msg["Subject"] = req.subject
    msg["From"] = "[email protected]"
    msg["To"] = req.to
    msg.set_content(req.body)

    # Safe SMTP transmission (example localhost; adapt as needed)
    try:
        with smtplib.SMTP("localhost") as server:
            server.send_message(msg)
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Failed to send email: {e}")

    return {"status": "sent", "to": req.to}

This pattern ensures that authenticated requests still validate email and text fields, blocking newline characters that could enable injection. For production, configure the SMTP client with secure transport and consider additional checks on recipient domains. middleBrick can help verify that input validation rules are present in your OpenAPI spec and that runtime tests do not expose raw email values in data exposure findings.

Frequently Asked Questions

Does using Basic Auth prevent email injection by itself?
No. Basic Auth only verifies identity for the API request; it does not sanitize or validate email header values. Injection prevention requires strict validation and safe construction of email headers and bodies.
How can I test my Fastapi endpoints for Email Injection without a pentest vendor?
Use a scanner like middleBrick which runs unauthenticated black-box checks including input validation and data exposure. You can also manually test by submitting newline characters in email fields (e.g., \r\nCc:) and inspecting whether headers are reflected or modified by the server or mail backend.