07 HTTP Protocol
Basics
The basic sequence of a HTTP request is as follows:
sequenceDiagram
participant Client as Client
participant Server as Server
participant DNS as DNS Server
participant SDNS as Subsequent DNS Servers
activate Client
opt DNS Request
Client->>DNS: A apsi.example.com
activate DNS
DNS->>SDNS: NS com
activate SDNS
SDNS-->>DNS: NS com = 1.2.3.5
deactivate SDNS
DNS->>SDNS: NS example.com
activate SDNS
SDNS-->>DNS: NS example.com = 1.2.3.6
deactivate SDNS
DNS->>SDNS: A apsi.example.com
activate SDNS
SDNS-->>DNS: A apsi.example.com = 1.2.3.4
deactivate SDNS
DNS-->>Client: A apsi.example.com = 1.2.3.4
deactivate DNS
end
opt HTTP Request
note right of Client: GET / HTTP/1.1<br>Host: apsi.example.com<br>Accept-Language: de_CH, en<br>[...]
Client->>Server: GET / HTTP/1.1
activate Server
note right of Client: HTTP/1.1 200 OK<br>Server: Apache<br>Date: Mon, Jul 20 1972 03:17:00 CET<br>ETag: "..."<br>Cache-Control: max-age=3600<br>[...]
Server-->>Client: HTTP/1.1 200 OK
deactivate Server
end
deactivate Client
Relevant are the DNS and actual HTTP request. Everything before the DNS request is considered unsafe.
HTTP
The HTTP protocol (up to HTTP/1.1) is a pure text protocol. Messages are made up of a “start line”, zero or more “header fields”, an empty line and lastly, an optional “message body”.
HTTP Request Example
GET /index.html HTTP/1.1
User-Agent: curl/7.64.1
Host: www.fhnw.ch
Accept-Language: de-CH, en
Accept-Encoding: gzip, deflate
Connection: keep-alive
HTTP Response Example
HTTP/1.1 200 OK
Date: Fri, 26 Jan 2024 10:17:00 CET
Server: Apache/2.2.14 (Win32)
Last-Modified: Mon, 22 Jan 2024 17:46:11 CET
Content-Length: 88
Content-Type: text/html
Connection: Closed
<html>
<body>
<h1>Hello, World!</h1>
</body>
</html>
There is no context between requests in HTTP. This means:
- Generally, there is one single request initiated by the client. The server responds exactly once in the same TCP connection.
- The HTTP protocol is human-readable (or can be made human-readable for versions >1.1).
- No context between requests. Permissions need to be checked on every request.
HTTPS
HTTPS is HTTP wrapped in TLS (Transport Layer Security). First the TCP connection is established, then the TLS handshake is performed (nine or more packets in version 1.2).
Simplified TLS Handshake (v1.2)
sequenceDiagram
participant Client as Client
participant Server as Server
note right of Client: Client Hello contains:<br>SSL/TLS version, supported ciphers, random value (client random)
activate Client
Client->>Server: Client Hello
activate Server
note left of Server: Server Hello contains:<br>SSL/TLS version, chosen cipher, random value (server random)
Server-->>Client: Server Hello, Certificate, Server Key Exchange, Server Hello Done
Client->>Server: Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
Server-->>Client: Change Cipher Spec, Encrypted Handshake Message
deactivate Server
deactivate Client
It is possible that the server sends a Client Certificate Request after the Server Hello. In this case, the client should respond with a Client Certificate response.
TLS version 1.3 combines the packets sent in sequence by the client and server into a single packet (reducing the handshake to five packets). This simplifies the handshake and reduces the number of round trips.
Encryption
Transport Encryption
Transport Encryption is the encryption of the communication between two parties. It is also called point-to-point encryption (P2PE). When using transport encryption, only the communication is encrypted but not the data itself.
Transport encryption only protects against passive attacks. Active attacks are still possible, except:
- the encryption cannot be manipulated into an unsafe state (e.g. downgrade attacks, like BEAST for TLSv1.0)
- both parties have verified each other’s identity (e.g. via a certificate)
HTTPS is an example of transport encryption. A TCP session is wrapped in TLS.
End-to-End Encryption
End-to-End Encryption (E2EE) is the encryption of the data itself. When using end-to-end encryption, infrastructure providers (e.g. mail server providers or chat server providers) cannot read the messages.
Metadata (e.g. sender, receiver, time, size) is typically not encrypted and is still readable.
E2EE is only possible if both parties can identify each other securely. A problem is the initial establishing of trust. Most of the time, this is done via a separate channel.
HTTP Authentication
Basic Authentication
Basic Authentication is the simplest form of authentication. When required, the server responds with an HTTP 401 Unauthorized response. The header contains a WWW-Authenticate header with the authentication method and realm.
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="..."
...
The client response should then contain an Authorization header with the username and password. Username and password are concatenated with a colon and then base64 encoded (username:password).
GET / HTTP/1.1
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
...
Conclusion: Basic Authentication is not secure. If no TLS is used, the username and password are sent in plain text. Additionally, there is no real way to log out (clearing the cache is possible).
Digest Authentication
Digest Authentication is more secure than Basic authentication. Is uses a challenge-response mechanism.
sequenceDiagram
Client->>Server: GET / HTTP/1.1
Server-->>Client: HTTP/1.1 401 Unauthorized (WWW-Authenticate: Digest realm="...", nonce="...")
Client->>Client: Calculate response
Client->>Server: GET / HTTP/1.1 (Authorization: Digest username="...", realm="...", nonce="...", uri="...", response="...")
Server->>Server: Calculate response and compare with client response
Server-->>Client: HTTP/1.1 200 OK
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Digest
realm="[email protected]",
qop="auth, auth-int",
algorithm=SHA-256,
nonce="7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v",
opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS"
...
GET / HTTP/1.1
Authorization: Digest
username="Mufasa",
realm="[email protected]",
uri="/dir/index.html",
algorithm=SHA-256,
nonce="7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v",
nc=00000001,
cnonce="f2/wE4q74E6zIJEtWaHKaf5wv/H5QzzpXusqGemxURZJ",
qop=auth,
response="753927fa0e85d155564e2e272a28d1802ca10daf4496794697cf8db5856cb6c1",
opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS"
...
Conclusion: Digest authentication is pretty secure. The password cannot be calculated and the authentication token changes with every login. But, also with Digest authentication, there is no default way to log out.
Form-based Authentication
Form-based Authentication is the most common form of authentication. A plain HTML form is used to submit the username and password to the server, where it is checked. Because the login is only valid for the current page, the server sets a token or cookie, which is used on subsequent requests as a substitute for the username and password.
Conclusion: Form-based authentication is insecure. The password is sent in plain text and the token is stored in the browser. This means that the token can be stolen via XSS or CSRF attacks.
TLS-based Authentication
TLS-based Authentication is the most secure form of authentication. It is a so-called “external authentication mechanism”.
The TLS protocol is used to authenticate. But:
- deploying certificates on user devices is difficult.
- certificate logins are not well supported, especially on mobile devices.
- users are not used to certificate logins.
Conclusion: TLS-based authentication is very secure. But sadly, not very well supported.