Trust Issues: Hijacking Appsmith Accounts via Origin Header Abuse
Jan 15, 2026·5 min read
Executive Summary (TL;DR)
Appsmith trusted the client-supplied 'Origin' header when generating password reset links. An attacker can send a reset request for a victim's email with a malicious Origin (e.g., evil.com). The victim receives a valid email from the Appsmith system, but the link points to the attacker's server. Clicking the link leaks the password reset token, allowing the attacker to hijack the account.
A critical Account Takeover (ATO) vulnerability in Appsmith allows unauthenticated attackers to poison password reset emails by spoofing the HTTP Origin header. This manipulation forces the application to generate legitimate emails containing links to attacker-controlled domains, facilitating credential harvesting.
The Low-Code Honeypot
Appsmith is the darling of the internal tooling world. It’s the glue that holds together your startups' PostgreSQL databases, your Stripe APIs, and your AWS S3 buckets. Developers love it because it turns hours of frontend boilerplate into minutes of drag-and-drop magic. Security researchers love it because it is effectively a centralized repository of your organization's most sensitive credentials.
Think about it: if I compromise your main web app, I might get customer data. If I compromise your Appsmith instance, I get the "God View"—direct access to the admin panels used to manage that customer data, refund transactions, and nuke databases. It is the soft underbelly of the enterprise network, often sitting behind a half-hearted VPN or, worse, exposed directly to the internet with default configurations.
CVE-2026-22794 isn't some complex memory corruption bug requiring a Ph.D. in heap feng shui. It’s a logic flaw born from a developer being too polite. The application asked the user, "Where are you connecting from?" and when the attacker replied, "I'm from the legitimate admin panel, trust me," the server just nodded and handed over the keys.
The Flaw: Blind Trust
The root cause here is a classic violation of the First Commandment of AppSec: Never Trust Client Input. Specifically, this is an implementation of CWE-346: Origin Validation Error. When a user requests a password reset, the server needs to construct a URL that points back to the frontend so the user can enter a new password.
In a robust system, the server knows its own name. It relies on a static configuration file or an environment variable like SITE_URL to build these links. However, prior to version 1.93, Appsmith's UserServiceCEImpl.java took a shortcut. Instead of checking a config, it looked at the HTTP Origin header provided in the request.
This is akin to a bank mailing your new credit card to whatever address you scribbled on a napkin, without checking if it matches the address on file. The server logic effectively said: String baseUrl = request.getHeader("Origin");. It then appended the sensitive reset token to this unvalidated string. If I send Origin: https://evil-hacker.com, the server dutifully generates a link to https://evil-hacker.com/user/resetPassword?token=SECRET_TOKEN.
The Smoking Gun
Let's look at the crime scene. The vulnerability existed in the forgotPasswordTokenGenerate and resendEmailVerification methods. The code grabbed the header and used it immediately. The fix, introduced in commit 6f9ee6226bac13fb4b836940b557913fff78b633, forces a reality check.
Here is the logic that was introduced to patch the hole. Notice the explicit validation against a trusted configuration:
// The Fix: UserServiceCEImpl.java
private Mono<Void> validateBaseUrl(String providedBaseUrl) {
// DANGER: If the config is missing, we might still be vulnerable!
if (!StringUtils.hasText(appsmithBaseUrl)) {
return Mono.empty();
}
// The actual security check
if (!appsmithBaseUrl.equals(providedBaseUrl)) {
return Mono.error(new AppsmithException(
AppsmithError.GENERIC_BAD_REQUEST,
"Origin header does not match APPSMITH_BASE_URL configuration."));
}
return Mono.empty();
}The developers added validateBaseUrl, which compares the incoming header against a server-side appsmithBaseUrl variable. If they don't match, the request dies. Simple, effective, but with a catch we'll discuss in the mitigation section.
The Exploit Chain
Exploiting this is terrifyingly simple because it leverages the victim's trust in the platform's own email infrastructure. This isn't a spoofed email; it is a legitimate email sent by the Appsmith server, DKIM-signed and everything.
Here is how an attacker pulls off the heist:
- Recon: The attacker identifies the email address of an Appsmith administrator (LinkedIn is great for this).
- The Hook: The attacker sends a
POST /api/v1/users/forgotPasswordrequest. They set the Host header correctly, but injectOrigin: https://attack-infrastructure.com. - The Line: Appsmith processes the request, generates a token, and emails the victim: "Click here to reset your password." The link points to
https://attack-infrastructure.com/user/resetPassword?token=.... - The Sinker: The victim clicks the link. Their browser navigates to the attacker's server. The attacker's server logs the URL (containing the token), then immediately redirects the victim back to the real Appsmith login page to avoid suspicion.
- Game Over: The attacker uses the stolen token to reset the victim's password and logs in.
Mitigation: The "Config" Trap
The fix is available in version 1.93. However, simply upgrading the binary is not enough to guarantee safety. The patch includes a conditional check designed for backward compatibility that leaves a massive gap.
Look closely at the patch logic again:
if (!StringUtils.hasText(appsmithBaseUrl)) {
return Mono.empty(); // Returns success if config is missing!
}If the administrator has not explicitly defined the APPSMITH_BASE_URL environment variable or configuration setting, the validation is skipped entirely, and the server reverts to the vulnerable behavior. This is a "secure by configuration" approach rather than "secure by default."
To be safe:
- Update to Appsmith v1.93 or later.
- IMPERATIVE: Set
APPSMITH_BASE_URLin yourdocker.envor environment configuration to your actual domain (e.g.,https://internal-tools.company.com). - Restart the container.
Official Patches
Fix Analysis (1)
Technical Appendix
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:HAffected Systems
Affected Versions Detail
| Product | Affected Versions | Fixed Version |
|---|---|---|
Appsmith Appsmith | < 1.93 | 1.93 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-346 |
| Attack Vector | Network |
| CVSS Score | 9.6 (Critical) |
| Vector String | CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H |
| Impact | Account Takeover |
| EPSS Score | 0.00027 |
MITRE ATT&CK Mapping
The application does not properly verify that the Origin header matches the expected source, allowing attackers to manipulate the base URL used in generated links.
Known Exploits & Detection
Vulnerability Timeline
Subscribe to updates
Get the latest CVE analysis reports delivered to your inbox.