{"id":"CVE-2026-34157","kind":"vulnerability","aliases":["CVE-2026-34157","GHSA-47hv-j4px-h3c9"],"related":[],"title":"Wails: wildcardPatternToRegex allows Origin bypass via suffix match in BindingsAllowedOrigins","description":"# 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 |","summary":"Wails v2 converts a trailing wildcard in BindingsAllowedOrigins into an unanchored regex, so an origin such as myapp.com.attacker.com or myapp.community passes the check. A page on such an origin can call any Go method bound to the app, which may expose file access, data or commands.","severity":"high","cvss":null,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"github.com/wailsapp/wails/v2","fixed":["2.13.0"],"affected":">= 2.0.0, < 2.13.0","ecosystem":"go"}],"ecosystems":["go"],"tags":["cwe-625","desktop-apps","go","linux","macos","package","wails","windows"],"not_affected_if":["exact-origins","no-bindings-allowed-origins","subdomain-prefix-pattern"],"how_to_check":"- Search the app's Go code and config for `BindingsAllowedOrigins` and look for patterns ending in `*` without a dot-prefixed subdomain, such as `https://myapp.com*`.\n- Check the Wails version with `go list -m github.com/wailsapp/wails/v2`; versions from `2.0.0` up to but not including `2.13.0` are affected.","fix":"- Upgrade `github.com/wailsapp/wails/v2` to `2.13.0` or later (fix PR #5074).\n- Until upgraded, replace trailing wildcards like `myapp.com*` with exact origins or `https://*.myapp.com` style subdomain patterns.","status":"open","published_at":"2026-10-27T13:29:47+00:00","first_seen_at":"2026-10-27T13:31:05+00:00","triaged_at":"2026-10-27T13:32:27+00:00","updated_at":"2026-10-27T13:32:27+00:00","category":"package","confidence":0.8,"triage":{"at":"2026-10-27T13:32:27Z","model":"claude-haiku-5-5","output":{"fix":"- Upgrade `github.com/wailsapp/wails/v2` to `2.13.0` or later (fix PR #5074).\n- Until upgraded, replace trailing wildcards like `myapp.com*` with exact origins or `https://*.myapp.com` style subdomain patterns.","reach":"internet","title":"Wails: wildcard origin pattern lets attacker domains invoke bound Go methods","impact":"high","summary":"Wails v2 converts a trailing wildcard in BindingsAllowedOrigins into an unanchored regex, so an origin such as myapp.com.attacker.com or myapp.community passes the check. A page on such an origin can call any Go method bound to the app, which may expose file access, data or commands.","category":"package","nicknames":[],"who_cares":["go","wails","desktop-apps","windows","linux","macos"],"confidence":0.8,"needs_auth":"no","worst_case":"Attacker page invokes bound Go methods, reading files or data.","analyst_note":"Confirm the exact fixed behaviour and whether stripping the wildcard breaks existing configs, via https://github.com/wailsapp/wails/pull/5074 and https://github.com/advisories/GHSA-47hv-j4px-h3c9.","how_to_check":"- Search the app's Go code and config for `BindingsAllowedOrigins` and look for patterns ending in `*` without a dot-prefixed subdomain, such as `https://myapp.com*`.\n- Check the Wails version with `go list -m github.com/wailsapp/wails/v2`; versions from `2.0.0` up to but not including `2.13.0` are affected.","needs_analyst":true,"not_affected_if":["exact-origins","subdomain-prefix-pattern","no-bindings-allowed-origins"],"who_is_affected":"Apps built with Wails v2 that set BindingsAllowedOrigins and use a trailing wildcard on a domain are exposed, because the wildcard matches any suffix after the domain. Apps that do not set BindingsAllowedOrigins, use exact origins, or only use the documented subdomain-prefix pattern are not affected according to the advisory's scope note. Desktop targets on Windows, Linux and macOS are all listed.","user_interaction":"yes","needs_special_setup":"yes","severity_if_unknown":"high"},"cost_usd":0.000878,"input_tokens":4773,"output_tokens":802,"severity_before":"high"},"analyst_status":null,"analyst_note":null,"search":"'-03':109C,460C,471C,481C '-2026':12A,20A '-26':110C,461C,472C,482C '-34157':13A,21A '-625':26B,130C '/av':116C '/wailsapp/wails/pull/5074':419C '/wailsapp/wails/v2':24A '2026':108C,459C,470C,480C '4.0':115C '47hv':16A '5074':489C '7.6':112C '90':494C 'access':78B,207C,414C 'achiev':204C 'acknowledg':484C 'add':454C 'addit':254C 'advisori':479C 'affect':96C,99C,345C 'allow':3A,169C,189C 'anchor':167C 'api':219C 'app':29B,73B,400C 'append':437C 'applic':216C,392C 'arbitrari':199C,323C 'attack':179C,318C,386C 'attacker-control':317C 'audit':467C 'backend':154C 'base':449C 'becom':282C,382C 'begin':309C 'bind':381C,409C 'bindingsallowedorigin':10A,43B,145C 'bound':70B,200C 'bypass':5A,89C,175C,450C 'call':66B 'callabl':383C 'caus':224C 'charact':237C,249C,285C 'check':58B 'code':211C,258C,466C 'com':304C,443C 'command':81B,404C 'comment':329C 'common':397C 'compon':256C,431C 'comprehens':451C 'configur':196C,411C 'contain':103C 'control':181C,319C 'convert':38B,164C,226C 'credenti':413C 'cve':11A,19A 'cvss':114C 'cvssv4.0':111C 'cwe':25B,128C,129C 'data':79B,208C 'databas':401C 'date':457C 'day':495C 'deadlin':498C 'depend':213C,389C 'desktop':28B,139C,399C 'desktop-app':27B 'detail':222C 'develop':351C 'differ':314C 'disclosur':455C,497C 'discov':463C 'domain':183C,255C,290C,367C,430C 'dot':252C,288C 'e.g':191C,442C 'escap':235C,271C,277C,279C,292C,294C,296C 'event':458C 'exampl':336C 'execut':212C,405C 'exfiltr':209C 'expand':424C 'expos':76B,218C,407C 'express':133C,233C 'file':77B,97C,205C,259C,393C 'fix':415C,486C 'full':429C 'func':262C 'generat':298C 'ghsa':15A 'ghsa-47hv-j4px-h3c9':14A 'github':477C 'github.com':23A,418C 'github.com/wailsapp/wails/pull/5074':417C 'github.com/wailsapp/wails/v2':22A 'give':332C 'go':30B,68B,153C,201C,261C,376C 'h/va':123C 'h/vi':122C 'h3c9':18A 'high':113C 'immedi':432C 'impact':374C 'includ':251C,287C,312C 'intend':363C 'invok':152C,198C 'ipc':157C 'j4px':17A 'l/at':118C 'l/sa':126C 'l/sc':124C 'l/si':125C 'label':441C 'latest':105C 'linux':31B,136C 'maco':32B,137C 'manifest':349C 'match':8A,161C,172C,247C,283C,306C 'may':75B 'method':69B,155C,202C,377C 'misus':361C 'myapp':303C 'myapp.com':194C,301C,311C,333C,356C 'myapp.com.attacker.com':53B,316C 'myapp.community':55B,192C,313C 'myapp.comxxxxx':321C 'n':127C 'n/ac':117C 'n/ui':120C 'natur':360C 'note':326C 'offici':328C 'open':488C 'options.go':331C 'origin':4A,50B,64B,87C,150C,173C,190C,388C 'originvalid':104C,264C 'os':403C 'p/pr':119C 'p/vc':121C 'packag':33B 'page':60B 'partial':440C 'pass':56B 'patch':491C 'pattern':92C,160C,229C,337C,342C 'permiss':131C 'permit':365C 'platform':134C 'port':373C 'potenti':203C 'pr':416C,487C 'prefix':186C,339C 'prevent':446C 'privat':473C 'product':93C 'provid':144C 'public':496C 'queri':402C 'rang':275C 'read':395C 'regex':47B,299C 'regist':378C 'regular':132C,232C 'releas':492C 'replac':239C 'report':84C,474C 'repres':427C 'restrict':147C,177C,245C 'return':295C 'root':223C 'saku0512':469C 'scope':325C 'secur':82C,478C 'sensit':410C 'separ':291C 'sequenc':250C,286C 'share':184C 'sourc':465C 'special':236C 'specialchar':269C,274C,276C,280C,281C 'string':267C,268C,270C,308C 'strings.replaceall':278C,293C 'strip':445C 'subcompon':168C 'subdomain':320C,338C 'submit':475C 'subpath':371C 'substitut':242C 'suffix':7A,171C,324C,448C 'suffix-bas':447C 'suffix-match':170C 'suit':453C 'summari':141C 'surfac':220C 'system':206C,394C 'target':140C 'tbd':490C,493C 'test':452C 'timelin':456C 'tld':315C 'trail':40B,354C 'unanchor':46B 'use':352C 'v':263C 'v2':37B,86C,95C,143C 'v2/internal/frontend/originvalidator/originvalidator.go':98C,260C 'valid':88C 'vendor':483C 'version':100C,102C 'via':6A,90C,156C,408C,476C 'vulner':83C,221C,257C,347C,462C 'wail':1A,34B,36B,85C,142C,380C 'wailsapp/wails':94C 'web':149C 'wildcard':41B,91C,159C,228C,340C,355C,420C,436C 'wildcardpattern':266C,272C 'wildcardpatterntoregex':2A,163C,225C,265C 'window':35B,135C 'without':166C 'write':396C","nicknames":[],"mitigations":[],"who_affected":"Apps built with Wails v2 that set BindingsAllowedOrigins and use a trailing wildcard on a domain are exposed, because the wildcard matches any suffix after the domain. Apps that do not set BindingsAllowedOrigins, use exact origins, or only use the documented subdomain-prefix pattern are not affected according to the advisory's scope note. Desktop targets on Windows, Linux and macOS are all listed.","tier":"B","verified":{},"analyst_revisit_at":null,"first_public_at":"2026-10-27T13:29:47+00:00","kev":null,"cvss_vector":null,"cvss_by":null,"poc_count":0,"sources":[{"source":"ghsa","external_id":"GHSA-47hv-j4px-h3c9","url":"https://github.com/advisories/GHSA-47hv-j4px-h3c9","severity":"high","published_at":"2026-10-27T13:29:47+00:00","modified_at":"2026-10-27T13:29:48+00:00","first_seen_at":"2026-10-27T13:31:05+00:00","fetched_at":"2026-10-27T13:31:05+00:00","note":null}],"documents":[],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}