Web Security 101 Remastered

security

This is a revised presentation of Web Security 101 in the virtual meetup. It was the first episode of the security series, therefore it included more generic discussion of security model.

Overview

What happens when Alice types a bank.com in the browser?

What happens when Alice type a bank.com in the browser?
What happens when Alice type a bank.com in the browser?

This is a canonical interview question to probe the candidate’s knowledge about the web stacks. Briefly:

  1. The browser tries to resolve the domain name bank.com to IP address with cached DNS records. If nothing found, it sends DNS requests to the DNS server specified by the /etc/resolve.conf.
  2. The browser establishes the connection with the web server with 3-way TCP handshake.
  3. The browser negotiates a session key with the web server in the SSL handshake.
  4. The server renders the sign-in page, Alice types her user name and password, and submits the form.
  5. The server challenges Alice with MFA secret. Under the hood, the code is scheduled in the message queue, and delivered by the telephony service provider, such as Twilio.
  6. Alice checks her cellphone, and types the secret code, then lands on the account page.

What are the attacking surfaces in such a over-simplified login process?

  • KeyLogger, the hacker can inject key loggers via malware, infected browser, and browser plugins to record key strokes and steal Alice’s password.
  • Supply chain attack, the hacker might control the upstream libraries to compromise the OS, browser, etc.
  • Man-in-the-middle attack, the hacker can fabricate the DNS response, and impersonate bank.com. This will not work thanks to the SSL.
  • CA cert attack, some corporations may issue private certificates for internal endpoints. It would compromise the trust chain if the private CA was compromised.
  • Social Engineering, the hacker might launch social engineer to trick Alice to acknowledge the nonce, or convince Alice’s ISP to swap the sim card.

CIA triad

Confidentiality, integrity, and availability are known as the CIA triad. It is worthy differentiating the confidentiality and integrity here:

  • Confidentiality is about the encryption: the hacker cannot peek the message, but he may modify the encrypted text without recipient’s notice.
  • Integrity is about the signing: the hack might be able to read the message, but he cannot tamper the message without recipient’s notice.

The web achieves confidentiality and integrity via the transport layer security, also known as tls. A popular implementation is OpenSSL.

SSL Handshake

I had a misconception that OpenSSL uses the RSA key pair to encrypt the communication. If this were correct, the browser also needs CA-trusted RSA key pair for the duplex communications. The communication is encrypted by the shared AES session key, and the RSA key pair is only used for the key exchange.1

SSL handshake with RSA key pairs

SSL Handshake with RSA key pairs
SSL Handshake with RSA key pairs

In the second step, the server sends the server random with public key certificate. The client validates the public key certificate against the trusted CA, then uses the public key to encrypt a premaster secret in the third step. The premaster can only be decrypted with the private key. At the last step, both client and server use server random, client random, and premaster secret to generate the session key for symmetric encryption, such as AES.

This key exchange scheme does not qualify forward secrecy. If a hacker manages to capture all the traffics between Alice and bank.com, and later bank.com’s private key is leaked; the hacker can use the private key to decrypt the premaster secret in the step 4, and generate the session key to recover past communications!

SSL handshake with Diffie-Hellman

The vulnerability of RSA key exchange is the random premaster secret is always encrypted with the same private key. Can we use one-time key, aka nonce instead?

SSL Handshake with Diffie-Hellman
SSL Handshake with Diffie-Hellman

In the Diffie-Hellman key exchange, the private key is only used for signing the payload in step 2b. The client validates the payload is NOT tampered with the public key, then send the client DH parameter in step 4. In another word, the server random, server DH parameter, and client DH parameters are transferred in plain text. How does this work to prevent the hacker to get the premaster secret?

This is based on the group theory: with predefined gg and pp:

  1. Alice has a secret aa, and send AA, where A=gamodpA = g^a \mod p
  2. Bank.com has a secret bb, and send BB, where B=gbmodpB = g^b \mod p.
  3. The DH parameter is s=gab˙modp=Abmodp=Bamodps = g^{a \dot b} \mod p = A^b \mod p = B^a \mod p

However with only AA and BB, the hacker cannot compute ss in a reasonably period of time. As both aa and bb are ephemeral and random, the session key cannot be recovered with reasonable efforts.

Browser security model

The browser is the gateway to access the internet, it follows instructions from the web server to implement designed security model.

Same-origin Policy

The same-origin policy is probably the cornerstone of the browser security. The origin is defined by the (protocol, host, port) tuple. Generally speaking, the cross region write such as navigation, and embedding such as images are allowed; but the cross-region read such as AJAX calls are disallowed unless the web server explicitly approves.

For example, in the Cross Origin Resource Sharing(CORS) scenario, the HTTP protocol requires the browser to send Origin header for the CORS request, the web server render the response with directives in the HTTP headers:

  • Access-Control-Allow-Origin
  • Access-Control-Request-Method
  • Access-Control-Request-Headers
  • Access-Control-Allow-Credentials

The browser follows the directives to accept or reject the payload.

Frame isolation

This paper in Usenix describes the history of the frame isolation. It is intuitive to enforce the same-origin policy for scripting, but kind of subtle for navigation policy:

  • Child Policy: A frame can navigate only its direct children.
  • Descendant Policy: A frame can navigate only its descendants.

Cross-site Scripting

Cross-site scripting, aka XSS is a common attack via user-generated content. As a service operator, we should never trust user inputs. We have several options to fence against the attack.

  • We can sanitize inputs and remove scripts before the persistence. It is non-trivial to do it right according to Ben Hoyt’s investigation.
  • We can prevent XSS by escaping inputs. This is probably most secure approach on the cost of degrade user experience.
  • We can use Markdown, BBCode, or other alternative markup languages for rich editing, and convert them to HTML.

The content security policy might mitigate the issue if it is configured strict enough, see below for more details.

Cookie Policy

The web server can enforce the cookie policy with Set-Cookie header, notably:

  • Secure — the cookie is only sent via HTTPS
  • HttpOnly — the cookie is NOT accessible by document.cookie
  • SameSite — Strict or Lax to prevent CSRF.
  • Generally do NOT use Domain attribute, as it instructs the browser to send Cookie header for subdomains!

Content Security Policy

The content security policy, often referenced as CSP is the consolidated efforts to fine-tune the access policy. There are several tools to generate, and analyze CSP:

As Gatsby, which powers this site, relies on the inline script for chunk delivery. It seems that I should use nonce, which is only feasible to introduce edge computing in the CDN side. I would continue to explore my options and report back.

Closing thoughts

The web is supposed to be open, extendable to facilitate resource sharing, but the script context should be isolated to prevent abuse.

The defense in depth strategy suggests the security is not shouldered only by the infosec team, it is everyone’s responsibility.


  1. The following diagrams are adapted from CloudFlare’s keyless solution.