
Laboratório baseado em Docker para reproduzir CVE-2026-42647, uma injeção SQL cega baseada em tempo não autenticada no plugin WordPress JoomSport através do parâmetro sortf. Inclui alvos vulneráveis e corrigidos para comparação.
sortfEste repositório contém um laboratório Docker local para reproduzir e validar a CVE-2026-42647, uma vulnerabilidade de injeção SQL não autenticada que afeta o plugin WordPress JoomSport - for Sports: Team & League, Football, Hockey & more.
O comportamento vulnerável ocorre no recurso de ordenação da lista de jogadores. Um visitante público pode controlar o parâmetro de consulta sortf, que é usado para construir uma cláusula SQL ORDER BY. Em versões vulneráveis, o valor é higienizado como texto e envolvido em crases, mas não é validado contra uma lista de permissões estrita antes de ser anexado à consulta SQL.
Este laboratório compara duas versões do JoomSport:
| Serviço | Versão do JoomSport | Finalidade | URL |
|---|---|---|---|
vuln | 5.7.6 | Alvo de comparação vulnerável | http://localhost:8081 |
patched | 5.7.8 | Alvo de comparação corrigido | http://localhost:8082 |
Os avisos públicos identificam as versões anteriores a 5.7.8 como afetadas e a 5.7.8 como a versão corrigida. Este laboratório utiliza a 5.7.6 como alvo vulnerável porque uma tag de origem 5.7.7 não estava disponível na listagem de tags SVN do plugin no WordPress.org no momento em que este laboratório foi preparado.
A cadeia de vulnerabilidade demonstrada é:```text Unauthenticated visitor → JoomSport season player list route → attacker-controlled sortf parameter → unsafe dynamic ORDER BY construction → SQL expression execution → measurable database delay in vulnerable version → patched version rejects the injected sort field and falls back to a safe allowlisted field
Este laboratório valida a vulnerabilidade como uma injeção SQL cega baseada em tempo. Ele não realiza dumping de banco de dados, extração de credenciais, modificação de dados ou operações SQL destrutivas.
Este laboratório foi projetado apenas para pesquisa local controlada, compreensão em nível de código-fonte e demonstração de portfólio.
## Fatos Verificados
| Alegação | Evidência | Como verificar neste laboratório |
| --- | --- | --- |
| JoomSport anterior à versão 5.7.8 é relatado como vulnerável a injeção SQL não autenticada. | Advisories públicos identificam JoomSport `< 5.7.8` / `<= 5.7.7` como afetados. | Revise a seção References e compare os serviços vulnerável/corrigido. |
| JoomSport 5.7.8 é a versão corrigida. | Advisories públicos e comparação de código-fonte mostram que a versão 5.7.8 valida o valor de `sortf` antes de construir a expressão de ordenação. | Inspecione `class-jsport-playerlist.php` em ambas as versões. |
| O parâmetro afetado é `sortf`. | O código vulnerável da lista de jogadores lê `classJsportRequest::get('sortf')`. | Execute o PoC e observe a requisição `sortf` injetada. |
| O código vulnerável constrói um valor de ordenação SQL dinâmico a partir da entrada do usuário. | Na versão vulnerável, `sortf` é usado para construir `$options['ordering']`. | Inspecione `sportleague/classes/objects/class-jsport-playerlist.php`. |
| O sink SQL é uma cláusula `ORDER BY`. | O valor `$ordering` gerado é posteriormente anexado a uma consulta SQL com `ORDER BY`. | Inspecione `sportleague/base/wordpress/classes/class-jsport-getplayers.php`. |
| A correção usa uma correção no estilo de allowlist. | A versão corrigida introduz colunas estáticas permitidas e padrões esperados de campos dinâmicos antes de usar o campo de ordenação. | Compare o código-fonte do JoomSport 5.7.6 e 5.7.8. |
| O laboratório demonstra injeção SQL cega baseada em tempo. | O alvo vulnerável atrasa quando uma expressão `SLEEP()` injetada é usada; o alvo corrigido não atrasa. | Execute `python3 poc/poc.py http://localhost:8081 http://localhost:8082`. |
## Premissas e Incógnitas
Este laboratório usa o JoomSport 5.7.6 como alvo vulnerável de comparação porque a versão pública corrigida é a 5.7.8 e uma tag de código-fonte 5.7.7 não estava disponível na listagem de tags SVN do plugin no WordPress.org quando o laboratório foi preparado.
O laboratório não afirma que 5.7.6 é a única versão vulnerável. Ele é usado como uma linha de base vulnerável reproduzível para comparar o comportamento vulnerável com o comportamento da versão corrigida 5.7.8.
O laboratório se concentra no parâmetro `sortf` no fluxo de ordenação da lista de jogadores.
O impacto demonstrado é injeção SQL cega baseada em tempo. O laboratório não demonstra:
* dumping direto de banco de dados,
* extração de credenciais,
* bypass de autenticação,
* escalonamento de privilégios,
* modificação arbitrária de dados,
* execução remota de código,
* persistência,
* callbacks externos,
* ou ataques contra sistemas fora do laboratório.
Comportamento baseado em erro ou booleano pode ser possível dependendo do comportamento do banco de dados, da configuração da aplicação e das diferenças de resposta, mas este laboratório não se baseia nessas técnicas. A prova principal é baseada em tempo.
## Resumo da Causa Raiz
A causa raiz é a construção insegura de uma cláusula SQL `ORDER BY` dinâmica a partir do parâmetro de requisição `sortf`.
O caminho do código vulnerável começa em:```text
sportleague/classes/objects/class-jsport-playerlist.php
Dentro da lógica de carregamento da lista de jogadores, o JoomSport lê o parâmetro da requisição:```text sortf
e usa-o para construir:```text
$options['ordering']
O padrão de código-fonte vulnerável relevante é:```php
if (classJsportRequest::get('sortf')) {
$typeAD = in_array(classJsportRequest::get('sortd'), array("ASC","DESC")) ? classJsportRequest::get('sortd') : "ASC";
$options['ordering'] = str_replace(" ","",sanitize_text_field("".classJsportRequest::get('sortf')."")).' '.$typeAD;
}
O problema não é principalmente o parâmetro `sortd`. O valor de `sortd` é restrito a:```text
ASC
DESC
O problema é o parâmetro sortf porque ele controla a posição do identificador/expressão SQL usada para ordenação.
A expressão perigosa é:```php
"".classJsportRequest::get('sortf').""
O código coloca a entrada controlada pelo atacante dentro de um contexto de identificador MySQL e então a passa adiante como um fragmento de ordenação SQL.
O código aplica:```php
sanitize_text_field()
mas sanitize_text_field() não é validação de identificador SQL. Ele foi projetado para limpar texto, não para construir sintaxe SQL com segurança.
O código vulnerável também envolve o campo de ordenação controlado pelo usuário em crases. No entanto, crases não são uma fronteira de segurança quando o atacante pode influenciar o conteúdo do identificador. Se um atacante puder injetar uma crase no valor, ele poderá escapar do contexto de identificador pretendido.
O valor de ordenação gerado é posteriormente passado para a consulta de recuperação do jogador e anexado a uma cláusula SQL ORDER BY em:```text
sportleague/base/wordpress/classes/class-jsport-getplayers.php
O padrão de sink é:```php
$query .= ' ORDER BY '.($ordering);
Isso cria o fluxo de dados vulnerável:```text sortf request parameter → classJsportRequest::get('sortf') → $options['ordering'] → $ordering → ORDER BY
O problema de segurança é que a aplicação trata um parâmetro de requisição controlado pelo usuário como um identificador/expressão SQL sem antes validá-lo contra uma allowlist rigorosa.
## Resumo do Patch de Origem