{"id":"GHSA-47hv-j4px-h3c9","summary":"Wails: wildcardPatternToRegex allows Origin bypass via suffix match in BindingsAllowedOrigins","details":"# Security Vulnerability Report: Wails v2 — Origin Validator Bypass via Wildcard Pattern\n\n| | |\n|---|---|\n| **Product** | wailsapp/wails (v2) |\n| **Affected File** | `v2/internal/frontend/originvalidator/originValidator.go` |\n| **Affected Versions** | All versions containing originValidator (latest as of 2026-03-26) |\n| **CVSSv4.0** | **7.6 HIGH** — `CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:H/VI:H/VA:L/SC:L/SI:L/SA:N` |\n| **CWE** | CWE-625: Permissive Regular Expression |\n| **Platforms** | Windows / Linux / macOS (all desktop targets) |\n\n---\n\n## Summary\n\nWails v2 provides `BindingsAllowedOrigins` to restrict which web origins can invoke Go backend methods via IPC. The wildcard pattern matching in `wildcardPatternToRegex` converts `*` to `.*` without anchoring subcomponents, allowing suffix-matched origins to bypass the restriction.\n\nAn attacker who controls a domain sharing a prefix with the allowed origin (e.g., `myapp.community` when `myapp.com*` is configured) can invoke arbitrary bound Go methods, potentially achieving file system access, data exfiltration, or code execution depending on the application's exposed API surface.\n\n---\n\n## Vulnerability Details\n\n### Root Cause\n\n`wildcardPatternToRegex` converts a wildcard pattern to a regular expression by escaping special characters and replacing `*` with `.*`. The substituted `.*` has no restriction — it matches any character sequence including dots and additional domain components.\n\n### Vulnerable Code\n\n**File:** `v2/internal/frontend/originvalidator/originValidator.go`\n\n```go\nfunc (v *OriginValidator) wildcardPatternToRegex(wildcardPattern string) string {\n    specialChars := []string{\"\\\\\", \".\", \"+\", \"?\", \"^\", \"$\", \"{\", \"}\", \"(\", \")\", \"|\", \"[\", \"]\"}\n\n    escaped := wildcardPattern\n    for _, specialChar := range specialChars {\n        escaped = strings.ReplaceAll(escaped, specialChar, \"\\\\\"+specialChar)\n    }\n\n    // * becomes .* — matches ANY character sequence, including dots and domain separators\n    escaped = strings.ReplaceAll(escaped, \"*\", \".*\")\n\n    return \"^\" + escaped + \"$\"\n}\n```\n\nThe generated regex for `https://myapp.com*` is:\n\n```\n^https://myapp\\.com.*$\n```\n\nThis matches any string beginning with `https://myapp.com`, including:\n\n- `https://myapp.community` — different TLD\n- `https://myapp.com.attacker.com` — attacker-controlled subdomain\n- `https://myapp.comXXXXX` — any arbitrary suffix\n\n### Scope Note\n\nThe official comment in `options.go` gives `https://*.myapp.com` as the example pattern (subdomain prefix wildcard). This pattern is **not affected**. The vulnerability only manifests when developers use a trailing wildcard (`myapp.com*`), which is a natural misuse when intending to permit a domain and all its subpaths or ports.\n\n---\n\n## Impact\n\nAny Go method registered with Wails bindings becomes callable from the attacker's origin. Depending on the application:\n\n- File system read / write (common in desktop apps)\n- Database queries\n- OS command execution (if exposed via bindings)\n- Sensitive configuration or credential access\n\n---\n\n## Fix\n\n**PR:** https://github.com/wailsapp/wails/pull/5074\n\nWildcards are now only expanded when they represent a full domain component (immediately after `://`, `.`, or `:`). A wildcard appended to a partial label (e.g. `com*`) is stripped, preventing suffix-based bypasses. Comprehensive test suite added.\n\n---\n\n## Disclosure Timeline\n\n| Date | Event |\n|---|---|\n| 2026-03-26 | Vulnerability discovered during source code audit by @Saku0512 |\n| 2026-03-26 | Private report submitted via GitHub Security Advisory |\n| 2026-03-26 | Vendor acknowledgement and fix PR opened (#5074) |\n| TBD | Patch release |\n| TBD + 90 days | Public disclosure deadline |","aliases":["CVE-2026-34157"],"modified":"2026-10-27T13:45:03.096294624Z","published":"2026-10-27T13:29:47Z","database_specific":{"nvd_published_at":null,"cwe_ids":["CWE-625"],"severity":"HIGH","github_reviewed":true,"github_reviewed_at":"2026-10-27T13:29:47Z"},"references":[{"type":"WEB","url":"https://github.com/wailsapp/wails/security/advisories/GHSA-47hv-j4px-h3c9"},{"type":"WEB","url":"https://github.com/wailsapp/wails/pull/5074"},{"type":"WEB","url":"https://github.com/wailsapp/wails/commit/bcc5941b72fdab6a13942b58871a2696faa85b81"},{"type":"PACKAGE","url":"https://github.com/wailsapp/wails"}],"affected":[{"package":{"name":"github.com/wailsapp/wails/v2","ecosystem":"Go","purl":"pkg:golang/github.com/wailsapp/wails/v2"},"ranges":[{"type":"SEMVER","events":[{"introduced":"2.0.0"},{"fixed":"2.13.0"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-47hv-j4px-h3c9/GHSA-47hv-j4px-h3c9.json"}}],"schema_version":"1.9.2","severity":[{"type":"CVSS_V4","score":"CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:H/VI:H/VA:L/SC:L/SI:L/SA:N"}]}