Linux - client_body_in_file_only - how to set file permissions for the temp file?
Asked Answered
R

2

5

We use the client_body_in_file_only option with nginx, to allow file upload via Ajax. The config looks like this:

location ~ ^(\/path1|\path2)$ {

  limit_except POST { deny all; }
  client_body_temp_path      /path/to/app/tmp;
  client_body_in_file_only   on;
  client_body_buffer_size    128K;
  client_max_body_size       1000M;

  #this option is a quick hack to make sure files get saved on (ie this type of request goes to) on a specific server
  proxy_pass                 http://admin;
  proxy_pass_request_headers on;
  proxy_set_header           X-FILE $request_body_file;
  proxy_set_body             off;
  proxy_redirect             off;

  # might not need?
  proxy_read_timeout         3m;
}

This works, but the web server process (Mongrel) that handles the request has to sudo the temp file that comes through in headers['X-FILE'], before it can do anything with it. This is because the temp file comes through with 600 permissions.

I'm not happy with this approach, which requires us to edit the /etc/sudoers file to allow the web server user to do sudo chmod without a password. It feels very unsecure.

Is there a way, with the nginx config, to change the permissions on the temp file that is created, eg to 775?

EDIT: I just tried changing the value of the umask option in the nginx init config, then restarting nginx, but it didn't help. It had been at 0022, I changed it to 0002. In both cases it comes through with 600 permissions.

EDIT2: I also tried adding this line under the proxy_redirect line, in the nginx config.

proxy_store_access user:rw group:rw all:r;

But, it didn't make any difference - it still just has user:rw

Rapine answered 15/2, 2019 at 11:24 Comment(0)
H
5

Looking through the nginx source, it appears that the only mechanism that would modify the permissions of the temporary file is the request_body_file_group_access property of the request, which is consulted in ngx_http_write_request_body():

if (r->request_body_file_group_access) {
    tf->access = 0660;
}

But even that limits you to 0660 and it seems that it is not a user-settable property, only being utilized by the ngx_http_dav module.

The permissions are ultimately set in ngx_open_tempfile(), where they default to 0600:

fd = open((const char *) name, O_CREAT|O_EXCL|O_RDWR, access ? access : 0600);

So it seems that there is currently no configuration-based solution. If you're willing/able to build nginx from source, one possibility is to apply a simple patch to set the permissions to whatever you want in ngx_http_write_request_body():

+    tf->access = 0644;
+
     if (r->request_body_file_group_access) {
         tf->access = 0660;
     }

     rb->temp_file = tf;

I tested this and obtained the following, the first file having been uploaded without the modification, and the second file with it:

$ ls -al /tmp/upload/
total 984
drwxr-xr-x  2 nobody root     12288 Feb 18 13:42 .
drwxrwxrwt 16 root   root     12288 Feb 18 14:24 ..
-rw-------  1 nobody nogroup 490667 Feb 18 13:40 0000000001
-rw-r--r--  1 nobody nogroup 490667 Feb 18 13:42 0063184684
Houser answered 18/2, 2019 at 20:28 Comment(1)
I'm marking this correct as it seems the only solution is to rebuild nginx.Rapine
B
3

It seems, that it is not possible at the moment to configure the file permissions, but there is an official feature request.

The file permissions are always 0600 making the application unable to read the file at all. [...] This is currently an unsupported scenario: [Nginx] creates the temporary file with the default permissions [...] 0600 (unless request_body_file_group_access is set - but unfortunately that property is not settable).

The ticket was opened in October 2018 with minor priority.

Braeunig answered 18/2, 2019 at 20:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.