CVE-2024-13431: Reflected XSS no Simply Schedule Appointments

A imagem mostra um alerta de segurança em fundo preto com texto em verde, no estilo de terminal de computador. No topo aparece "CVE-2024-13431" seguido de "Reflected XSS". No centro há o logotipo de um plugin chamado "Simply Schedule Appointments" com uma ilustração de uma raposa laranja. Abaixo há um box verde com informações sobre a vulnerabilidade: "Vulnerabilidade em Versões

Introdução

As vulnerabilidades de Cross-Site Scripting (XSS) continuam sendo uma das falhas de segurança mais comuns em aplicações web. Recentemente, identifiquei uma vulnerabilidade de Reflected XSS no plugin de WordPress “Appointment Booking Calendar — Simply Schedule Appointments”, que afeta todas as versões até 1.6.8.3.

Informações relevantes:

  • Plugin: Appointment Booking Calendar — Simply Schedule Appointments Booking Plugin
  • Versões afetadas: <= 1.6.8.3
  • CVE: CVE-2024-13431
  • CWE: CWE-79 (Improper Neutralization of Input During Web Page Generation)
  • CVSS: 6.1 (Médio) – CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
  • Data de publicação: 6 de março de 2025 (Wordfence Intelligence)

O Plugin e a Vulnerabilidade

Simply Schedule Appointments

Simply Schedule Appointments é um plugin para WordPress com mais de 50.000 instalações ativas que oferece funcionalidades de agendamento automático de compromissos. Ele permite que clientes de empresas agendem compromissos diretamente através do site.

A Vulnerabilidade

A vulnerabilidade encontrada permite que um atacante, sem necessidade de autenticação, execute ataques de Reflected Cross-Site Scripting (XSS) através dos parâmetros accent_color e background no endpoint /wp-json/ssa/v1/embed-inner. Devido à falta de sanitização adequada desses parâmetros, é possível injetar código JavaScript malicioso que será executado no navegador da vítima quando acessar URLs especialmente elaboradas.

Análise Técnica

A vulnerabilidade está localizada na forma como o plugin processa os parâmetros de cor. No arquivo class-styles.php, a função hex_to_rgba() é usada para converter valores hexadecimais em formato RGBA:

/**
 * Transforms an hex color into rgba, necessary to calculate contrast.
 *
 * @since 3.7.6
 *
 * @param string $hex_string
 * @return string
 */
public function hex_to_rgba( $hex_string ) {
	// remove hash sign if it's passed on the hex string
	$hex_string = ltrim($hex_string, '#');
	$color_type = $this->is_hex_or_rgba( $hex_string );

	// if not a valid hex or rgba color, return
	if( ! $color_type ) {
		return null;
	}

	if( $color_type === 'rgba' ) {
		return $hex_string;
	}
	
	if( strlen( $hex_string ) === 6 ) {
		sscanf($hex_string, "%02x%02x%02x", $r, $g, $b);
	} else {
		$r = hexdec(str_repeat($hex_string[0], 2));
		$g = hexdec(str_repeat($hex_string[1], 2));
		$b = hexdec(str_repeat($hex_string[2], 2));
	}

	return "rgba($r,$g,$b,1)";
}

O problema principal está no método is_hex_or_rgba(), que verifica se uma string é um valor hexadecimal ou RGBA válido:

/**
 * checks if a string is a valid hex color or rgba.
 *
 * @since 3.7.6
 *
 * @param string $color
 * @return string|boolean
 */
public function is_hex_or_rgba( $color ) {
	if( strpos( $color, 'rgba' ) !== false ) {
		return 'rgba';
	}
	if( preg_match('/^#?(([a-f0-9]{3}){1,2})$/i', $color ) ) {
		return 'hex';
	}

	return null;
}

Esta função tem uma falha crítica: se a string contiver “rgba”, a função a classifica como um valor RGBA válido sem realizar qualquer validação adicional do formato. Isso permite que um atacante injete qualquer string contendo “rgba” seguida por código malicioso, que será retornada sem sanitização pelo método hex_to_rgba().

Na implementação do endpoint /wp-json/ssa/v1/embed-inner, o código processa os valores dos parâmetros accent_color e background diretamente da requisição GET:

