Prevenzione dello spoofing del server remoto con PHP & cURL

3

Sto scrivendo uno script PHP che richiede dati riservati da un server remoto. Sto usando cURL per ottenere le informazioni sul certificato del server remoto (per il suo output, vedi sotto).

Quali chiavi di array devo verificare la validità del certificato per assicurarmi che nessuno possa spoofarle?

Ad esempio, la chiave [certinfo] [0] [Subject] [CN] può essere falsificata da un certificato autofirmato.

Potrei semplicemente convalidare l'hash MD5 del file di CA-bundle che sto usando sul lato client, ma quando il certificato del server sta per scadere, devo sostituire di conseguenza il file di CA-bundle di conseguenza, e aggiornare il hash in PHP. Questo è inaccettabile per me. L'unico criterio di acquiescenza è sostituire il file di CA-bundle senza aggiornare lo script PHP. Per questo ho bisogno di convalidare gli attributi del certificato del server, che rimangono gli stessi attraverso la rigenerazione del certificato futuro e non possono essere falsificati dai malfattori.

print_r (curl_getinfo ($ ch)):

[url] => https://remoteserver.com
[content_type] => text/html
[http_code] => 200
[header_size] => 148
[request_size] => 79
[filetime] => -1
[ssl_verify_result] => 0
[redirect_count] => 0
[total_time] => 0.374
[namelookup_time] => 0
[connect_time] => 0.062
[pretransfer_time] => 0.203
[size_upload] => 0
[size_download] => 20618
[speed_download] => 55128
[speed_upload] => 0
[download_content_length] => -1
[upload_content_length] => 0
[starttransfer_time] => 0.281
[redirect_time] => 0
[certinfo] => Array
    (
        [0] => Array
            (
                [Subject] => Array
                    (
                        [OU] => Globe Standard SSL
                        [CN] => www.remoteserver.com
                    )

                [Issuer] => Array
                    (
                        [C] => US
                        [O] => Globe Hosting, Inc.
                        [OU] => GlobeSSL DV Certification Authority
                        [CN] => GlobeSSL CA
                    )

                [Version] => 2
                [Signature Algorithm] => sha1WithRSAEncryption
                [Start date] => 2011-09-30 00:00:00 GMT
                [Expire date] => 2014-09-30 23:59:59 GMT
                [Public Key Algorithm] => rsaEncryption
                [RSA Public Key] => 2048
                [rsa(n)] => d7:c0:0b:3f:f3:3e:d6:ed:92:56:22:12:64:c1:c4:00:d7:c9:a1:1e:..cut..
                [rsa(e)] => 01:00:01:
                [X509v3 Authority Key Identifier] => keyid:C3:AB:A0:02:F0:9B:F5:66:7F:28:15:92:22:95:DB:B8:4E:D3:93:08
                [X509v3 Subject Key Identifier] => 13:1B:B2:52:14:3C:70:1C:B2:93:F1:C5:04:06:86:60:8A:D4:E5:5C
                [X509v3 Key Usage] => DigitalSignature,KeyEncipherment
                [X509v3 Basic Constraints] => CA:FALSE
                [X509v3 Extended Key Usage] => TLSWebServerAuthentication,TLSWebClientAuthentication
                [X509v3 Certificate Policies] => Policy:1.3.6.1.4.1.6449.1.2.2.27, CPS:http://www.globessl.com/docs/GlobeSSL_CPS.pdf
                [X509v3 CRL Distribution Points] => URI:http://crl.globessl.com/GlobeSSLDVCertificationAuthority.crl
                [Authority Information Access] => CAIssuers-URI:http://crt.globessl.com/GlobeSSLDVCertificationAuthority.crt, OCSP-URI:http://ocsp.globessl.com
                [X509v3 Subject Alternative Name] => DNS:www.remoteserver.com,DNS:remoteserver.com
                [Signature] => 61:38:06:d4:30:9c:14:a4:e5:1e:b2:c8:c4:..cut..
                [Cert] => -----BEGIN CERTIFICATE-----cut-----END CERTIFICATE-----

            )

        [1] => Array
            (
                [Subject] => Array
                    (
                        [C] => US
                        [O] => Globe Hosting, Inc.
                        [OU] => GlobeSSL DV Certification Authority
                        [CN] => GlobeSSL CA
                    )

                [Issuer] => Array
                    (
                        [C] => SE
                        [O] => AddTrust AB
                        [OU] => AddTrust External TTP Network
                        [CN] => AddTrust External CA Root
                    )

                [Version] => 2
                [Signature Algorithm] => sha1WithRSAEncryption
                [Start date] => 2010-06-22 00:00:00 GMT
                [Expire date] => 2020-05-30 10:48:38 GMT
                [Public Key Algorithm] => rsaEncryption
                [RSA Public Key] => 2048
                [rsa(n)] => a0:47:04:ce:a8:33:ab:..cut..
                [rsa(e)] => 01:00:01:
                [X509v3 Authority Key Identifier] => keyid:AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A
                [X509v3 Subject Key Identifier] => C3:AB:A0:02:F0:9B:F5:66:7F:28:15:92:22:95:DB:B8:4E:D3:93:08
                [X509v3 Key Usage] => CertificateSign,CRLSign
                [X509v3 Basic Constraints] => CA:TRUE,pathlen:0
                [X509v3 Certificate Policies] => Policy:1.3.6.1.4.1.6449.1.2.2.27
                [X509v3 CRL Distribution Points] => URI:http://crl.usertrust.com/AddTrustExternalCARoot.crl
                [Authority Information Access] => CAIssuers-URI:http://crt.usertrust.com/AddTrustExternalCARoot.p7c, CAIssuers-URI:http://crt.usertrust.com/AddTrustUTNSGCCA.crt, OCSP-URI:http://ocsp.usertrust.com
                [Signature] => 66:9c:13:6d:d2:7e:2c:..cut..
                [Cert] => -----BEGIN CERTIFICATE-----cut-----END CERTIFICATE-----

            )

    )
    
