Pular para o conteúdo
ecdsa.com
Python ssl module (OpenSSL 3)Python (cryptography)

Mensagem de erro

[SSL: UNSAFE_LEGACY_RENEGOTIATION_DISABLED] unsafe legacy renegotiation disabled

Aparece com o Python vinculado ao OpenSSL 3.0 ou posterior (a maioria dos builds do Python desde 2022); o OpenSSL 1.1.1 ainda aceitava esses servidores. Em seguida vem uma localização no código-fonte, como “(_ssl.c:1082)”.

Python ssl module (OpenSSL 3) — ssl.SSLError, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED

O que significa

O servidor negociou TLS 1.2 ou anterior sem a extensão de renegociação segura da RFC 5746. Clientes com OpenSSL 3 recusam esses servidores por padrão, porque a renegociação legada permitia que um atacante man-in-the-middle inserisse os próprios dados antes da requisição do cliente (CVE-2009-3555). O Python herda esse padrão, então a conexão falha durante o handshake.

Por que acontece

Como corrigir

  1. 1.

    Confirmar que o servidor não tem renegociação segura

    O openssl s_client informa “Secure Renegotiation IS NOT supported” para esses servidores.

    bash
    openssl s_client -connect legacy.example.com:443 -servername legacy.example.com </dev/null 2>/dev/null \
      | grep -i 'secure renegotiation'
    # "Secure Renegotiation IS NOT supported" confirms the server lacks RFC 5746
  2. 2.

    Corrigir o servidor

    Atualizar a pilha TLS ou o firmware do servidor, ou oferecer TLS 1.3, elimina o problema para todos os clientes.

    text
    Server / appliance owners: update the TLS stack or firmware to any release
    supporting RFC 5746 (every mainstream TLS library since 2010), or enable TLS 1.3,
    which has no renegotiation at all.
  3. 3.

    Solução temporária: permitir só para um host

    ssl.OP_LEGACY_SERVER_CONNECT (Python 3.12+) reativa as conexões com esses servidores somente nesse contexto. A opção reabre o risco de inserção de dados via renegociação para esse host, por isso não a defina globalmente nem pela configuração do OpenSSL do sistema.

    python
    # Temporary workaround for one legacy host only (Python 3.12+: ssl.OP_LEGACY_SERVER_CONNECT)
    import ssl, urllib.request
    
    ctx = ssl.create_default_context()
    ctx.options |= ssl.OP_LEGACY_SERVER_CONNECT
    urllib.request.urlopen("https://legacy.example.com/", context=ctx)

Erros relacionados

Ver toda a base de erros de assinatura