CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Dashboard
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-27899
8.80.07%

CVE-2026-27899: The 'Are You God?' Checkbox in WireGuard Portal

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 27, 2026·6 min read·13 visits

PoC Available

Executive Summary (TL;DR)

WireGuard Portal trusted user input too much. By sending `"IsAdmin": true` in a profile update, any standard user becomes a root-level administrator. Fixed in v2.1.3 by explicitly filtering sensitive fields.

A critical Privilege Escalation vulnerability in h44z/wg-portal allows any authenticated user to promote themselves to Administrator by simply adding a JSON field to a profile update request. This classic Mass Assignment vulnerability exposes the entire VPN management interface to compromise.

The Hook: Trusting the Client

WireGuard is the darling of the VPN world—lean, fast, and cryptographically sound. But nobody likes managing config files via CLI, so tools like wg-portal exist to give us a nice, shiny web UI. It handles user management, peer provisioning, and the delicate dance of public keys. It is the gatekeeper to your private network.

Now, imagine that gatekeeper has a clipboard. When you walk up to update your profile (say, to change your last name), the gatekeeper hands you the clipboard and says, "Here, write down your new details." You write your name, and then, at the bottom of the page, you scribble in a new box: "Is Boss: YES."

In a secure system, the gatekeeper would look at that and say, "Nice try, buddy." In wg-portal versions prior to 2.1.3, the gatekeeper just nods, types it into the database, and hands you the keys to the castle. This is CVE-2026-27899, a classic, textbook Mass Assignment vulnerability that turns a lowly user into a network god with a single HTTP request.

The Flaw: A fatal lack of boundaries

The root cause here is a failure in the Object-Relational Mapping (ORM) or, more specifically, the JSON unmarshalling logic. In modern web development, we love convenience. We love taking a JSON blob from a frontend request and magically mapping it to a backend struct. It saves us from writing boring code like user.Name = request.Name fifty times.

However, this convenience is a loaded gun. The wg-portal application defined a User struct that represented the database schema. This struct contained everything about a user: their email, their name, their linked peers, and—crucially—their privileges, represented by the IsAdmin boolean.

When the PUT /api/v1/user/profile endpoint received a request, it didn't use a Data Transfer Object (DTO) or a whitelist of allowed fields. It took the raw JSON and unmarshalled it directly into the User domain model. Because the IsAdmin field was public (exported in Go) and tagged for JSON, the standard library happily overwrote the existing false value with whatever the attacker provided. The application failed to ask the most important question: "Is this user actually allowed to change this specific field?"

The Code: The Smoking Gun

Let's look at the anatomy of the failure. In Go, if you have a struct like this:

type User struct {
    Identifier string `json:"id"`
    Email      string `json:"email"`
    IsAdmin    bool   `json:"isAdmin"` // <--- The dangerous field
    // ... other fields
}

And you handle updates like this:

func UpdateProfile(c echo.Context) error {
    u := new(User)
    if err := c.Bind(u); err != nil { // <--- Auto-binds ALL JSON fields
        return err
    }
    // Save u to database...
}

You have created a security hole. The fix, introduced in version 2.1.3 (specifically commit fe4485037a25426446ced95050e9498f477bf71d), was to stop trusting the binding process blindly. The developer introduced a method called CopyAdminAttributes.

Instead of taking the user's input as gospel, the system now fetches the existing user from the database. If the user making the request is NOT an admin, the system forcibly overwrites the sensitive fields in the input object with the values from the database, effectively ignoring the attacker's attempt to toggle the boolean.

// The Fix Logic (Simplified)
func (u *User) CopyAdminAttributes(src *User, apiAdminOnly bool) {
    // ...
    if !apiAdminOnly {
        u.IsAdmin = src.IsAdmin // Reset to DB value, ignoring input
        u.Locked = src.Locked
        u.Disabled = src.Disabled
    }
}

They also added validateAdminModifications to throw an explicit error, but the CopyAdminAttributes function is the real shield here. It ensures that even if you send the data, it gets sanitized before persistence.

