Securing The Client Side Web
HTTPS, CSP, and Sandboxes
15.1.2015
Hello World!
Niklas Lindgren
Specialist
Email: niklas@sc5.io
Twitter: @nikcorg
Psst!
Not a
securityspecialist
Do you trust me?
● can I be sure I know who I’m talking to?
● can I be sure no one is eavesdropping?
● can I be sure messages aren’t tampered with during
transit?
Man in the Middle
WWW
Switch Gateway
Normal traffic flow
WWW
Switch Gateway
Traffic Flow in a Man-in-the-Middle Attack
HTTPS (HTTP + SSL/TLS)
● ensures you know who you are talking to
● ensures delivered content is unmodified in transit
● eliminates man-in-the-middle attacks
● use HTTP only for redirecting to HTTPS
● enables using secure cookies
● Google rewards SSL protected websites
○ http://googlewebmastercentral.blogspot.fi/2014/08/https-as-
ranking-signal.html
● performance hit is negligible
○ https://IsTLSFastYet.com/
Certificate Shopping
● https://www.startssl.com/
○ from 0 USD and up
● https://sslmate.com/
○ from ~15 USD / year
○ buy and renew from the command line
● https://letsencrypt.org/
○ free service
○ coming summer 2015
● HTTP to HTTPS redirect is done client side
● ensures no network connection is unencrypted HTTP
● if a secure connection cannot be established, the
connection is blocked
● fixes SSL stripping man-in-the-middle
HTTP Strict Transport Security (HSTS)
WWW
SSL Stripping Man in the Middle Attack
Plain text HTTP Encrypted HTTPS
Browser Support
Strict-Transport-Security:
max-age=123456789;
includeSubDomains
● max-age defines the expiry time in seconds
● includeSubDomains declares the policy should be
enforced on the declaring host and all its
subdomains
Howto
Caveats
● first ever connection could still be over HTTP, leaving
a window for a SSL stripping man-in-the-middle
attack
HTTP Public Key Pinning (HPKP)
● prevents certificate forgery
Browser Support
Public-Key-Pins:
pin-sha256="<hash>=";
max-age=<secs>;
includeSubDomains
● pin-sha256 is the key hash (can have multiple)
● max-age defines the expiry time in seconds
● includeSubDomains declares the policy should be
enforced on the declaring host and all its
subdomains
Howto
● unless you have a backup certificate and you have to
revoke your primary certificate, your site will be
unreachable
● first ever connection could still be over HTTP, leaving
a window for a SSL stripping man-in-the-middle
attack
Caveats
● sites can be added to HSTS Preload lists included in
the browser application
● solves the initial non-HTTPS connection problem
● doesn’t scale
● in Chrome you can verify, add and delete sites
manually via chrome://net-internals/#hsts
HSTS Preloading
Howto
Strict-Transport-Security:
max-age=123456789;
includeSubDomains;
preload
● add preload to your existing HSTS policy and submit
your site via https://hstspreload.appspot.com/
● NB! Only for Chrome, but Firefox & Safari supposedly
include Chrome’s preload list at least partially
Recap
● use HTTPS
● use HSTS
● consider HPKP
● consider including your app on a HSTS preload list
Content Security Policy (CSP)
● mitigates XSS attacks
○ If script is inject into your application, it’s no longer your
application -- Brad Hill, PayPal
● white list origins that are considered good sources
● separate lists for different media
● provides policy violation reports
● not a replacement for other counter measures, but a
great supplement
Browser Support
● no inline Styles
● no inline JavaScript, including inline event handlers
● no eval
● setTimeout/setInterval won’t accept strings as first
param, only functions
Caveats
● media-src
○ video/audio
● object-src
○ plugins
● sandbox
○ sandboxes the document
● style-src
○ stylesheets
● script-src
○ javascript
● report-uri
○ violation reports
Directives
● default-src
○ catch all
● connect-src
○ XHR / WebSocket /
EventSource
● font-src
○ fonts
● frame-src
○ iframes
● img-src
○ images
Origins
● ‘none’ (nothing matches)
● ‘self’ (matches own origin, not subdomains)
● ‘unsafe-inline’ (allow inline script and style)
● ‘unsafe-eval’ (allow eval’ed script)
● data:, blob:
● scheme://host:port/path
● *, *.mycdn.com (wildcards)
Howto
● transmitted as a HTTP header
● semicolon delimited list of directives
● directive has space delimited list of origins
Content-Security-Policy(-Report-Only):
default-src ‘self’;
script-src ‘none’;
default-src
● default-src ‘none’
○ disallow any non-whitelisted sources
● default-src ‘self’
○ allow all connections to the host documents origin
● default-src https
○ allow any connections, as long they’re HTTPS
● default-src *
○ allow everything that doesn’t have its own directive
● script-src ‘self’
○ only scripts from own origin is allowed (excludes subdomains)
● script-src ‘unsafe-inline’
○ allow inline scripts
● script-src ‘unsafe-eval’
○ allow eval’ed scripts
● script-src blob:
○ allow blobs as script source, useful for inlined web workers
● script-src www.google-analytics.com
○ allow scripts coming from www.google-analytics.com
script-src
report-uri
{
"csp-report": {
"document-uri": "http://example.org/page.html",
"referrer": "http://evil.example.com/haxor.html",
"blocked-uri": "http://evil.example.com/image.png",
"violated-directive": "default-src 'self'",
"original-policy":
"default-src 'self';
report-uri http://example.org/csp-report.cgi"
}
}
● level 2 (formerly 1.1) is a work in progress
○ Last Call Working Draft since 3.7.2014
○ http://www.w3.org/TR/CSP2/
● available in Chrome behind flags
CSP Level 2
script-src
Content-Security-Policy: script-src ‘nonce-12345’;
<script nonce=”12345”>alert(“Hello”)</script>
Content-Security-Policy: script-src
‘sha256-<base64 encoded hash>’;
<script>alert(“Hello”);</script>
child-src
● allowed sources for worker contexts
● allowed sources for child browsing contexts
● deprecates frame-src
form-action
● limit where forms can be submitted to using the
form’s action attribute
● does not fall back to default-src must be explicitly
defined
referrer
● allows fine grained control on the referrer header
sent when leaving the site
● available settings are:
○ none (never send referrer)
○ none-when-downgrade (never send when https -> http)
○ origin (send origin only)
○ origin-when-cross-origin (origin only to cross origin
destinations)
○ unsafe-url (business as usual)
plugin-types
● list of allowed mime types handles by plugins
● deprecates object-src
Sandboxes
<iframe sandbox />
● unique origin
● will never match any origin, including its own
● secure by default (least privilege)
● switch features on as needed
● messaging can be used for transport between host
and sandbox
● Chrome, Firefox, Safari, Opera, IE10
Browser Support
Capabilities you can enable
● allow-forms
● allow-popups
● allow-pointer-lock
● allow-same-origin
● allow-scripts
● allow-top-navigation
● object is not allowed in sandboxed iframes, i.e. no
flash, so applicability for e.g. ads is limited
● iframes within sandboxed iframes cannot be
seamless
● sandboxed iframes with allow-same-origin, who
share the origin with host document, can remove the
sandbox attribute
Caveats
Use Cases
● load 3rd party widgets in sandboxes
<iframe src=”http://twitter.com/widget”
sandbox=”allow-same-origin allow-popups allow-scripts”
/>
● sandbox your own code that would violate your CSP
○ message passing via postMessage is still possible
○ see HTML5Rocks introduction for demo
○ http://www.html5rocks.com/en/tutorials/security/sandboxed-
iframes/#safely-sandboxing-eval
● the whole document is treated as though it was
loaded inside a sandboxed iframe
● no plugins
● no seamless iframes
Sandbox directive in CSP
X-XSS-Protection
● from our friends at Microsoft
● XSS protection through heuristics
● first appeared in IE8
○ very buggy implementation
○ awarded a PWNIE award in 2010
X-XSS-Protection: 0 // OFF
X-XSS-Protection: 1 // ON
// Block connection if filter matches
X-XSS-Protection: 1; mode=block
X-Frame-Options
● prevents clickjacking and framesniffing
X-Frame-Options: DENY
X-Frame-Options: SAMEORIGIN
X-Frame-Options: ALLOW-FROM origin
X-Content-Type-Options
● forbids the browser to perform mime type sniffing
● prevents evaluating scripts and stylesheets delivered
with incorrect mime type headers
● must be sent with the resource being downloaded
● IE >= 9
X-Content-Type-Options: noSniff
X-Download-Options
● prevents the browser displaying downloaded
content, i.e. force save
● must be sent with the resource being downloaded
● IE only
X-Download-Options: noOpen
Tools
● CSP Builder https://cspbuilder.info
○ compiles a CSP policy based on violation reports
● Helmet (Express/Connect)
○ CSP (1.0 only) and some other
● Zend Framework 2.3 has built in CSP support
● Nelmio Security Bundle (Symfony)
● Content-Security-Policy plugin for WordPress (sadly
outdated)
Thank you
@nikcorg
Links
● https://hstspreload.appspot.com/
● https://wiki.mozilla.org/Privacy/Features/HSTS_Preload_List
● https://developer.mozilla.org/en-US/docs/Web/Security/Public_Key_Pinning
● http://caniuse.com/#feat=contentsecuritypolicy
● http://caniuse.com/#feat=iframe-sandbox
● http://caniuse.com/#feat=stricttransportsecurity
● https://developer.mozilla.org/en-US/docs/Web/Security/Public_Key_Pinning#Browser_compatibility
● http://www.html5rocks.com/en/tutorials/security/transport-layer-security/
● http://www.html5rocks.com/en/tutorials/security/content-security-policy/
● http://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/
● http://content-security-policy.com/
● https://blog.twitter.com/2011/improving-browser-security-csp
● https://docs.angularjs.org/api/ng/directive/ngCsp
● http://www.dotnetnoob.com/2012/09/security-through-http-response-headers.html
● http://blogs.msdn.com/b/ie/archive/2008/07/02/ie8-security-part-v-comprehensive-protection.aspx
● https://w3c.github.io/webappsec/specs/content-security-policy/#changes-from-level-1
● https://wiki.mozilla.org/Security/Server_Side_TLS
● https://scotthelme.co.uk/hsts-the-missing-link-in-tls/
● https://www.chromium.org/hsts
● http://www.cspplayground.com/

