discourse/app/controllers/post_action_users_controller.rb
Alan Guo Xiang Tan bfc3132bb2
SECURITY: Impose a upper bound on limit params in various controllers
What is the problem here?

In multiple controllers, we are accepting a `limit` params but do not
impose any upper bound on the values being accepted. Without an upper
bound, we may be allowing arbituary users from generating DB queries
which may end up exhausing the resources on the server.

What is the fix here?

A new `fetch_limit_from_params` helper method is introduced in
`ApplicationController` that can be used by controller actions to safely
get the limit from the params as a default limit and maximum limit has
to be set. When an invalid limit params is encountered, the server will
respond with the 400 response code.
2023-07-28 12:53:46 +01:00

59 lines
1.7 KiB
Ruby

# frozen_string_literal: true
class PostActionUsersController < ApplicationController
INDEX_LIMIT = 200
def index
params.require(:post_action_type_id)
params.require(:id)
post_action_type_id = params[:post_action_type_id].to_i
page = params[:page].to_i
page_size = fetch_limit_from_params(default: INDEX_LIMIT, max: INDEX_LIMIT)
# Find the post, and then determine if they can see the post (if deleted)
post = Post.with_deleted.where(id: params[:id].to_i).first
guardian.ensure_can_see!(post)
unknown_user_ids = Set.new
if current_user.present?
result = DB.query_single(<<~SQL, user_id: current_user.id)
SELECT mu.muted_user_id AS id FROM muted_users AS mu WHERE mu.user_id = :user_id
UNION
SELECT iu.ignored_user_id AS id FROM ignored_users AS iu WHERE iu.user_id = :user_id
SQL
unknown_user_ids.merge(result)
end
post_actions =
post
.post_actions
.where(post_action_type_id: post_action_type_id)
.includes(:user)
.offset(page * page_size)
.order("post_actions.created_at ASC")
.limit(page_size)
if !guardian.can_see_post_actors?(post.topic, post_action_type_id)
raise Discourse::InvalidAccess unless current_user
post_actions = post_actions.where(user_id: current_user.id)
end
action_type = PostActionType.types.key(post_action_type_id)
total_count = post["#{action_type}_count"].to_i
data = {
post_action_users:
serialize_data(
post_actions.to_a,
PostActionUserSerializer,
unknown_user_ids: unknown_user_ids,
),
}
data[:total_rows_post_action_users] = total_count if total_count > page_size
render_json_dump(data)
end
end