The Exploit: Promoting yourself

Exploiting this is almost insultingly easy. You don't need buffer overflows or heap spraying. You just need Burp Suite, Postman, or curl.

Step 1: Authenticate Log in as a standard user. Get your session cookie or JWT.

Step 2: Capture the Update Request Go to your profile page and change something trivial, like your name. Capture that request. It will look something like this:

PUT /api/v1/user/profile HTTP/1.1
Host: vpn.target.com
Content-Type: application/json
Cookie: session=...
 
{
  "firstname": "John",
  "lastname": "Doe",
  "email": "john@example.com"
}

Step 3: The Injection Modify the JSON body to include the forbidden flag. You don't even need to be subtle.

{
  "firstname": "John",
  "lastname": "Doe",
  "email": "john@example.com",
  "IsAdmin": true
}

Step 4: Execute Send the request. The server responds with 200 OK. The database is updated.

Step 5: Enjoy the Power Refresh the page or log out and back in. The UI will render the "Administration" tab. You can now revoke the CEO's VPN keys, create backdoors for yourself, or delete the entire user base.

The Impact: Total Network Compromise

Why is this a CVSS 8.8 and not higher? Only because you need a valid account first. But in a corporate environment, "valid account" just means "any employee" or "anyone who phished an employee."

Once an attacker becomes an Admin in wg-portal, the game is over. They gain:

  1. Confidentiality Loss: They can view the configuration of every peer, potentially exposing private subnets and internal IP schemes.
  2. Integrity Loss: They can inject new peers. This is the big one. An attacker can generate a new WireGuard config for themselves, authorize it, and instantly gain L3 network access to the internal network protected by the VPN.
  3. Availability Loss: They can lock out legitimate administrators or revoke certificates/keys for critical infrastructure, causing a Denial of Service.

This isn't just about changing a flag in a database; it's about bypassing the perimeter security of the organization.

The Fix: Remediation and Lessons

If you are running wg-portal < 2.1.3, you are vulnerable. The remediation is straightforward: Update immediately.

  • Pull the latest Docker image: docker pull h44z/wg-portal:latest (or specifically tag v2.1.3).
  • Verify: Check your version number in the footer.

For Developers: This vulnerability is a harsh lesson in API design. Never bind your internal database models directly to your public API endpoints. Always use DTOs (Data Transfer Objects).

Create a UpdateUserRequest struct that only contains the fields a user is allowed to change (FirstName, LastName). If IsAdmin isn't in that struct, the JSON parser physically cannot overwrite it, no matter what the attacker sends. Explicit whitelisting is always safer than blacklisting or manual sanitization.

Official Patches

h44zRelease v2.1.3 containing the fix

Fix Analysis (1)

Technical Appendix

CVSS Score
8.8/ 10
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
EPSS Probability
0.07%
Top 79% most exploited

Affected Systems

WireGuard Portal (wg-portal) < v2.1.3

Affected Versions Detail

Product
Affected Versions
Fixed Version
wg-portal
h44z
< 2.1.32.1.3
AttributeDetail
CWE IDCWE-269 (Improper Privilege Management)
Attack VectorNetwork (API)
CVSS v3.18.8 (High)
Exploit StatusProof-of-Concept (Trivial)
Patch Date2026-02-23
ImpactFull Administrative Access

MITRE ATT&CK Mapping

T1068Exploitation for Privilege Escalation
Privilege Escalation
T1078Valid Accounts
Initial Access
CWE-269
Improper Privilege Management

The application does not properly assign, modify, track, or check privileges for an actor, creating an unintended sphere of control for that actor.

Known Exploits & Detection

GitHub AdvisoryOfficial advisory containing reproduction steps
NucleiDetection Template Available

Vulnerability Timeline

Patch committed to master branch
2026-02-23
CVE Published and GHSA released
2026-02-26

References & Sources

  • [1]GHSA Advisory
  • [2]NVD Entry

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.