Skip to content

Limit api/graphql requests to recognized origins.#2939

Open
Soxasora wants to merge 1 commit into
stackernews:masterfrom
Soxasora:feat/dynamic-graphql-access
Open

Limit api/graphql requests to recognized origins.#2939
Soxasora wants to merge 1 commit into
stackernews:masterfrom
Soxasora:feat/dynamic-graphql-access

Conversation

@Soxasora

@Soxasora Soxasora commented Apr 30, 2026

Copy link
Copy Markdown
Member

Description

Adds a dynamic CORS to api/graphql. If the current origin of the request is the main domain (stacker.news) or a valid ACTIVE custom domain, Access-Control-Allow-Origin will feature the current origin. If not, CORS won't be injected and the browser won't make the request.

Additional Context

This doesn't serve any real purpose at the moment, imo. Cross-origin requests are already prohibited due to missing CORS, and we only make same-origin requests in-app (stacker.news/api/graphql, customdomain.com/api/graphql). At most it enables future cross-origin requests.

Checklist

Are your changes backward compatible? Please answer below:

Yes

On a scale of 1-10 how well and how have you QA'd this change and any features it might affect? Please answer below:

6, works correctly, cross-origin is prevented on non-recognized domains as expected.

Did you use AI for this? If so, how much did it assist you?

CORS review


Note

Medium Risk
Touches the GraphQL API edge surface and cross-origin behavior; a mistake could unintentionally block legitimate clients or overly broaden allowed origins if domain mapping validation is wrong.

Overview
Adds an origin allowlist for /api/graphql by injecting CORS response headers only when the request Origin matches the main site domain or an ACTIVE custom domain mapping.

Introduces isAllowedOrigin in lib/domains.js to validate/parse the Origin URL and check it against cached domain mappings, and updates the GraphQL API handler to set Vary: Origin and short-circuit OPTIONS preflights (returning 204 without CORS headers when not allowlisted).

Reviewed by Cursor Bugbot for commit c14d954. Bugbot is set up for automated code reviews on this repo. Configure here.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c14d954. Configure here.

Comment thread lib/domains.js
if (originHost === SN_MAIN_DOMAIN.host) return true

const mapping = await getDomainMapping(originHost)
return !!mapping

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Port stripping allows unintended origins through CORS check

Low Severity

isAllowedOrigin passes originUrl.host (which includes non-standard ports, e.g. verified-domain.com:8443) to getDomainMapping, which internally calls normalizeDomain that strips the port by splitting on :. This means any non-standard port on a verified custom domain (e.g. https://verified-domain.com:9999) would pass the CORS origin check, even though it's a distinct origin from the verified verified-domain.com.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit c14d954. Configure here.

@Soxasora Soxasora Apr 30, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The custom domain must set a CNAME pointed directly to us, can't have port numbers. Now yes, at the moment there is no DNS check cronjob, but custom domains won't be public until it gets implemented.

@Soxasora

Copy link
Copy Markdown
Member Author

This doesn't serve any real purpose at the moment, imo. Cross-origin requests are already prohibited due to missing CORS, and we only make same-origin requests in-app

We could deny access to api/graphql to non-recognized domains by checking the host header instead (?)

@sir-opti

Copy link
Copy Markdown
Contributor

We could deny access to api/graphql to non-recognized domains by checking the host header instead (?)

I don't think that Host: changes with cross-origin requests? Just Origin:? What situation are you trying to prevent?

@huumn

huumn commented May 1, 2026

Copy link
Copy Markdown
Member

What situation are you trying to prevent?

This was motivated by a discussion about phishing - someone trivially running an SN lookalike to do something.

  1. I'm not sure how realistic a problem this is
  2. anyone can get around CORS with a reverse proxy

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants