Skip to content

security: validate preview CORS origins by hostname #681

Description

@Osraka

Summary

The faucet and Index Supply API routes currently detect Vercel preview origins with substring matching:

  • src/pages/_api/api/faucet.ts
  • src/pages/_api/api/index-supply.ts

For example, an origin such as:

https://preview.vercel.app.attacker.example

contains vercel.app and may be reflected through Access-Control-Allow-Origin.

This does not appear to enable account compromise, but it weakens the CORS boundary and can allow unintended origins to invoke or read public API responses.

Existing behavior

The recent CORS fix in #612 improved exact allow-list matching, but preview-origin validation still uses origin.includes('vercel.app').

The feedback endpoint already uses URL parsing and hostname validation.

Proposed fix

Validate the origin with new URL(origin) and require:

  • https: protocol
  • hostname ending with .vercel.app
  • existing Tempo and local-development origins remain unchanged

The scope can start with the faucet route if both API routes should not be changed together.

Regression coverage

Tests should:

  • allow a valid Vercel preview origin
  • reject https://preview.vercel.app.attacker.example
  • reject non-HTTPS preview origins
  • preserve existing Tempo and development behavior

I would be happy to prepare a small PR after confirming whether this should cover both routes or start with the faucet route only.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions