Passa al contenuto principale

RFC 2818 - HTTP Over TLS (HTTPS)

Stato: Documento informativo
Autore: E. Rescorla (RTFM, Inc.)
Data: Maggio 2000

Sommario (Abstract)

Questo memo descrive come utilizzare TLS per proteggere le connessioni HTTP su Internet. La pratica attuale consiste nel sovrapporre HTTP su SSL (il predecessore di TLS), distinguendo il traffico protetto da quello non protetto mediante l'uso di una porta server diversa. Questo documento documenta questa pratica utilizzando TLS.

Importanza

RFC 2818 è la pietra angolare della sicurezza Web:

  • 🔒 Definisce il meccanismo di base di HTTPS
  • 🌐 Fondamento della sicurezza per tutti i siti Web moderni
  • 🔑 Validazione dei certificati e verifica dell'identità
  • ⚡ Creazione e chiusura sicura delle connessioni

1. Introduction (Introduzione)

HTTP [RFC2616] era originariamente utilizzato in chiaro su Internet. Tuttavia, l'uso crescente di HTTP per applicazioni sensibili ha reso necessarie misure di sicurezza. SSL e il suo successore TLS [RFC2246] sono stati progettati per fornire sicurezza orientata al canale. Questo documento descrive come utilizzare HTTP su TLS.

Concetto centrale

HTTPS = HTTP + TLS

┌────────────────────────────────────────┐
│ HTTP/1.1 Protocol │
│ (Application Layer Protocol) │
├────────────────────────────────────────┤
│ TLS/SSL Protocol │
│ (Transport Layer Security) │
├────────────────────────────────────────┤
│ TCP Protocol │
│ (Transmission Control Protocol) │
└────────────────────────────────────────┘

1.1. Requirements Terminology (Terminologia dei requisiti)

Le parole chiave "deve (MUST)", "non deve (MUST NOT)", "richiesto (REQUIRED)", "dovrebbe (SHOULD)", "non dovrebbe (SHOULD NOT)" e "può (MAY)" che appaiono in questo documento devono essere interpretate come descritto in [RFC2119].


2. HTTP Over TLS (HTTP su TLS)

Principio centrale

Concettualmente molto semplice: HTTP/TLS è molto semplice. Utilizzare HTTP su TLS esattamente come si userebbe HTTP su TCP.

2.1. Connection Initiation (Avvio della connessione)

Processo:

1. Client → Server: Stabilire connessione TCP (porta 443)
2. Client → Server: Inviare TLS ClientHello
3. ↔ Processo di handshake TLS ↔
4. Dopo il completamento dell'handshake: Il client può avviare la prima richiesta HTTP

Requisiti:

  • ✅ Il client HTTP deve (MUST) agire come client TLS
  • ✅ Connettersi alla porta appropriata (predefinita 443)
  • ✅ Inviare TLS ClientHello per iniziare l'handshake
  • ✅ Tutti i dati HTTP devono (MUST) essere inviati come "dati applicazione" TLS

Esempio di flusso:

Client:
1. Connessione TCP a www.example.com:443
2. Inviare ClientHello

Server:
3. Rispondere ServerHello + Certificato
4. ServerHelloDone

Client:
5. ClientKeyExchange
6. ChangeCipherSpec
7. Finished

Server:
8. ChangeCipherSpec
9. Finished

← Handshake TLS completato →

Client:
10. Inviare richiesta HTTP crittografata:
GET / HTTP/1.1
Host: www.example.com

2.2. Connection Closure (Chiusura della connessione)

TLS fornisce una funzionalità per la chiusura sicura delle connessioni.

Closure Alert (Avviso di chiusura)

Definizioni:

  • Chiusura valida (Valid Closure): Avviso di chiusura corretto ricevuto
  • Chiusura incompleta (Incomplete Close): Chiudere la connessione immediatamente dopo l'invio dell'avviso di chiusura
  • Chiusura prematura (Premature Close): Connessione chiusa senza ricevere l'avviso di chiusura

Requisiti:

  • ✅ Le implementazioni devono (MUST) avviare uno scambio di avvisi di chiusura prima di chiudere una connessione
  • ⚠️ Le implementazioni possono (MAY) chiudere la connessione dopo aver inviato l'avviso di chiusura (senza attendere)
  • ❌ Le connessioni con chiusura prematura non devono (MUST NOT) riutilizzare la sessione

2.2.1. Client Behavior (Comportamento del client)

