Why it happens?
It seems like an attempt to at least test for, or exploit, a remote code execution vulnerability. Potentially a generic one (targeting a platform other than Rails), or one that existed in earlier versions.
The actual error however stems from the fact that the request is an HTTP PUT with application/json headers, but the body isn’t a valid json.
To reproduce this on your dev environment:
curl -D - -X PUT --data "not json" -H "Content-Type: application/json" http://localhost:3000
More details
Rails action_dispatch tries to parse any json requests by passing the body to be decoded
# lib/action_dispatch/middleware/params_parser.rb
def parse_formatted_parameters(env)
...
strategy = @parsers[mime_type]
...
case strategy
when Proc
...
when :json
data = ActiveSupport::JSON.decode(request.body)
...
In this case, it’s not a valid JSON, and the error is raised, causing the server to report a 500.
Possible solutions
I’m not entirely sure what’s the best strategy to deal with this. There are several possibilities:
- you can block the IP address using
iptables - filter (
PUTor all) requests to/ali.txtwithin yournginxorapacheconfigs. - use a tool like the
rack-attackgem and apply the filter there. (see this rack-attack issue ) - use the
request_exception_handlergem to catch the error and handle it from within Rails (See this SO answer and this github issue) blockPUTrequests within Rails’routes.rbto all urls but those that are explicitly allowed. It looks like that in this case, the error is raised even before it reaches Rails’ routes – so this might not be possible.- Use the
rack-robustnessmiddleware and catch the json parse error with something like this configuration inconfig/application.rb - Write your own middleware. Something along the lines of the stuff on this post
I’m currently leaning towards options #3, #4 or #6. All of which might come in handy for other types of bots/scanners or other invalid requests that might pop-up in future…
Happy to hear what people think about the various alternative solutions