if( isset( $_GET['background'] ) && ! empty( $_GET['background'] ) ) {
    $background = $ssa->styles->hex_to_rgba( '#'. $_GET['background'] );
    if( $background ) {
        $styles_params['background'] = $background;
    }
}

Esta implementação permite que um atacante insira um valor como ffffffrgba;</style><script>alert(1)</script>, que será processado como um valor RGBA válido e retornado sem sanitização, resultando em um ataque XSS quando o JavaScript é executado no navegador da vítima.

Prova de Conceito (POC)

Durante meus testes no plugin, consegui demonstrar a vulnerabilidade com o seguinte URL:

http://exemplo.com/wp-json/ssa/v1/embed-inner?background=ffffffrgba;</style><script>alert(1)</script>

Ao acessar este URL em um navegador, o script JavaScript alert(1) é executado, confirmando a existência da vulnerabilidade de Reflected XSS.

Impacto e Riscos

Esta vulnerabilidade de XSS Refletido pode ter vários impactos negativos:

  1. Roubo de cookies de sessão e sequestro de contas de usuários (session hijack)
  2. Redirecionamento para sites maliciosos
  3. Exibição de conteúdo fraudulento para os usuários
  4. Modificação do conteúdo da página para realizar ataques de phishing
  5. Execução de ações não autorizadas no contexto do usuário logado

O impacto é amplificado pelo fato de que a vulnerabilidade não requer autenticação para ser explorada e pode ser facilmente incorporada em links maliciosos enviados por e-mail, mensagens ou redes sociais.

Como Foi Corrigido

Na versão 1.6.8.5, os desenvolvedores implementaram uma nova função de sanitização ssa_sanitize_color_input() que realiza uma validação mais rigorosa dos valores de cores:

/**
* Sanitizes the accent color input.
*
* @param string $color The input color string.
* @return string|null The sanitized color or null if the input is invalid.
*/
function ssa_sanitize_color_input($color) {
	$hex_pattern = '/^[a-fA-F0-9]+$/';

	$rgba_pattern = '/^rgba\(\d{1,3},\d{1,3},\d{1,3},(?:0|1|0?\.\d+)\)$/i';

	if (preg_match($hex_pattern, $color) && in_array(strlen($color), [6, 3])) {
		return strtolower($color);
	}

	if (preg_match($rgba_pattern, $color)) {
		return $color;
	}

	return null;
}

A nova implementação utiliza expressões regulares mais rigorosas para validar tanto valores hexadecimais quanto valores no formato RGBA:

  1. Para cores hexadecimais: Verifica se o valor contém apenas caracteres hexadecimais (a-f, A-F, 0-9) e tem exatamente 3 ou 6 caracteres.
  2. Para cores RGBA: Valida se o formato segue o padrão exato rgba(R,G,B,A) onde R, G e B são números de 0 a 255 e A é um valor entre 0 e 1.

Além disso, a função retorna null para qualquer entrada que não passe nas validações, o que impede que valores maliciosos sejam processados pelo plugin.

O código foi modificado para utilizar esta função de sanitização antes de passar os valores para hex_to_rgba():

if( isset( $_GET['background'] ) && ! empty( $_GET['background'] ) ) {
    $background_input = ssa_sanitize_color_input( $_GET['background'] );
    $background = $ssa->styles->hex_to_rgba( '#'. $background_input );
    // ... resto do código
}

Conclusão

O CVE-2024-13431 demonstra a importância de implementar uma validação e sanitização adequada de entradas de usuário, especialmente em plugins com grande número de instalações. A vulnerabilidade foi corrigida na versão 1.6.8.5 do Simply Schedule Appointments, e todos os usuários são fortemente recomendados a atualizar para esta versão ou posterior.

Agradeço à equipe do Wordfence Intelligence pelo profissionalismo durante o processo de divulgação e aos desenvolvedores do Simply Schedule Appointments pela implementação rápida de uma correção eficaz.


Este post foi escrito com base em minha descoberta do CVE-2024-13431, documentado no banco de dados de vulnerabilidades do Wordfence Intelligence. Se você tiver dúvidas ou comentários, deixe-os abaixo ou entre em contato diretamente.

Posts relacionados

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *