Unit 6: The browser security model · Lesson 3 of 5 · 18 min

Content-Security-Policy

A list of where a page may load things from, enforced by the browser.

mission

You are
The analyst reviewing the shop.
Situation
Developers want to roll the /shop policy out to every page and ask you to explain what it allows.
Goal
Read the shop's policies directive by directive.
Hand in
A plain-language summary of each directive and the pages that have none.
01

Read the policy on /shop

learner@web-lab
curl -sI http://127.0.0.1:8000/shop | grep -i '^content-security-policy' | cut -d' ' -f2- | tr ';' '\n' | sed 's/^ //'
default-src 'self'
script-src 'self' https://cdn.example.com
object-src 'none'
frame-ancestors 'none'

you should see Four directives, one per line.

curl
Sends web requests and prints the response. Built into Linux, macOS and Windows 10 and later.
grep
Prints the lines of text that match a pattern. Built into Linux and macOS.
cut
Keeps only chosen columns or characters from each line. Built into Linux and macOS.
tr
Replaces or deletes characters. Built into Linux and macOS.
sed
Edits text as it streams past, for example to replace or delete lines. Built into Linux and macOS.
02

Pages without one

learner@web-lab
for p in / /shop /login /help /account; do printf '%-9s ' $p; curl -sI http://127.0.0.1:8000$p | grep -ci content-security-policy; done
/         0
/shop     1
/login    0
/help     1
/account  0

you should see Only two pages carry a policy.

printf
Prints formatted text. Built into Linux and macOS.
03

A policy written for an AI widget

The help page loads a chat assistant. Its policy has to let the page talk to the AI provider.

learner@web-lab
curl -sI http://127.0.0.1:8000/help | grep -i '^content-security-policy' | cut -d' ' -f2- | tr ';' '\n' | sed 's/^ //'
default-src 'self'
connect-src 'self' https://api.example-ai.com

you should see connect-src names an outside host. Every host listed is one the page may send data to.

defender tip In Firefox, anything a policy blocks shows up in the Console tab with the directive that stopped it. Ship new policies as Content-Security-Policy-Report-Only first and read those reports.

04

Find the framing rule

learner@web-lab
curl -sI http://127.0.0.1:8000/shop | grep -io "frame-ancestors[^;]*"
frame-ancestors 'none'

you should see frame-ancestors 'none': no other site may frame the shop page. It replaces X-Frame-Options in modern browsers.

The /shop policy

default-src 'self'; script-src 'self' https://cdn.example.com; object-src 'none'; frame-ancestors 'none'
  1. 1default-src 'self'fallback: this origin only
  2. 2script-src 'self' https://cdn.example.comscripts from here and one CDN
  3. 3object-src 'none'no plugins
  4. 4frame-ancestors 'none'nobody may frame it

What a defender takes away

  1. 1CSP limits what injected content can load or send.
  2. 2Every host in a policy is a host you trust with your users.
  3. 3Roll out in report-only mode, then enforce.

Questions

0 of 3 solved

Answer each one from what you find on your lab machine.