Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Please excuse the silly question: Would proper directory and file ownerships not prevent this traversal?

If nginx does not run as root, how can it read other files than the ones explicitly assigned to the nginx user?




It would absolutely prevent it. Run app as one user, nginx as other, go-rwx on all app files, set the group of the "static" files as www-data and g+r on them and now web server can't access app files.

It's LITERALLY app hosting 101 and people did it that way 20+ years ago.


Ah the wonders of 022 umask. Personally I would always recommend making files unreadable to other users. If not for all files then at least significant directories like everything under /home, etc.

It may require more fiddling with group memberships, but it's well worth it.


I don't know about everyone else, but at this point I'm no longer doing a proper installation of nginx for personal stuff. I always just spin up a docker image... and I'm not checking if it runs as root or not, really.

Probably really screwing things up. Ouch.


Typical umask is 022 so most things are readable by nginx workers but not writable, they don’t need to be explicitly assigned (e.g. to www-data). If your application generates sensitive data of course you should probably use a 077 umask.


You could make an argument that bitwarden vaults constitute sensitive information.


You are correct.

Unfortunately, nginx (and other web servers) generally need to run as root in normal web applications because they are listening on port 80 or 443. Ports below 1024 can be opened only by root.

A more detailed explanation can be found here: https://unix.stackexchange.com/questions/134301/why-does-ngi...


> Ports below 1024 can be opened only by root.

Or processes running with the CAP_NET_BIND_SERVICE capability! [1]

Capabilities are a Linux kernel feature. Granting CAP_NET_BIND_SERVICE to nginx means you do not need to start it with full root privileges. This capability gives it the ability to open ports below 1024

Using systemd, you can use this feature like this:

    [Service]
    ExecStart=/usr/bin/nginx -c /etc/my_nginx.conf
    AmbientCapabilities=CAP_NET_BIND_SERVICE
    CapabilityBoundingSet=CAP_NET_BIND_SERVICE
    User=nginx
    Group=nginx
(You probably also want to enable a ton of other sandboxing options, see `systemd-analyze security` for tips)

[1]: https://man7.org/linux/man-pages/man7/capabilities.7.html


Nginx is started as root but it does not run as root, it changes its user after opening log files and sockets. (unless you use a lazy docker container and just run everything as root inside it).


Even in (the official) docker image, a nginx user is created: (latest, layer 6)

/bin/sh -c set -x && groupadd --system --gid 101 nginx && useradd --system --gid nginx --no-create-home --home /nonexistent --comment "nginx user" --shell /bin/false --uid 101 nginx .....

[1] https://hub.docker.com/layers/library/nginx/latest/images/sh...


Nginx workers shouldn’t run as root and certainly don’t on any distro I know. Typically you have a www-data user/group or equivalent. Dropping privilege is very basic.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: