github.com/dctrud/umoci@v0.4.3-0.20191016193643-05a1d37de015/doc/site/reference/security.md (about) 1 +++ 2 title = "Security Considerations" 3 weight = 25 4 +++ 5 6 umoci is entrusted with taking a particular image and expanding it on the 7 filesystem (as well as computing deltas of the expanded filesystem). As a 8 result, umoci must be very careful about filesystem access to avoid 9 vulnerabilities that may impact other components of the system. If you feel 10 something is missing from this document, feel free to 11 [contribute][contributing.md]. 12 13 If you've found a security flaw in umoci that comes from a security 14 consideration we haven't considered before, please follow our instructions on 15 [how to responsibly disclose a security issue][contributing.md]. Once it has 16 been resolved, feel free to contribute to this document a description of the 17 consideration that we were missing. 18 19 [contributing.md]: /contributing 20 21 ### Path Traversal ### 22 23 The most obvious vulnerabilities that umoci has to protect against is path 24 traversal vulnerabilities. However, path traversal vulnerabilities in umoci 25 are even more dangerous because umoci has to emulate a `chroot` when 26 interacting with the filesystem (as well as never mutating inodes in case it 27 may be referenced by a path external to the root filesystem). 28 29 > **NOTE**: Users are expected to appreciate the risks of interacting with a 30 > foreign filesystem rootfs, if they intend to not use a virtualization system 31 > such as `chroot` or containers when interacting with the rootfs umoci has 32 > expanded. 33 34 There are multiple ways that umoci defends against this. The first and most 35 important is that all path computation of destination and source paths is done 36 using the [`filepath-securejoin`][securejoin] library (which was written by the 37 author of umoci<sup>[1](#foot1)</sup>). `filepath-securejoin` solves this 38 problem by effectively implementing a variant of `filepath.EvalSymlinks` except 39 that all symlink and lexical evaluation is done manually within a particular 40 scope. We have extensive testing (in both projects) to show that a variety of 41 attacks will not succeed against our implementation. 42 43 In addition, umoci has a series of sanity checks that ensures that operations 44 that involve modifying the filesystem based on arbitrary image input will not 45 affect anything outside of the intended directory root. These additions are 46 purely defensive in nature, as `filepath-securejoin` handles all known 47 instances of path traversal attacks in this context. 48 49 umoci **does not** attempt to be safe against shared filesystem access during 50 an `unpack` or `repack` operation. This is because it is not possible with any 51 modern Unix<sup>[2](#foot2)</sup> system to safely ensure that a particular 52 user-space path evaluation will be atomic (nor that the returned result cannot 53 later become unsafe given further filesystem manipulation). Once an `unpack` or 54 `repack` operation has completed, arbitrary filesystem modification of the root 55 filesystem will not cause umoci to act unsafely in future operations. 56 57 umoci also defends against inode mutation by always replacing inodes. This 58 actually makes the code simpler, but makes sure that hardlinks to inodes inside 59 a root filesystem won't see any modifications because of umoci (not that 60 umoci currently permits unpacking into existing directories). 61 62 <a name="foot1">1</a>: The implementation linked is loosely based on Docker's 63 implementation of a similar concept (to protect against similar path 64 traversals). Interestingly, the security vulnerabilities that alerted Docker to 65 this issue several years ago were discovered and fixed by this author as well. 66 67 <a name="foot2">2</a>: Interestingly, Plan9 has effectively solved this problem 68 by removing symlinks and instead using namespaces. However, umoci's main user 69 demographic is not Plan9 so this tid-bit is not of much use to us. 70 71 [securejoin]: https://github.com/cyphar/filepath-securejoin 72 73 ### Arbitrary Inode and Mode Creation ### 74 75 Note that this attack is only applicable if umoci is being executed as a 76 **privileged user** (on GNU/Linux this means having `CAP_SYS_ADMIN` and a host 77 of other capabilities). umoci running in rootless mode cannot create 78 arbitrary inodes due to ordinary access control implemented by the operating 79 system (umoci only uses standard VFS operations to implement rootless mode, 80 which have very well-understood access control restrictions). 81 82 Effectively this attack boils down to the fact that a `tar` archive (which is 83 what makes up the layers in OCI images) contains inode information that can be 84 used to cause umoci to create block devices with arbitrary major and minor 85 numbers. In the absolute worst case, this could allow a user to create a 86 world-writeable inode that corresponds to the host's hard-drive (or 87 `/dev/kmem`). There are a variety of other possible attacks that can occur. 88 Note that the default umoci runtime configuration defends against containers 89 from being able to mess with such files, but this doesn't help against 90 host-side attackers. This attack also could be used to provide an unprivileged 91 user (in the host) access unsafe set-uid binaries, allowing for possible 92 privilege escalation. 93 94 umoci's defence against this attack is to make the `bundle` directory `chmod 95 go-rwx` which will ensure that unprivileged users won't be able to resolve the 96 dangerous inode or setuid binary (note that bind-mounts can circumvent this, 97 but a user cannot create a bind-mount without being able to resolve the path). 98 99 ### Compression Bomb Attacks ### 100 101 OCI images specifically require implementations to support layers compressed 102 with `gzip`. This results in [gzip bomb attacks][gzip-bomb] being potentially 103 practical. In the worst cases this can result in denial-of-service attacks, if 104 umoci is run in a context without any storage or I/O quotas. 105 106 umoci uses the [Go standard library implementation of `gzip`][go-gzip], which 107 *does not appear* to support multiple-round decompression. This somewhat 108 reduces the amplification nature of this attack, but the attack is still 109 present. 110 111 **umoci currently has no specific defences against this attack.** There is a 112 very trivial solution that we can add, which is a `--maximum-layer-size` flag 113 that will abort an `unpack` operation if any single layer is deemed too large. 114 Unfortunately, it does not seem reasonable to enable such an option for all 115 `unpack` operations, and picking a reasonable default is an even more serious 116 concern. There does not appear to be much analysis on heuristics that can be 117 used to detect compression bombs, but I am under the impression that that would 118 be the only reasonable way to detect this in the general case (a heuristic 119 based on the Shannon entropy or the compression ratio would be very 120 interesting). 121 122 A workaround for this problem is to place umoci inside of the relevant 123 cgroups so that it will not drain the system resources too heavily if 124 encountering a compression bomb. As mentioned above, detecting generic 125 compression bombs does not appear to be a solved problem, so this workaround 126 only helps to reduce the impact and does not mitigate it. 127 128 [gzip-bomb]: https://www.rapid7.com/db/modules/auxiliary/dos/http/gzip_bomb_dos 129 [go-gzip]: https://golang.org/pkg/compress/gzip/