Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

file

nginx

temp

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

like image 248
Max Williams Avatar asked Feb 15 '19 11:02

Max Williams


2 Answers

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
like image 139
cody Avatar answered Oct 02 '22 10:10

cody


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.

like image 41
Samuel Philipp Avatar answered Oct 02 '22 10:10

Samuel Philipp