Un problema menor y quizás uno mayor:
Hay un parámetro nonce obligatorio que no se menciona en la documentación:
def require_params
%i[public_key nonce scopes client_id application_name].each { |p| params.require(p) }
end
Ahora el problema más complicado. Discourse llama al método public_encrypt sin argumentos:
Eso significa que el argumento padding se establece por defecto en PKCS1_PADDING. Según la documentación de Ruby:
Cifra
stringcon la clave pública.paddingse establece por defecto enPKCS1_PADDING, que se sabe que no es seguro pero se mantiene por compatibilidad con versiones anteriores.
Desafortunadamente, Node v20.14.0 (el LTS actual) devuelve un error si intentas llamar a crypto.privateDecrypt con RSA_PKCS1_PADDING:
function decryptData(data: string, privateKey: string) {
const buffer = Buffer.from(data, "base64");
const decrypted = crypto.privateDecrypt(
{
key: privateKey,
padding: crypto.constants.RSA_PKCS1_PADDING,
},
buffer
);
return decrypted.toString("utf8");
}
TypeError: RSA_PKCS1_PADDING ya no se admite para la descifración privada; esto se puede revertir con --security-revert=CVE-2023-46809
Una posible solución para las aplicaciones Node es ejecutar Node con la bandera insegura:
node --security-revert=CVE-2023-46809
Una solución en el lado de Discourse sería fácil, pero sospecho que rompería muchas integraciones existentes:
public_key = OpenSSL::PKey::RSA.new(params[:public_key])
@payload = Base64.encode64(public_key.public_encrypt(@payload, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING))