Typical blog posts about Dropbox security concentrate on data or network encryption. I want to talk about protecting your system from Dropbox the application, as well as Dropbox the company. In this blog post I tell you how to prepare for a theoretical scenario where Dropbox turns malicious. I’ve done a number of things to make Dropbox run in a much more secure fashion on my Ubuntu laptop. Hopefully I will introduce you to some vulnerabilities that you weren’t aware of, and teach how to protect against them. Many of the attacks and defenses described here are portable to apps other than Dropbox.
X11 and File Permissions
First of all, X11 is hideously insecure. I log into my X11 desktop as user “mike”. This means that any other process running under the same user id is able to connect to the X11 service, sniff every key I press in any app, and even inject new fake key presses. This is not something new, but a lot of people aren’t aware of it. So when you enter your password into your bank’s login form in Firefox, or when you type your master password to unlock your super secure password manager vault, it’s worth noting that any other process running under the same uid as yours, is able to quietly read what you’re typing.
Just to prove it to you, open Terminal and type “xinput list”. Find the item with “keyboard” in the name and note down the id. Then type “xinput test TheID” (replacing “TheID” with the id you noted). Now start typing into some other application like your browser address bar. You’ll see that in the terminal it is noting down the character code for every key you press.
So I thought to myself, why should I allow Dropbox to potentially attack my X11 session in this way? And more than that, why should I allow it to have access to read and write any file belonging to user “mike”? The first thing I did was create a new password-less user on the system named “mike.dropbox”. Under the Terminal program on the Ubuntu desktop run the following:
sudo adduser --force-badname mike.dropbox
The –force-badname option was required because it complains about the full stop in the username otherwise. You can use whatever username/format you want though.
The next step was to set up Dropbox under that new user. First of all, I needed to give the user “mike.dropbox” temporary access to X11 so I could access the installation GUI as that user. To do this I ran:
Then I su’d to the “mike.dropbox” user and ran the dropbox executable:
sudo su -s /bin/bash mike.dropbox dropbox start
At this point, you go through the normal installation process, entering your Dropbox credentials and so on. The next steps are to stop Dropbox, remove X11 access for the “mike.dropbox” user and then restart it. Run the following command as your “mike.dropbox” user:
And then the following command as your “mike” user:
And finally, the following command as your “mike.dropbox” user:
At this point, it might be a good idea to configure up the system to start Dropbox when it boots up. You can do this by creating a cron job entry for the “mike.dropbox” user which looks like this:
/dev/nulldropbox start &>
You might also want to test Dropbox at this point to make sure it’s working. To do this, try adding/removing some files in “/home/mike.dropbox/Dropbox/“ and check to see if the changes propagate to your other Dropbox clients. If you don’t have any other Dropbox clients configured, you can use the web interface.
You might be thinking now that a “/home/mike.dropbox/Dropbox/“ folder which is completely inaccessible to user “mike” is not a lot of use. You might have thoughts about adding the “mike” user to the “mike.dropbox” group, and fiddling with permissions. That is not going to work out well; the dropbox executable will want to create new files owned by “mike.dropbox” only. So what I did next was an “apt-get install samba smbfs”. The idea was to export the folder as a network mount, mounting it at “/home/mike/Dropbox/“. You can probably use NFS for this too. In my /etc/samba/smb.conf I added:
[dropbox] comment = Mikes Dropbox path = /home/mike.dropbox/Dropbox guest ok = no create mask = 0600 directory mask = 0700 valid users = mike.dropbox read only = no
And then restarted samba with a, “service smbd restart”. I then added a “mike.dropbox” user to samba by running the following command as root, and picking a long random password:
smbpasswd -a mike.dropbox
I then created a directory at /home/mike/Dropbox/ and put a file named “credentials” in it containing the following:
In my /etc/fstab I then added the following new entry:
//localhost/dropbox /home/mike/Dropbox smbfs defaults,noexec,nosuid,user,uid=1000,gid=1000,credentials=/home/mike/Dropbox/credentials 0 0
The uid and gid should be set to whatever the uid and gid are for your equivalent of the “mike” user. The noexec and nosuid bits are optional. They add a bit more security (see “man mount”). Finally, you need to run a “mount ~/Dropbox/“ as the “mike” user. You will only need to do this the first time. On subsequent reboots it will be mounted automatically.
So now we have a /home/mike/Dropbox/ folder, full of files which appear to be owned by the “mike” user, syncing with the Dropbox cloud, just as before. The only “negative” difference is that we don’t get the GUI magic which allows us to see the status of file transfers and such. But now the dropbox process is isolated under the “mike.dropbox” user, it can no longer connect to my X11 session to sniff my key presses, and it can no longer read/write any of the files owned by my main user.
More File Permissions
Ok, so the Dropbox process can no longer read/write any files owned by user “mike”. It can still read any globally readable files on the system though and data from volumes like /proc/. Why though? There are only a very limited number of files that it needs to be able to read and write in order to operate. To restrict the process to only being able to read and write certain files, I created an AppArmor profile. Amongst other things, AppArmor allows you to limit an application so it can only read and write certain whitelisted files. Non Debian based systems probably want to use SELinux for this instead. There are plenty of AppArmor tutorials out there, so I wont go into details on how to use it. Basically, you use the command “aa-genprof” on /usr/bin/dropbox to collect a list of which files it accesses and how it accesses them, and you store that list in a special format in /etc/apparmor.d/. Any attempted violations are blocked and logged to /var/log/kern.log.
My Dropbox allowance is 8.5GB. So why would I allow the Dropbox application the opportunity to use up more than 8.5GB of disk space on my laptop? It could potentially DOS the system, either maliciously or accidently. So I’ve implemented filesystem quotas. I’m using ext4, and I have a single / partition so YMMV. First of all I added the options “usrquota,grpquota” to the “/“ mount point in /etc/fstab and remounted it with a “mount / -o remount”. Then I enabled disk quotas by running the following two commands:
quotacheck -cavugm quotaon /
This might take a while to run as it has to calculate the current usage of every user on the system. I then ran the following command to limit the “mike.dropbox” user to ~10GB of space only:
quotatool -bu mike.dropbox -l 10000MB /
I know I said “8.5GB”, but I suspect the Dropbox application needs storage for other purposes as well so I’ve given it some leeway. Now if I want to see the quota and usage for user “mike.dropbox”, I can simply do this:
root@laptop:~# quota -u mike.dropbox Disk quotas for user mike.dropbox (uid 1005): Filesystem blocks quota limit grace files quota limit grace /dev/mapper/cryptdisk 288188 0 10240000 2660 0 0 root@laptop:~#
You can see from the output above, that the “mike.dropbox” user is using about 288MB of disk space on “/“ currently, and has an allowance of about 10GB.
Another good thing about isolating applications to run under unique uids, is that iptables allows you to specify outgoing firewall rules on a per user basis. If for example, I wanted to block Dropbox from connecting to the Internet all together (I obviously don’t), I could simply run the following command as root:
iptables -A OUTPUT -m owner --uid-owner mike.dropbox -j REJECT
I initially tried to collect a list of IPs that Dropbox was connecting to, by monitoring the output of “netstat -anp”. The idea was going to be that I blocked “mike.dropbox” from making any outgoing connections other than to a list of approved IPs on approved ports. I quickly realised that this was going to be difficult and error prone; it makes connections to multiple IPs in Amazons cloud, some of which I expect will change over time. You may want to try this though, so I thought I’d mention it. It’s also worth noting that Dropbox broadcasts packets to the network using UDP when Lan Sync is enabled, so if you want that to continue, you’ll want to allow that traffic.
Even though I decided against this sort of blocking, I still wanted to do something interesting to the Dropbox traffic. I have Tor running on my laptop. If I could use Tor to connect to the Dropbox cloud, that would afford me some privacy. This should be safe, as the Dropbox traffic is all secured using encryption, so it isn’t possible for a Tor Exit node to MITM it. Doing this would prevent Dropbox from maintaining a log of my whereabouts (IP addresses and times) at least. I editted my /etc/tor/torrc, added the following two lines, and then restarted Tor:
TransPort 9040 DNSPort 5300
I then added the following additional firewall rules:
iptables -t nat -A OUTPUT -m owner --uid-owner mike.dropbox -p tcp -j REDIRECT --to-ports 9040 iptables -t nat -A OUTPUT -m owner --uid-owner mike.dropbox -p udp --dport 53 -j REDIRECT --to-ports 5300 iptables -A OUTPUT -m owner --uid-owner mike.dropbox -p tcp -d 127.0.0.1 --dport 9040 -j ACCEPT iptables -A OUTPUT -m owner --uid-owner mike.dropbox -p udp -d 127.0.0.1 --dport 5300 -j ACCEPT iptables -A OUTPUT -m owner --uid-owner mike.dropbox -j REJECT
Now all traffic from any applications running under the “mike.dropbox” user id, are forced to route their network traffic through Tor. This even includes DNS lookups. You can read more about using Tor’s Transparent Proxy mode at https://trac.torproject.org/projects/tor/wiki/doc/TransparentProxy
Despite what Dropbox says, they can read the files which you store in your Dropbox folder. The only way to prevent them being able to do that, is by handling the encryption on the client side. Luckily, on Linux this is easy. Do an “apt-get install encfs” and then run the following:
encfs ~/Dropbox/Encrypted/ ~/SecureDropbox/
The first time you run it, you will be asked a couple of questions to initialise the encrypted mountpoint. Once it has finished, you will have a directory called “~/SecureDropbox/“. When you make any changes to that directory, they are mirrored to “~/Dropbox/Encrypted/“, except they are encrypted before hand. Don’t touch any files in “~/Dropbox/Encrypted/“, only in “~/SecureDropbox/“. There is one encrypted file per real file. If you unmount it with a “fusermount -u ~/SecureDropbox/“ the files will disappear from that directory, but they will still be in their encrypted form in “~/Dropbox/Encrypted/“. You can run the same encfs command as above to remount “~/SecureDropbox/“. This time it will just ask you to re-enter the password that you initially provided.
If you want the whole of your Dropbox to be encrypted, rather than just a single folder, you could maybe change your /etc/fstab to mount your Dropbox at “~/.Dropbox.unencrypted” instead of “~/Dropbox/“ and place your encfs mount at “~/Dropbox/“ instead. The problem with this is, you wont be able to access encrypted files from other devices that don’t support encfs.
Can you think of any other ways to lock down Dropbox? Are you aware of any other avenues of attack? Please let me know in the comments.