mirror of
https://github.com/discourse/discourse.git
synced 2025-06-06 03:06:53 +08:00
FIX: add a basic validator for topic params
This cuts down on log noise when people try out sql injection
This commit is contained in:
@ -371,7 +371,12 @@ class ListController < ApplicationController
|
|||||||
params[:tags] = [params[:tag_id].parameterize] if params[:tag_id].present? && guardian.can_tag_pms?
|
params[:tags] = [params[:tag_id].parameterize] if params[:tag_id].present? && guardian.can_tag_pms?
|
||||||
|
|
||||||
TopicQuery.public_valid_options.each do |key|
|
TopicQuery.public_valid_options.each do |key|
|
||||||
options[key] = params[key]
|
if params.key?(key)
|
||||||
|
val = options[key] = params[key]
|
||||||
|
if !TopicQuery.validate?(key, val)
|
||||||
|
raise Discourse::InvalidParameters.new key
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# hacky columns get special handling
|
# hacky columns get special handling
|
||||||
|
@ -10,6 +10,34 @@ require_dependency 'avatar_lookup'
|
|||||||
|
|
||||||
class TopicQuery
|
class TopicQuery
|
||||||
|
|
||||||
|
def self.validators
|
||||||
|
@validators ||= begin
|
||||||
|
|
||||||
|
zero_or_more = lambda do |x|
|
||||||
|
Integer === x && x >= 0
|
||||||
|
end
|
||||||
|
|
||||||
|
array_zero_or_more = lambda do |x|
|
||||||
|
Array === x && x.length > 0 && x.all? { |i| Integer === i && i >= 0 }
|
||||||
|
end
|
||||||
|
|
||||||
|
{
|
||||||
|
max_posts: zero_or_more,
|
||||||
|
exclude_category_ids: array_zero_or_more,
|
||||||
|
min_posts: zero_or_more,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.validate?(option, value)
|
||||||
|
|
||||||
|
if fn = validators[option.to_sym]
|
||||||
|
fn.call(value)
|
||||||
|
else
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def self.public_valid_options
|
def self.public_valid_options
|
||||||
@public_valid_options ||=
|
@public_valid_options ||=
|
||||||
%i(page
|
%i(page
|
||||||
|
@ -16,6 +16,17 @@ RSpec.describe ListController do
|
|||||||
expect(response.status).to eq(200)
|
expect(response.status).to eq(200)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "does not return a 500 for invalid input" do
|
||||||
|
get "/latest?exclude_category_ids[]=bob"
|
||||||
|
expect(response.status).to eq(400)
|
||||||
|
|
||||||
|
get "/latest?min_posts=bob"
|
||||||
|
expect(response.status).to eq(400)
|
||||||
|
|
||||||
|
get "/latest?max_posts=bob"
|
||||||
|
expect(response.status).to eq(400)
|
||||||
|
end
|
||||||
|
|
||||||
it "doesn't throw an error with page params as an array" do
|
it "doesn't throw an error with page params as an array" do
|
||||||
get "/#{Discourse.anonymous_filters[1]}", params: { page: ['7'] }
|
get "/#{Discourse.anonymous_filters[1]}", params: { page: ['7'] }
|
||||||
expect(response.status).to eq(200)
|
expect(response.status).to eq(200)
|
||||||
|
Reference in New Issue
Block a user