Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stop using PATCH #6294

Open
simoheinonen opened this issue May 6, 2024 · 18 comments
Open

Stop using PATCH #6294

simoheinonen opened this issue May 6, 2024 · 18 comments

Comments

@simoheinonen
Copy link
Contributor

The boolean toggles are broken for our application because nginx doesn't have PATCH enabled by default and it's somewhat complicated to change.

Modern servers do not allow for PUT DELETE PATCH requests to be available by default.

https://gridpane.com/kb/making-nginx-accept-put-delete-and-patch-verbs/

Thoughts on making it use POST instead?

@Seb33300
Copy link
Contributor

Seb33300 commented May 6, 2024

We may be able to replace the PATCH method by a POST + add a _method param with the value PATCH so Symfony will interpret it as a PATCH method internally.
See: https://symfony.com/doc/current/forms.html#changing-the-action-and-http-method

@zorn-v
Copy link
Contributor

zorn-v commented May 13, 2024

"Stop using PATCH" - "our application is broken"
Looks like hysteria.

"because nginx doesn't have PATCH enabled by default" - it is just a blatant lie.

zorn@zorn-PC:~$ curl -v -XPATCH localhost:8000
* Host localhost:8000 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:8000...
* Connected to localhost (::1) port 8000
> PATCH / HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/8.5.0
> Accept: */*
> 
< HTTP/1.1 302 Found
< Server: nginx/1.24.0
< Content-Type: text/html; charset=utf-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< X-Powered-By: PHP/8.2.18
< Cache-Control: max-age=0, must-revalidate, private
< Date: Mon, 13 May 2024 18:40:15 GMT
< Location: http://localhost:8000/login
< X-Debug-Token: 6bce7e
< X-Debug-Token-Link: http://localhost:8000/_profiler/6bce7e
< X-Robots-Tag: noindex
< Expires: Mon, 13 May 2024 18:40:15 GMT< 
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="refresh" content="0;url='http://localhost:8000/login'" />

        <title>Redirecting to http://localhost:8000/login</title>
    </head>
    <body>
        Redirecting to <a href="http://localhost:8000/login">http://localhost:8000/login</a>.
    </body>
* Connection #0 to host localhost left intact
</html>

As you can see Server: nginx/1.24.0 - not so old )

@zorn-v
Copy link
Contributor

zorn-v commented May 13, 2024

And what you mean "not enabled" by the way ?

@Geolim4
Copy link
Contributor

Geolim4 commented May 13, 2024

"Stop using PATCH" - "our application is broken" Looks like hysteria.

"because nginx doesn't have PATCH enabled by default" - it is just a blatant lie.

zorn@zorn-PC:~$ curl -v -XPATCH localhost:8000
* Host localhost:8000 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:8000...
* Connected to localhost (::1) port 8000
> PATCH / HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/8.5.0
> Accept: */*
> 
< HTTP/1.1 302 Found
< Server: nginx/1.24.0
< Content-Type: text/html; charset=utf-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< X-Powered-By: PHP/8.2.18
< Cache-Control: max-age=0, must-revalidate, private
< Date: Mon, 13 May 2024 18:40:15 GMT
< Location: http://localhost:8000/login
< X-Debug-Token: 6bce7e
< X-Debug-Token-Link: http://localhost:8000/_profiler/6bce7e
< X-Robots-Tag: noindex
< Expires: Mon, 13 May 2024 18:40:15 GMT< 
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="refresh" content="0;url='http://localhost:8000/login'" />

        <title>Redirecting to http://localhost:8000/login</title>
    </head>
    <body>
        Redirecting to <a href="http://localhost:8000/login">http://localhost:8000/login</a>.
    </body>
* Connection #0 to host localhost left intact
</html>

As you can see Server: nginx/1.24.0 - not so old )

Many modern hosts (like o2switch and others shared hosts plans) are disabling PATCH/PUT/DELETE verbs by default, except if you make a ticket that they can charge you up to an hour to make it work, so yes, there's should be an option somewhere to allow the use of internal "_method" property from Symfony.

@zorn-v
Copy link
Contributor

zorn-v commented May 14, 2024

Many modern hosts (like o2switch and others shared hosts plans)

So just not use them, no ?
Why they should dictate the rules ?

@simoheinonen
Copy link
Contributor Author

Yeah we solved this by just enabling it in nginx but I think it wouldn't hurt if people wouldn't have to tinker with server/host to get this feature to work

@Geolim4
Copy link
Contributor

Geolim4 commented May 14, 2024

Many modern hosts (like o2switch and others shared hosts plans)

So just not use them, no ? Why they should dictate the rules ?

Because you generally discover this kind of thing after buying your hosting. It's a technical detail that they don't specify ....

@Geolim4
Copy link
Contributor

Geolim4 commented May 14, 2024

Yeah we solved this by just enabling it in nginx but I think it wouldn't hurt if people wouldn't have to tinker with server/host to get this feature to work