Securing the client side web

  • 1.
    Securing The ClientSide Web HTTPS, CSP, and Sandboxes 15.1.2015
  • 2.
    Hello World! Niklas Lindgren Specialist Email:niklas@sc5.io Twitter: @nikcorg Psst! Not a securityspecialist
  • 3.
    Do you trustme? ● can I be sure I know who I’m talking to? ● can I be sure no one is eavesdropping? ● can I be sure messages aren’t tampered with during transit?
  • 4.
    Man in theMiddle WWW Switch Gateway Normal traffic flow WWW Switch Gateway Traffic Flow in a Man-in-the-Middle Attack
  • 5.
    HTTPS (HTTP +SSL/TLS) ● ensures you know who you are talking to ● ensures delivered content is unmodified in transit ● eliminates man-in-the-middle attacks ● use HTTP only for redirecting to HTTPS ● enables using secure cookies ● Google rewards SSL protected websites ○ http://googlewebmastercentral.blogspot.fi/2014/08/https-as- ranking-signal.html ● performance hit is negligible ○ https://IsTLSFastYet.com/
  • 6.
    Certificate Shopping ● https://www.startssl.com/ ○from 0 USD and up ● https://sslmate.com/ ○ from ~15 USD / year ○ buy and renew from the command line ● https://letsencrypt.org/ ○ free service ○ coming summer 2015
  • 7.
    ● HTTP toHTTPS redirect is done client side ● ensures no network connection is unencrypted HTTP ● if a secure connection cannot be established, the connection is blocked ● fixes SSL stripping man-in-the-middle HTTP Strict Transport Security (HSTS) WWW SSL Stripping Man in the Middle Attack Plain text HTTP Encrypted HTTPS
  • 8.
  • 9.
    Strict-Transport-Security: max-age=123456789; includeSubDomains ● max-age definesthe expiry time in seconds ● includeSubDomains declares the policy should be enforced on the declaring host and all its subdomains Howto
  • 10.
    Caveats ● first everconnection could still be over HTTP, leaving a window for a SSL stripping man-in-the-middle attack
  • 11.
    HTTP Public KeyPinning (HPKP) ● prevents certificate forgery
  • 12.
  • 13.
    Public-Key-Pins: pin-sha256="<hash>="; max-age=<secs>; includeSubDomains ● pin-sha256 isthe key hash (can have multiple) ● max-age defines the expiry time in seconds ● includeSubDomains declares the policy should be enforced on the declaring host and all its subdomains Howto
  • 14.
    ● unless youhave a backup certificate and you have to revoke your primary certificate, your site will be unreachable ● first ever connection could still be over HTTP, leaving a window for a SSL stripping man-in-the-middle attack Caveats
  • 15.
    ● sites canbe added to HSTS Preload lists included in the browser application ● solves the initial non-HTTPS connection problem ● doesn’t scale ● in Chrome you can verify, add and delete sites manually via chrome://net-internals/#hsts HSTS Preloading
  • 16.
    Howto Strict-Transport-Security: max-age=123456789; includeSubDomains; preload ● add preloadto your existing HSTS policy and submit your site via https://hstspreload.appspot.com/ ● NB! Only for Chrome, but Firefox & Safari supposedly include Chrome’s preload list at least partially
  • 17.
    Recap ● use HTTPS ●use HSTS ● consider HPKP ● consider including your app on a HSTS preload list
  • 18.
    Content Security Policy(CSP) ● mitigates XSS attacks ○ If script is inject into your application, it’s no longer your application -- Brad Hill, PayPal ● white list origins that are considered good sources ● separate lists for different media ● provides policy violation reports ● not a replacement for other counter measures, but a great supplement
  • 19.
  • 20.
    ● no inlineStyles ● no inline JavaScript, including inline event handlers ● no eval ● setTimeout/setInterval won’t accept strings as first param, only functions Caveats
  • 21.
    ● media-src ○ video/audio ●object-src ○ plugins ● sandbox ○ sandboxes the document ● style-src ○ stylesheets ● script-src ○ javascript ● report-uri ○ violation reports Directives ● default-src ○ catch all ● connect-src ○ XHR / WebSocket / EventSource ● font-src ○ fonts ● frame-src ○ iframes ● img-src ○ images
  • 22.
    Origins ● ‘none’ (nothingmatches) ● ‘self’ (matches own origin, not subdomains) ● ‘unsafe-inline’ (allow inline script and style) ● ‘unsafe-eval’ (allow eval’ed script) ● data:, blob: ● scheme://host:port/path ● *, *.mycdn.com (wildcards)
  • 23.
    Howto ● transmitted asa HTTP header ● semicolon delimited list of directives ● directive has space delimited list of origins Content-Security-Policy(-Report-Only): default-src ‘self’; script-src ‘none’;
  • 24.
    default-src ● default-src ‘none’ ○disallow any non-whitelisted sources ● default-src ‘self’ ○ allow all connections to the host documents origin ● default-src https ○ allow any connections, as long they’re HTTPS ● default-src * ○ allow everything that doesn’t have its own directive
  • 25.
    ● script-src ‘self’ ○only scripts from own origin is allowed (excludes subdomains) ● script-src ‘unsafe-inline’ ○ allow inline scripts ● script-src ‘unsafe-eval’ ○ allow eval’ed scripts ● script-src blob: ○ allow blobs as script source, useful for inlined web workers ● script-src www.google-analytics.com ○ allow scripts coming from www.google-analytics.com script-src
  • 26.
    report-uri { "csp-report": { "document-uri": "http://example.org/page.html", "referrer":"http://evil.example.com/haxor.html", "blocked-uri": "http://evil.example.com/image.png", "violated-directive": "default-src 'self'", "original-policy": "default-src 'self'; report-uri http://example.org/csp-report.cgi" } }
  • 27.
    ● level 2(formerly 1.1) is a work in progress ○ Last Call Working Draft since 3.7.2014 ○ http://www.w3.org/TR/CSP2/ ● available in Chrome behind flags CSP Level 2
  • 28.
    script-src Content-Security-Policy: script-src ‘nonce-12345’; <scriptnonce=”12345”>alert(“Hello”)</script> Content-Security-Policy: script-src ‘sha256-<base64 encoded hash>’; <script>alert(“Hello”);</script>
  • 29.
    child-src ● allowed sourcesfor worker contexts ● allowed sources for child browsing contexts ● deprecates frame-src
  • 30.
    form-action ● limit whereforms can be submitted to using the form’s action attribute ● does not fall back to default-src must be explicitly defined
  • 31.
    referrer ● allows finegrained control on the referrer header sent when leaving the site ● available settings are: ○ none (never send referrer) ○ none-when-downgrade (never send when https -> http) ○ origin (send origin only) ○ origin-when-cross-origin (origin only to cross origin destinations) ○ unsafe-url (business as usual)
  • 32.
    plugin-types ● list ofallowed mime types handles by plugins ● deprecates object-src
  • 33.
    Sandboxes <iframe sandbox /> ●unique origin ● will never match any origin, including its own ● secure by default (least privilege) ● switch features on as needed ● messaging can be used for transport between host and sandbox ● Chrome, Firefox, Safari, Opera, IE10
  • 34.
  • 35.
    Capabilities you canenable ● allow-forms ● allow-popups ● allow-pointer-lock ● allow-same-origin ● allow-scripts ● allow-top-navigation
  • 36.
    ● object isnot allowed in sandboxed iframes, i.e. no flash, so applicability for e.g. ads is limited ● iframes within sandboxed iframes cannot be seamless ● sandboxed iframes with allow-same-origin, who share the origin with host document, can remove the sandbox attribute Caveats
  • 37.
    Use Cases ● load3rd party widgets in sandboxes <iframe src=”http://twitter.com/widget” sandbox=”allow-same-origin allow-popups allow-scripts” /> ● sandbox your own code that would violate your CSP ○ message passing via postMessage is still possible ○ see HTML5Rocks introduction for demo ○ http://www.html5rocks.com/en/tutorials/security/sandboxed- iframes/#safely-sandboxing-eval
  • 38.
    ● the wholedocument is treated as though it was loaded inside a sandboxed iframe ● no plugins ● no seamless iframes Sandbox directive in CSP
  • 39.
    X-XSS-Protection ● from ourfriends at Microsoft ● XSS protection through heuristics ● first appeared in IE8 ○ very buggy implementation ○ awarded a PWNIE award in 2010 X-XSS-Protection: 0 // OFF X-XSS-Protection: 1 // ON // Block connection if filter matches X-XSS-Protection: 1; mode=block
  • 40.
    X-Frame-Options ● prevents clickjackingand framesniffing X-Frame-Options: DENY X-Frame-Options: SAMEORIGIN X-Frame-Options: ALLOW-FROM origin
  • 41.
    X-Content-Type-Options ● forbids thebrowser to perform mime type sniffing ● prevents evaluating scripts and stylesheets delivered with incorrect mime type headers ● must be sent with the resource being downloaded ● IE >= 9 X-Content-Type-Options: noSniff
  • 42.
    X-Download-Options ● prevents thebrowser displaying downloaded content, i.e. force save ● must be sent with the resource being downloaded ● IE only X-Download-Options: noOpen
  • 43.
    Tools ● CSP Builderhttps://cspbuilder.info ○ compiles a CSP policy based on violation reports ● Helmet (Express/Connect) ○ CSP (1.0 only) and some other ● Zend Framework 2.3 has built in CSP support ● Nelmio Security Bundle (Symfony) ● Content-Security-Policy plugin for WordPress (sadly outdated)
  • 44.
  • 45.
    Links ● https://hstspreload.appspot.com/ ● https://wiki.mozilla.org/Privacy/Features/HSTS_Preload_List ●https://developer.mozilla.org/en-US/docs/Web/Security/Public_Key_Pinning ● http://caniuse.com/#feat=contentsecuritypolicy ● http://caniuse.com/#feat=iframe-sandbox ● http://caniuse.com/#feat=stricttransportsecurity ● https://developer.mozilla.org/en-US/docs/Web/Security/Public_Key_Pinning#Browser_compatibility ● http://www.html5rocks.com/en/tutorials/security/transport-layer-security/ ● http://www.html5rocks.com/en/tutorials/security/content-security-policy/ ● http://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/ ● http://content-security-policy.com/ ● https://blog.twitter.com/2011/improving-browser-security-csp ● https://docs.angularjs.org/api/ng/directive/ngCsp ● http://www.dotnetnoob.com/2012/09/security-through-http-response-headers.html ● http://blogs.msdn.com/b/ie/archive/2008/07/02/ie8-security-part-v-comprehensive-protection.aspx ● https://w3c.github.io/webappsec/specs/content-security-policy/#changes-from-level-1 ● https://wiki.mozilla.org/Security/Server_Side_TLS ● https://scotthelme.co.uk/hsts-the-missing-link-in-tls/ ● https://www.chromium.org/hsts ● http://www.cspplayground.com/