如何在Ruby on Rails的POST请求中防范无参数方法的SQL注入
Great question—let's break this down. First, let's clarify: your current get_auth_token implementation doesn't actually use any external parameters (it relies on server-side session data), so it's not directly vulnerable to SQL injection right now. But the fact that ZAP can add query parameters and the request still processes is a red flag because it opens up the possibility of accidental parameter usage later, or confusion about what the endpoint should accept.
Here are concrete steps to ensure this method rejects any external parameters entirely:
1. Explicitly Check for Empty Parameters in the Controller Method
Add a check at the start of your get_auth_token method to reject any request that includes query parameters or POST body parameters. This is a straightforward way to enforce that the endpoint only accepts "clean" requests:
def get_auth_token # Reject any request with external parameters head :bad_request unless params.empty? user = User.find_by(id: session[:user_id], disabled: false) if session[:user_id] if user token = AuthToken.issue(user_id: user.username) session[:user_id] = user.id session[:username] = user.username session[:project_id] = user.get_setting('xyz', nil) User.update(user.id, :token => token) # Don't forget to render/return your intended response here! end end end
The params.empty? check will catch both query parameters (like the ?query=... ZAP added) and any POST body parameters. If parameters exist, it returns a 400 Bad Request immediately, preventing the rest of the logic from running.
2. Restrict Parameters at the Route Level
Add a constraint to your route in config/routes.rb to only match requests with no query parameters. This blocks invalid requests before they even reach your controller:
Rails.application.routes.draw do # Only match POST requests to get_auth_token with no query parameters post 'api/sessions/get_auth_token', to: 'sessions#get_auth_token', constraints: ->(request) { request.query_parameters.empty? } end
This ensures that any request with a query string (like the one ZAP tested) won't match the route at all, resulting in a 404 Not Found instead of reaching your controller.
3. Double Down on Safe Database Practices
Even though your current code is safe (you're using Rails' parameterized queries with User.find_by and User.update), it's good to reinforce these habits to avoid future risks:
- Never directly interpolate user-controlled data into SQL strings (always use Rails' hash conditions or
wherewith placeholders) - Avoid accessing
paramsvalues in database queries unless you explicitly validate and sanitize them first
Why ZAP's Request Worked
Rails automatically parses query parameters and POST bodies into the params hash regardless of whether your controller method accepts arguments. This is normal behavior, but it's up to you to enforce that your endpoint doesn't accept or use those parameters.
内容的提问来源于stack exchange,提问作者Hemant Goyal

