Estou configurando o DiscourseConnect entre um site WordPress e uma instância hospedada do Discourse e estou enfrentando uma falha persistente na validação da assinatura HMAC.
O WordPress recebe a requisição do DiscourseConnect e retorna o callback contendo sso e sig.
O callback chega ao Discourse, mas o Discourse o rejeita porque a assinatura HMAC não é validada.
Realizamos uma depuração bastante extensa e reduzimos bastante o escopo do problema.
O que confirmamos
wp_unslash() não altera os valores do callback.
As entradas de validação do EA/WordPress correspondem aos parâmetros reconstruídos a partir da string de consulta observada pelo WordPress.
O código do callback esperado está definitivamente sendo executado.
Os arquivos de fonte implantados correspondem ao nosso manifesto de compilação.
Verificamos problemas de arquivo incorreto e definições duplicadas.
O PHP-FPM foi reiniciado após as últimas correções, então isso não é um estado antigo de processo PHP/opcache.
Uma requisição completamente nova do DiscourseConnect após essas alterações ainda falha na validação HMAC.
Em outras palavras, a falha atual é reproduzível em uma requisição nova.
O que ainda não conseguimos provar
Que o segredo efetivo usado pelo Discourse em tempo de execução é idêntico, byte a byte, ao segredo usado pelo WordPress.
Que o payload sso não está sendo alterado em algum ponto antes de o WordPress observar a requisição.
Nesta etapa, não queremos continuar alterando configurações ou código às cegas.
Pergunta
Para o Discourse/DiscourseConnect atual, qual é a melhor maneira de determinar exatamente qual payload e segredo o Discourse está usando ao calcular o HMAC esperado?
Existe um método de depuração/registro recomendado que nos permita comparar a entrada do HMAC do lado do Discourse com a entrada do lado do WordPress sem expor o segredo real publicamente?
Se houver problemas conhecidos envolvendo o processamento do WordPress/PHP, codificação de URL, payloads Base64, proxies reversos ou Discourse hospedado que possam causar essa situação, também apreciaria indicações.
Posso fornecer valores de requisição/callback sanitizados, o código relevante do WordPress e logs, se necessário.
Olá, Richard. O WP-Discourse está instalado, mas o provedor DiscourseConnect e as funções de sincronização de login estão desativados.
Estamos usando um pequeno plugin WordPress personalizado como provedor DiscourseConnect. Ele recebe os parâmetros sso e sig do Discourse, verifica o HMAC recebido usando o segredo compartilhado e, em seguida, constrói e assina a resposta de volta para o Discourse.
A falha está ocorrendo atualmente na solicitação recebida do Discourse para o WordPress — nosso diagnóstico recente mostra que a recomputação do HMAC não corresponde ao sig recebido do Discourse.
Ficarei feliz em postar o código relevante de callback/validação em PHP. Vou remover os valores de configuração/segredos antes de postá-lo.
Sim — você está correto. Minha redação na publicação original estava invertida.
A falha atual é Discourse → WordPress.
O Discourse gera a requisição DiscourseConnect contendo sso e sig. O WordPress a recebe, e nosso provedor EA personalizado tenta verificar a assinatura. A verificação de HMAC recebida falha, então o WordPress para por ali. Ele não chega ao ponto de retornar o payload do usuário autenticado ao Discourse.
O WP-Discourse está instalado, mas seu provedor DiscourseConnect e as funções de sincronização de login de usuário estão desativados. Atualmente, estamos usando o provedor EA personalizado porque queremos que a camada de conta/perfil do EA permaneça sob nosso controle.
Postarei abaixo o código relevante de callback/config/validação de HMAC, com todos os segredos e configurações privadas removidos.
Obrigado, Richard. Verifiquei esse ponto em relação ao processamento de solicitações do PHP/WordPress e ao fluxo atual de assinatura do Discourse.
Em nosso callback, lemos de $_GET, portanto o PHP já decodificou os parâmetros da query antes que o EA os receba. wp_unslash() apenas reverte o “slashing” de solicitações do WordPress; ele não está fazendo decodificação de URL.
Aplicar urldecode() novamente nesse ponto resultaria em uma decodificação dupla do valor e pode transformar um + em Base64 em um espaço, o que por si só quebraria o HMAC.
Também confirmei que nosso novo diagnóstico ainda falha no HMAC, mesmo após os segredos do WordPress e do Discourse terem sido corrigidos para corresponder.
Portanto, não acredito que substituir wp_unslash() por urldecode() seja a correção adequada para este caminho específico de callback. Estou continuando a rastrear onde o payload assinado pode estar divergindo antes de chegar ao PHP.