Especially when you don't have hand on server configuration on shared hosting or when the HTTP verb is firewall-filtered before nginx being aware of the http request.

@simoheinonen
Copy link
Contributor Author

"Stop using PATCH" - "our application is broken" Looks like hysteria.

"because nginx doesn't have PATCH enabled by default" - it is just a blatant lie.

zorn@zorn-PC:~$ curl -v -XPATCH localhost:8000
* Host localhost:8000 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:8000...
* Connected to localhost (::1) port 8000
> PATCH / HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/8.5.0
> Accept: */*
> 
< HTTP/1.1 302 Found
< Server: nginx/1.24.0
< Content-Type: text/html; charset=utf-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< X-Powered-By: PHP/8.2.18
< Cache-Control: max-age=0, must-revalidate, private
< Date: Mon, 13 May 2024 18:40:15 GMT
< Location: http://localhost:8000/login
< X-Debug-Token: 6bce7e
< X-Debug-Token-Link: http://localhost:8000/_profiler/6bce7e
< X-Robots-Tag: noindex
< Expires: Mon, 13 May 2024 18:40:15 GMT< 
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="refresh" content="0;url='http://localhost:8000/login'" />

        <title>Redirecting to http://localhost:8000/login</title>
    </head>
    <body>
        Redirecting to <a href="http://localhost:8000/login">http://localhost:8000/login</a>.
    </body>
* Connection #0 to host localhost left intact
</html>

As you can see Server: nginx/1.24.0 - not so old )

Your console log only shows you made a PATCH request, not if nginx handled it as such.

@zorn-v
Copy link
Contributor

zorn-v commented May 15, 2024

Your console log only shows you made a PATCH request, not if nginx handled it as such.

How nginx should handled it ? It can do something like

if ($request_method = "PATCH") {
  return 405; # method not allowed
}

in config, but it is NOT "by default"

@simoheinonen
Copy link
Contributor Author

Your console log only shows you made a PATCH request, not if nginx handled it as such.

How nginx should handled it ? It can do something like

if ($request_method = "PATCH") {
  return 405; # method not allowed
}

in config, but it is NOT "by default"

If you open the Symfony profiler you should see PATCH as the method. For us nginx was converting them to GET by default.

@zorn-v
Copy link
Contributor

zorn-v commented May 15, 2024

Well, ok.
изображение

server {
    root /var/www/html/public;

    client_max_body_size 50M;

    location / {
        # try to serve file directly, fallback to index.php
        try_files $uri /index.php$is_args$args;
    }

    location ~ ^/index\.php(/|$) {
        fastcgi_pass php:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;

        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;

        internal;
    }

    # return 404 for all other php files not matching the front controller
    # this prevents access to other php files you don't want to be accessible.
    location ~ \.php$ {
        return 404;
    }
}

@Seb33300
Copy link
Contributor

We may be able to replace the PATCH method by a POST + add a _method param with the value PATCH so Symfony will interpret it as a PATCH method internally. See: https://symfony.com/doc/current/forms.html#changing-the-action-and-http-method

Just realized that the http_method_override option allowing this to work is no longer enabled by default since Symfony 7.0

@zorn-v
Copy link
Contributor

zorn-v commented May 21, 2024

And this is right. Dubious feature.
If you can't configure server, framework should not introduce "crutches and props"

@Geolim4
Copy link
Contributor

Geolim4 commented May 21, 2024

And this is right. Dubious feature. If you can't configure server, framework should not introduce "crutches and props"

Do you realize that not everyone can afford a dedicated server and that most shared hosting, still today, keep blocking PATCH/PUT/DELETE verbs for security. I agree that this is a dumb pretext, but you can do shit in this case without having a fallback proposed by Symfony to make the software working by a little and universal tweak (lot of frameworks are support this tweak today).

Interoperability concept exists for this kind of precise case :/

@zorn-v
Copy link
Contributor

zorn-v commented May 21, 2024

keep blocking PATCH/PUT/DELETE verbs for security

Really ? For security ? How ?

lot of frameworks are support this tweak today

Not support ugly providers and they allow PATCH/PUT/DELETE (fact) or close their business )

PS. Why ugly solutions should be in framework anyway ?

@Geolim4
Copy link
Contributor

Geolim4 commented May 21, 2024

Really ? For security ? How ?

That's literally the same excuse written by the support of 2 different hosting provider for "DDOS fighting purpose", I know its crap, but this is why we must keep supporting this tweak from Symfony. It does not change that much the security or maintainability of the code and keep a high level of Interoperability.

Not support ugly providers and they allow PATCH/PUT/DELETE (fact) or close their business )

The hidden "_method" field is known across many frameworks to bypass inaccessible CRUD verbs blocked by cheap hosting providers :)

@zorn-v
Copy link
Contributor

zorn-v commented May 21, 2024

I know its crap

But push it farther )

The hidden "_method" is known across many framework to bypass inaccessible CRUD verb blocked by cheap hosting providers :)

Sorry, does not use it. But argument )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants