Tor Browser vs NOEXEC - Where should the Tor Browser folder be placed?

It’s fragile since it breaks on folder structure changes by upstream (which happen a lot in past). No prior notification and hard to follow upstream development (limitation of resources). And time of upgrades is also up to upstream only.

Also possibly breaking the updater unless using more trickery (modifying files inside the browser folder).

The root cause of this mess is always the absence of a deb package of Tor Browser.


Oh. So probably not a good idea then.

Maybe put everything in /usr/bin? /usr/bin wouldn’t be mounted with noexec anyway.

1 Like

With or without sub folder?

Contents of tor-browser folder currently are:

  • Browser
  • start-tor-browser.desktop

but these might expand vastly in future if Tor Project restructures.

With sub folder it could be /usr/bin/tor-browser folder(!). I.e. : /usr/bin/torbrowser/start-tor-browser.desktop

But that would not be in PATH. But no big deal since users can/should start it using the wrapper /usr/bin/torbrowser anyhow.

Then folder /usr/bin/tor-browser should be owned by user user and profile data would also be stored there?

It would break multi user systems. But likely a sacrifice we could make.

And would we gain actual security benefits? User could not store files in /home/user anymore and make executable (noexec mount option) but then user could write files into /usr/bin/tor-browser folder, make them executable.

Or can making executable be prevented? Maybe. But then that also could break future Tor Browser updates (might ship new executable such as plugin container and whatnot).

1 Like

A sub folder would be best.

It’s more likely for something to try to execute malware in the user’s home folder than in the tor browser folder.

We could probably do some filesystem permissions magic to make that work.

Maybe even mount parts of /usr/bin/tor-browser with noexec e.g. /usr/bin/tor-browser/Browser/Downloads.

Disadvantage of such a non-standard folder: likely mandatory access control frameworks like firejail. Tried to execute Tor Browser from /var/cache/tb-binary in Qubes DispVMs (for non-security reason: so no need to copy to home folder to save startup time). But couldn’t make firejail work when Tor Browser was in that folder. Used mount --bind instead which works with both AppArmor (Qubes using that for years now) and firejail.

Maybe we can mount mount /home with noexec but just the Tor Browser folder without noexec?

(So at some point, there could be a VM config with/without Tor Browser. Those without Tor Browser, more hardened.)

We could again get rid of off-the-shelf malware.

That sounds good.

1 Like

Looks not too hard. One can mount a folder onto itself!

sudo mount --bind /home/user/folder-name /home/user/folder-name -o noexec

Seems not a big deal about Tor Browser then since we can remount to remove noexec when needed?

1 Like

That could be easily fixed with a custom profile.

Is there an exec mount option? If so, we could use that for the Tor Browser folder while mounting the rest of /home with noexec.

That sounds good.

1 Like

There is.

1 Like

Not an issue at all with our without exec option, I think. Since we can mount a folder on itself at that point we can redefine mount options.

Next step: (re-)mount home [and other?] with noexec (and nosuid [among other useful mount options]) for better security? needs to be sorted. Help welcome.

Over next step: /usr/bin/torbrowser remounting Tor Browser folder. This could even be protected by a lxsudo prompt.

1 Like

I can’t tell if there was a decision made here.

I wrote a script once that would make a copy of a clean profile with settings for using system tor and disabling updates (to allow concurrent use) and run TB with -profile pointing to the new profile.
It seemed to work with a few (harmless?) errors, but it would still access the default profile directory ./Browser/TorBrowser/Data/Browser/profile.default for some reason I never discovered (I think the Torbutton extension).
I could try again with the ./Browser directory itself unwritable by user.
Normally the bundle appears to modify only in directories
Browser/TorBrowser/UpdateInfo (ok with updates off?)
Browser/TorBrowser/Data/Tor/ (ok with system tor?)
Browser/TorBrowser/Data/Browser/profile.default/ (ok with new profile?)
Making that work properly would be ideal (but a job for upstream).
Then the browser could live in a system directory with a profile in $HOME. It would check for updates but they’d be installed by admin.
It would also be convenient to be able to do a quick search in a new profile without having to restart or make a complete copy of TB.