Problema: HTTP utilizza la chiusura della connessione per segnalare la fine dei dati del server.

Il client deve (MUST):

  • ✅ Trattare qualsiasi chiusura prematura come errore
  • ✅ Trattare i dati ricevuti come potenzialmente troncati
  • ✅ Inviare avviso di chiusura prima di chiudere la connessione

Casi speciali:

  1. Risposta senza Content-Length:
HTTP/1.1 200 OK
Content-Type: text/html
[La chiusura della connessione indica la fine]

← La chiusura prematura non può distinguere il server dall'attaccante →
  1. Content-Length presente ma non completamente letto:
HTTP/1.1 200 OK
Content-Length: 1000
[Solo 500 byte ricevuti prima della chiusura]

← Non può determinare se è un errore del server o un attacco →

Eccezione: Se i dati ricevuti corrispondono a Content-Length, dovrebbe (SHOULD) essere trattato come completato.

Esempio client:

✅ Chiusura normale:
Client: Inviare closure_alert
Attendere closure_alert del server
Chiudere la connessione

⚡ Chiusura rapida:
Client: Inviare closure_alert
Chiudere la connessione immediatamente (non attendere)
← Questo genera una chiusura incompleta lato server →

2.2.2. Server Behavior (Comportamento del server)

Requisito RFC 2616: I server devono (MUST) riprendersi correttamente dalla chiusura del client.

Il server dovrebbe (SHOULD):

  • ✅ Essere preparato a ricevere una chiusura incompleta dal client
  • ✅ Essere disposto a riprendere le sessioni TLS chiuse in questo modo
  • ✅ Tentare di scambiare avvisi di chiusura con il client
  • ⚡ Può (MAY) chiudere la connessione dopo aver inviato l'avviso di chiusura

Nota di implementazione:

HTTP senza connessioni persistenti:
- Il server segnala la fine dei dati chiudendo la connessione
- Ma il client potrebbe aver già inviato l'avviso di chiusura e disconnesso

2.3. Port Number (Numero di porta)

Porta predefinita: 443

Motivazione:

Il server HTTP si aspetta: Request-Line (ad es. GET / HTTP/1.1)
Il server TLS si aspetta: ClientHello

← Non può distinguere sulla stessa porta →

Soluzione: Utilizzare porte diverse
- HTTP: 80
- HTTPS: 443

Esempi:

# HTTP (testo in chiaro)
curl http://www.example.com:80/

# HTTPS (crittografato)
curl https://www.example.com:443/

2.4. URI Format (Formato URI)

Identificatore di protocollo: https:// (invece di http://)

Esempi:

https://www.example.com/~smith/home.html
https://api.example.com:8443/v1/users
https://192.168.1.1/admin

Componenti URI:

https://www.example.com:443/path?query#fragment
↑ ↑ ↑ ↑ ↑ ↑
scheme host port path query fragment

3. Endpoint Identification (Identificazione degli endpoint)

3.1. Server Identity (Identità del server)

Requisito centrale: I client devono (MUST) verificare l'identità del server per prevenire attacchi man-in-the-middle.

Processo di verifica dell'identità

1. Il client ottiene l'hostname dall'URI
ad es.: https://www.example.com

2. Il server fornisce il certificato nell'handshake TLS

3. Il client verifica se l'hostname corrisponde all'identità del certificato

Priorità dei campi di identità

Priorità 1: subjectAltName (Nome alternativo del soggetto)

Estensione subjectAltName nel certificato (tipo dNSName):
dNSName: www.example.com
dNSName: api.example.com

← Questo campo deve (MUST) essere utilizzato (se presente) →

Priorità 2: Common Name (Nome comune)

CN nel campo Subject del certificato:
CN=www.example.com

← Utilizzare solo in assenza di subjectAltName →
← Deprecato, le CA dovrebbero utilizzare dNSName →

Regole di corrispondenza

1. Corrispondenza con caratteri jolly:

Certificato: *.example.com
✅ Corrisponde: foo.example.com
❌ Non corrisponde: bar.foo.example.com

Certificato: f*.com
✅ Corrisponde: foo.com
❌ Non corrisponde: bar.com

2. Indirizzi IP:

URI: https://192.168.1.1/
Il certificato deve (MUST) contenere: iPAddress subjectAltName
Il valore deve (MUST) corrispondere esattamente: 192.168.1.1

3. Identità multiple:

Se il certificato contiene più dNSName:
- www.example.com
- api.example.com
- *.app.example.com

