Sanitise parameters used in URL generation

This commit is contained in:
Tom Hughes 2017-06-02 20:26:33 +01:00
parent 4ef7b2c651
commit 80d27a7fae
6 changed files with 48 additions and 44 deletions

View file

@ -250,46 +250,48 @@ class ChangesetController < ApplicationController
## ##
# list non-empty changesets in reverse chronological order # list non-empty changesets in reverse chronological order
def list def list
if request.format == :atom && params[:max_id] @params = params.permit(:display_name, :bbox, :friends, :nearby, :max_id, :list)
redirect_to url_for(params.merge(:max_id => nil)), :status => :moved_permanently
if request.format == :atom && @params[:max_id]
redirect_to url_for(@params.merge(:max_id => nil)), :status => :moved_permanently
return return
end end
if params[:display_name] if @params[:display_name]
user = User.find_by(:display_name => params[:display_name]) user = User.find_by(:display_name => @params[:display_name])
if !user || !user.active? if !user || !user.active?
render_unknown_user params[:display_name] render_unknown_user @params[:display_name]
return return
end end
end end
if (params[:friends] || params[:nearby]) && !@user if (@params[:friends] || @params[:nearby]) && !@user
require_user require_user
return return
end end
if request.format == :html && !params[:list] if request.format == :html && !@params[:list]
require_oauth require_oauth
render :action => :history, :layout => map_layout render :action => :history, :layout => map_layout
else else
changesets = conditions_nonempty(Changeset.all) changesets = conditions_nonempty(Changeset.all)
if params[:display_name] if @params[:display_name]
changesets = if user.data_public? || user == @user changesets = if user.data_public? || user == @user
changesets.where(:user_id => user.id) changesets.where(:user_id => user.id)
else else
changesets.where("false") changesets.where("false")
end end
elsif params[:bbox] elsif @params[:bbox]
changesets = conditions_bbox(changesets, BoundingBox.from_bbox_params(params)) changesets = conditions_bbox(changesets, BoundingBox.from_bbox_params(params))
elsif params[:friends] && @user elsif @params[:friends] && @user
changesets = changesets.where(:user_id => @user.friend_users.identifiable) changesets = changesets.where(:user_id => @user.friend_users.identifiable)
elsif params[:nearby] && @user elsif @params[:nearby] && @user
changesets = changesets.where(:user_id => @user.nearby) changesets = changesets.where(:user_id => @user.nearby)
end end
if params[:max_id] if @params[:max_id]
changesets = changesets.where("changesets.id <= ?", params[:max_id]) changesets = changesets.where("changesets.id <= ?", @params[:max_id])
end end
@edits = changesets.order("changesets.id DESC").limit(20).preload(:user, :changeset_tags, :comments) @edits = changesets.order("changesets.id DESC").limit(20).preload(:user, :changeset_tags, :comments)

View file

