Validate some text in a ruby on rails model - ruby-on-rails

I want to validate a text string to make sure it is safe. I do not want to escape it, as I want to display it.
I have tried
validates :description, :format => { :with => /^[\-$ ?!."'\/,a-z0-9]+$/i
and it works in that it passes text with characters that are allowed and fails when characters not listed above are include.
But Brakeman issues a message that advocates replacing the ^ with \A and the $ with /z. However if I do this, the validator fails all tests.

It is not working cause you are using forward slash/ instead of back slash \. The /z means matching the characters / and z literally. It is \z or \Z And they mean as follows:
\z means the end of the string. Whereas
\Z means before an optional \n, and the end of the string.
So use the one which fits best with you!

Related

Brakeman insufficient validation warning of regex anchors

I'm trying to implement a validation in a model like this.
validates_format_of :field, with: /[0-9]/, message: 'must have at least one number (0-9)'
Brakeman detects this a Format Validation security issue and it recommends to add the anchors between the regular expression.
Insufficient validation for 'field' using /[0-9]/. Use \A and \z as anchors near line 54
If I add those anchors, the regular expression stops working, so I don't know what to do in this case. Here's the tests I made using rails c.
"asdf1234".match(/\A[0-9]\z/) # => nil
"foobar1".match(/\A[0-9]\z/) # => nil
I need that the method return #<MatchData "1"> in both cases.
Any ideas?
Thanks.
If you need to match a string that has at least 1 digit inside, and any other chars before and after, you may use
/\A[^0-9]*[0-9].*\z/m
or just
/\A.*[0-9].*\z/m
Details
\A - start of string
[^0-9]* - zero or more chars other than an ASCII digit
[0-9] - an ASCII digit
.* - any 0+ chars, as many as possible, up to the
\z - end of string.
The m modifier makes . match any char, including a line break char.
Actually, /\A.*[0-9].*\z/m will be a bit slower, as the first .* will grab all the string at once and then will backtrack to find the last digit. The first one is more optimized.

Insufficient validation for 'name' using / +\w/. Use \A and \z as anchors

I used brakeman for generating scanning reports in my application. It generated a Format Validation security warning with High Confidence in my model page:
Insufficient validation for 'name' using / +\w/. Use \A and \z as
anchors near line 54
This is the line in my model where I am facing error:
validates_format_of :name, :with => / +\w/, :message => "must be your first and last name."
If there is no space in the name field, I am showing above validation. How can show it \A and\z format?
Brakeman is recommending the use of \A and \z-anchors in your validation regex. They define where the match has to start at (\A) and end at (\z). Without them, the regex can simply match to any part of the name. Let's transform your regex to encompass the whole string:
/\A\w+ +\w+\z/
You can remove the + after the space if you only want to accept one space.
Using the normal regex line begin (^) and end ($) anchors is also not recommended, because it would be enough to have one line which matches, and all other lines could be invalid.

Regular Expression for excluding numbers or special characters

I'm setting up a user form in Rails that requires a first name and last name. I decided to use the 3rd to last regular expression from the this Ruby doc to ensure that they don't enter any numbers or special characters. Unfortunately when I return to the form I get this error:
The provided regular expression is using multiline anchors (^ or $),
which may present a security risk. Did you mean to use \A and \z, or
forgot to add the :multiline => true option?.
I'm just beginning to learn RegEx so if there's a better way to write this validation I'm all ears.
Code:
validates :first_name, :last_name, length: {minimum: 2}, format: {with: /^([^\d\W]|[-])*$/, message: 'First Name/Last Name cannot have any numbers or special characters'}
The documentation you linked to states:
Note: use \A and \Z to match the start and end of the string, ^ and $ match the start/end of a line.
Since you don't need multiline support for names (i.e. newlines in the name should be regarded invalid), you can safely change this to:
/\A([^\d\W]|[-])*\Z/
See also this answer which explains the security risk a bit more.
You will need to use \A for start of line and \z for end of line instead of ^ and $ due to security reasons. So your regexp should be
/\A([^\d\W]|[-])*\z/

The Ruby %r{ } expression

In a model there is a field
validates :image_file_name, :format => { :with => %r{\.(gif|jpg|jpeg|png)$}i
It looks pretty odd for me. I am aware that this is a regular expression. But I would like:
to know what exactly it means. Is %r{value} equal to /value/ ?
be able to replace it with normal Ruby regex operator /some regex/ or =~. Is this possible?
%r{} is equivalent to the /.../ notation, but allows you to have '/' in your regexp without having to escape them:
%r{/home/user}
is equivalent to:
/\/home\/user/
This is only a syntax commodity, for legibility.
Edit:
Note that you can use almost any non-alphabetic character pair instead of '{}'.
These variants work just as well:
%r!/home/user!
%r'/home/user'
%r(/home/user)
Edit 2:
Note that the %r{}x variant ignores whitespace, making complex regexps more readable. Example from GitHub's Ruby style guide:
regexp = %r{
start # some text
\s # white space char
(group) # first group
(?:alt1|alt2) # some alternation
end
}x
With %r, you could use any delimiters.
You could use %r{} or %r[] or %r!! etc.
The benefit of using other delimeters is that you don't need to escape the / used in normal regex literal.
\. => contains a dot
(gif|jpg|jpeg|png) => then, either one of these extensions
$ => the end, nothing after it
i => case insensitive
And it's the same as writing /\.(gif|jpg|jpeg|png)$/i.
this regexp matches all strings that ends with .gif, .jpg...
you could replace it with
/\.(gif|jpg|jpeg|png)$/i
It mean that image_file_name must end ($) with dot and one of gif, jpg, jpeg or png.
Yes %r{} mean exactly the same as // but in %r{} you don't need to escape /.

Parentheses messing up validation in rails

I have the following validation:
validates_format_of :title,
:with => /^[A-Z0-9 áàâäãçéèêëíìîïñóòôøöõúùûüý'-.]*$/i,
:message => "must contain only letters, numbers, dashes, periods, and single quotes"
This works most of the time, but when a title contains an open and closed parentheses, it passes. Anyone know how to get around this or maybe there is something wrong with my validation regex?
At the end of your regular expression you have '-.
This means that you want to allow all characters between (and including) the apostrophe and the period just like you did at the beginning of the regular expression with A-Z and 0-9.
The expression /['-.]/ allows all these characters: '()*+,-.
Inside the [], you need to escape the - character. I think that this will work the way you are hoping:
/^[A-Z0-9 áàâäãçéèêëíìîïñóòôøöõúùûüý'\-.]*$/i
PS. You don't have to escape the . inside the square brackets []

Resources