← La corrispondenza con uno di essi è accettabile →

Comportamento in caso di mancata corrispondenza

Client orientati all'utente (browser):

  • ✅ Deve (MUST) notificare l'utente
  • ⚠️ Può (MAY) dare all'utente l'opzione di continuare
  • O terminare la connessione

Client automatizzati (client API):

  • ✅ Deve (MUST) registrare l'errore nel log di audit
  • ✅ Dovrebbe (SHOULD) terminare la connessione
  • ⚠️ Può (MAY) fornire un'opzione di configurazione per disabilitare il controllo

Avviso di sicurezza

Fonte URI non affidabile:

Scenario di attacco:
1. L'utente clicca su un link in una pagina HTTP
2. La pagina HTTP stessa non è crittografata
3. Il man-in-the-middle potrebbe aver sostituito l'URI

Protezione:
Gli utenti dovrebbero esaminare attentamente il certificato del server

3.2. Client Identity (Identità del client)

Caso tipico: Il server non ha conoscenza esterna dell'identità del client.

Se il server ha conoscenza esterna (da fuori HTTP o TLS):

  • Dovrebbe (SHOULD) verificare l'identità come descritto sopra

Autenticazione con certificato client:

Scenari comuni:
- Sistemi interni aziendali
- Controllo accesso API
- TLS mutuo (mTLS)

Verifica:
- Catena di certificati radicata in CA appropriata
- Opzionale: Verificare l'identità specifica del client

Security Considerations (Considerazioni sulla sicurezza)

Questo intero documento riguarda la sicurezza.

Punti chiave sulla sicurezza

  1. La validazione dei certificati è obbligatoria (Mandatory)

    • I client devono (MUST) verificare i certificati del server
    • Previene attacchi man-in-the-middle
  2. Chiusura corretta della connessione (Proper Connection Closure)

    • Utilizzare avvisi di chiusura TLS
    • Rileva attacchi di troncamento dati
  3. Verifica del nome host (Hostname Verification)

    • Previene attacchi di sostituzione del certificato
    • Preferire subjectAltName a CN
  4. Attenzione agli URI non affidabili (Beware Untrusted URIs)

    • Gli URI ottenuti tramite HTTP potrebbero essere manomessi
    • Gli utenti dovrebbero esaminare i certificati

Esempi pratici

Connessione HTTPS completa

Operazioni del client:

1. Analizzare l'URI: https://www.example.com/page.html
→ Hostname: www.example.com
→ Porta: 443 (predefinita)

2. Connessione TCP a www.example.com:443

3. Handshake TLS:
ClientHello →
← ServerHello + Certificate
Verificare l'hostname nel certificato
...handshake completato...

4. Inviare richiesta HTTP crittografata:
GET /page.html HTTP/1.1
Host: www.example.com

5. Ricevere risposta HTTP crittografata:
HTTP/1.1 200 OK
Content-Length: 1234
...

6. Chiudere la connessione:
Inviare closure_alert
Chiudere la connessione TCP

Esempio di verifica del certificato

# Esempio Python (concettuale)
import ssl
import socket

# Creare contesto SSL
context = ssl.create_default_context()

# Connettersi al server
sock = socket.create_connection(('www.example.com', 443))
ssock = context.wrap_socket(sock, server_hostname='www.example.com')

# wrap_socket verifica automaticamente:
# 1. La catena di certificati è valida
# 2. L'hostname corrisponde
# 3. Il certificato non è scaduto

# Ottenere informazioni sul certificato
cert = ssock.getpeercert()
print(f"Subject: {cert['subject']}")
print(f"Issuer: {cert['issuer']}")
print(f"SANs: {cert.get('subjectAltName', [])}")

Gestione degli errori comuni

Errore 1: Mancata corrispondenza del nome host del certificato
Certificate Hostname Mismatch
- Certificato: *.example.com
- Accesso: www.different.com
→ Terminare la connessione o avvisare l'utente

Errore 2: Certificato scaduto
Certificate Expired
- Not After: 2023-12-31
- Corrente: 2024-01-01
→ Rifiutare la connessione

Errore 3: Certificato autofirmato
Self-Signed Certificate
- Non nell'elenco delle CA attendibili
→ Avvisare l'utente o rifiutare

Errore 4: Catena di certificati incompleta
Incomplete Certificate Chain
- Manca il certificato intermedio
→ Impossibile verificare, rifiutare la connessione

Relazione con gli standard moderni