In the mean time, less likely to break anything: bind mount the system browser directory into user home, and then the user settings under that.
I think this allows multiple profiles simultaneously, and the browser shouldn’t notice.

root@host:~# mount -o bind test ~user/browser1
root@host:~# mount -o bind ~user/data1/ ~user/browser1/data/
root@host:~# mount -o bind test ~user/browser2
root@host:~# mount -o bind ~user/data2/ ~user/browser2/data/
root@host:~# ls -l ~user/browser1
total 4
drwxr-xr-x 2 user user 4096 Sep 11 07:24 data
-rw-r--r-- 1 root root    0 Sep 11 07:23 systemdir
root@host:~# ls -l ~user/browser1/data
total 0
-rw-r--r-- 1 user user 0 Sep 11 07:24 userdata1
root@host:~# ls ~user/browser2
data  systemdir
root@host:~# ls ~user/browser2/data

But you have to mount them in the correct order. If you mount browser2 before data1 both data end up being userdata2. Also browser2/data must be unmounted before browser1 can be unmounted.
It would work best with a fixed set of profiles being mounted somehow on login. I’m not a fan of sudo in general because even without X sniffing, if the user may be compromised how do I know I’m not running a pseudo sudo? It would have to be a specific sudoer rule.
Better would be a user mount namespace (unshare -f -m -p -U -r)? It might be more complicated but it can be done completely as an unprivileged user. (Edit: Operation not permitted on Whonix. Guess not.)

If you want everything owned by user, how about mounting ./Browser read-only and then ./Browser/TorBrowser/Data rw,noexec
Maybe simpler if ./Browser/TorBrowser/Data is a symlink to …/…/$data, so there is only one mount.

Strangely the noexec bind mount is system dependent? On another machine:

root@host:~# mount -o bind,noexec test test
root@host:~# ./test/ok

But on another this seems to work

root@host:~# mkdir -p test/rw
root@host:~# mount -o bind,ro test test
root@host:~# mount -o bind,rw,noexec test/rw test/rw
root@host:~# touch test/ok
touch: cannot touch 'test/ok': Read-only file system
root@host:~# echo -e "#\!/bin/bash\necho ok" > test/rw/ok
root@host:~# chmod a+x test/rw/ok
root@host:~# ./test/rw/ok
bash: ./test/rw/ok: Permission denied
root@host:~# umount test/rw
root@host:~# ./test/rw/ok

The idea is to make every directory writable by user noexec?
Edit: better ideas

1 Like


Concurrent use by same user? This works anyhow? Not sure what I am missing?

Hard to say without seeing the errors. I guess generally we shouldn’t do things which make Tor Browser produce errors which Tor Browser otherwise would not produce.

Upstream bug report?

Sounds like fragile when Tor Browser Internal Updater runs. Consult upstream?

[idea] There could be two different desktop starters.

  • [A] Tor Browser (security restricted)
  • [B] Tor Browser (internal updater allowed)

Tor Browser folder would come with restrictive mount options by default.

  • application folder, generally: ro,nosuid,nodev
  • browser profile folder: rw,nosuid,nodev,noexec

[A] Would just start Tor Browser manually. (And run a script that re-enforced restrictive mount options. That could have a /etc/sudoers.d exception so no user password entry is required.)
[B] Would Mount the application folder ro,nosuid,nodev so internal updater can work. (This would require entering sudo password. [X])

