Alex's Notes

CS253 Lecture Summaries: Part II DNS, HTTP, Cookies

Part of Web Security - Stanford CS 253

Reviews what happens when you enter a URL into a browser.

First step is a DNS query. User friendly domain name is matched to an ip.

A client sends a request to a server asking the question, what’s the IP address for stanford.edu DNS server responds with the IP.

But what’s the DNS server doing? It does a bunch of work on behalf of the client - we call it the ‘recursive resolver’, it continually queries other servers until it gets the full answer.

First there’s the root or nameserver. The DNS server will ask for standford.edu and the root nameserver will respond with the name server for the .edu domain, this is the TLD (top level domain) name server.

Then the resolver will query that server for stanford.edu, it will respond with the name server able to actually answer the query, then the final call to that server will fulfil the request.

Now we have the IP we can send a request to the actual server and get the response.

This gives us our first attack vector DNS Hijacking

Here the attacker changes DNS records of the target to point to their own IP address.

All site visitors are directed to the attacker’s web server. They can use this for phishing, revenue through ads/crypto mining etc.

How can you do it?

You can use malware on the user’s system, to change local DNS settings.

You can hack the recursive resolver

You can hack the router

You can hack a nameserver

or you could compromise a user account at a DNS provider.

DNS privacy is also an issue - queries are in plain text. ISPs have been known to sell the data that results from just the DNS lookups.

One tip - you can set your DNS settings to cloudfare (1.1.1.1) or another provider with a good privacy policy.

There is a new protocol - DNS over HTTPS, that lets us encrypt our DNS query itself. Default in FF, optional in Chrome.

So what about the HTTP request part. Gives an anatomy of the request.

First line GET / HTTP/1.1 ie <method> <path> <protocol version>

Response will be HTTP/1.1 200 OK headers, body.

Some things that make HTTP cool - it’s simple, text base, client-server model. It’s extensible - just add HTTP headers. It’s stateless, two requests have no relation to each other. It’s transport-protocol agnostic, just has to be reliable.

Obviously we interact with ‘stateful’ servers all the time, but this is layered on top of http itself the protocol stores no state.

Headers

General format is <Name>: <Value> like Host: example.com

They let the client and server pass additional info that’s not part of the request or response body.

Some useful request headers:

Host the domain name of the server. Most servers won’t respond if you don’t include it.

User-Agent the name of your browser and OS. Useful for detecting a search engine (eg google name their agent googlebot).

Referer the webpage which led you to this page, who linked them.

Cookie The cookie the server gave you earlier. Keeps you logged in.

Range specifies a subset of bytes to fetch (eg part of a video).

Cache-Control specifies if you want a cached response or not.

If-Modified-Since only send resource if changed recently.

Connnection Control TCP Socket (eg keep-alive or close).

Accept which type of content do we want (eg text/html).

Accept-Encoding encoding algorithms we understand (eg gzip).

Accept-Language what language we ant (eg es).

Useful HTTP Response headers:

Date when response was sent

Last-Modified when content was last modified

Cache-Control specify whether to cache or not

Expires Discard response from cache after this date

Vary List of headers which affect response; used by cache. Signals when a header difference should trigger a fresh request. EG if the Accept-Language header will trigger a different response for a different language version, the client should fetch a fresh request if the user changes language and the header changes: Vary: Accept-Language

Set-Cookie Set a cookie on the client.

Location url to redirect the client to (used with 3xx responses).

matching headers for requests: Connection, Content-Type, Content-Encoding, Content-Language, Content-Length.

Shows building an http client in node over the node standard socket and dns libraries:

const net = require('net')
const dns = require('dns')

dns.lookup('example.com', (err, address) => {

  if (err) throw err

  const socket = net.createConnection({
    host: address,
    port: 80
  })

  const request = `
GET / HTTP/1.1
Host: example.com

`.slice(1) //this gets rid of the leading newline char

  socket.write(request)
  socket.pipe(process.stdout)
})

//nb the process will hang as the socket isn't closed