GHSA-J9GF-VW2F-9HRW
Vulnerability from github – Published: 2026-06-12 18:28 – Updated: 2026-06-12 18:28Summary
A configuration-dependent origin validation bypass was identified in Appsmith’s password reset and email verification flows on current release.
Both flows derive the email-link base URL from the request Origin header. The current validation only enforces a trusted base URL when APPSMITH_BASE_URL is configured. If that setting is unset, the application accepts the caller-supplied origin and uses it to generate token-bearing reset and verification links.
On deployments with email delivery enabled and APPSMITH_BASE_URL unset, this can cause Appsmith to send security-sensitive links whose clickable host is attacker-controlled, which can plausibly lead to account takeover after victim interaction.
Details
The current release head at commit e77639eca4974469c1e676904851ffdaedd38111 was reviewed.
The relevant routes are publicly reachable in SecurityConfig.java:
POST /forgotPasswordis permitted without authentication at line209POST /resendEmailVerificationis permitted without authentication at line228
In UserControllerCE.java, both flows copy the request Origin header into the DTO field used as the email-link base URL:
forgotPasswordRequest(...)at lines91-94resendEmailVerification(...)at lines189-193
In UserServiceCEImpl.java, base URL validation is conditional:
@Value("${APPSMITH_BASE_URL:}")at line113resolveSecureBaseUrl(...)at lines132-145
That method explicitly documents and implements this behavior:
- if
APPSMITH_BASE_URLis configured, the provided URL must match it - if
APPSMITH_BASE_URLis unset, the provided URL is accepted for backward compatibility
The resulting base URL is then used to construct token-bearing links:
FORGOT_PASSWORD_CLIENT_URL_FORMATat line149- reset URL generation at lines
282-289 EMAIL_VERIFICATION_CLIENT_URL_FORMATat line152- verification URL generation at lines
931-940
This means the base URL is not only used for branding or display purposes. It directly controls the clickable host of security-sensitive reset and verification links.
Note that the admin UI describes APPSMITH_BASE_URL as required for password reset and email verification links in:
app/client/src/ce/pages/AdminSettings/config/configuration.tsxat lines41-49
The reviewed self-host material indicates this protection is not fail-closed by default, which makes the vulnerable condition realistic on existing deployments where operators have not set APPSMITH_BASE_URL.
PoC
These steps were designed for validation on an Appsmith deployment that I own or am explicitly authorized to test.
- Deploy a non-production Appsmith instance from current
release, or any build containing the affected code. - Enable outbound email delivery.
- Leave
APPSMITH_BASE_URLunset or blank. - Use a test mailbox account you control, for example
victim@example.test. - Send a password reset request with a forged
Originheader:
curl -i -X POST 'https://YOUR-INSTANCE/api/v1/users/forgotPassword' \
-H 'Content-Type: application/json' \
-H 'Origin: https://attacker.example' \
--data '{"email":"victim@example.test"}'
- Inspect the delivered email. If affected, the clickable reset link is generated under
https://attacker.example/...instead of the legitimate Appsmith host. - Repeat the same validation for resend email verification using an unverified test account:
curl -i -X POST 'https://YOUR-INSTANCE/api/v1/users/resendEmailVerification' \
-H 'Content-Type: application/json' \
-H 'Origin: https://attacker.example' \
--data '{"email":"victim@example.test"}'
- Inspect the delivered verification email. If affected, the clickable verification link is generated under
https://attacker.example/.... - Set
APPSMITH_BASE_URL=https://YOUR-INSTANCE, restart the server, and repeat the same requests. - The expected secure behavior is that mismatched
Originis rejected, or the generated links no longer follow the forged request header.
Live tokens, third-party data, or unsafe exploitation material was not included in this report. The attached archive contains source excerpts, data-flow proof, safe validation notes, and supporting evidence collected from the reviewed current branch.
Impact
This is a trust-boundary failure in token-bearing email authentication flows.
Affected deployments are those where:
APPSMITH_BASE_URLis unset or blank- outbound email is enabled
- password reset and/or email verification flows are enabled
Attacker requirements are low:
- no prior authentication is required to reach the relevant endpoints
- the attacker only needs to trigger an email flow toward a target account
Security impact:
- Appsmith can generate password reset or verification emails whose clickable host is attacker-controlled
- victim interaction can expose security-sensitive token material
- this can plausibly result in account takeover
- at minimum, it enables trusted-email abuse and phishing through the application itself
mitigation
- Remove the fallback behavior in
resolveSecureBaseUrl(...)that accepts caller-supplied origin data whenAPPSMITH_BASE_URLis unset. - Fail closed for all token-bearing email flows when no trusted base URL is configured.
- Use a single trusted-base-url helper across:
- password reset
- resend email verification
- invite flows
- instance admin invite flows
- Add regression tests for the unset-configuration case.
- Add startup or admin-level validation so security-sensitive email flows cannot operate until a trusted base URL is configured.
Attachment
{
"affected": [
{
"package": {
"ecosystem": "Maven",
"name": "com.appsmith:server"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-346",
"CWE-807"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-12T18:28:52Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "### Summary\nA configuration-dependent origin validation bypass was identified in Appsmith\u2019s password reset and email verification flows on current `release`.\n\nBoth flows derive the email-link base URL from the request `Origin` header. The current validation only enforces a trusted base URL when `APPSMITH_BASE_URL` is configured. If that setting is unset, the application accepts the caller-supplied origin and uses it to generate token-bearing reset and verification links.\n\nOn deployments with email delivery enabled and `APPSMITH_BASE_URL` unset, this can cause Appsmith to send security-sensitive links whose clickable host is attacker-controlled, which can plausibly lead to account takeover after victim interaction.\n\n### Details\nThe current `release` head at commit `e77639eca4974469c1e676904851ffdaedd38111` was reviewed.\n\nThe relevant routes are publicly reachable in `SecurityConfig.java`:\n\n- `POST /forgotPassword` is permitted without authentication at line `209`\n- `POST /resendEmailVerification` is permitted without authentication at line `228`\n\nIn `UserControllerCE.java`, both flows copy the request `Origin` header into the DTO field used as the email-link base URL:\n\n- `forgotPasswordRequest(...)` at lines `91-94`\n- `resendEmailVerification(...)` at lines `189-193`\n\nIn `UserServiceCEImpl.java`, base URL validation is conditional:\n\n- `@Value(\"${APPSMITH_BASE_URL:}\")` at line `113`\n- `resolveSecureBaseUrl(...)` at lines `132-145`\n\nThat method explicitly documents and implements this behavior:\n\n- if `APPSMITH_BASE_URL` is configured, the provided URL must match it\n- if `APPSMITH_BASE_URL` is unset, the provided URL is accepted for backward compatibility\n\nThe resulting base URL is then used to construct token-bearing links:\n\n- `FORGOT_PASSWORD_CLIENT_URL_FORMAT` at line `149`\n- reset URL generation at lines `282-289`\n- `EMAIL_VERIFICATION_CLIENT_URL_FORMAT` at line `152`\n- verification URL generation at lines `931-940`\n\nThis means the base URL is not only used for branding or display purposes. It directly controls the clickable host of security-sensitive reset and verification links.\n\nNote that the admin UI describes APPSMITH_BASE_URL as required for password reset and email verification links in:\n\n- `app/client/src/ce/pages/AdminSettings/config/configuration.tsx` at lines `41-49`\n\nThe reviewed self-host material indicates this protection is not fail-closed by default, which makes the vulnerable condition realistic on existing deployments where operators have not set `APPSMITH_BASE_URL`.\n\n\n### PoC\nThese steps were designed for validation on an Appsmith deployment that I own or am explicitly authorized to test.\n\n1. Deploy a non-production Appsmith instance from current `release`, or any build containing the affected code.\n2. Enable outbound email delivery.\n3. Leave `APPSMITH_BASE_URL` unset or blank.\n4. Use a test mailbox account you control, for example `victim@example.test`.\n5. Send a password reset request with a forged `Origin` header:\n\n```bash\ncurl -i -X POST \u0027https://YOUR-INSTANCE/api/v1/users/forgotPassword\u0027 \\\n -H \u0027Content-Type: application/json\u0027 \\\n -H \u0027Origin: https://attacker.example\u0027 \\\n --data \u0027{\"email\":\"victim@example.test\"}\u0027\n```\n\n6. Inspect the delivered email. If affected, the clickable reset link is generated under `https://attacker.example/...` instead of the legitimate Appsmith host.\n7. Repeat the same validation for resend email verification using an unverified test account:\n```bash\ncurl -i -X POST \u0027https://YOUR-INSTANCE/api/v1/users/resendEmailVerification\u0027 \\\n -H \u0027Content-Type: application/json\u0027 \\\n -H \u0027Origin: https://attacker.example\u0027 \\\n --data \u0027{\"email\":\"victim@example.test\"}\u0027\n```\n\n8. Inspect the delivered verification email. If affected, the clickable verification link is generated under `https://attacker.example/....`\n9. Set `APPSMITH_BASE_URL=https://YOUR-INSTANCE`, restart the server, and repeat the same requests.\n10. The expected secure behavior is that mismatched `Origin` is rejected, or the generated links no longer follow the forged request header.\n\nLive tokens, third-party data, or unsafe exploitation material was not included in this report. The attached archive contains source excerpts, data-flow proof, safe validation notes, and supporting evidence collected from the reviewed current branch.\n\n### Impact\nThis is a trust-boundary failure in token-bearing email authentication flows.\n\nAffected deployments are those where:\n\n- `APPSMITH_BASE_URL` is unset or blank\n- outbound email is enabled\n- password reset and/or email verification flows are enabled\n\nAttacker requirements are low:\n\n- no prior authentication is required to reach the relevant endpoints\n- the attacker only needs to trigger an email flow toward a target account\n\nSecurity impact:\n\n- Appsmith can generate password reset or verification emails whose clickable host is attacker-controlled\n- victim interaction can expose security-sensitive token material\n- this can plausibly result in account takeover\n- at minimum, it enables trusted-email abuse and phishing through the application itself\n \n### mitigation\n1. Remove the fallback behavior in `resolveSecureBaseUrl(...)` that accepts caller-supplied origin data when `APPSMITH_BASE_URL` is unset.\n2. Fail closed for all token-bearing email flows when no trusted base URL is configured.\n3. Use a single trusted-base-url helper across:\n - password reset\n - resend email verification\n - invite flows\n - instance admin invite flows\n4. Add regression tests for the unset-configuration case.\n5. Add startup or admin-level validation so security-sensitive email flows cannot operate until a trusted base URL is configured.\n\n### Attachment\n[appsmith-email-link-origin-validation-bypass-20260321.zip](https://github.com/user-attachments/files/26153718/appsmith-email-link-origin-validation-bypass-20260321.zip)",
"id": "GHSA-j9gf-vw2f-9hrw",
"modified": "2026-06-12T18:28:52Z",
"published": "2026-06-12T18:28:52Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/appsmithorg/appsmith/security/advisories/GHSA-j9gf-vw2f-9hrw"
},
{
"type": "PACKAGE",
"url": "https://github.com/appsmithorg/appsmith"
},
{
"type": "WEB",
"url": "https://github.com/appsmithorg/appsmith/releases/tag/v2.0"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "Appsmith: Configuration-dependent origin validation bypass in password reset and email verification link generation"
}
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.