* Patch for SymlinksIfOwnerMatches @ 2018-07-03 18:19 Hanno Böck 2018-07-03 18:48 ` Jann Horn 2018-07-03 19:47 ` Jann Horn 0 siblings, 2 replies; 6+ messages in thread From: Hanno Böck @ 2018-07-03 18:19 UTC (permalink / raw) To: kernel-hardening Hi, There's a nasty problem in many webserver configurations on multiuser systems, I've blogged about it a while ago [1]. With a symlink it's often possible to read out configuration files of other users. This was famously used in the freedom hosting II hack [2]. grsecurity had a workaround for this: By not allowing file operations to follow symlinks if the owner of the link and the target don't match it can block this kind of attack. I saw a need to keep this feature alive in a post-grsecurity world, so a while ago I extracted it from the grsecurity patch. I've now made that public: https://github.com/hannob/symlinkown I'm not sure about upstreaming, I think it's a worthy feature, but it might need some work in polishing it. But for now I'll just share it and I will hopefully be able to keep the patch working for future kernels. [1] https://blog.hboeck.de/archives/873-The-tricky-security-issue-with-FollowSymLinks-and-Apache.html [2] https://securityaffairs.co/wordpress/55990/deep-web/freedom-hosting-ii-hack.html -- Hanno Böck https://hboeck.de/ mail/jabber: hanno@hboeck.de GPG: FE73757FA60E4E21B937579FA5880072BBB51E42 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Patch for SymlinksIfOwnerMatches 2018-07-03 18:19 Patch for SymlinksIfOwnerMatches Hanno Böck @ 2018-07-03 18:48 ` Jann Horn 2018-07-03 18:58 ` Jann Horn 2018-07-03 19:47 ` Jann Horn 1 sibling, 1 reply; 6+ messages in thread From: Jann Horn @ 2018-07-03 18:48 UTC (permalink / raw) To: hanno; +Cc: Kernel Hardening On Tue, Jul 3, 2018 at 8:29 PM Hanno Böck <hanno@hboeck.de> wrote: > There's a nasty problem in many webserver configurations on multiuser > systems, I've blogged about it a while ago [1]. With a symlink it's > often possible to read out configuration files of other users. This was > famously used in the freedom hosting II hack [2]. > > grsecurity had a workaround for this: By not allowing file operations > to follow symlinks if the owner of the link and the target don't match > it can block this kind of attack. > > I saw a need to keep this feature alive in a post-grsecurity world, so > a while ago I extracted it from the grsecurity patch. I've now made > that public: > https://github.com/hannob/symlinkown > > I'm not sure about upstreaming, I think it's a worthy feature, but it > might need some work in polishing it. But for now I'll just share it > and I will hopefully be able to keep the patch working for future > kernels. > > [1] > https://blog.hboeck.de/archives/873-The-tricky-security-issue-with-FollowSymLinks-and-Apache.html > [2] > https://securityaffairs.co/wordpress/55990/deep-web/freedom-hosting-ii-hack.html Does upstream's /proc/sys/fs/protected_symlinks not work for that? ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Patch for SymlinksIfOwnerMatches 2018-07-03 18:48 ` Jann Horn @ 2018-07-03 18:58 ` Jann Horn 2018-07-03 19:31 ` Salvatore Mesoraca 0 siblings, 1 reply; 6+ messages in thread From: Jann Horn @ 2018-07-03 18:58 UTC (permalink / raw) To: hanno; +Cc: Kernel Hardening On Tue, Jul 3, 2018 at 8:48 PM Jann Horn <jannh@google.com> wrote: > > On Tue, Jul 3, 2018 at 8:29 PM Hanno Böck <hanno@hboeck.de> wrote: > > There's a nasty problem in many webserver configurations on multiuser > > systems, I've blogged about it a while ago [1]. With a symlink it's > > often possible to read out configuration files of other users. This was > > famously used in the freedom hosting II hack [2]. > > > > grsecurity had a workaround for this: By not allowing file operations > > to follow symlinks if the owner of the link and the target don't match > > it can block this kind of attack. > > > > I saw a need to keep this feature alive in a post-grsecurity world, so > > a while ago I extracted it from the grsecurity patch. I've now made > > that public: > > https://github.com/hannob/symlinkown > > > > I'm not sure about upstreaming, I think it's a worthy feature, but it > > might need some work in polishing it. But for now I'll just share it > > and I will hopefully be able to keep the patch working for future > > kernels. > > > > [1] > > https://blog.hboeck.de/archives/873-The-tricky-security-issue-with-FollowSymLinks-and-Apache.html > > [2] > > https://securityaffairs.co/wordpress/55990/deep-web/freedom-hosting-ii-hack.html > > Does upstream's /proc/sys/fs/protected_symlinks not work for that? Ah, nevermind, that's for a slightly different problem; protected_symlinks only applies in very specific cases for some reason. But I wonder if it'd make sense to try to integrate this with protected_symlinks, perhaps as protected_symlinks=2 or so; if you think about a situation like an attacker-owned directory /tmp/foo containing a symlink /tmp/foo/link, it looks like protected_symlinks doesn't currently protect against that either; and this situation isn't very different from the scenario you're talking about, I think. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Patch for SymlinksIfOwnerMatches 2018-07-03 18:58 ` Jann Horn @ 2018-07-03 19:31 ` Salvatore Mesoraca 0 siblings, 0 replies; 6+ messages in thread From: Salvatore Mesoraca @ 2018-07-03 19:31 UTC (permalink / raw) To: Jann Horn; +Cc: hanno, Kernel Hardening, Solar Designer 2018-07-03 20:58 GMT+02:00 Jann Horn <jannh@google.com>: > On Tue, Jul 3, 2018 at 8:48 PM Jann Horn <jannh@google.com> wrote: >> >> On Tue, Jul 3, 2018 at 8:29 PM Hanno Böck <hanno@hboeck.de> wrote: >> > There's a nasty problem in many webserver configurations on multiuser >> > systems, I've blogged about it a while ago [1]. With a symlink it's >> > often possible to read out configuration files of other users. This was >> > famously used in the freedom hosting II hack [2]. >> > >> > grsecurity had a workaround for this: By not allowing file operations >> > to follow symlinks if the owner of the link and the target don't match >> > it can block this kind of attack. >> > >> > I saw a need to keep this feature alive in a post-grsecurity world, so >> > a while ago I extracted it from the grsecurity patch. I've now made >> > that public: >> > https://github.com/hannob/symlinkown >> > >> > I'm not sure about upstreaming, I think it's a worthy feature, but it >> > might need some work in polishing it. But for now I'll just share it >> > and I will hopefully be able to keep the patch working for future >> > kernels. >> > >> > [1] >> > https://blog.hboeck.de/archives/873-The-tricky-security-issue-with-FollowSymLinks-and-Apache.html >> > [2] >> > https://securityaffairs.co/wordpress/55990/deep-web/freedom-hosting-ii-hack.html >> >> Does upstream's /proc/sys/fs/protected_symlinks not work for that? > > Ah, nevermind, that's for a slightly different problem; > protected_symlinks only applies in very specific cases for some > reason. > > But I wonder if it'd make sense to try to integrate this with > protected_symlinks, perhaps as protected_symlinks=2 or so; if you > think about a situation like an attacker-owned directory /tmp/foo > containing a symlink /tmp/foo/link, it looks like protected_symlinks > doesn't currently protect against that either; and this situation > isn't very different from the scenario you're talking about, I think. Some months ago I discussed with Solar Deisgner (adding in CC) about a feature[1] that included this kind of restrictions. But It was intended more as a debugging feature than a security one, because of some possible false positives. Unfortunately that discussion ended up nowhere, at least for the moment. [1] https://lkml.kernel.org/r/20171130191438.GA4646@openwall.com Salvatore ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Patch for SymlinksIfOwnerMatches 2018-07-03 18:19 Patch for SymlinksIfOwnerMatches Hanno Böck 2018-07-03 18:48 ` Jann Horn @ 2018-07-03 19:47 ` Jann Horn 2018-07-03 21:02 ` Hanno Böck 1 sibling, 1 reply; 6+ messages in thread From: Jann Horn @ 2018-07-03 19:47 UTC (permalink / raw) To: hanno, Al Viro; +Cc: Kernel Hardening On Tue, Jul 3, 2018 at 8:29 PM Hanno Böck <hanno@hboeck.de> wrote: > > Hi, > > There's a nasty problem in many webserver configurations on multiuser > systems, I've blogged about it a while ago [1]. With a symlink it's > often possible to read out configuration files of other users. This was > famously used in the freedom hosting II hack [2]. > > grsecurity had a workaround for this: By not allowing file operations > to follow symlinks if the owner of the link and the target don't match > it can block this kind of attack. > > I saw a need to keep this feature alive in a post-grsecurity world, so > a while ago I extracted it from the grsecurity patch. I've now made > that public: > https://github.com/hannob/symlinkown > > I'm not sure about upstreaming, I think it's a worthy feature, but it > might need some work in polishing it. But for now I'll just share it > and I will hopefully be able to keep the patch working for future > kernels. > > [1] > https://blog.hboeck.de/archives/873-The-tricky-security-issue-with-FollowSymLinks-and-Apache.html > [2] > https://securityaffairs.co/wordpress/55990/deep-web/freedom-hosting-ii-hack.html +cc Al Viro because this is related to AT_BENEATH and other path walk stuff Hmm. Actually, I wonder whether the kernel is a good place to handle this at all. As you note, Apache already has the option SymLinksIfOwnerMatch, which means that it already has to do a component-wise path walk in userspace (because AT_BENEATH hasn't landed yet). Here's what "strace" reports when Apache with that option is following a symlink: root@vm:~# strace -f -p5559 -p5560 -e trace='!accept4,futex,epoll_wait,epoll_ctl,read,write,fcntl,getsockname' strace: Process 5559 attached with 27 threads strace: Process 5560 attached with 27 threads [pid 5613] mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f584a463000 [pid 5613] mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f584a461000 [pid 5613] mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f584a45f000 [pid 5613] stat("/var/www/html/foo/bar/link/subdir/hello", {st_mode=S_IFREG|0644, st_size=12, ...}) = 0 [pid 5613] lstat("/var", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 [pid 5613] lstat("/var/www", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 [pid 5613] lstat("/var/www/html", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 [pid 5613] lstat("/var/www/html/foo", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 [pid 5613] lstat("/var/www/html/foo/bar", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 [pid 5613] lstat("/var/www/html/foo/bar/link", {st_mode=S_IFLNK|0777, st_size=17, ...}) = 0 [pid 5613] stat("/var/www/html/foo/bar/link", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 [pid 5613] lstat("/var/www/html/foo/bar/link/subdir", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 [pid 5613] lstat("/var/www/html/foo/bar/link/subdir/hello", {st_mode=S_IFREG|0644, st_size=12, ...}) = 0 [pid 5613] mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f584a45d000 [pid 5613] openat(AT_FDCWD, "/var/www/html/foo/bar/link/subdir/hello", O_RDONLY|O_CLOEXEC) = 13 If, instead of using lstat() and open(), this code used fstatat() and openat(), you could deal with symlink races in userspace. In theory, for very long paths, this might also be faster; the current code has to follow O(n^2) path elements. At that point, the only small remaining problem would be that you could determine whether a given path exists by using a symlink that points into that path and traverses back out with a sequence of ".."; if you want to also deal with that, you'd have to also do symlink resolution in userspace. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Patch for SymlinksIfOwnerMatches 2018-07-03 19:47 ` Jann Horn @ 2018-07-03 21:02 ` Hanno Böck 0 siblings, 0 replies; 6+ messages in thread From: Hanno Böck @ 2018-07-03 21:02 UTC (permalink / raw) To: Jann Horn; +Cc: Al Viro, Kernel Hardening On Tue, 3 Jul 2018 21:47:34 +0200 Jann Horn <jannh@google.com> wrote: > Hmm. Actually, I wonder whether the kernel is a good place to handle > this at all. > > As you note, Apache already has the option SymLinksIfOwnerMatch, which > means that it already has to do a component-wise path walk in > userspace (because AT_BENEATH hasn't landed yet). Here's what "strace" > reports when Apache with that option is following a symlink: Maybe for context: I haven't looked into the details of the technical implementation and I'm not claiming this is a good solution (nor do I claim to have good knowledge of these things at all). But when I looked into this a while ago it was the only solution that was available. Right now the apache option has 2 problems: * There are many web apps that will enable "FollowSymlinks". If you start forbidding that you'll break them. There's currently no way to configure apache in a way that both enforces symlink owner match and doesn't break half of the PHP ecosystem. It would need an option like "treat FollowSymlinks like FollowSymlinksIfOwnerMatch" * The option has a documented race condition. (Apache has this habit of documenting security bugs and thinking this makes them go away...) I have heard people saying that this is unfixable in userspace, but well, if you say it's possible I'm not going to argue with it. Point is: I merely wanted to keep the grsecurity option working, so I ripped it out of grsec into a separate patch. If there's a better way I'm all for it. -- Hanno Böck https://hboeck.de/ mail/jabber: hanno@hboeck.de GPG: FE73757FA60E4E21B937579FA5880072BBB51E42 ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2018-07-03 21:02 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2018-07-03 18:19 Patch for SymlinksIfOwnerMatches Hanno Böck 2018-07-03 18:48 ` Jann Horn 2018-07-03 18:58 ` Jann Horn 2018-07-03 19:31 ` Salvatore Mesoraca 2018-07-03 19:47 ` Jann Horn 2018-07-03 21:02 ` Hanno Böck
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.