From dd1614434554c29a826f7cdf4d9a1f4255a8c1dd Mon Sep 17 00:00:00 2001 From: Richard Towers Date: Wed, 15 May 2024 16:07:31 +0100 Subject: [PATCH] Reject HTTP requests using a non-standard method At the moment, request with methods such as DEBUG or PROPFIND will be passed through the CDN and hit the origin, where they'll be rejected by nginx as 501s. This means we end up with a bunch of 5XX responses in our metrics and logs, even though there's nothing wrong with our system. $ curl -w '\n%{http_code}\n' -X DEBUG https://www.gov.uk DEBUG method is not supported 501 This commit rejects these at the CDN, and uses the 405 HTTP status instead of 501 to avoid polluting the CDN metrics with unactionable 5XXs. I've included all standard HTTP methods, and additionally FASTLYPURGE which is how the non-standard PURGE method appears in VCL[1]. I've also checked which non-standard HTTP methods have appeared in requests so far in May: select method, count(*) from fastly_logs.govuk_www where year=2024 and month=5 and method not in ('GET','HEAD','POST','PUT','DELETE','CONNECT','OPTIONS','TRACE','PATCH','FASTLYPURGE') group by method order by count(*) desc # method _col1 1 DEBUG 23086 2 TENB 14458 3 PROPFIND 7700 4 HEADX 4029 5 TRACK 3 6 BVRPGMCC 1 7 CET 1 8 get 1 9 INDEX 1 ... which is enough evidence for me that this won't block anything unintentionally. Temporarily, I've restricted this to integration so I can test it, instead of just yeeting it into production. [1]: https://www.fastly.com/documentation/reference/vcl/variables/client-request/req-method/ --- modules/www/www.vcl.tftpl | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/modules/www/www.vcl.tftpl b/modules/www/www.vcl.tftpl index 361aab7..465b040 100644 --- a/modules/www/www.vcl.tftpl +++ b/modules/www/www.vcl.tftpl @@ -199,6 +199,14 @@ sub vcl_recv { if (!req.http.Fastly-SSL) { error 801 "Force SSL"; } + + # Temporary if statement to test changes before going to production: + %{ if environment == "integration" } + # Reject HTTP requests which don't use a standard method + if (req.method !~ "^(GET|HEAD|POST|PUT|DELETE|CONNECT|OPTIONS|TRACE|PATCH|FASTLYPURGE)") { + error 805 "Method not allowed"; + } + %{ endif ~} %{ if private_extra_vcl_recv != "" ~} ${private_extra_vcl_recv} @@ -559,6 +567,32 @@ sub vcl_error { return (deliver); } + if (obj.status == 805) { + set obj.status = 405; + set obj.response = "Method not allowed"; + set obj.http.Fastly-Backend-Name = "force_method_not_allowed"; + + synthetic {" + + + + Welcome to GOV.UK + + + +

GOV.UK

+

We cannot find the page you're looking for. Please try searching on GOV.UK.

+ + "}; + + return (deliver); + } + ${indent(2, file("${module_path}/../shared/_security_txt_response.vcl"))} %{ if basic_authentication != null }