Tag: ssl

  • Ruby e OSX: problemi coi certificati SSL durante l’installazione delle gem

    Nella nuova versione dell’installer di RubyGems è presente un check di sicurezza sul certificato SSL del sito da cui si scaricano le gem che si stanno per installare.
    Questo può comportare un errore durante l’installazione di una qualsiasi gem:

    ERROR: Could not find a valid gem 'rails' (= 3.2.14), here is why: Unable to download data from https://rubygems.org/ - SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
    

    Sono disponibili due strade per risolvere il problema:

    • creare un file ~/.gemrc contentente :ssl_verify_mode: 0. Questa soluzione, oltre a non essere dipendente dall’utente con cui si installano le gems, è fortemente sconsigliata: infatti, disabilita il controllo del certificato SSL del sito da cui si prelevano le gems, con immaginabili problematiche di security. Usate questa soluzione solo in ambiente di test.
    • importare il certificato system-wide:
      	cert_file=$(ruby -ropenssl -e 'puts OpenSSL::X509::DEFAULT_CERT_FILE')
      security find-certificate -a -p /Library/Keychains/System.keychain > "$cert_file"
      security find-certificate -a -p /System/Library/Keychains/SystemRootCertificates.keychain >> "$cert_file"

      	
  • HTTPS e le applicazioni di terze parti: attenzione!

    “È sufficiente usare HTTPS per essere sicuri: protegge la comunicazione cifrando il traffico e usando certificati validati da CA riconosciute”.

    SBAGLIATO. Spesso si sente pronunciare questa frase, ma non è del tutto vero: ho recentemente letto con molta attenzione un paper presentato alla conferenza CCS 2012, una conferenza dedicata alla Computer Security. Il paper ha un titolo curioso: “The Most Dangerous Code in the World: Validating SSL Certificates in Non-Browser Software“.

    Si parla di HTTPS/SSL in contesti in cui è richiesta una comunicazione cifrata tra due sistemi (trasmissione di dati sensibili); distinguiamo due tecnologie lato end-user per accedere a sistemi HTTPS: un browser (accediamo, per esempio, ad un sito di e-commerce e facciamo il checkout in modalità protetta) oppure un’applicazione 3rd party (per esempio, lo stesso sito di e-commerce tramite un’app dedicata a smartphone/tablets).

    Bene: i browser non sono in discussione e non risentono dei problemi presentati nel paper. Invece, le libraries SSL (due nomi su tutti: OpenSSL e JSSE) che solitamente vengono utilizzate nei back-end o utilizzate dagli sviluppatori per costruire applicazioni che accedono a risorse tramite HTTPS soffrono di alcuni problemi che rendono l’intera comunicazione vulnerabile a diversi tipi di attacchi, come il famoso man-in-the-middle. In breve, il problema principale è il processo di validazione dei certificati SSL (solitamente: si risale la chain fino alla root CA). Se lato client non viene effettivamente fatta la validazione del certificato presentato dal server, il client è una facile preda! Questa non-validazione è causata da molteplici fattori:

    • pigrizia dei developers che, nell’utilizzare queste librerie, disabilitano controlli fondamentali durante la fase di sviluppo (perché si usano dei certificati self-signed) che poi dovrebbero essere riabilitati al go-live. Ma così non accade;
    • utilizzo sbagliato delle API che settano impostazioni non congruenti (setto il check per la verifica del certificato ma poi non ricordo/non so/non è specificato che devo leggere un’ulteriore return code per verificare se la validazione è andata a buon fine).

    Nel paper sono presenti alcuni esempi interessanti con tanto di codice reverse engineered.

    Quali sono i rimedi?

    • Come sviluppatori: configurare correttamente i parametri di validazione SSL della libreria che si usa, controllando anche i valori di ritorno della validazione se devono essere richiamati tramite un’ulteriore chiamata alle API della library utilizzata
    • Come sviluppatori: fare sempre un testing utilizzando certificati SSL non verificati.

    La lettura del paper è davvero molto interessante ed è vivamente consigliata per tutti quelli che hanno a che fare con lo sviluppo di applicazioni 3rd party che accedono a risorse esposte tramite HTTPS/SSL.

  • Ubuntu: Apache2 con certificati self-signed e senza password all’avvio

    Recentemente mi è capitato di dover installare apache [in particolare, apache2] su una macchina Ubuntu. In particolare, mi è stato chiesto di installare la versione con ssl, ovvero che implementa il protocollo cifrato https.

    Apache2+ssl richiede l’utilizzo di un certificato firmato da un’autorità [es. Thawte, Verisign, etc.]. Se non vogliamo pagare una CA per ottenere un certificato firmato, possiamo generare un certificato firmato da noi stessi. Tuttavia, seguendo molte delle guide che si trovano in rete, apache viene installato con l’opzione ssl ma ogni volta che viene avviato richiede la password per l’utilizzo del certificato.

    Per questo riporterò qui una guida passo-passo che fa in modo che Apache2 non richieda la password per l’utilizzo del certificato: questa procedura è consigliata solamente se l’utilizzo è volto al testing o allo sviluppo. Qualsiasi altro uso è sconsigliato [richiedere una password per l’utilizzo del certificato è più che normale].

    • Abilitate il modulo ssl per apache2: sudo a2enmod ssl
    • Generiamo il certificato: cd /tmp; sudo openssl req -new > new.cert.csr
    • Vi verranno chieste delle informazioni a scopo puramente informativo e che compariranno nel certificato. Riempite le varie informazioni come credete
    • Ed ora una serie di comandi per generare tutti i file richiesti dai certificati: sudo openssl rsa -in privkey.pem -out new.cert.key
      sudo openssl x509 -in new.cert.csr -out new.cert.cert -req -signkey new.cert.key -days 1825
      sudo cp new.cert.cert /etc/ssl/certs/server.crt
      sudo cp new.cert.key /etc/ssl/private/server.key
    • Ora abilitiamo l’utilizzo dei certificati appena generati:sudo cp /etc/apache2/sites-available/default /etc/apache2/sites-available/ssl
    • Modificate il file /etc/apache2/sites-available/default con il vostro editor preferito, ad esempio vi: sudo vi /etc/apache2/sites-available/default e cambiate le seguenti linee:
      Cambiare da… A…
      NameVirtualHost: * NameVirtualHost: *:80
      <VirtualHost *> <VirtualHost *:80>
    • Modificate ora il file /etc/apache2/sites-available/ssl sempre con il vostro editor preferito e cambiate le seguenti linee:
      Cambiare da… A…
      NameVirtualHost: * NameVirtualHost: *:443
      <VirtualHost *> <VirtualHost *>

      Dopo la linea che contiene DocumentRoot, aggiungete le seguenti righe:

      SSLEngine on
      SSLOptions +StrictRequire
      SSLCertificateFile /etc/ssl/certs/server.crt
      SSLCertificateKeyFile /etc/ssl/private/server.key
      
    • Ora date il seguente comando per abilitare l’utilizzo dei certificati in apache2: sudo a2ensite ssl
    • Infine riavviate Apache2 e finalmente non chiederà più la password del certificato: sudo /etc/init.d/apache2 restart

    Nota: se avete problemi controllate che il vostro file /etc/hosts sia fatto in questo modo:

    127.0.0.1 localhost localhost.localdomain {il vostro hostname}
    127.0.1.1 {il vostro hostname}
    {IP statico se ne avete uno} {DNS fully qualified se ne avete uno}
  • Python: come mandare un e-mail con GMail TLS/SSL

    Mi è capitato di dover mandare un e-mail da uno script Python: quale provider utilizzare? Ovviamente GMail!

    Per questioni di spam, alcuni server SMTP non permettono di inviare e-mail senza essersi prima autenticati; nel caso di GMail, il protocollo per l’invio di mail non è il semplice SMTP in chiaro, bensì SMTP con autenticazione via TLS/SSL.

    Ecco lo script Python che vi permetterà di mandare un’e-mail con GMail tramite il vostro account GMail:

    #!/usr/bin/python
    
    import smtplib
    import time
    import datetime
    from email.MIMEMultipart import MIMEMultipart
    from email.MIMEBase import MIMEBase
    from email.MIMEText import MIMEText
    from email import Encoders
    import os
    
    gmail_user = "username@gmail.com"
    gmail_pwd = "password"
    
    def mail(to, subject, text):
    msg = MIMEMultipart()
    
    msg['From'] = gmail_user
    msg['To'] = to
    msg['Subject'] = subject
    
    msg.attach(MIMEText(text))
    
    mailServer = smtplib.SMTP("smtp.gmail.com", 587)
    mailServer.ehlo()
    mailServer.starttls()
    mailServer.ehlo()
    mailServer.login(gmail_user, gmail_pwd)
    mailServer.sendmail(gmail_user, to, msg.as_string())
    mailServer.close()
    
    file = open('body.txt','r')
    document = file.read()
    mail("dst_addr@gmail.com",
    "Subject",
    document,
    )