I don’t think we’d need to manipulate Tor Browser folder structure that way? No need to move (mv) folders around`?

What do you think?


This is unrelated here.
This is also documented here: [Y] Safely Use Root Commands

My above [idea] should implement this.

Your sudo related concerns are valid, but unrelated here and well covered by [Y]? You could still use [Y] to start [B] (Tor Browser (internal updater allowed)).

Don’t know. Didn’t use yet. Still required with my [idea]?

remount is required in some situations such as when previous mounted.

What are the different options being proposed? Decision for what?

Would you like to contribute this? Great!

As per my last post…

Sounds like a good way forward?

Could you start with [1] please and then perhaps [2] if you like to contribute?

I mean running two profiles with separate identities at the same time without having to copy the entire Browser directory, only profile.
I am thinking about how to create multiple views of the same directory except with one subdirectory replaced by user data.
I can do it as a regular user on Ubuntu with user namespaces (unshare -m -r bash, mount …) but I guess Whonix is more restrictive.
Maybe it can be done with firejail (it can also unshare mount namespace) but I don’t know much about it yet.
None of this would be necessary if Tor Browser worked with profiles the same way Firefox does, so that would be the ideal solution. Everything else is workaround.

Are you intending them both to be used on the same boot?
The use cases I have in mind are exclusive:
(1) Run normally with persistent user data (separate virtual disk or shared folder) and immutable system → [A] as user
(2) Update with no (untrusted) user data and persistent system → [B] as admin
Goal: no persistent compromise.
A separate user makes the difference more obvious and prevents accidental contamination.
But the difference can be enforced by a wrapper on the host that disables one disk before making the other writable.
So updating (2) can be done as the same user as (1) if you are careful and can assume (2) always has clean user (not just root).

I think of files as:
(A) System files the user can’t touch. Persistent changes only in case (2)
(B) Trusted user files (.bashrc, .local/share/applications/*.desktop, browser profile, etc). Can be modified by user but not persist in case (1).
(C ) Persistent untrusted files only visible in case (1).
(D) Everything else, do not exist on boot, never persist.
On a single user machine, particularly something like Whonix, maybe there is not much difference between (A) and (B).
Malicious (B) can compromise user by design, so they must be trusted by user but not root.
Malicious (C ) should require an unpatched vulnerability to cause problems as long as it remains untrusted (an important question is how much software can be trusted to not trust untrusted files). They were copied from somewhere unsafe or might have been created by (hopefully temporary) malware.

Trying to stay on topic here:

A decision for where the Tor Browser folder should be placed.
Since Whonix is intended as a single user system, home makes sense. But need to be careful about updating it as user.
*Important to think about: even if the Browser directory is read-only, if it lives in user home the whole directory may be replaced by malicious user, and then gain exec.

It sounds like this old thing
Kernel dependent? On my Whonix 14 a second mount is required:

root@host:~# mount -o bind,noexec test test
root@host:~# ./test/ok 
root@host:~# mount -o remount,noexec test test
root@host:~# ./test/ok
-bash: ./test/ok: Permission denied

There’s a big difference between getting something to work and doing it right. I have experience with the former. Just vague ideas for the latter.

This thread is based on noexec everything under user control. To be honest I’m not sure what the end result is, since startup scripts, user .desktop files etc are not affected by noexec.

I don’t know. See note* above about user control. Also bind mounts are subtle.

user@host:~$ ./ok
root@host:~# mount -o bind,noexec ~user/ ~user/
user@host:~$ ./ok
user@host:~$ cd
user@host:~$ ./ok
bash: ./ok: Permission denied

Race conditions to think about too.

Changing any folders can break MAC (apparmor, firejail).

Possibly most users would do that, yes.

Tor Browser started security restricted ([A] with ro,nosuid,nodev executable files and rw browser profile) → get exploited → MAC confines it into its folder → modified firefox binary → terminated → later restarted using [B] (internal updater allowed) → browser updated, still compromised. Gained little except nosuid,nodev. Maybe breaking some malware requiring exec inside browser binary folder.

Maybe before starting the browser using [A] it could run Dev/VirusForget - Kicksecure to checksum the browser binary folder. On any startup, all changes to any files in browser binary folder are undone and only changes in user profile folder are kept. That would make exploits harder. Malware could no longer persist in browser binary folder. But malware could persist in browser profile folder perhaps as a malicious browser add-on.

A Dev/VirusForget - Kicksecure checksum mechanism might also set the browser binary folder immutable. That’s no noexec but the same result as noexec. Perhaps don’t care so much about noexec for Tor Browser folder but just make it non-writeable (as good as noexec - no new binaries since no write access). And the browser profile folder can be noexec. Should be as good as complete noexec.

Sounds nice in theory but in practice can’t work since Tor Browser mixes application data and browser data folder. I.e. some anonymity related settings reside in browser profile folder and need to be updated as well. So by updating while moving the untrusted profile folder out of the way, the update may result in a different web fingerprint.

Folder should stay stay as is unless a strong rationale is provided.
Splitting the folder seems fragile on Tor Browser updates.
Moving to other folders breaks MAC.

Maybe higher security may be possible for users who are ok to purge their browser profile on each upgrade. I.e. install a new Tor Browser version using tb-updater (should be renamed to tb-downloader) rather than updating using Tor Browser internal updater.

I don’t see any better solution unless things are improved upstream.

We could also say that VMs using Tor Browser shouldn’t be used for anything else due to this mess vs noexec. Always results in lower security level.

Just the one thing. One thing at a time. (re-)mount home [and other?] with noexec (and nosuid [among other useful mount options]) for better security? is about changing proc-hidepid.service into a more generalized service that gets all mount options enhanced.

startup scripts, user .desktop files are for later work → Dev/VirusForget - Kicksecure

Not sure yet about noexec.
Since noexec does not block scripts execution… See also
Chromium OS Docs - Shell scripts & noexec mounts
I was considering to contact apparmor / firejail developers to ask if we can get that under control somehow. noexec is also worth its own forum thread.

Instead of messing with our own mounts, why not use Firejail’s noexec option?

As per

noexec file_or_directory
          Remount the file or the directory noexec, nodev and nosuid.

Mounting files read-only can be done with the read-only option.

1 Like

Firejail is cool but for firejail setting readonly we’d need two different firejail profiles. One without Tor Browser internal updater allowed and one with.

1 Like

I don’t see why that would be much of a problem.

Perhaps just different command line switches?

Firejail can make something noexec but it shouldn’t be able to make something exec again*. Which means Browser must start off exec. Should it be read-only before login, or is it enough to be read-only to the sandboxed Browser itself?

*Except it can. Just playing around, with noexec bind mount on browser/data,

user@host:~$ ./browser/data/ok
bash: ./browser/data/ok: Permission denied
user@host:~$ firejail --quiet --overlay-tmpfs ./browser/data/ok

The filesystem is sandboxed now but firejail --overlay-tmpfs ignores the bind mounts completely. Actually it ignores regular mounts too. I guess it does something like a bind mount on / instead of an rbind. (It also doesn’t stack, which may be an issue if one sandboxed application wants to launch another one.)

Maybe Tor Browser could be run normally with a disposable overlay, whitelisting Downloads etc.
If you’re running in the default private mode then maybe you don’t want anything else to stick around anyway.
Unfortunately user settings changed through the browser are stored in prefs.js, along with other settings. But they can be manually pulled out and set in user.js, and probably not changed much. But this might be too much for a normal user.
Bookmarks unfortunately are in places.sqlite which is rather opaque. They might be rewritten into tracking redirects or proxies with typo or homographic domains. Apparently browser.places.importBookmarksHTML and browser.bookmarks.autoExportHTML allow usage of plain html but I haven’t tried.
Search engines are in a mozlz4 file to prevent tampering by malware, ironically making it very difficult for a user to detect tampering.

1 Like

Since (re-)mount home [and other?] with noexec (and nosuid [among other useful mount options]) for better security? - #18 by Patrick was recently implemented… (And after the recent firejail controversy in thread Tor Browser Hardening (hardened malloc, firejail, apparmor) vs Web Fingerprint …) Any idea ideas for this issue?

Remounting /home/user/.tb with exec (rather than noexec) for Tor Browser is possible. I am experimenting successfully wit that in Qubes-Whonix DispVM already. But remounting /home/user/.tb with exec or “don’t use Tor Browser anymore”, i.e. pick one “noexec or Tor Browser” isn’t a great solution.

That threat model I am having in mind here is an attacker who reached local code execution who would be blocked from exploiting from user to root or kernel thanks to noexec. This currently can be circumvented in a target attack:
(A script, not program, but easily reproducible to make the point.)

file /home/user/.tb/evil-program

echo "evil program"

chmod +x /home/user/.tb/evil-program



I would like to somehow restrict that not “all of user user” can create and run executable in folder /home/user/.tb.


apparmor-profile-everything can give fine-grained execute permissions and already does for /home. It only allows the user to execute /home/*/.tb/tor-browser/Browser/{,start-tor-browser,firefox} and write permission for .tb/tor-browser/ is denied (so an attacker can’t overwrite those files).

Any other things TB needs to execute is handled by apparmor-profile-torbrowser (which is a dependency).