posta Alexander Malygin 27.10.2012 - 22:43
fonte

1 risposta

5

La teoria è: cURL dovrebbe convalidare il certificato del server (e afferma di farlo ). La validazione è un processo complesso (vedi la sezione 6 di RFC 5280 se non apprezzi molto la tua sanità mentale) ma il succo è che, date alcune chiavi attendibili a priori (che è il "certino CA CA" di CURL), può verificare che il certificato inviato dal server sia stato più o meno emesso direttamente da una di queste CA di fiducia ( chiamato "trust anchors" o "root CA" in linguaggio X.509.

Quindi, cURL dovrebbe anche verificare che il nome nel certificato del server corrisponda realmente al nome del server previsto. Questo è descritto in RFC 2818 . La documentazione di cURL non è chiara su questo argomento, ma gli strumenti da riga di comando di cURL che ho qui (7.21.4, come distribuito con MacOS X 10.7 e 7.23.1) sembrano eseguire anche quella verifica: ho un server SSL su una macchina che ha diversi nomi DNS; se uso un nome sbagliato, non corrisponde a ciò che contiene il certificato del server, quindi curl si lamenta a voce alta:

curl: (35) error:14077458:SSL routines:SSL23_GET_SERVER_HELLO:reason(1112)

Pertanto ciò che dovresti fare è utilizzare un file "CA cert bundle" sul client che è limitato al minor numero possibile di CA (probabilmente solo uno). Per definizione, il client si fiderà di tutti queste CA, quindi questa è una ragione sufficiente per limitare il loro numero. Quando il certificato del server scade, non è necessario modificare il pacchetto di CA : è sufficiente modificarlo quando una CA stessa scade (ma le CA di root sono in genere molto longeve, proprio perché cambiando una di essi comporta l'aggiornamento dei "pacchetti di CA" o di un concetto equivalente su ogni cliente, che è faticoso e costoso).

Non devi fare ulteriori controlli dal tuo script PHP, poiché sarebbe ridondante con ciò che già cURL fa.

Notate che recentemente è stato segnalato che molte applicazioni che eseguono un certo tipo di SSL compromettono totalmente la parte di convalida del certificato del server, a causa della lettura errata della documentazione delle librerie utilizzate o di una totale mancanza di tale documentazione. Almeno, cURL ha un po 'di documentazione che è ragionevolmente chiara. Vi incoraggio a controllare la parte "controllo del nome del server" come descritto sopra.

    
risposta data 27.10.2012 - 23:16
fonte

Leggi altre domande sui tag