-
Notifications
You must be signed in to change notification settings - Fork 72
Description
Currently the CNB platform spec says:
The platform MUST ensure that:
- The image config's User field is set to a non-root user with a writable home directory.
...
The following variables SHOULD be set in the lifecycle execution environment and SHALL be directly inherited by the buildpack without modification:
...
HOME | Current user's home directory
However it doesn't make any guarantees as to whether $HOME is set to the same path as $CNB_APP_DIR or not.
This might seem like a trivial implementation detail, but with classic buildpacks on Heroku, several buildpacks write to $HOME during the build, treating it as an ephemeral directory that won't be included in the build output.
For example the heroku-buildpack-github-netrc buildpack intentionally writes to $HOME, knowing that various tooling automatically uses such a .netrc for authentication:
https://github.com/timshadel/heroku-buildpack-github-netrc/blob/5e417127367e49fdf4243da4798d89be474bf709/bin/compile#L30-L40
I'm concerned about this scenario:
- platform A has
$HOMEand$CNB_APP_DIRas different paths on the filesystem - platform B has
$HOMEand$CNB_APP_DIRbeing equivalent - a buildpack author writes a netrc buildpack for platform A and it works as expected
- the netrc buildpack is then used on platform B, where the
.netrcis then saved in the runtime image (and potentially served publicly, if their web server is configured suboptimally) - the users and buildpack authors don’t notice this since it’s subtle/undefined behaviour, particularly if platforms don’t call out explicitly what paths are used for
$HOMEetc (and why would they, since on the most part the exact path used for$HOMEis irrelevant for builds)
There are also cases where buildpacks unknowingly write to $HOME. For example, imagine a Python buildpack that intentionally caches only site-packages and not pip's cache (so doesn't explicitly change the pip cache directory to be in <layers>/...), but forgets to pass --no-cache-dir to the pip install invocation. This would results in pip's http/wheel cache being saved to the default path of $HOME/.cache/pip, which could easily go unnoticed on platform A in the scenario above. However on platform B, this would result in the pip cache being included in the runtime image, bloating it (which at least isn't a security issue, but still not ideal).
As such I was wondering whether the platform spec should define whether $HOME is (or is not) equivalent to the $CNB_APP_DIR path? I'm somewhat undecided to to whether "the same path" or "different paths" is best -- so long as the choice is consistent across platforms to improve buildpack portability and prevent platform-specific security issues.
This issue is something that's also come up for Heroku classic buildpacks, since we're exploring moving the build directory from a directory under /tmp to /app (so we have path parity between build-time and run-time, to resolve relocatability issues). However currently we have $HOME set to /app, so unless we change $HOME to something else (which itself will cause compatibility issues), we're going to have the same path for both $HOME and the build directory and so have to perform outreach for the netrc buildpacks et al.
cc @hone @jabrown85