OWASP AppSecEU 2018 – Attacking "Modern" Web Technologies
- 3. Modern = stuff people use
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque
laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto
beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur
aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi
nesciunt.
- 4. Author name her
Frans Rosén
Attacking Modern Web Technologies
Frans Rosén @fransrosen
• "The Swedish Ninja"
• Security Advisor @detectify ( twitter: @fransrosen )
• HackerOne #7 @ /leaderboard/all-time
• Blog at labs.detectify.com
- 5. Author name her
Frans Rosén
Attacking Modern Web Technologies
Frans Rosén @fransrosen
• Winner of MVH at H1-702 Live Hacking in Vegas!
• Winner Team Sweden in San Francisco (Oath)
• Best bug at H1-202 in Washington (Mapbox)
• Best bug at H1-3120 in Amsterdam (Dropbox)
- 6. Attacking Modern Web Technologies
Rundown
AppCache
• Bug in all browsers
Upload Policies
• Weak Implementations
• Bypassing business logic
Deep dive in postMessage implementations
• The postMessage-tracker extension
• Abusing sandboxed domains
• Leaks, extraction, client-side race conditions
Frans Rosén @fransrosen
- 7. Attacking Modern Web Technologies
Rundown
Frans Rosén @fransrosen
Tool share!
AppCache
• Bug in all browsers
Upload Policies
• Weak Implementations
• Bypassing business logic
Deep dive in postMessage implementations
• The postMessage-tracker extension
• Abusing sandboxed domains
• Leaks, extraction, client-side race conditions
- 8. AppCache – Not modern!
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque
laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto
beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur
aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi
nesciunt.
- 9. Author name her
Disclaimer
Attacking Modern Web Technologies
Frans Rosén @fransrosen
https://speakerdeck.com/filedescriptor/exploiting-the-unexploitable-with-lesser-known-browser-tricks?slide=22
Found independently by
@filedescriptor
Announced last AppSecEU
- 13. Author name her
Cookie Stuffing/Bombing
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Will make EVERY page return 500 Error = Manifest FALLBACK will be used
- 14. Author name her
Bug in every browser
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Manifest placed in /u/2241902/manifest.txt
Would use the FALLBACK for EVERYTHING, even outside the dir
- 15. Author name her
Surprise – Specification was vague
Attacking Modern Web Technologies
Frans Rosén @fransrosen
"To mitigate this, manifests can only specify
fallbacks that are in the same path as the
manifest itself."
https://www.w3.org/TR/2015/WD-html51-20150506/browsers.html#concept-appcache-manifest-fallback
- 16. Author name her
Surprise – Specification was vague
Attacking Modern Web Technologies
Frans Rosén @fransrosen
"To mitigate this, manifests can only specify
fallbacks that are in the same path as the
manifest itself."
https://www.w3.org/TR/2015/WD-html51-20150506/browsers.html#concept-appcache-manifest-fallback
This was confusing, could mean the path to the fallback-
URL and that was what browsers thought. They missed:
"Fallback namespaces must also be in the same path as the manifest's URL."
- 19. Author name her
AppCache on Dropbox
Attacking Modern Web Technologies
Frans Rosén @fransrosen
• Could run XML on dl.dropboxusercontent.com as HTML
• XML installs manifest in browser on root
• Any file downloaded from Dropbox would use the
fallback XML-HTML page, which would log the current
URL to an external logging site
• Every secret link would be leaked to the attacker
- 20. Author name her
AppCache on Dropbox
Attacking Modern Web Technologies
Frans Rosén @fransrosen
• Could run XML on dl.dropboxusercontent.com as HTML
• XML installs manifest in browser on root
• Any file downloaded from Dropbox would use the
fallback XML-HTML page, which would log the current
URL to an external logging site
• Every secret link would be leaked to the attacker
Bounty: $12,845
- 21. Author name her
Dropbox mitigations
Attacking Modern Web Technologies
Frans Rosén @fransrosen
• No more XML-HTML on dl.dropboxusercontent.com
• No more public directory for Dropbox users
• Coordinated bug reporting to every browser
• No more FALLBACK on root from path file
• Argumented for faster deprecation of AppCache
• Random subdomains for user-files
- 22. Author name her
Dropbox mitigations
Attacking Modern Web Technologies
Frans Rosén @fransrosen
• No more XML-HTML on dl.dropboxusercontent.com
• No more public directory for Dropbox users
• Coordinated bug reporting to every browser
• No more FALLBACK on root from path file
• Argumented for faster deprecation of AppCache
• Random subdomains for user-files
Chrome Fixed Edge/IE Fixed
Firefox Fixed Safari Fixed
https://bugs.chromium.org/p/chromium/issues/detail?id=696806#c40
Reported 28 Feb 2017, fixed ~June 2017
- 23. Author name her
Dropbox mitigations
Attacking Modern Web Technologies
Frans Rosén @fransrosen
• No more XML-HTML on dl.dropboxusercontent.com
• No more public directory for Dropbox users
• Coordinated bug reporting to every browser
• No more FALLBACK on root from path file
• Argumented for faster deprecation of AppCache
• Random subdomains for user-files
Chrome Fixed Edge/IE Fixed
Firefox Fixed Safari Fixed
https://bugs.chromium.org/p/chromium/issues/detail?id=696806#c40
Reported 28 Feb 2017, fixed ~June 2017
Browser bounties: $3000
- 24. Author name her
AppCache vulns still possible
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Requirements:
• HTTPS only (was changed recently)
• Files uploaded can run HTML
• Files could be on a isolated sandboxed domain
• Files are uploaded to the same directory for all users
- 25. Author name her
ServiceWorkers, big brother of AppCache
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Requirements:
• HTTPS only
• Files uploaded can run HTML
• Files could be on a isolated sandboxed domain
• Files are uploaded to the root path
For example: bucket123.s3.amazonaws.com/test.html
- 26. Upload Policies
AWS and Google Cloud
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque
laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto
beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur
aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi
nesciunt.
- 27. Author name her
Upload Policies
Attacking Modern Web Technologies
Frans Rosén @fransrosen
A way to upload files directly to a bucket, without
passing the company’s server first.
" Faster upload
" Secure (signed policy)
- 28. Author name her
Upload Policies
Attacking Modern Web Technologies
Frans Rosén @fransrosen
A way to upload files directly to a bucket, without
passing the company’s server first.
" Faster upload
" Secure (signed policy)
" Easy to do wrong!
- 29. Author name her
Upload Policies
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Looks like this:
- 30. Author name her
Upload Policies
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Policy is a signed base64 encoded JSON
- 31. Author name her
Pitfalls AWS S3
Attacking Modern Web Technologies
Frans Rosén @fransrosen
" starts-with $key does not contain anything
We can replace any file in the bucket!
- 32. Author name her
Pitfalls AWS S3
Attacking Modern Web Technologies
Frans Rosén @fransrosen
" starts-with $key does not contain anything
We can replace any file in the bucket!
" starts-with $key does not contain path-separator
We can place stuff in root,
remember ServiceWorkers/AppCache?
- 33. Author name her
Pitfalls AWS S3
Attacking Modern Web Technologies
Frans Rosén @fransrosen
" $Content-Type uses empty starts-with + content-disp
We can now upload HTML-files:
Content-type: text/html
- 34. Author name her
Pitfalls AWS S3
Attacking Modern Web Technologies
Frans Rosén @fransrosen
" $Content-Type uses empty starts-with + content-disp
We can now upload HTML-files:
Content-type: text/html
" $Content-Type uses starts-with = image/jpeg
We can still upload HTML:
Content-type: image/jpegz;text/html
- 35. Author name her
Custom business logic (Google Cloud)
Attacking Modern Web Technologies
Frans Rosén @fransrosen
POST /user_uploads/signed_url/ HTTP/1.1
Host: example.com
Content-Type: application/json;charset=UTF-8
{"file_name":"images/test.png","content_type":"image/png"}
- 36. Author name her
Custom business logic (Google Cloud)
Attacking Modern Web Technologies
Frans Rosén @fransrosen
POST /user_uploads/signed_url/ HTTP/1.1
Host: example.com
Content-Type: application/json;charset=UTF-8
{"file_name":"images/test.png","content_type":"image/png"}
{"signed_url":"https://storage.googleapis.com/uploads/images/test.png?
Expires=1515198382&GoogleAccessId=example%40example.iam.gserviceaccount.com&
Signature=dlMAFC2Gs22eP%2ByoAhwGqo0A0ijySYYtRdkaIHVUr%2FvwKfNSKkKwTTpBpyOF..."}
Signed URL back to upload to:
- 38. Author name her
Attacking Modern Web Technologies
Frans Rosén @fransrosen
" We can select what file to override
" If signed URL allows viewing = read any file
Just fetch the URL and we have the invoice
POST /user_uploads/signed_url/ HTTP/1.1
Host: example.com
Content-Type: application/json;charset=UTF-8
{"file_name":"documents/invoice1.pdf","content_type":"application/pdf"}
{"signed_url":"https://storage.googleapis.com/uploads/documents/invoice1.pdf?
Expires=1515198382&GoogleAccessId=example%40example.iam.gserviceaccount.com&
Signature=dlMAFC2Gs22eP%2ByoAhwGqo0A0ijySYYtRdkaIHVUr%2FvwKfNSKkKwTTpBpyOF..."}
Vulnerabilities
- 39. Author name her
Attacking Modern Web Technologies
Frans Rosén @fransrosen
" We can select what file to override
" If signed URL allows viewing = read any file
Just fetch the URL and we have the invoice
POST /user_uploads/signed_url/ HTTP/1.1
Host: example.com
Content-Type: application/json;charset=UTF-8
{"file_name":"documents/invoice1.pdf","content_type":"application/pdf"}
{"signed_url":"https://storage.googleapis.com/uploads/documents/invoice1.pdf?
Expires=1515198382&GoogleAccessId=example%40example.iam.gserviceaccount.com&
Signature=dlMAFC2Gs22eP%2ByoAhwGqo0A0ijySYYtRdkaIHVUr%2FvwKfNSKkKwTTpBpyOF..."}
Total bounties: ~$15,000
Vulnerabilities
- 40. Rolling your own
policy logic sucks
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque
laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto
beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur
aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi
nesciunt.
- 41. Author name her
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Goal is to reach the bucket-root, or another file
Custom Policy Logic
- 42. Author name her
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Back to the 90s!
Path traversal with path normalization
- 43. Author name her
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Back to the 90s!
Path traversal with path normalization
Full read access to every object + listing
- 44. Author name her
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Expected:
Regex extraction of URL-parts
https://example-bucket.s3.amazonaws.com/dir/file.png
Result:
https://s3.amazonaws.com/example-bucket/dir/file.png?Signature..
- 47. Author name her
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Bypass:
Regex extraction of URL-parts
Full read access to every object + listing
- 50. Author name her
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Temporary URLs with signed links
https://secure.example.com/files/xx11
- 51. Author name her
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Temporary URLs with signed links
https://secure.example.com/files/xx11
- 52. Author name her
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Temporary URLs with signed links
https://secure.example.com/files/xx11Full read access to every object
- 55. Deep dive in postMessage
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque
laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto
beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur
aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi
nesciunt.
- 56. Author name her
Birth of the postMessage-tracker extension
Attacking Modern Web Technologies
Frans Rosén @fransrosen
• 1 year ago, discussion on last AppSecEU!
- 57. Author name her
Birth of the postMessage-tracker extension
Attacking Modern Web Technologies
Frans Rosén @fransrosen
• Catch every listener in all frames.
• Find the function receiving the message
• Log all messages btw all frames
- 58. Author name her
Birth of the postMessage-tracker extension
Attacking Modern Web Technologies
Frans Rosén @fransrosen
• Catch every listener in all frames.
• Find the function receiving the message
• Log all messages btw all frames
- 59. Author name her
What have I found?
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Regular vuln cases (XSS)
- 60. Author name her
What have I found?
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Regular vuln cases (XSS)
- 61. Author name her
What have I found?
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Regular vuln cases (XSS)
- 62. Author name her
What have I found?
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Regular vuln cases (XSS)
if (e.data.JSloadScript) {
if (e.data.JSloadScript.type == "iframe") {
// create the new iframe element with the src given to us via the event
local_create_element(doc, ['iframe', 'width', '0', 'height', '0', 'src',
e.data.JSloadScript.value], parent);
} else {
localLoadScript(e.data.JSloadScript.value)
}
}
- 63. Author name her
What have I found?
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Regular vuln cases (XSS)
if (e.data.JSloadScript) {
if (e.data.JSloadScript.type == "iframe") {
// create the new iframe element with the src given to us via the event
local_create_element(doc, ['iframe', 'width', '0', 'height', '0', 'src',
e.data.JSloadScript.value], parent);
} else {
localLoadScript(e.data.JSloadScript.value)
}
}
b.postMessage({"JSloadScript":{"value":"data:text/javascript,alert(document.domain)"}},'*')
- 64. Author name her
What have I found?
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Complex ones: Data-Extraction
- 72. Author name her
Data-Extraction
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Trigger: {
"params": {
"testRules": {
"rules": [
{
"name": "xxx",
"triggers": {
"type": "Delay",
"delay": 5000
}
...
}
]
}
}
}
- 73. Author name her
Attacking Modern Web Technologies
Frans Rosén @fransrosen
State:
...
"states": {
"type": "JSVariableExists",
"name": "ClickTaleCookieDomain",
"value": "example.com"
},
...
Data-Extraction
- 74. Author name her
Data-Extraction
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Action:
...
"action": {
"actualType": "CTEventAction",
"type": "TestRuleEvent",
"dynamicEventName": {
"parts": [
{
"type": "ElementValue",
"ctSelector": {
"querySelector": ".content-wrapper script"
}
},
{
"type": "CookieValue",
"name": "csrf_token"
}
]
}
- 77. Author name her
XSS on isolated but "trusted" domain
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Sandboxed domain being trusted and not trusted at the same time.
postMessage used to transfer data from/to trusted domain.
- 79. Author name her
XSS on sandbox
Attacking Modern Web Technologies
Frans Rosén @fransrosen
usersandbox.com
- 80. Author name her
User creates a document
Attacking Modern Web Technologies
Frans Rosén @fransrosen
ACME.COM
usersandbox.com
Create new doc
- 81. Author name her
Sandbox opens up in iframe for doc-converter
Attacking Modern Web Technologies
Frans Rosén @fransrosen
ACME.COM
usersandbox.com
usersandbox.com
Create new doc
- 82. Author name her
Hijack the iframe js, due to SOP
Attacking Modern Web Technologies
Frans Rosén @fransrosen
ACME.COM
usersandbox.com
usersandbox.com
Create new doc
- 83. Author name her
User uploads file, postMessage data to converter
Attacking Modern Web Technologies
Frans Rosén @fransrosen
ACME.COMusersandbox.com
usersandbox.com
- 84. Author name her
Iframe leaks data to attacker’s sandbox window
Attacking Modern Web Technologies
Frans Rosén @fransrosen
ACME.COMusersandbox.com
usersandbox.com
- 85. Author name her
And we have the document-data!
Attacking Modern Web Technologies
Frans Rosén @fransrosen
- 86. Author name her
What have I found?
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Client-side Race Conditions!
- 87. Author name her
Localized welcome screen, JS loaded w/ postMsg
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Loading…
- 88. Author name her
Attacking Modern Web Technologies
Frans Rosén @fransrosen
mpel.com
Welcome!
Välkommen!
Willkommen!
localeservice.com
Localized welcome screen, JS loaded w/ postMsg
- 89. Author name her
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Welcome!
Välkommen!
Willkommen!
link.com.example.com = OK
localeservice.com
Localized welcome screen, JS loaded w/ postMsg
- 90. Author name her
Only works once
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Welcome!
Välkommen!
Willkommen!
localeservice.com
- 91. Author name her
Only works once
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Welcome!
Välkommen!
Willkommen!
localeservice.com
- 92. Author name her
Curr not escaped
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Welcome!
Välkommen!
Willkommen!
- 93. Author name her
Loaded JS, osl vuln param
Attacking Modern Web Technologies
Frans Rosén @fransrosen
...&curr=&osl='-alert(1)-'
- 95. Author name her
alert was blocked. yawn… easy fix
Attacking Modern Web Technologies
Frans Rosén @fransrosen
- 97. Author name her
Attacker site opens victim site
Attacking Modern Web Technologies
Frans Rosén @fransrosen
link.com.example.com
Loading…
- 102. Author name her
Client-Side Race Condition
Attacking Modern Web Technologies
Frans Rosén @fransrosen
postMessage between JS-load and iframe-load
Worked in all browsers.
- 103. Author name her
Client-Side Race Condition #2
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Multiple bugs incoming, hang on!
- 104. Author name her
Can you find the bug(s)?
Attacking Modern Web Technologies
Frans Rosén @fransrosen
SecureCreditCardController.prototype.isValidOrigin = function (origin) {
if (origin === null || origin === undefined) {
return false;
}
var domains = [".example.com", ".example.to", ".example.at", ".example.ca",
".example.ch", ".example.be", ".example.de", ".example.es", ".example.fr", ".example.ie",
".example.it", ".example.nl", ".example.se", ".example.dk", ".example.no", ".example.fi",
".example.cz", ".example.pt", ".example.pl", ".example.cl", ".example.my", ".example.co.jp",
".example.co.nz", ".example.co.uk", ".example.com.au", ".example.com.br", ".example.com.ph",
".example.com.mx", ".example.com.sg", ".example.com.ar", ".example.com.tr",
".example.com.hk", ".example.com.tw"];
var escapedDomains = $.map(domains, function (domain) {
return domain.replace('.', '.');
});
var exampleDomainsRE = '^https://.*(' + escapedDomains.join('|') + ')$';
return Boolean(origin.match(exampleDomainsRE));
};
- 105. Author name her
1st bug!
Attacking Modern Web Technologies
Frans Rosén @fransrosen
SecureCreditCardController.prototype.isValidOrigin = function (origin) {
if (origin === null || origin === undefined) {
return false;
}
var domains = [".example.com", ".example.to", ".example.at", ".example.ca",
".example.ch", ".example.be", ".example.de", ".example.es", ".example.fr", ".example.ie",
".example.it", ".example.nl", ".example.se", ".example.dk", ".example.no", ".example.fi",
".example.cz", ".example.pt", ".example.pl", ".example.cl", ".example.my", ".example.co.jp",
".example.co.nz", ".example.co.uk", ".example.com.au", ".example.com.br", ".example.com.ph",
".example.com.mx", ".example.com.sg", ".example.com.ar", ".example.com.tr",
".example.com.hk", ".example.com.tw"];
var escapedDomains = $.map(domains, function (domain) {
return domain.replace('.', '.');
});
var exampleDomainsRE = '^https://.*(' + escapedDomains.join('|') + ')$';
return Boolean(origin.match(exampleDomainsRE));
};
- 106. Author name her
1st bug!
Attacking Modern Web Technologies
Frans Rosén @fransrosen
".example.co.nz".replace('.', '.')
".example.co.nz"
- 107. Author name her
Can you find the next bug?
Attacking Modern Web Technologies
Frans Rosén @fransrosen
SecureCreditCardController.prototype.isValidOrigin = function (origin) {
if (origin === null || origin === undefined) {
return false;
}
var domains = [".example.com", ".example.to", ".example.at", ".example.ca",
".example.ch", ".example.be", ".example.de", ".example.es", ".example.fr", ".example.ie",
".example.it", ".example.nl", ".example.se", ".example.dk", ".example.no", ".example.fi",
".example.cz", ".example.pt", ".example.pl", ".example.cl", ".example.my", ".example.co.jp",
".example.co.nz", ".example.co.uk", ".example.com.au", ".example.com.br", ".example.com.ph",
".example.com.mx", ".example.com.sg", ".example.com.ar", ".example.com.tr",
".example.com.hk", ".example.com.tw"];
var escapedDomains = $.map(domains, function (domain) {
return domain.replace('.', '.');
});
var exampleDomainsRE = '^https://.*(' + escapedDomains.join('|') + ')$';
return Boolean(origin.match(exampleDomainsRE));
};
- 108. SecureCreditCardController.prototype.isValidOrigin = function (origin) {
if (origin === null || origin === undefined) {
return false;
}
var domains = [".example.com", ".example.to", ".example.at", ".example.ca",
".example.ch", ".example.be", ".example.de", ".example.es", ".example.fr", ".example.ie",
".example.it", ".example.nl", ".example.se", ".example.dk", ".example.no", ".example.fi",
".example.cz", ".example.pt", ".example.pl", ".example.cl", ".example.my", ".example.co.jp",
".example.co.nz", ".example.co.uk", ".example.com.au", ".example.com.br", ".example.com.ph",
".example.com.mx", ".example.com.sg", ".example.com.ar", ".example.com.tr",
".example.com.hk", ".example.com.tw"];
var escapedDomains = $.map(domains, function (domain) {
return domain.replace('.', '.');
});
var exampleDomainsRE = '^https://.*(' + escapedDomains.join('|') + ')$';
return Boolean(origin.match(exampleDomainsRE));
};
Author name her
2nd bug!
Attacking Modern Web Technologies
Frans Rosén @fransrosen
- 109. Author name her
.nz is allowed since 2015!
Attacking Modern Web Technologies
Frans Rosén @fransrosen
https://en.wikipedia.org/wiki/.nz
- 110. Author name her
2nd bug!
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Boolean("https://www.exampleaco.nz".match('^https:/
/.*(.example.co.nz)$'))
true
- 111. Author name her
2nd bug!
Attacking Modern Web Technologies
Frans Rosén @fransrosen
Boolean("https://www.exampleaco.nz".match('^https:/
/.*(.example.co.nz)$'))
true
- 113. Author name her
Opens PCI-certified domain for payment
Attacking Modern Web Technologies
Frans Rosén @fransrosen
ilikefood.com
Subscribe!
foodpayments.com
- 114. Author name her
Iframe loaded, main frame sends INIT to iframe
Attacking Modern Web Technologies
Frans Rosén @fransrosen
ilikefood.com
Subscribe!
iframe.postMessage('INIT', '*')
foodpayments.com
- 115. Author name her
Iframe registers the sender of INIT as msgTarget
Attacking Modern Web Technologies
Frans Rosén @fransrosen
ilikefood.com
Subscribe!
iframe.postMessage('INIT', '*')
if(e.data==INIT && originOK) {
msgTarget = event.source
msgTarget.postMessage('INIT','*')
}
foodpayments.com
- 116. Author name her
Iframe tells main all is OK
Attacking Modern Web Technologies
Frans Rosén @fransrosen
ilikefood.com
Subscribe!
foodpayments.com
if(e.data==INIT and e.source==iframe) {
all_ok_dont_kill_frame()
}
msgTarget.postMessage('INIT','*')
- 117. Author name her
Main window sends over provider data
Attacking Modern Web Technologies
Frans Rosén @fransrosen
ilikefood.com
Subscribe!
if(INIT) {
iframe.postMessage('["LOAD",
"stripe","pk_abc123"]}’, '*')
}
foodpayments.com
- 118. Author name her
Iframe loads payment provider and kills channel
Attacking Modern Web Technologies
Frans Rosén @fransrosen
ilikefood.com
Subscribe!
if(INIT) {
if(e.data[0]==LOAD && originOK) {
initpayment(e.data[1], e.data[2])
window.removeEventListener
('message', listener)
}
}
foodpayments.com
if(INIT) {
iframe.postMessage('["LOAD",
"stripe","pk_abc123"]}’, '*')
}
- 120. Author name her
Open ilikefood.com from attacker
Attacking Modern Web Technologies
Frans Rosén @fransrosen
exampleaco.nz ilikefood.com
Subscribe!
- 121. Author name her
Victim clicks subscribe, iframe is loaded
Attacking Modern Web Technologies
Frans Rosén @fransrosen
ilikefood.com
Subscribe!
foodpayments.com
exampleaco.nz
- 122. Author name her
Attacker sprays out LOAD to iframe
Attacking Modern Web Technologies
Frans Rosén @fransrosen
ilikefood.com
Subscribe!
foodpayments.com
setInterval(function(){
child.frames[0].postMessage('["LOAD","stripe","pk_diffkey"]}’,'*')
}, 100)
exampleaco.nz
- 123. Author name her
INIT-dance resolves, but attacker wins with LOAD
Attacking Modern Web Technologies
Frans Rosén @fransrosen
ilikefood.com
Subscribe!
foodpayments.com
setInterval(function(){
child.frames[0].postMessage('["LOAD","stripe","pk_diffkey"]}’,'*')
}, 100)
'INIT'<->'INIT'
exampleaco.nz
- 124. Author name her
LOAD kills listener, we won the race! Stripe loads…
Attacking Modern Web Technologies
Frans Rosén @fransrosen
ilikefood.com
Subscribe!
foodpayments.com
exampleaco.nz
Frame loads
api.stripe.com?key=pk_diffkey…
- 125. Author name her
It’s now the attacker’s Stripe account
Attacking Modern Web Technologies
Frans Rosén @fransrosen
ilikefood.com
Subscribe!
foodpayments.com
Enter credit card
Pay!
exampleaco.nz
- 126. Author name her
Payment will fail for site…
Attacking Modern Web Technologies
Frans Rosén @fransrosen
foodpayments.com
Payment failed :(
- 127. Author name her
Payment will fail for site…but worked for Stripe!
Attacking Modern Web Technologies
Frans Rosén @fransrosen
foodpayments.com
Payment failed :(
- 128. Author name her
From Stripe-logs we can charge the card anything!
Attacking Modern Web Technologies
Frans Rosén @fransrosen
- 129. Author name her
From Stripe-logs we can charge the card anything!
Attacking Modern Web Technologies
Frans Rosén @fransrosen
- 130. Author name her
Client-Side Race Condition #2
Attacking Modern Web Technologies
Frans Rosén @fransrosen
postMessage from opener between two other postMessage-calls
Chrome seems to be the only one allowing this to happen afaik.
- 133. Author name her
Attacking Modern Web Technologies
Frans Rosén @fransrosen
• Problem 1: Function-wrapping, Raven.js, rollbar, bugsnag, NewRelic
Before:
postMessage-tracker Speedbumps
- 134. Author name her
Attacking Modern Web Technologies
Frans Rosén @fransrosen
• Problem 1: Function-wrapping, Raven.js, rollbar, bugsnag, NewRelic
Before: After:
Solution: Find wrapper and jump over it. console better due to this!
postMessage-tracker Speedbumps
- 135. Author name her
Attacking Modern Web Technologies
Frans Rosén @fransrosen
• Problem 2: jQuery-wrapping, such a mess (diff btw version)
Before:
postMessage-tracker Speedbumps
- 136. Author name her
Attacking Modern Web Technologies
Frans Rosén @fransrosen
• Problem 2: jQuery-wrapping, such a mess (diff btw version)
Before: After:
Solution: Use either ._data, .expando or .events from jQuery object!
postMessage-tracker Speedbumps
- 137. Author name her
Attacking Modern Web Technologies
Frans Rosén @fransrosen
• Problem 3: Anonymous functions. Could not identify them at all.
Before:
postMessage-tracker Speedbumps
- 138. Author name her
Attacking Modern Web Technologies
Frans Rosén @fransrosen
• Problem 3: Anonymous functions. Could not identify them at all.
Before: After:
Solution: Can’t extract using Function.toString() in Chrome :(
Will however at least show them as tracked now
postMessage-tracker Speedbumps
- 141. Author name her
postMessage-tracker released?
Attacking Modern Web Technologies
Frans Rosén @fransrosen
No :( I suck. "Soon"?
Want to complete more features!
• Trigger debugger to breakpoint messages (since we own the order)
• Try to see if .origin is being used and how
• If regex, run through Rex!