statamic / cms

The core Laravel CMS Composer package
https://statamic.com
Other
3.89k stars 521 forks source link

Glide assets with parantheses in filename return 400 error #10168

Closed vluijkx closed 2 months ago

vluijkx commented 4 months ago

Bug description

Hi! We are currently experiencing an issue similar to https://github.com/statamic/cms/issues/10053. Images containing parentheses in their filenames, respond with Symfony-style 400 errors on our servers. An example can be found on this url:

https://staging.cell-0.com/img/asset/aW1hZ2VzL2JhY2tncm91bmQtKDEuanBn/background-%281.jpg?w=1500&fm=webp&s=283b81e74f43ece5f0175b4c01accde0

Note the %28 in the filename. Filenames without parentheses like these work fine.

CleanShot 2024-05-22 at 17 06 58

We've removed our NGINX rule targeting images because of https://github.com/statamic/cms/issues/10053. This is our current NGINX config:

server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    server_name localhost;
    root /var/www/public;
    index index.php index.html index.htm;

    client_max_body_size 100M;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location = /sitemap.xml {
        try_files $uri $uri/ /index.php$is_args$args;
        expires           -1;
    }

    location ~* \.(?:css|js)$ {
        access_log        off;
        log_not_found     off;
        expires           1y;
        add_header        Cache-Control "public";
    }

    location ~* \.(?:eot|woff|woff2|ttf|svg|otf) {
        access_log        off;
        log_not_found     off;
        expires           1y;
        add_header        Cache-Control "public";
        add_header        Access-Control-Allow-Origin *;

        types     {font/opentype otf;}
        types     {application/vnd.ms-fontobject eot;}
        types     {font/truetype ttf;}
        types     {application/font-woff woff;}
        types     {font/x-woff woff2;}
        types     {image/svg+xml svg svgz;}
    }

    location ~ \.php$ {
        try_files $uri /index.php =404;
        fastcgi_pass php-upstream;
        fastcgi_index index.php;
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        #fixes timeouts
        fastcgi_read_timeout 600;
        include fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }
}

How to reproduce

We are not sure what server configuration is causing this problem. You could try to run Statamic on a server with an NGINX configuration like ours and upload/view an image with parentheses in the filename. However, I doubt that the NGINX-config is the cause as there is no rule specifically targeting images.

Logs

No response

Environment

Environment
Application Name: Cell0
Laravel Version: 11.7.0
PHP Version: 8.2.6
Composer Version: -
Environment: staging
Debug Mode: OFF
URL: staging.cell-0.com
Maintenance Mode: OFF

Cache
Config: NOT CACHED
Events: NOT CACHED
Routes: NOT CACHED
Views: CACHED

Drivers
Broadcasting: log
Cache: statamic
Database: mysql
Logs: stack / single
Mail: mailgun
Queue: sync
Session: file

Sentry
Enabled: YES
Environment: staging
Laravel SDK Version: 4.5.1
PHP SDK Version: 4.7.0
Release: NOT SET
Sample Rate Errors: 100%
Sample Rate Performance Monitoring: 0%
Sample Rate Profiling: NOT SET
Send Default PII: DISABLED

Statamic
Addons: 3
Sites: 1
Stache Watcher: Disabled
Static Caching: Disabled
Version: 5.2.0 PRO

Statamic Addons
goldnead/statamic-toc: dev-support-statamic-5
rias/statamic-redirect: 3.7.1
statamic/eloquent-driver: 4.0.0

Statamic Eloquent Driver
Asset Containers: file
Assets: eloquent
Blueprints: file
Collection Trees: eloquent
Collections: file
Entries: eloquent
Forms: file
Global Sets: file
Global Variables: eloquent
Navigation Trees: eloquent
Navigations: file
Revisions: eloquent
Taxonomies: file
Terms: eloquent

Installation

Fresh statamic/statamic site via CLI

Additional details

No response

brianshepherd commented 4 months ago

I have the same issue β€” all works fine locally but not when deployed live.

duncanmcclean commented 2 months ago

I've just copied most of your Nginx config into a Forge server of mine, and I wasn't able to reproduce the issue. πŸ€”

@brianshepherd Are you able to share your Nginx config too?

vluijkx commented 2 months ago

It took a little while but we seem to have figured this one out πŸ™‚. The 400 error was caused by the Glide image signature check and our Nginx proxy setup.

Our proxy sent unescaped URL's to our main server. An URL like https://example.com/%28.jpg would be transformed to https://example.com/(.jpg by our proxy. As these paths differ, different Glide signatures would be generated.

We solved this by removing a / in our proxy Nginx config. Removing the slash causes URL's to be passed correctly.

location / {
-    proxy_pass http://{{ upstream_name }}/;
+    proxy_pass http://{{ upstream_name }};
}

Will close this for now. It might be interesting to build some kind of fallback for cases like this by always encoding the request url before generating a signature.