Successori di RFC 2818

Sebbene RFC 2818 rimanga valido, ci sono specifiche aggiornate:

RFCTitoloDescrizione
RFC 2818HTTP Over TLSQuesto documento (2000)
RFC 5246TLS 1.2Protocollo TLS aggiornato
RFC 8446TLS 1.3Ultimo protocollo TLS
RFC 6125Validazione certificatiVerifica più dettagliata del nome host
RFC 7230-7235HTTP/1.1Specifiche HTTP aggiornate
RFC 7540HTTP/2HTTP/2 funziona tipicamente su TLS

Aggiornamenti delle pratiche moderne

  1. Versioni TLS:
RFC 2818: SSL/TLS (1.0/1.1)
Moderno: TLS 1.2+ (TLS 1.0/1.1 deprecato)
  1. Validazione dei certificati:
RFC 2818: Regole di base
RFC 6125: Specifiche dettagliate
  1. HSTS:
RFC 6797: HTTP Strict Transport Security
Forza i browser a utilizzare HTTPS

Riferimento rapido

HTTPS vs HTTP

CaratteristicaHTTPHTTPS
Protocollohttp://https://
Porta80443
Crittografia❌ Testo in chiaro✅ Crittografato TLS
Integrità❌ Nessuna protezione✅ Protezione MAC
Autenticazione❌ Nessuna auth server✅ Auth certificato
Privacy❌ Può essere intercettato✅ Trasmissione crittografata

Panoramica dell'handshake TLS

Client                           Server
| |
|--- ClientHello --------------->|
| |
|<-- ServerHello, Certificate ---|
|<-- ServerHelloDone ------------|
| |
|--- ClientKeyExchange --------->|
|--- ChangeCipherSpec ---------->|
|--- Finished ------------------>|
| |
|<-- ChangeCipherSpec -----------|
|<-- Finished -------------------|
| |
|=== Canale crittografato ======|
| |
|--- Richiesta HTTP crittografata->|
|<-- Risposta HTTP crittografata-|

Strumenti comuni

# OpenSSL visualizzare certificato
openssl s_client -connect www.example.com:443 -showcerts

# Testare versione TLS
openssl s_client -connect www.example.com:443 -tls1_2

# Visualizzare dettagli certificato
echo | openssl s_client -connect www.example.com:443 2>/dev/null | \
openssl x509 -noout -text

# cURL utilizzare HTTPS
curl -v https://www.example.com

Riferimenti

Riferimenti normativi

  • [RFC 2119] - Parole chiave da utilizzare nelle RFC per indicare i livelli di requisito
  • [RFC 2246] - Il protocollo TLS
  • [RFC 2459] - Infrastruttura a chiave pubblica Internet X.509 Profilo certificato e CRL
  • [RFC 2616] - Hypertext Transfer Protocol -- HTTP/1.1

Riferimenti informativi

  • [RFC 2817] - Aggiornamento a TLS all'interno di HTTP/1.1
  • [RFC 5246] - Il protocollo Transport Layer Security (TLS) Versione 1.2
  • [RFC 6125] - Rappresentazione e verifica dell'identità del servizio applicativo basata su dominio
  • [RFC 6797] - HTTP Strict Transport Security (HSTS)
  • [RFC 7230-7235] - Hypertext Transfer Protocol (HTTP/1.1) Specifiche aggiornate
  • [RFC 8446] - Il protocollo Transport Layer Security (TLS) Versione 1.3

Glossario

Termini centrali

TLS (Transport Layer Security)

  • Protocollo di sicurezza del livello di trasporto, successore di SSL

SSL (Secure Sockets Layer)

  • Predecessore di TLS, ora deprecato

Certificate (Certificato)

  • Documento digitale contenente chiave pubblica e informazioni di identità

CA (Certificate Authority / Autorità di certificazione)

  • Autorità di certificazione che emette certificati attendibili

Closure Alert (Avviso di chiusura)

  • Meccanismo TLS per la chiusura sicura della connessione

Premature Close (Chiusura prematura)

  • Chiusura impropria della connessione TLS

Man-in-the-Middle Attack (Attacco man-in-the-middle)

  • L'attaccante intercetta e potenzialmente modifica la comunicazione

subjectAltName (Nome alternativo del soggetto)

  • Estensione del certificato che specifica nomi host aggiuntivi

Common Name (Nome comune)

  • Campo CN nel soggetto del certificato

Ritorna: Elenco documenti RFC

RFC correlati: