Skip to content

fix: require subdomain boundary in isAppwriteOwned domain check#11873

Open
yogeshwaran-c wants to merge 1 commit intoappwrite:1.9.xfrom
yogeshwaran-c:fix/proxy-isappwriteowned-subdomain-matching
Open

fix: require subdomain boundary in isAppwriteOwned domain check#11873
yogeshwaran-c wants to merge 1 commit intoappwrite:1.9.xfrom
yogeshwaran-c:fix/proxy-isappwriteowned-subdomain-matching

Conversation

@yogeshwaran-c
Copy link
Copy Markdown

What kind of change does this PR introduce?

Bug fix

What is the current behavior?

The isAppwriteOwned() method in src/Appwrite/Platform/Modules/Proxy/Action.php uses \str_ends_with($domain, $appwriteDomain) to determine if a domain is owned by Appwrite. This check is too permissive — it matches any domain whose name ends with the Appwrite domain string, even if it is not an actual subdomain.

For example, if _APP_DOMAIN_SITES is set to appwrite.network:

  • myapp.appwrite.network → correctly matches (legitimate subdomain)
  • evil-appwrite.networkincorrectly matches (completely different domain)

When isAppwriteOwned() returns true, the proxy rule creation endpoints skip DNS verification and immediately set the rule status to RULE_STATUS_VERIFIED with owner 'Appwrite'. This means a domain like evil-appwrite.network would bypass domain verification entirely.

What is the new behavior?

The check now requires either:

  1. An exact match ($domain === $appwriteDomain), or
  2. A proper subdomain match — the domain must end with '.' . $appwriteDomain (note the dot separator)

This ensures only legitimate subdomains of Appwrite-owned domains are recognized:

  • myapp.appwrite.network → matches (ends with .appwrite.network)
  • evil-appwrite.network → does not match (does not end with .appwrite.network)

Additional context

The fix is a single-line change. The same pattern of requiring a dot boundary for subdomain matching is a well-established security practice to prevent domain confusion attacks.

Test plan

  • Create a proxy rule with a domain that is a legitimate subdomain of an Appwrite domain (e.g., test.appwrite.network when _APP_DOMAIN_SITES=appwrite.network) — should be recognized as Appwrite-owned and skip verification
  • Create a proxy rule with a domain that merely ends with an Appwrite domain string but is not a subdomain (e.g., evil-appwrite.network) — should NOT be recognized as Appwrite-owned and should require DNS verification
  • Create a proxy rule with the exact Appwrite domain (e.g., appwrite.network) — should be recognized as Appwrite-owned

The isAppwriteOwned method used str_ends_with to check if a domain
belongs to Appwrite. This incorrectly matched domains like
evil-appwrite.network against appwrite.network because str_ends_with
only checks the suffix without requiring a subdomain boundary (dot).

This could allow a non-Appwrite domain to bypass DNS verification and
be marked as verified with owner Appwrite, since isAppwriteOwned sets
RULE_STATUS_VERIFIED for matching domains.

The fix requires either an exact match or a proper subdomain match
(preceded by a dot separator).
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 12, 2026

Greptile Summary

This PR fixes a domain confusion vulnerability in isAppwriteOwned() by replacing a bare str_ends_with check with an exact-match-or-dot-boundary check, preventing domains like evil-appwrite.network from being auto-verified as Appwrite-owned when _APP_DOMAIN_SITES=appwrite.network. The fix is minimal, correct, and covers all four Create callers (Site, Redirect, Function, API) through the shared base method.

Confidence Score: 5/5

Safe to merge — single-line fix correctly closes a domain verification bypass with no regressions.

The change is minimal, targeted, and logically correct. The dot-boundary pattern is the standard approach for subdomain matching. All four callers of isAppwriteOwned() benefit automatically through the shared base method. No new dependencies or logic paths are introduced.

No files require special attention.

Important Files Changed

Filename Overview
src/Appwrite/Platform/Modules/Proxy/Action.php Single-line security fix: adds exact-match and dot-boundary subdomain check to isAppwriteOwned(), closing a domain confusion bypass that would grant RULE_STATUS_VERIFIED to domains like evil-appwrite.network.

Reviews (1): Last reviewed commit: "fix: require subdomain boundary in isApp..." | Re-trigger Greptile

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.

1 participant