Using a Downloaded HTML File to Steal Files From a Mac
Anton Lopanitsyn (via Felix Schwarz):
Interestingly, .
DS_Store
can easily be parsed to get the names of all the files on in the catalog. […] And this means that, with this information, we can now recursively call .DS_Store to get the complete hierarchy of files on my computer — all without authorized access to any of the directories.[…]
We know that in the Chrome browser, reading local files is not that straightforward. The only way to do that is to launch Chrome with a special argument ( — disable-web-security).
Safari also warns that it can’t work with the local files: such as
file://
HOWEVER, if the file has originally been downloaded from the internet, Safari is a lot more permissive towards this kind of requests. Thus one can send XHR request to a local file and get back its content […] …if a file is local — you get access!
Knowing this Safari idiosyncrasy, with a full path name we can load the complete file content and upload it to an external server.
It seems like Safari’s Local File Restrictions should cover XMLHttpRequest
in addition to file: URLs.
18 Comments RSS · Twitter
I don't really understand the DS_Store section. Leaving aside that there's a few bugs in the Python script, what really has me stumped is this paragraph:
>As you can see, I have just retrieved all the files from my home directory. And this means that , with this information, we can now recursively call .DS_Store to get the complete hierarchy of files on my computer — all without authorized access to any of the directories.
You could've done the first thing with a simple `ls`. The DS_Store files does absolutely nothing to expose additional information in that regard. Nor is it more easily accessible than a directory listing.
Where it does get interesting is the final subclause in the paragraph. And I don't really see how it's true? If I use fast user switching to switch to a different user, browse to their home directory in their Finder, then switch back, change the script to read their home directory, and run the script, I get exactly what I would expect:
>IOError: [Errno 13] Permission denied: '/Users/Guest/.DS_Store'
Yes, there may be a privacy issue lurking here, but I'm not quite seeing it yet.
The Safari local file access issue does seem concerning.
@Sören The issue is that you can’t do ls from JavaScript, but you can use JavaScript to read the .DS_Store file. So this does expose additional information. The Python script is just a demonstration, not part of the HTML exploit.
I don't understand the Safari exploit. I understand that JS code could read the dirs by using XMLHttpRequest, with a file URL to a .DS_Store file. But that only works on downloaded files. So, on a website, I'd have to offer a file named ".DS_Store", and if that gets downloaded with Safari, it would end up in the Downloads folder, usually, overwriting the existing .DS_Store there, possibly (or not, as it'll get renamed). So, that would still not enable the JS code to get permission to read any .DS_Store file, or does it? (If that would work, it would mean that Safari's permission rule for downloaded files would just check the download name, ignoring the path, and the name that actually ends up on disk, after renaming it?)
In other words, can a malicious website offer a "passwd" file for download, and after the user has downloaded it, the site can read from file://etc/passwd??
@Thomas It’s about downloading a .html file that, when viewed locally, reads existing .DS_Store files, e.g. starting at the root of your drive.
In fact, https://web.archive.org/web/20081218055512/http://developer.apple.com:80/internet/webcontent/xmlhttpreq.html (with which I initially learned to use XHR, my, how time flies) specifically warns that it is not possible to use local html files for testing XHR code due to security restrictions in "most browsers". It is a wonder why Safari supports it to this day.
. DS_Store is a terrible idea to begin with. Apple makes the whole widget; surely, they could have found a better place to store the Finder's data.
In the beginning of OS X, .DS_Store hadn't had the invisible flag set, it was just invisible because Mac OS X (stupidly) hides files whose names start with a dot, and existing Mac apps didn't know about it. This meant that a lot of applications treated it like a normal file. Let's say you were working on a web application, and uploading all changed files to a server. Your file sync app would automatically upload the .DS_Store file. So unless you prevented website visitors from opening .DS_Store files, that was like enabling directory browsing on all directories on your web server.
Terrible idea of .DS_Store file + terrible idea of hiding files starting with a dot = stupid security problem.
"DS_Store is a terrible idea to begin with. Apple makes the whole widget; surely, they could have found a better place to store the Finder's data."
Legacy from the pre-OS X Finder.
It worked just fine for the transition to the NeXTSTEP/Mac OS merger, so they never bothered to do something cleaner.
@Michael Tsai: I assume @Chucky meant that they were a fallout of trying to map pre-OS X's extensive use of resource forks and file attributes to a UNIX-based filesystem that didn't necessarily support such features.
"I assume @Chucky meant that they were a fallout of trying to map pre-OS X's extensive use of resource forks and file attributes to a UNIX-based filesystem that didn't necessarily support such features."
Yup. If I hadn't been commenting in the middle of the night, I would have written "legacy from the muddled NeXTSTEP / Mac OS merger", rather than leaving a comment that Michael correctly read as nonsensical.
(And kudos, Daniel, for prying actual meaning out of that mess. If you ever find yourself considering purchasing a poorly coded app, I have confidence you'll be able to rewrite it properly.)
@Daniel Were you at Apple at that time? I would be interested to know more about this. I think it must have been a different goal than that because most Macs ran HFS+, and they had already implemented a separate system for emulating Mac metadata on UFS. So maybe it was about storing more view state than was possible on OS 9. Or maybe they wanted to reduce the proliferation of per-file metadata sidecar files.
@Michael While Daniel is a far better source than I am on this topic for several obvious reasons, and I hope he chimes in, my recollection differs from yours.
My recollection is that the HFS+ improvements didn't incorporate anything about Folder view states. And while HFS+ did incorporate some individual file metadata, (maybe file/application mapping ???), it was very limited.
So in the OS X transition, Apple had to either preserve a total dependence on resource forks, add a per-file sidecar file for every single file, or do something along the lines of DS_Store. And the first two options still wouldn't have addressed Folder view states without replicating the horrific Desktop Database system. So DS_Store was the least worst option, and the only problem is that they didn't find a more elegant solution over the years. (Hell, they could have even accomplished FTFF in the process.)
But I'm a layman on these topics, so I may well be totally wrong, or at least missing some subtleties that Daniel would better know.
@Chucky Yes, you’re right that HFS+ improvements did not address this. I guess they didn't want too many sidecar files, and the existing desktop database was probably dependent on HFS-style file IDs. Personally, I’ve had more trouble with .DS_Store files than I ever did with the desktop database—it never seemed to have problems saving state. And it’s too bad that they never went back and redo it with xattrs or something.
"And it’s too bad that they never went back and redo it with xattrs or something."
Yeah. It makes sense that xattrs would've the been the perfect elegant solution, especially since it covers folders too.
"I’ve had more trouble with .DS_Store files than I ever did with the desktop database—it never seemed to have problems saving state."
FWIW, I have zero problems with saved state in OS X, given that I eventually trained myself to use the Finder in a very precise and constrained manner, specifically to avoid such problems. So, I don't think that is a DS_Store corruption issue, and instead is a broader OS X Finder design issue.
In other words, DS_Store works just fine, but they were very unambitious in what they tasked DS_Store to do with regard to saved state during the transition. (Or even worse, it was actually an intentional design decision.)
So, I don't think that is a DS_Store corruption issue, and instead is a broader OS X Finder design issue.
Agreed. Aside from the basic issues of my own window states not being saved, I also run into this a lot with DropDMG. Despite some hints from Apple engineers at the dawn of OS X, they never actually made an API for Desktop Services, the subsystem behind .DS_Store. So if you want to make a disk image with a certain icon layout or view options, you either have to reverse-engineer the (changing) .DS_Store format and hope that if you make your own .DS_Store file the Finder won’t overwrite it, or you have to AppleScript the Finder and hope that it actually saves your changes to disk. You would think that with a script doing the same steps in the same order every time this would be somewhat predictable, but there are all sorts of cases (which I try to work around) where Finder doesn’t save a .DS_Store file or only saves some of the changes into the .DS_Store file.
"they never actually made an API for Desktop Services ... You would think that with a script doing the same steps in the same order every time this would be somewhat predictable, but there are all sorts of cases (which I try to work around) where Finder doesn’t save a .DS_Store file or only saves some of the changes into the .DS_Store file."
That's insane.
But at least we've solved the issue now. Apple just has to transition from DS_Store to xattrs, which didn't exist back in 10.0, and we'll have accomplished FTFF. When we bring this to Jony Ive's attention, I'm sure he'll implement it immediately.