@ -10,22 +10,21 @@ class GeocoderController < ApplicationController
before_action :require_oauth, :only => [:search] before_action :require_oauth, :only => [:search]
def search def search
normalize_params @params = normalize_params
@sources = [] @sources = []
if params[:lat] && params[:lon] if @params[:lat] && @params[:lon]
@sources.push "latlon" @sources.push "latlon"
@sources.push "osm_nominatim_reverse" @sources.push "osm_nominatim_reverse"
@sources.push "geonames_reverse" if defined?(GEONAMES_USERNAME) @sources.push "geonames_reverse" if defined?(GEONAMES_USERNAME)
elsif params[:query] elsif @params[:query]
if params[:query] =~ /^\d{5}(-\d{4})?$/ if @params[:query] =~ /^\d{5}(-\d{4})?$/
@sources.push "us_postcode" @sources.push "us_postcode"
@sources.push "osm_nominatim" @sources.push "osm_nominatim"
elsif params[:query] =~ /^(GIR 0AA|[A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]|[A-HK-Y][0-9]([0-9]|[ABEHMNPRV-Y]))|[0-9][A-HJKS-UW])\s*[0-9][ABD-HJLNP-UW-Z]{2})$/i elsif @params[:query] =~ /^(GIR 0AA|[A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]|[A-HK-Y][0-9]([0-9]|[ABEHMNPRV-Y]))|[0-9][A-HJKS-UW])\s*[0-9][ABD-HJLNP-UW-Z]{2})$/i
@sources.push "uk_postcode" @sources.push "uk_postcode"
@sources.push "osm_nominatim" @sources.push "osm_nominatim"
elsif params[:query] =~ /^[A-Z]\d[A-Z]\s*\d[A-Z]\d$/i elsif @params[:query] =~ /^[A-Z]\d[A-Z]\s*\d[A-Z]\d$/i
@sources.push "ca_postcode" @sources.push "ca_postcode"
@sources.push "osm_nominatim" @sources.push "osm_nominatim"
else else
@ -316,29 +315,30 @@ class GeocoderController < ApplicationController
end end
def normalize_params def normalize_params
query = params[:query] if query = params[:query]
return unless query query.strip!
query.strip! if latlon = query.match(/^([NS])\s*(\d{1,3}(\.\d*)?)\W*([EW])\s*(\d{1,3}(\.\d*)?)$/).try(:captures) # [NSEW] decimal degrees
params.merge!(nsew_to_decdeg(latlon)).delete(:query)
elsif latlon = query.match(/^(\d{1,3}(\.\d*)?)\s*([NS])\W*(\d{1,3}(\.\d*)?)\s*([EW])$/).try(:captures) # decimal degrees [NSEW]
params.merge!(nsew_to_decdeg(latlon)).delete(:query)
if latlon = query.match(/^([NS])\s*(\d{1,3}(\.\d*)?)\W*([EW])\s*(\d{1,3}(\.\d*)?)$/).try(:captures) # [NSEW] decimal degrees elsif latlon = query.match(/^([NS])\s*(\d{1,3})°?\s*(\d{1,3}(\.\d*)?)?[']?\W*([EW])\s*(\d{1,3})°?\s*(\d{1,3}(\.\d*)?)?[']?$/).try(:captures) # [NSEW] degrees, decimal minutes
params.merge!(nsew_to_decdeg(latlon)).delete(:query) params.merge!(ddm_to_decdeg(latlon)).delete(:query)
elsif latlon = query.match(/^(\d{1,3}(\.\d*)?)\s*([NS])\W*(\d{1,3}(\.\d*)?)\s*([EW])$/).try(:captures) # decimal degrees [NSEW] elsif latlon = query.match(/^(\d{1,3})°?\s*(\d{1,3}(\.\d*)?)?[']?\s*([NS])\W*(\d{1,3})°?\s*(\d{1,3}(\.\d*)?)?[']?\s*([EW])$/).try(:captures) # degrees, decimal minutes [NSEW]
params.merge!(nsew_to_decdeg(latlon)).delete(:query) params.merge!(ddm_to_decdeg(latlon)).delete(:query)
elsif latlon = query.match(/^([NS])\s*(\d{1,3})°?\s*(\d{1,3}(\.\d*)?)?[']?\W*([EW])\s*(\d{1,3})°?\s*(\d{1,3}(\.\d*)?)?[']?$/).try(:captures) # [NSEW] degrees, decimal minutes elsif latlon = query.match(/^([NS])\s*(\d{1,3})°?\s*(\d{1,2})[']?\s*(\d{1,3}(\.\d*)?)?["″]?\W*([EW])\s*(\d{1,3})°?\s*(\d{1,2})[']?\s*(\d{1,3}(\.\d*)?)?["″]?$/).try(:captures) # [NSEW] degrees, minutes, decimal seconds
params.merge!(ddm_to_decdeg(latlon)).delete(:query) params.merge!(dms_to_decdeg(latlon)).delete(:query)
elsif latlon = query.match(/^(\d{1,3})°?\s*(\d{1,3}(\.\d*)?)?[']?\s*([NS])\W*(\d{1,3})°?\s*(\d{1,3}(\.\d*)?)?[']?\s*([EW])$/).try(:captures) # degrees, decimal minutes [NSEW] elsif latlon = query.match(/^(\d{1,3})°?\s*(\d{1,2})[']?\s*(\d{1,3}(\.\d*)?)?["″]\s*([NS])\W*(\d{1,3})°?\s*(\d{1,2})[']?\s*(\d{1,3}(\.\d*)?)?["″]?\s*([EW])$/).try(:captures) # degrees, minutes, decimal seconds [NSEW]
params.merge!(ddm_to_decdeg(latlon)).delete(:query) params.merge!(dms_to_decdeg(latlon)).delete(:query)
elsif latlon = query.match(/^([NS])\s*(\d{1,3})°?\s*(\d{1,2})[']?\s*(\d{1,3}(\.\d*)?)?["″]?\W*([EW])\s*(\d{1,3})°?\s*(\d{1,2})[']?\s*(\d{1,3}(\.\d*)?)?["″]?$/).try(:captures) # [NSEW] degrees, minutes, decimal seconds elsif latlon = query.match(/^\s*([+-]?\d+(\.\d*)?)\s*[\s,]\s*([+-]?\d+(\.\d*)?)\s*$/)
params.merge!(dms_to_decdeg(latlon)).delete(:query) params.merge!(:lat => latlon[1].to_f, :lon => latlon[3].to_f).delete(:query)
elsif latlon = query.match(/^(\d{1,3})°?\s*(\d{1,2})[']?\s*(\d{1,3}(\.\d*)?)?["″]\s*([NS])\W*(\d{1,3})°?\s*(\d{1,2})[']?\s*(\d{1,3}(\.\d*)?)?["″]?\s*([EW])$/).try(:captures) # degrees, minutes, decimal seconds [NSEW] end
params.merge!(dms_to_decdeg(latlon)).delete(:query)
elsif latlon = query.match(/^\s*([+-]?\d+(\.\d*)?)\s*[\s,]\s*([+-]?\d+(\.\d*)?)\s*$/)
params.merge!(:lat => latlon[1].to_f, :lon => latlon[3].to_f).delete(:query)
end end
params.permit(:query, :lat, :lon, :zoom, :minlat, :minlon, :maxlat, :maxlon)
end end
def nsew_to_decdeg(captures) def nsew_to_decdeg(captures)

View file

@ -480,9 +480,11 @@ class UserController < ApplicationController
redirect_to url_for(:status => params[:status], :ip => params[:ip], :page => params[:page]) redirect_to url_for(:status => params[:status], :ip => params[:ip], :page => params[:page])
else else
@params = params.permit(:status, :ip)
conditions = {} conditions = {}
conditions[:status] = params[:status] if params[:status] conditions[:status] = @params[:status] if @params[:status]
conditions[:creation_ip] = params[:ip] if params[:ip] conditions[:creation_ip] = @params[:ip] if @params[:ip]
@user_pages, @users = paginate(:users, @user_pages, @users = paginate(:users,
:conditions => conditions, :conditions => conditions,

View file

@ -1,6 +1,6 @@
atom_feed(:language => I18n.locale, :schema_date => 2009, atom_feed(:language => I18n.locale, :schema_date => 2009,
:id => url_for(params.merge(:only_path => false)), :id => url_for(@params.merge(:only_path => false)),
:root_url => url_for(params.merge(:action => :list, :format => nil, :only_path => false)), :root_url => url_for(@params.merge(:action => :list, :format => nil, :only_path => false)),
"xmlns:georss" => "http://www.georss.org/georss") do |feed| "xmlns:georss" => "http://www.georss.org/georss") do |feed|
feed.title changeset_list_title(params, @user) feed.title changeset_list_title(params, @user)

View file

@ -4,7 +4,7 @@
</h2> </h2>
<% @sources.each do |source| %> <% @sources.each do |source| %>
<h4 class="inner12"><%= raw(t "geocoder.search.title.#{source}") %></h4> <h4 class="inner12"><%= raw(t "geocoder.search.title.#{source}") %></h4>
<div class="search_results_entry" data-href="<%= url_for params.merge(:action => "search_#{source}") %>"> <div class="search_results_entry" data-href="<%= url_for @params.merge(:action => "search_#{source}") %>">
<%= image_tag "searching.gif", :class => "loader" %> <%= image_tag "searching.gif", :class => "loader" %>
</div> </div>
<% end %> <% end %>

View file

@ -24,7 +24,7 @@
:count => @user_pages.current_page.last_item - @user_pages.current_page.first_item + 1 :count => @user_pages.current_page.last_item - @user_pages.current_page.first_item + 1
%> %>
<% if @user_pages.page_count > 1 %> <% if @user_pages.page_count > 1 %>
| <%= raw pagination_links_each(@user_pages, {}) { |n| link_to n, params.merge(:page => n) } %> | <%= raw pagination_links_each(@user_pages, {}) { |n| link_to n, @params.merge(:page => n) } %>
<% end %> <% end %>
</td> </td>
<td> <td>