mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 10:33:51 +08:00
DEV: Quote values when constructing SQL (#18827)
All of these cases should already be safe, but still good to quote for "defense in depth".
This commit is contained in:
parent
a356e2fe30
commit
167181f4b7
|
@ -65,7 +65,7 @@ class GroupsController < ApplicationController
|
|||
|
||||
if !guardian.is_staff?
|
||||
# hide automatic groups from all non stuff to de-clutter page
|
||||
groups = groups.where("automatic IS FALSE OR groups.id = #{Group::AUTO_GROUPS[:moderators]}")
|
||||
groups = groups.where("automatic IS FALSE OR groups.id = ?", Group::AUTO_GROUPS[:moderators])
|
||||
type_filters.delete(:automatic)
|
||||
end
|
||||
|
||||
|
@ -129,7 +129,7 @@ class GroupsController < ApplicationController
|
|||
format.json do
|
||||
groups = Group.visible_groups(current_user)
|
||||
if !guardian.is_staff?
|
||||
groups = groups.where("automatic IS FALSE OR groups.id = #{Group::AUTO_GROUPS[:moderators]}")
|
||||
groups = groups.where("automatic IS FALSE OR groups.id = ?", Group::AUTO_GROUPS[:moderators])
|
||||
end
|
||||
|
||||
render_json_dump(
|
||||
|
|
|
@ -29,7 +29,7 @@ module Jobs
|
|||
|
||||
Emoji.clear_cache
|
||||
|
||||
Post.where("cooked LIKE '%#{Emoji.base_url}%'").find_each do |post|
|
||||
Post.where("cooked LIKE ?", "%#{Emoji.base_url}%").find_each do |post|
|
||||
post.rebake!
|
||||
end
|
||||
end
|
||||
|
|
|
@ -46,8 +46,9 @@ module Jobs
|
|||
# UserHistory for delete_user logs the user's IP. Note this is quite ugly but we don't
|
||||
# have a better way of querying on details right now.
|
||||
UserHistory.where(
|
||||
"action = :action AND details LIKE 'id: #{@user_id}\n%'",
|
||||
action: UserHistory.actions[:delete_user]
|
||||
"action = :action AND details LIKE :details",
|
||||
action: UserHistory.actions[:delete_user],
|
||||
details: "id: #{@user_id}\n%",
|
||||
).update_all(ip_address: new_ip)
|
||||
end
|
||||
|
||||
|
|
|
@ -41,9 +41,9 @@ module Jobs
|
|||
if upload.sha1.present?
|
||||
# TODO: Remove this check after UploadReferences records were created
|
||||
encoded_sha = Base62.encode(upload.sha1.hex)
|
||||
next if ReviewableQueuedPost.pending.where("payload->>'raw' LIKE '%#{upload.sha1}%' OR payload->>'raw' LIKE '%#{encoded_sha}%'").exists?
|
||||
next if Draft.where("data LIKE '%#{upload.sha1}%' OR data LIKE '%#{encoded_sha}%'").exists?
|
||||
next if UserProfile.where("bio_raw LIKE '%#{upload.sha1}%' OR bio_raw LIKE '%#{encoded_sha}%'").exists?
|
||||
next if ReviewableQueuedPost.pending.where("payload->>'raw' LIKE ? OR payload->>'raw' LIKE ?", "%#{upload.sha1}%", "%#{encoded_sha}%").exists?
|
||||
next if Draft.where("data LIKE ? OR data LIKE ?", "%#{upload.sha1}%", "%#{encoded_sha}%").exists?
|
||||
next if UserProfile.where("bio_raw LIKE ? OR bio_raw LIKE ?", "%#{upload.sha1}%", "%#{encoded_sha}%").exists?
|
||||
|
||||
upload.destroy
|
||||
else
|
||||
|
|
|
@ -23,12 +23,12 @@ module Jobs
|
|||
.where(staged: false)
|
||||
.joins(:user_option, :user_stat, :user_emails)
|
||||
.where("user_options.email_digests")
|
||||
.where("user_stats.bounce_score < #{SiteSetting.bounce_score_threshold}")
|
||||
.where("user_stats.bounce_score < ?", SiteSetting.bounce_score_threshold)
|
||||
.where("user_emails.primary")
|
||||
.where("COALESCE(last_emailed_at, '2010-01-01') <= CURRENT_TIMESTAMP - ('1 MINUTE'::INTERVAL * user_options.digest_after_minutes)")
|
||||
.where("COALESCE(user_stats.digest_attempted_at, '2010-01-01') <= CURRENT_TIMESTAMP - ('1 MINUTE'::INTERVAL * user_options.digest_after_minutes)")
|
||||
.where("COALESCE(last_seen_at, '2010-01-01') <= CURRENT_TIMESTAMP - ('1 MINUTE'::INTERVAL * user_options.digest_after_minutes)")
|
||||
.where("COALESCE(last_seen_at, '2010-01-01') >= CURRENT_TIMESTAMP - ('1 DAY'::INTERVAL * #{SiteSetting.suppress_digest_email_after_days})")
|
||||
.where("COALESCE(last_seen_at, '2010-01-01') >= CURRENT_TIMESTAMP - ('1 DAY'::INTERVAL * ?)", SiteSetting.suppress_digest_email_after_days)
|
||||
.order("user_stats.digest_attempted_at ASC NULLS FIRST")
|
||||
|
||||
# If the site requires approval, make sure the user is approved
|
||||
|
|
|
@ -480,7 +480,7 @@ class Upload < ActiveRecord::Base
|
|||
db = RailsMultisite::ConnectionManagement.current_db
|
||||
|
||||
scope = Upload.by_users
|
||||
.where("url NOT LIKE '%/original/_X/%' AND url LIKE '%/uploads/#{db}%'")
|
||||
.where("url NOT LIKE '%/original/_X/%' AND url LIKE ?", "%/uploads/#{db}%")
|
||||
.order(id: :desc)
|
||||
|
||||
scope = scope.limit(limit) if limit
|
||||
|
|
|
@ -446,10 +446,10 @@ class Search
|
|||
def post_action_type_filter(posts, post_action_type)
|
||||
posts.where("posts.id IN (
|
||||
SELECT pa.post_id FROM post_actions pa
|
||||
WHERE pa.user_id = #{@guardian.user.id} AND
|
||||
pa.post_action_type_id = #{post_action_type} AND
|
||||
WHERE pa.user_id = ? AND
|
||||
pa.post_action_type_id = ? AND
|
||||
deleted_at IS NULL
|
||||
)")
|
||||
)", @guardian.user.id, post_action_type)
|
||||
end
|
||||
|
||||
advanced_filter(/^in:(likes)$/i) do |posts, match|
|
||||
|
@ -464,17 +464,17 @@ class Search
|
|||
# search based on a RegisteredBookmarkable's #search_query method.
|
||||
advanced_filter(/^in:(bookmarks)$/i) do |posts, match|
|
||||
if @guardian.user
|
||||
posts.where(<<~SQL)
|
||||
posts.where(<<~SQL, @guardian.user.id)
|
||||
posts.id IN (
|
||||
SELECT bookmarkable_id FROM bookmarks
|
||||
WHERE bookmarks.user_id = #{@guardian.user.id} AND bookmarks.bookmarkable_type = 'Post'
|
||||
WHERE bookmarks.user_id = ? AND bookmarks.bookmarkable_type = 'Post'
|
||||
)
|
||||
SQL
|
||||
end
|
||||
end
|
||||
|
||||
advanced_filter(/^in:posted$/i) do |posts|
|
||||
posts.where("posts.user_id = #{@guardian.user.id}") if @guardian.user
|
||||
posts.where("posts.user_id = ?", @guardian.user.id) if @guardian.user
|
||||
end
|
||||
|
||||
advanced_filter(/^in:(created|mine)$/i) do |posts|
|
||||
|
@ -640,7 +640,7 @@ class Search
|
|||
advanced_filter(/^user:(.+)$/i) do |posts, match|
|
||||
user_id = User.where(staged: false).where('username_lower = ? OR id = ?', match.downcase, match.to_i).pluck_first(:id)
|
||||
if user_id
|
||||
posts.where("posts.user_id = #{user_id}")
|
||||
posts.where("posts.user_id = ?", user_id)
|
||||
else
|
||||
posts.where("1 = 0")
|
||||
end
|
||||
|
@ -656,7 +656,7 @@ class Search
|
|||
end
|
||||
|
||||
if user_id
|
||||
posts.where("posts.user_id = #{user_id}")
|
||||
posts.where("posts.user_id = ?", user_id)
|
||||
else
|
||||
posts.where("1 = 0")
|
||||
end
|
||||
|
@ -1043,13 +1043,13 @@ class Search
|
|||
|
||||
posts.where("topics.category_id in (?)", category_ids)
|
||||
elsif is_topic_search
|
||||
posts.where("topics.id = #{@search_context.id}")
|
||||
posts.where("topics.id = ?", @search_context.id)
|
||||
.order("posts.post_number #{@order == :latest ? "DESC" : ""}")
|
||||
elsif @search_context.is_a?(Tag)
|
||||
posts = posts
|
||||
.joins("LEFT JOIN topic_tags ON topic_tags.topic_id = topics.id")
|
||||
.joins("LEFT JOIN tags ON tags.id = topic_tags.tag_id")
|
||||
posts.where("tags.id = #{@search_context.id}")
|
||||
posts.where("tags.id = ?", @search_context.id)
|
||||
end
|
||||
else
|
||||
posts = categories_ignored(posts) unless @category_filter_matched
|
||||
|
@ -1243,8 +1243,8 @@ class Search
|
|||
end
|
||||
|
||||
if min_id > 0
|
||||
low_set = query.dup.where("post_search_data.post_id < #{min_id}")
|
||||
high_set = query.where("post_search_data.post_id >= #{min_id}")
|
||||
low_set = query.dup.where("post_search_data.post_id < ?", min_id)
|
||||
high_set = query.where("post_search_data.post_id >= ?", min_id)
|
||||
|
||||
return { default: wrap_rows(high_set), remaining: wrap_rows(low_set) }
|
||||
end
|
||||
|
|
|
@ -506,7 +506,7 @@ def recover_uploads_from_index(path)
|
|||
|
||||
db = RailsMultisite::ConnectionManagement.current_db
|
||||
cdn_path = SiteSetting.cdn_path("/uploads/#{db}").sub(/https?:/, "")
|
||||
Post.where("cooked LIKE '%#{cdn_path}%'").each do |post|
|
||||
Post.where("cooked LIKE ?", "%#{cdn_path}%").each do |post|
|
||||
regex = Regexp.new("((https?:)?#{Regexp.escape(cdn_path)}[^,;\\]\\>\\t\\n\\s)\"\']+)")
|
||||
uploads = []
|
||||
post.raw.scan(regex).each do |match|
|
||||
|
@ -663,9 +663,10 @@ def correct_inline_uploads
|
|||
verbose = ENV["VERBOSE"]
|
||||
|
||||
scope = Post.joins(:upload_references).distinct("posts.id")
|
||||
.where(<<~SQL)
|
||||
raw LIKE '%/uploads/#{RailsMultisite::ConnectionManagement.current_db}/original/%'
|
||||
SQL
|
||||
.where(
|
||||
"raw LIKE ?",
|
||||
"%/uploads/#{RailsMultisite::ConnectionManagement.current_db}/original/%",
|
||||
)
|
||||
|
||||
affected_posts_count = scope.count
|
||||
fixed_count = 0
|
||||
|
|
|
@ -31,7 +31,7 @@ def gather_uploads
|
|||
puts "", "Gathering uploads for '#{current_db}'...", ""
|
||||
|
||||
Upload.where("url ~ '^\/uploads\/'")
|
||||
.where("url !~ '^\/uploads\/#{current_db}'")
|
||||
.where("url !~ ?", "^\/uploads\/#{current_db}")
|
||||
.find_each do |upload|
|
||||
begin
|
||||
old_db = upload.url[/^\/uploads\/([^\/]+)\//, 1]
|
||||
|
|
|
@ -311,9 +311,9 @@ class TopicQuery
|
|||
def list_group_topics(group)
|
||||
list = default_results.where("
|
||||
topics.user_id IN (
|
||||
SELECT user_id FROM group_users gu WHERE gu.group_id = #{group.id.to_i}
|
||||
SELECT user_id FROM group_users gu WHERE gu.group_id = ?
|
||||
)
|
||||
")
|
||||
", group.id.to_i)
|
||||
|
||||
create_list(:group_topics, {}, list)
|
||||
end
|
||||
|
|
|
@ -118,20 +118,20 @@ class TopicQuery
|
|||
result = result.joins("INNER JOIN group_users gu ON gu.group_id = tag.group_id AND gu.user_id = #{user.id.to_i}")
|
||||
end
|
||||
elsif type == :user
|
||||
result = result.where("topics.id IN (SELECT topic_id FROM topic_allowed_users WHERE user_id = #{user.id.to_i})")
|
||||
result = result.where("topics.id IN (SELECT topic_id FROM topic_allowed_users WHERE user_id = ?)", user.id.to_i)
|
||||
elsif type == :all
|
||||
group_ids = group_with_messages_ids(user)
|
||||
|
||||
result =
|
||||
if group_ids.present?
|
||||
result.where(<<~SQL)
|
||||
result.where(<<~SQL, user.id.to_i, group_ids)
|
||||
topics.id IN (
|
||||
SELECT topic_id
|
||||
FROM topic_allowed_users
|
||||
WHERE user_id = #{user.id.to_i}
|
||||
WHERE user_id = ?
|
||||
UNION ALL
|
||||
SELECT topic_id FROM topic_allowed_groups
|
||||
WHERE group_id IN (#{group_ids.join(",")})
|
||||
WHERE group_id IN (?)
|
||||
)
|
||||
SQL
|
||||
else
|
||||
|
@ -259,10 +259,10 @@ class TopicQuery
|
|||
end
|
||||
|
||||
def have_posts_from_others(list, user)
|
||||
list.where(<<~SQL)
|
||||
list.where(<<~SQL, user.id.to_i)
|
||||
NOT (
|
||||
topics.participant_count = 1
|
||||
AND topics.user_id = #{user.id.to_i}
|
||||
AND topics.user_id = ?
|
||||
AND topics.moderator_posts_count = 0
|
||||
)
|
||||
SQL
|
||||
|
|
|
@ -58,7 +58,7 @@ task "poll:migrate_old_polls" => :environment do
|
|||
options = post.custom_fields["polls"]["poll"]["options"]
|
||||
# iterate over all votes
|
||||
PluginStoreRow.where(plugin_name: "poll")
|
||||
.where("key LIKE 'poll_vote_#{post_id}_%'")
|
||||
.where("key LIKE ?", "poll_vote_#{post_id}_%")
|
||||
.pluck(:key, :value)
|
||||
.each do |poll_vote_key, vote|
|
||||
# extract the user_id
|
||||
|
|
Loading…
Reference in New Issue
Block a user