From 80d27a7fae408e22300723b746666540da0360b8 Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Fri, 2 Jun 2017 20:26:33 +0100 Subject: [PATCH] Sanitise parameters used in URL generation --- app/controllers/changeset_controller.rb | 28 ++++++------ app/controllers/geocoder_controller.rb | 58 ++++++++++++------------- app/controllers/user_controller.rb | 6 ++- app/views/changeset/list.atom.builder | 4 +- app/views/geocoder/search.html.erb | 2 +- app/views/user/list.html.erb | 2 +- 6 files changed, 52 insertions(+), 48 deletions(-) diff --git a/app/controllers/changeset_controller.rb b/app/controllers/changeset_controller.rb index 185a3bd19..71fc2a59a 100644 --- a/app/controllers/changeset_controller.rb +++ b/app/controllers/changeset_controller.rb @@ -250,46 +250,48 @@ class ChangesetController < ApplicationController ## # list non-empty changesets in reverse chronological order def list - if request.format == :atom && params[:max_id] - redirect_to url_for(params.merge(:max_id => nil)), :status => :moved_permanently + @params = params.permit(:display_name, :bbox, :friends, :nearby, :max_id, :list) + + if request.format == :atom && @params[:max_id] + redirect_to url_for(@params.merge(:max_id => nil)), :status => :moved_permanently return end - if params[:display_name] - user = User.find_by(:display_name => params[:display_name]) + if @params[:display_name] + user = User.find_by(:display_name => @params[:display_name]) if !user || !user.active? - render_unknown_user params[:display_name] + render_unknown_user @params[:display_name] return end end - if (params[:friends] || params[:nearby]) && !@user + if (@params[:friends] || @params[:nearby]) && !@user require_user return end - if request.format == :html && !params[:list] + if request.format == :html && !@params[:list] require_oauth render :action => :history, :layout => map_layout else changesets = conditions_nonempty(Changeset.all) - if params[:display_name] + if @params[:display_name] changesets = if user.data_public? || user == @user changesets.where(:user_id => user.id) else changesets.where("false") end - elsif params[:bbox] + elsif @params[:bbox] 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) - elsif params[:nearby] && @user + elsif @params[:nearby] && @user changesets = changesets.where(:user_id => @user.nearby) end - if params[:max_id] - changesets = changesets.where("changesets.id <= ?", params[:max_id]) + if @params[:max_id] + changesets = changesets.where("changesets.id <= ?", @params[:max_id]) end @edits = changesets.order("changesets.id DESC").limit(20).preload(:user, :changeset_tags, :comments) diff --git a/app/controllers/geocoder_controller.rb b/app/controllers/geocoder_controller.rb index a5f1810b7..234842588 100644 --- a/app/controllers/geocoder_controller.rb +++ b/app/controllers/geocoder_controller.rb @@ -10,22 +10,21 @@ class GeocoderController < ApplicationController before_action :require_oauth, :only => [:search] def search - normalize_params - + @params = normalize_params @sources = [] - if params[:lat] && params[:lon] + if @params[:lat] && @params[:lon] @sources.push "latlon" @sources.push "osm_nominatim_reverse" @sources.push "geonames_reverse" if defined?(GEONAMES_USERNAME) - elsif params[:query] - if params[:query] =~ /^\d{5}(-\d{4})?$/ + elsif @params[:query] + if @params[:query] =~ /^\d{5}(-\d{4})?$/ @sources.push "us_postcode" @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 "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 "osm_nominatim" else @@ -316,29 +315,30 @@ class GeocoderController < ApplicationController end def normalize_params - query = params[:query] - return unless query - - 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) - - 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!(ddm_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] - params.merge!(ddm_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 - params.merge!(dms_to_decdeg(latlon)).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] - 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) + if query = params[:query] + 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) + + 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!(ddm_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] + params.merge!(ddm_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 + params.merge!(dms_to_decdeg(latlon)).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] + 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 def nsew_to_decdeg(captures) diff --git a/app/controllers/user_controller.rb b/app/controllers/user_controller.rb index 2ff9646e6..430051c17 100644 --- a/app/controllers/user_controller.rb +++ b/app/controllers/user_controller.rb @@ -480,9 +480,11 @@ class UserController < ApplicationController redirect_to url_for(:status => params[:status], :ip => params[:ip], :page => params[:page]) else + @params = params.permit(:status, :ip) + conditions = {} - conditions[:status] = params[:status] if params[:status] - conditions[:creation_ip] = params[:ip] if params[:ip] + conditions[:status] = @params[:status] if @params[:status] + conditions[:creation_ip] = @params[:ip] if @params[:ip] @user_pages, @users = paginate(:users, :conditions => conditions, diff --git a/app/views/changeset/list.atom.builder b/app/views/changeset/list.atom.builder index 68b4a1985..0235d182a 100644 --- a/app/views/changeset/list.atom.builder +++ b/app/views/changeset/list.atom.builder @@ -1,6 +1,6 @@ atom_feed(:language => I18n.locale, :schema_date => 2009, - :id => url_for(params.merge(:only_path => false)), - :root_url => url_for(params.merge(:action => :list, :format => nil, :only_path => false)), + :id => url_for(@params.merge(: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| feed.title changeset_list_title(params, @user) diff --git a/app/views/geocoder/search.html.erb b/app/views/geocoder/search.html.erb index ac655147a..21484d4c0 100644 --- a/app/views/geocoder/search.html.erb +++ b/app/views/geocoder/search.html.erb @@ -4,7 +4,7 @@ <% @sources.each do |source| %>

<%= raw(t "geocoder.search.title.#{source}") %>

-
"> +
"> <%= image_tag "searching.gif", :class => "loader" %>
<% end %> diff --git a/app/views/user/list.html.erb b/app/views/user/list.html.erb index fcd0c41fc..903a51c5b 100644 --- a/app/views/user/list.html.erb +++ b/app/views/user/list.html.erb @@ -24,7 +24,7 @@ :count => @user_pages.current_page.last_item - @user_pages.current_page.first_item + 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 %> -- 2.39.5