top | item 39766469

(no title)

jewel | 1 year ago

This has security implications! Example exploitable ruby code:

  unless person_id =~ /^\d+$/
    abort "Bad person ID"
  end
  sql = "select * from people where person_id = #{person_id}"
In addition to injection attacks, this also can bite people when parsing headers, where a bad header is allowed to sneak past a filter.

discuss

order

jfhufl|1 year ago

Unsure what you mean?

    $ ruby -e 'x = "25" ; if x =~ /^\d+$/ ; puts "yes" ; else ; puts "no" ; end'
    yes
    $ ruby -e 'x = "25\n" ; if x =~ /^\d+$/ ; puts "yes" ; else ; puts "no" ; end' 
    yes
    $ ruby -e 'x = "a25\n" ; if x =~ /^\d+$/ ; puts "yes" ; else ; puts "no" ; end'
    no
Also, you'd want to use something that parameterizes the query with '?' (I use the Sequel gem) instead of just stuffing it into a sql string.

halostatue|1 year ago

You need to make your regex multi-line (`/^\d+$/m`), but that isn't the problem shown. Your query will be searching for `25\n`, not `25` despite your pre-check that it’s a good value.

The second line should always be no, which if you use `\A\d+\z`, it will be.

jfhufl|1 year ago

Well, learned something today after reading a bit further in the thread:

    ruby -e 'x = "a\n25\n" ; if x =~ /^\d+$/ ; puts "yes" ; else ; puts "no" ; end'
    yes
Good to know.

dr-smooth|1 year ago

    $ ruby -e 'x = "25\n; delete from people" ; if x =~ /^\d+$/ ; puts "yes" ; else ; puts "no" ; end'
    yes