#2373 closed defect (invalid)
1.23.0 - Spaces in path name result in 400 error when using a proxy server to generate thumbnails — at Version 2
Reported by: | Owned by: | ||
---|---|---|---|
Priority: | minor | Milestone: | |
Component: | nginx-core | Version: | 1.23.x |
Keywords: | 1.23.0, spaces, %20, 400, thumbnails, proxy | Cc: | robjbrain@… |
uname -a: | Linux test 5.15.0-43-generic #46-Ubuntu SMP Tue Jul 12 10:30:17 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux | ||
nginx -V: |
nginx version: nginx/1.18.0
nginx version: nginx/1.23.0 |
Description (last modified by )
The following server works perfectly on 1.18.0 but on 1.23.0 results in a 400 error for paths with a space in the name e.g.
domain/test dir/image.png = 400 error
domain/testdir/image.png = Works
There are no entries in either "nginx-thumbnails-error.log" or "nginx-thumbnails-localhost-error.log".
There is an entry in "nginx-thumbnails-localhost-access.log" but not in "nginx-thumbnails-access.log".
In requests that resolve (i.e. without spaces) there are entries in both access logs.
When the request fails the user agent is missing from "nginx-thumbnails-localhost-access.log" (no idea if that's relevant).
server { # Internal image resizing server. server_name localhost; listen 8888; access_log /var/log/nginx/nginx-thumbnails-localhost-access.log; error_log /var/log/nginx/nginx-thumbnails-localhost-error.log error; location ~ "^/width/(?<width>\d+)/(?<image>.+)$" { alias /home/$image; image_filter resize $width -; image_filter_jpeg_quality 95; image_filter_buffer 8M; } location ~ "^/height/(?<height>\d+)/(?<image>.+)$" { alias /home/$image; image_filter resize - $height; image_filter_jpeg_quality 95; image_filter_buffer 8M; } location ~ "^/resize/(?<width>\d+)/(?<height>\d+)/(?<image>.*)$" { alias /home/$image; image_filter resize $width $height; image_filter_jpeg_quality 95; image_filter_buffer 8M; } location ~ "^/crop/(?<width>\d+)/(?<height>\d+)/(?<image>.*)$" { alias /home/$image; image_filter crop $width $height; image_filter_jpeg_quality 95; image_filter_buffer 8M; } } proxy_cache_path /tmp/nginx-thumbnails-cache/ levels=1:2 keys_zone=thumbnails:10m inactive=24h max_size=1000m; server { listen 80; listen [::]:80; server_name ; access_log /var/log/nginx/nginx-thumbnails-access.log; error_log /var/log/nginx/nginx-thumbnails-error.log error; location ~ "^/width/(?<width>\d+)/(?<image>.+)$" { # Proxy to internal image resizing server. proxy_pass localhost:8888/width/$width/$image; proxy_cache thumbnails; proxy_cache_valid 200 24h; } location ~ "^/height/(?<height>\d+)/(?<image>.+)$" { # Proxy to internal image resizing server. proxy_pass localhost:8888/height/$height/$image; proxy_cache thumbnails; proxy_cache_valid 200 24h; } location ~ "^/resize/(?<width>\d+)/(?<height>\d+)/(?<image>.+)$" { # Proxy to internal image resizing server. proxy_pass localhost:8888/resize/$width/$height/$image; proxy_cache thumbnails; proxy_cache_valid 200 24h; } location ~ "^/crop/(?<width>\d+)/(?<height>\d+)/(?<image>.+)$" { # Proxy to internal image resizing server. proxy_pass localhost:8888/crop/$width/$height/$image; proxy_cache thumbnails; proxy_cache_valid 200 24h; } }
A test for this error can be created very easily, I did so on an Ubuntu 22 Digital Ocean Droplet.
apt update
apt install nginx
ufw allow 'Nginx Full'
nginx -v
nginx version: nginx/1.18.0
nano /etc/nginx/sites-available/thumbnails
service nginx restart
mkdir /home/testdir
mkdir /home/"test dir"
curl "path/to/image" > /home/testdir/nginx.png
curl "path/to/image" > /home/test dir/nginx.png
Test "/resize/200/200/testdir/nginx.png" and "/resize/200/200/test dir/nginx.png" in the browser and see they both work.
apt-add-repository ppa:ondrej/nginx-mainline -y
apt update
apt install nginx
nginx -v
nginx version: nginx/1.23.0
service nginx restart
Test the two urls in the browser again and you will be able to see that the image directory "test dir" results in a 400 error.
Change History (2)
comment:1 by , 3 years ago
comment:2 by , 3 years ago
Description: | modified (diff) |
---|---|
Resolution: | → invalid |
Status: | new → closed |
That's because spaces are not allowed in request URIs, and since nginx 1.21.1 these are rejected. Quoting CHANGES:
*) Change: now nginx always returns an error if spaces or control characters are used in the request line.
See ticket #196 for details.
Your configuration results in incorrect URIs being used during proxying, as it uses named captures from $uri, which is unescaped, in proxy_pass, which expects all variables to be properly escaped if used with variables.
As far as I can see, in your configuration the most simple fix would be to change all proxy_pass
directives to don't use any URI components, that is:
location ~ "/width/(?<width>\d+)/(?<image>.+)$" { proxy_pass http://localhost:8888; proxy_cache thumbnails; proxy_cache_valid 200 24h; }
This way, nginx will pass URIs from the client request unmodified (and properly escaped), and these match URIs you've been trying to reconstruct with variables.
Hope this helps.
Please note it should say "proxy_pass http://localhost:8888" but it would not let me through the spam filter due to posting external links.