brakeman-llm 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/brakeman-llm +10 -0
- data/docs/warning_types/CVE-2010-3933/index.markdown +17 -0
- data/docs/warning_types/CVE-2011-0446/index.markdown +17 -0
- data/docs/warning_types/CVE-2011-3186/index.markdown +17 -0
- data/docs/warning_types/attribute_restriction/index.markdown +32 -0
- data/docs/warning_types/authentication/index.markdown +23 -0
- data/docs/warning_types/authentication_whitelist/index.markdown +13 -0
- data/docs/warning_types/basic_auth/index.markdown +14 -0
- data/docs/warning_types/basic_authentication/index.markdown +25 -0
- data/docs/warning_types/command_injection/index.markdown +26 -0
- data/docs/warning_types/content_tag/index.markdown +30 -0
- data/docs/warning_types/cross-site_request_forgery/index.markdown +19 -0
- data/docs/warning_types/cross_site_request_forgery/index.markdown +18 -0
- data/docs/warning_types/cross_site_scripting/index.markdown +64 -0
- data/docs/warning_types/cross_site_scripting_to_json/index.markdown +55 -0
- data/docs/warning_types/dangerous_eval/index.markdown +13 -0
- data/docs/warning_types/dangerous_evaluation/index.markdown +14 -0
- data/docs/warning_types/dangerous_send/index.markdown +44 -0
- data/docs/warning_types/default_routes/index.markdown +27 -0
- data/docs/warning_types/denial_of_service/index.markdown +42 -0
- data/docs/warning_types/dynamic_render_path/index.markdown +14 -0
- data/docs/warning_types/dynamic_render_paths/index.markdown +17 -0
- data/docs/warning_types/evaluation/index.markdown +14 -0
- data/docs/warning_types/file_access/index.markdown +23 -0
- data/docs/warning_types/format_validation/index.markdown +15 -0
- data/docs/warning_types/http_verb_confusion/index.markdown +42 -0
- data/docs/warning_types/information_disclosure/index.markdown +20 -0
- data/docs/warning_types/link_to/index.markdown +19 -0
- data/docs/warning_types/link_to_href/index.markdown +19 -0
- data/docs/warning_types/mass_assignment/index.markdown +67 -0
- data/docs/warning_types/model_validation/index.markdown +14 -0
- data/docs/warning_types/path_traversal/index.markdown +57 -0
- data/docs/warning_types/redirect/index.markdown +60 -0
- data/docs/warning_types/remote_code_execution/index.markdown +17 -0
- data/docs/warning_types/remote_code_execution_yaml_load/index.markdown +19 -0
- data/docs/warning_types/session_manipulation/index.markdown +28 -0
- data/docs/warning_types/session_setting/index.markdown +24 -0
- data/docs/warning_types/session_settings/index.markdown +18 -0
- data/docs/warning_types/sql_injection/index.markdown +41 -0
- data/docs/warning_types/ssl_verification_bypass/index.markdown +41 -0
- data/docs/warning_types/unmaintained_dependency/index.markdown +33 -0
- data/docs/warning_types/unsafe_deserialization/index.markdown +17 -0
- data/docs/warning_types/unscoped_find/index.markdown +25 -0
- data/lib/brakeman-llm.rb +226 -0
- metadata +120 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
---
|
2
|
+
layout: page
|
3
|
+
title: "HTTP Verb Confusion"
|
4
|
+
date: 2020-10-23 15:21
|
5
|
+
comments: false
|
6
|
+
sharing: true
|
7
|
+
footer: true
|
8
|
+
---
|
9
|
+
|
10
|
+
Ruby on Rails treats `HEAD` requests just like `GET` requests, except it drops the
|
11
|
+
response body and does not return it to the client _and_ `request.get?` returns `false`.
|
12
|
+
|
13
|
+
If code is assuming a request is either a `GET` or a `POST` and uses `request.get?` to check,
|
14
|
+
then a `HEAD` request will be treated like a `POST` instead of a `GET`.
|
15
|
+
This may trigger the wrong logic or allow a request to bypass CSRF protection
|
16
|
+
(since `GET`/`HEAD` requests are not protected).
|
17
|
+
|
18
|
+
[This post explains a vulnerability in GitHub](https://blog.teddykatz.com/2019/11/05/github-oauth-bypass.html)
|
19
|
+
arising from this confusion.
|
20
|
+
|
21
|
+
To avoid introducing a vulnerabilty with `request.get?`,
|
22
|
+
either use completely separate routes and actions for `GET` vs `POST` (preferred!):
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
get '/some/path', to: 'my_controller#some_action'
|
26
|
+
post '/some/path', to: 'my_controller#a_different_action'
|
27
|
+
```
|
28
|
+
|
29
|
+
|
30
|
+
or else check `request.post?` explicitly:
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
if request.get?
|
34
|
+
# do something
|
35
|
+
elsif request.post?
|
36
|
+
# do something else
|
37
|
+
end
|
38
|
+
```
|
39
|
+
|
40
|
+
|
41
|
+
---
|
42
|
+
Back to [Warning Types](/docs/warning_types)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
---
|
2
|
+
layout: page
|
3
|
+
title: "Information Disclosure"
|
4
|
+
date: 2013-10-17 14:37
|
5
|
+
comments: false
|
6
|
+
sharing: true
|
7
|
+
footer: true
|
8
|
+
---
|
9
|
+
|
10
|
+
Also known as [information leakage](https://www.owasp.org/index.php/Information_Leakage) or [information exposure](http://cwe.mitre.org/data/definitions/200.html), this vulnerability refers to system or internal information (such as debugging output, stack traces, error messages, etc.) which is displayed to an end user.
|
11
|
+
|
12
|
+
For example, Rails provides detailed exception reports by default in the development environment, but it is turned off by default in production:
|
13
|
+
|
14
|
+
# Full error reports are disabled
|
15
|
+
config.consider_all_requests_local = false
|
16
|
+
|
17
|
+
Brakeman warns if this setting is `true` in production or there is a `show_detailed_exceptions?` method in a controller which does not return `false`.
|
18
|
+
|
19
|
+
---
|
20
|
+
Back to [Warning Types](/docs/warning_types)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
---
|
2
|
+
layout: page
|
3
|
+
title: "Cross Site Scripting: link\_to"
|
4
|
+
date: 2012-07-11 11:36
|
5
|
+
comments: false
|
6
|
+
sharing: true
|
7
|
+
footer: true
|
8
|
+
---
|
9
|
+
|
10
|
+
In the 2.x versions of Rails, `link_to` would not escape the body of the HREF.
|
11
|
+
|
12
|
+
For example, this will popup an alert box:
|
13
|
+
|
14
|
+
link_to "<script>alert(1)</script>", "http://google.com"
|
15
|
+
|
16
|
+
Brakeman warns on cases where the first parameter contains user input.
|
17
|
+
|
18
|
+
---
|
19
|
+
Back to [Warning Types](/docs/warning_types)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
---
|
2
|
+
layout: page
|
3
|
+
title: "Cross Site Scripting: link\_to HREF"
|
4
|
+
date: 2012-07-11 11:36
|
5
|
+
comments: false
|
6
|
+
sharing: true
|
7
|
+
footer: true
|
8
|
+
---
|
9
|
+
|
10
|
+
Even though Rails will escape the link provided to `link_to`, values starting with "javascript:" or "data:" are unescaped and dangerous.
|
11
|
+
|
12
|
+
Brakeman will warn on if user values are used to provide the HREF value in `link_to` or if they are interpolated at the beginning of a string.
|
13
|
+
|
14
|
+
The `--url-safe-methods` option can be used to specify methods which make URLs safe.
|
15
|
+
|
16
|
+
See [here](https://github.com/presidentbeef/brakeman/pull/45) for more details.
|
17
|
+
|
18
|
+
---
|
19
|
+
Back to [Warning Types](/docs/warning_types)
|
@@ -0,0 +1,67 @@
|
|
1
|
+
---
|
2
|
+
layout: page
|
3
|
+
title: "Mass Assignment"
|
4
|
+
date: 2011-11-09 14:37
|
5
|
+
comments: false
|
6
|
+
sharing: true
|
7
|
+
footer: true
|
8
|
+
---
|
9
|
+
|
10
|
+
Mass assignment is a feature of Rails which allows an application to create a record from the values of a hash.
|
11
|
+
|
12
|
+
Example:
|
13
|
+
|
14
|
+
User.new(params[:user])
|
15
|
+
|
16
|
+
Unfortunately, if there is a user field called `admin` which controls administrator access, now any user can make themselves an administrator with a query like
|
17
|
+
|
18
|
+
?user[admin]=true
|
19
|
+
|
20
|
+
### Rails With Strong Parameters
|
21
|
+
|
22
|
+
In Rails 4 and newer, protection for mass assignment is on by default.
|
23
|
+
|
24
|
+
Query parameters must be explicitly whitelisted via `permit` in order to be used in mass assignment:
|
25
|
+
|
26
|
+
User.new(params.permit(:name, :password))
|
27
|
+
|
28
|
+
Care should be taken to only whitelist values that are safe for a user (or attacker) to set. Foreign keys such as `account_id` are likely unsafe, allowing an attacker to manipulate records belonging to other accounts.
|
29
|
+
|
30
|
+
Brakeman will warn on potentially dangerous attributes that are whitelisted.
|
31
|
+
|
32
|
+
Brakeman will also warn about uses of `params.permit!`, since that allows everything.
|
33
|
+
|
34
|
+
|
35
|
+
### Rails Without Strong Parameters
|
36
|
+
|
37
|
+
In older versions of Rails, `attr_accessible` and `attr_protected` can be used to limit mass assignment.
|
38
|
+
However, Brakeman will warn unless `attr_accessible` is used, or mass assignment is completely disabled.
|
39
|
+
|
40
|
+
There are two different mass assignment warnings which can arise. The first is when mass assignment actually occurs, such as the example above. This results in a warning like
|
41
|
+
|
42
|
+
Unprotected mass assignment near line 61: User.new(params[:user])
|
43
|
+
|
44
|
+
The other warning is raised whenever a model is found which does not use `attr_accessible`. This produces generic warnings like
|
45
|
+
|
46
|
+
Mass assignment is not restricted using attr_accessible
|
47
|
+
|
48
|
+
with a list of affected models.
|
49
|
+
|
50
|
+
In Rails 3.1 and newer, mass assignment can easily be disabled:
|
51
|
+
|
52
|
+
config.active_record.whitelist_attributes = true
|
53
|
+
|
54
|
+
Unfortunately, it can also easily be bypassed:
|
55
|
+
|
56
|
+
User.new(params[:user], :without_protection => true)
|
57
|
+
|
58
|
+
Brakeman will warn on uses of `without_protection`.
|
59
|
+
|
60
|
+
### More Information
|
61
|
+
|
62
|
+
[Strong Parameters in Rails Security Guide](http://edgeguides.rubyonrails.org/action_controller_overview.html#strong-parameters)
|
63
|
+
[Mass Assignment in Rails Security Guide](http://guides.rubyonrails.org/v3.2.8/security.html#mass-assignment)
|
64
|
+
|
65
|
+
---
|
66
|
+
|
67
|
+
Back to [Warning Types](/docs/warning_types)
|
@@ -0,0 +1,14 @@
|
|
1
|
+
---
|
2
|
+
layout: page
|
3
|
+
title: "Format Validation"
|
4
|
+
date: 2011-11-10 12:47
|
5
|
+
comments: false
|
6
|
+
sharing: true
|
7
|
+
footer: true
|
8
|
+
---
|
9
|
+
|
10
|
+
<script>
|
11
|
+
window.location.replace("http://brakemanscanner.org/docs/warning_types/format_validation/");
|
12
|
+
</script>
|
13
|
+
|
14
|
+
Content moved to [Format Validation](format_validation/).
|
@@ -0,0 +1,57 @@
|
|
1
|
+
---
|
2
|
+
layout: page
|
3
|
+
title: "Path Traversal"
|
4
|
+
date: 2024-01-24 16:01
|
5
|
+
comments: false
|
6
|
+
sharing: true
|
7
|
+
footer: true
|
8
|
+
---
|
9
|
+
|
10
|
+
Path traversal vulnerabilities allow an attacker to access or manipulate files outside the intended
|
11
|
+
directory by providing specially crafted paths as input to read or write sensitive data. This can occur when
|
12
|
+
improperly handling user-supplied input in filesystem-related operations such as image uploads, dynamic content loading, and user file downloads.
|
13
|
+
|
14
|
+
An attacker could exploit a path traversal vulnerability to:
|
15
|
+
|
16
|
+
* Read sensitive files, including configuration files or other data containing credentials or encryption keys.
|
17
|
+
* Write files into restricted directories that enables code injection or privilege escalation.
|
18
|
+
* Download or delete critical system files.
|
19
|
+
* Gain access to user data and perform unauthorized actions.
|
20
|
+
|
21
|
+
## Example
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
# `params[:file][:path]` could contain "../../../../../etc/passwd", e.g.
|
25
|
+
|
26
|
+
send_file File.join('some', 'path', params[:file][:path])
|
27
|
+
```
|
28
|
+
|
29
|
+
## Pathname Confusion
|
30
|
+
|
31
|
+
`Pathname#join` has some confusing behavior: _any_ absolute path segment (e.g. starting with `/`) causes the path to be absolute from that point.
|
32
|
+
|
33
|
+
Example:
|
34
|
+
|
35
|
+
```
|
36
|
+
> Pathname.new('a').join("a", "b", "/c", "d")
|
37
|
+
=> #<Pathname:/c/d>
|
38
|
+
```
|
39
|
+
|
40
|
+
Note that `Rails.root` is a `Pathname`.
|
41
|
+
|
42
|
+
Exercise extreme caution when passing user-provided input to this function.
|
43
|
+
|
44
|
+
### Additional Protections
|
45
|
+
|
46
|
+
Besides coding defensively, there are additional options for protecting against path traversal:
|
47
|
+
|
48
|
+
* Use the ActiveStorage module for handling uploaded files and store them in a service like S3, rather than storing user data on the same server or directory as the application.
|
49
|
+
* Configure permissions on the application server to disallow writing files or reading files outside of the application directory.
|
50
|
+
* Never include user-provided values in the file path or the file name.
|
51
|
+
|
52
|
+
A common pattern is to store files using application-generated file names, but keep a record of the user-provided name. When the user downloads the file, the [`download`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-download) attribute and/or the [Content Disposition](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) header can be used to tell the browser the preferred name of the file, which can be the original user-provided name. Note that libraries like ActiveStorage will handle this for you.
|
53
|
+
|
54
|
+
However, be careful if users can download files named by _other_ users. Overall, it is safer to generate file names from known-safe values.
|
55
|
+
|
56
|
+
---
|
57
|
+
Back to [Warning Types](/docs/warning_types)
|
@@ -0,0 +1,60 @@
|
|
1
|
+
---
|
2
|
+
layout: page
|
3
|
+
title: "Redirect"
|
4
|
+
date: 2011-11-09 15:21
|
5
|
+
comments: false
|
6
|
+
sharing: true
|
7
|
+
footer: true
|
8
|
+
---
|
9
|
+
|
10
|
+
Unvalidated redirects and forwards are #10 on the [OWASP Top Ten](https://web.archive.org/web/20190223031311/https://www.owasp.org/index.php/Top_10_2010-A10).
|
11
|
+
|
12
|
+
Redirects which rely on user-supplied values can be used to "spoof" websites or hide malicious links in otherwise harmless-looking URLs. They can also allow access to restricted areas of a site if the destination is not validated.
|
13
|
+
|
14
|
+
|
15
|
+
Brakeman will raise warnings whenever `redirect_to` appears to be used with a user-supplied value that may allow them to change the `:host` option.
|
16
|
+
|
17
|
+
For example,
|
18
|
+
|
19
|
+
redirect_to params.merge(:action => :home)
|
20
|
+
|
21
|
+
will create a warning like
|
22
|
+
|
23
|
+
Possible unprotected redirect near line 46: redirect_to(params)
|
24
|
+
|
25
|
+
This is because `params` could contain `:host => 'evilsite.com'` which would redirect away from your site and to a malicious site.
|
26
|
+
|
27
|
+
If the first argument to `redirect_to` is a hash, then adding `:only_path => true` will limit the redirect to the current host. Another option is to specify the host explicitly.
|
28
|
+
|
29
|
+
redirect_to params.merge(:only_path => true)
|
30
|
+
|
31
|
+
redirect_to params.merge(:host => 'myhost.com')
|
32
|
+
|
33
|
+
If the first argument is a string, then it is possible to parse the string and extract the path:
|
34
|
+
|
35
|
+
redirect_to URI.parse(some_url).path
|
36
|
+
|
37
|
+
**If the URL does not contain a protocol (e.g., `http://`), then you will probably get unexpected results, as `redirect_to` will prepend the current host name and a protocol.**
|
38
|
+
|
39
|
+
### Rails 7 Updates
|
40
|
+
|
41
|
+
If `config.action_controller.raise_on_open_redirects` is `true` (default for _new_ Rails 7.0 applications), then Rails will not allow redirecting to a domain that differs from the request.
|
42
|
+
|
43
|
+
Even if the configuration setting is not `true`, the protection can be applied by setting `allow_other_host: false` explicitly:
|
44
|
+
|
45
|
+
redirect_to params[:url], allow_other_host: false
|
46
|
+
|
47
|
+
The code above will raise an exception if `params[:url]` does not match the current domain.
|
48
|
+
|
49
|
+
Brakeman will warn about calls where `allow_other_host` is set to `true`.
|
50
|
+
|
51
|
+
To coerce the URL to be "safe", use [`url_from`](https://api.rubyonrails.org/v7.0/classes/ActionController/Redirecting.html#method-i-url_from):
|
52
|
+
|
53
|
+
redirect_to url_from(params[:url])
|
54
|
+
|
55
|
+
If the URL is does not match the current domain, then `url_from` returns `false`. The recommended pattern is to provide a fallback:
|
56
|
+
|
57
|
+
redirect_to url_from(params[:url]) || some_safe_default_url
|
58
|
+
|
59
|
+
---
|
60
|
+
Back to [Warning Types](/docs/warning_types)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
---
|
2
|
+
layout: page
|
3
|
+
title: "Remote Code Execution"
|
4
|
+
date: 2013-03-01 11:22
|
5
|
+
comments: false
|
6
|
+
sharing: true
|
7
|
+
footer: true
|
8
|
+
---
|
9
|
+
|
10
|
+
Brakeman reports on several cases of remote code execution, in which a user is able to control and execute code in ways unintended by application authors.
|
11
|
+
|
12
|
+
The obvious form of this is the use of `eval` with user input.
|
13
|
+
|
14
|
+
However, Brakeman also reports on dangerous uses of `send`, `constantize`, and other methods which allow creation of arbitrary objects or calling of arbitrary methods.
|
15
|
+
|
16
|
+
---
|
17
|
+
Back to [Warning Types](/docs/warning_types)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
---
|
2
|
+
layout: page
|
3
|
+
title: "Remote Code Execution in YAML.Load"
|
4
|
+
date: 2013-01-18 17:08
|
5
|
+
comments: false
|
6
|
+
sharing: true
|
7
|
+
footer: true
|
8
|
+
---
|
9
|
+
|
10
|
+
As seen in [CVE-2013-0156](https://groups.google.com/d/topic/rubyonrails-security/61bkgvnSGTQ/discussion), calling `YAML.load` with user input can lead to remote execution of arbitrary code. (To see a real point-and-fire exploit, see the [Metasploit payload](https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/multi/http/rails_xml_yaml_code_exec.rb)). While upgrading Rails, disabling XML parsing, or disabling YAML types in XML request parsing will fix the Rails vulnerability, manually passing user input to `YAML.load` remains unsafe.
|
11
|
+
|
12
|
+
For example:
|
13
|
+
|
14
|
+
#Do not do this!
|
15
|
+
YAML.load(params[:file])
|
16
|
+
|
17
|
+
---
|
18
|
+
|
19
|
+
Back to [Warning Types](/docs/warning_types)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
---
|
2
|
+
layout: page
|
3
|
+
title: "Session Manipulation"
|
4
|
+
date: 2015-12-28 07:43
|
5
|
+
comments: false
|
6
|
+
sharing: true
|
7
|
+
footer: true
|
8
|
+
---
|
9
|
+
|
10
|
+
Session manipulation can occur when an application allows user-input in session keys.
|
11
|
+
Since sessions are typically considered a source of truth (e.g. to check the logged-in user or to match CSRF tokens),
|
12
|
+
allowing an attacker to manipulate the session may lead to unintended behavior.
|
13
|
+
|
14
|
+
For example:
|
15
|
+
|
16
|
+
user_id = session[params[:name]]
|
17
|
+
current_user = User.find(user_id)
|
18
|
+
|
19
|
+
In this scenario, the attacker can point the `name` parameter to some other session value (for example, `_csrf_token`) that will be interpreted
|
20
|
+
as a user ID. If the ID matches an existing account, the attacker will now have access to that account.
|
21
|
+
|
22
|
+
To prevent this type of session manipulation, avoid using user-supplied input as session keys.
|
23
|
+
|
24
|
+
([See here for a tiny, self-contained challenge demonstrating this issue](https://gist.github.com/joernchen/9dfa57017b4732c04bcc).)
|
25
|
+
|
26
|
+
---
|
27
|
+
|
28
|
+
Back to [Warning Types](/docs/warning_types)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
---
|
2
|
+
layout: page
|
3
|
+
title: "Session Settings"
|
4
|
+
date: 2011-11-10 16:15
|
5
|
+
comments: false
|
6
|
+
sharing: true
|
7
|
+
footer: true
|
8
|
+
---
|
9
|
+
|
10
|
+
### HTTP Only
|
11
|
+
|
12
|
+
It is recommended that session cookies be set to "http-only". This helps prevent stealing of cookies via cross site scripting.
|
13
|
+
|
14
|
+
### Secret Length
|
15
|
+
|
16
|
+
Brakeman will warn if the key length for the session cookies is less than 30 characters.
|
17
|
+
|
18
|
+
### Version control inclusion
|
19
|
+
|
20
|
+
Brakeman will warn if the config/initializers/secret_token.rb is included in the version control. It is recommended that secret_token.rb is excluded from version control, and included in .gitignore
|
21
|
+
|
22
|
+
---
|
23
|
+
Back to [Warning Types](/docs/warning_types)
|
24
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
---
|
2
|
+
layout: page
|
3
|
+
title: "Session Settings"
|
4
|
+
date: 2011-11-10 16:15
|
5
|
+
comments: false
|
6
|
+
sharing: true
|
7
|
+
footer: true
|
8
|
+
---
|
9
|
+
|
10
|
+
<script>
|
11
|
+
window.location.replace("http://brakemanscanner.org/docs/warning_types/session_setting/");
|
12
|
+
</script>
|
13
|
+
|
14
|
+
Content has moved to [Session Setting](/docs/warning_types/session_setting/)
|
15
|
+
|
16
|
+
---
|
17
|
+
Back to [Warning Types](/docs/warning_types)
|
18
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
---
|
2
|
+
layout: page
|
3
|
+
title: "SQL Injection"
|
4
|
+
date: 2011-11-09 14:12
|
5
|
+
comments: false
|
6
|
+
sharing: true
|
7
|
+
footer: true
|
8
|
+
---
|
9
|
+
|
10
|
+
Injection is #1 on the 2010 [OWASP Top Ten](https://web.archive.org/web/20190223031311/https://www.owasp.org/index.php/Top_10_2010-A1) web security risks. SQL injection is when a user is able to manipulate a value which is used unsafely inside a SQL query. This can lead to data leaks, data loss, elevation of privilege, and other unpleasant outcomes.
|
11
|
+
|
12
|
+
Brakeman focuses on ActiveRecord methods dealing with building SQL statements.
|
13
|
+
|
14
|
+
A basic (Rails 2.x) example looks like this:
|
15
|
+
|
16
|
+
User.first(:conditions => "username = '#{params[:username]}'")
|
17
|
+
|
18
|
+
Brakeman would produce a warning like this:
|
19
|
+
|
20
|
+
Possible SQL injection near line 30: User.first(:conditions => ("username = '#{params[:username]}'"))
|
21
|
+
|
22
|
+
The safe way to do this query is to use a parameterized query:
|
23
|
+
|
24
|
+
User.first(:conditions => ["username = ?", params[:username]])
|
25
|
+
|
26
|
+
Brakeman also understands the new Rails 3.x way of doing things (and local variables and concatentation):
|
27
|
+
|
28
|
+
username = params[:user][:name].downcase
|
29
|
+
password = params[:user][:password]
|
30
|
+
|
31
|
+
User.first.where("username = '" + username + "' AND password = '" + password + "'")
|
32
|
+
|
33
|
+
This results in this kind of warning:
|
34
|
+
|
35
|
+
Possible SQL injection near line 37:
|
36
|
+
User.first.where((((("username = '" + params[:user][:name].downcase) + "' AND password = '") + params[:user][:password]) + "'"))
|
37
|
+
|
38
|
+
See [the Ruby Security Guide](http://guides.rubyonrails.org/security.html#sql-injection) for more information and [Rails-SQLi.org](http://rails-sqli.org) for many examples of SQL injection in Rails.
|
39
|
+
|
40
|
+
---
|
41
|
+
Back to [Warning Types](/docs/warning_types)
|
@@ -0,0 +1,41 @@
|
|
1
|
+
---
|
2
|
+
layout: page
|
3
|
+
title: "SSL Verification Bypass"
|
4
|
+
date: 2014-01-06 17:27
|
5
|
+
comments: false
|
6
|
+
sharing: true
|
7
|
+
footer: true
|
8
|
+
---
|
9
|
+
|
10
|
+
Simply using SSL isn't enough to ensure the data you are sending is secure. Man in the middle (MITM) attacks are well known and widely used. In some cases, these attacks rely on the client to establish a connection that doesn't check the validity of the SSL certificate presented by the server. In this case, the attacker can present their own certificate and act as a man in the middle.
|
11
|
+
|
12
|
+
In Ruby, this happens when the OpenSSL verification mode is set to `VERIFY_NONE`
|
13
|
+
|
14
|
+
require "net/https"
|
15
|
+
require "uri"
|
16
|
+
|
17
|
+
uri = URI.parse("https://ssl-site.com/")
|
18
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
19
|
+
http.use_ssl = true
|
20
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
21
|
+
|
22
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
23
|
+
|
24
|
+
response = http.request(request)
|
25
|
+
|
26
|
+
In this case, if an invalid certificate was presented, no verification would occur, providing an opportunity for attack. When successful, the data transmitted (cookies, request parameters, POST bodies, etc.) would all be able to be intercepted by the MITM.
|
27
|
+
|
28
|
+
Brakeman would produce a warning like this:
|
29
|
+
|
30
|
+
SSL certificate verification was bypassed near line 24: http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
31
|
+
|
32
|
+
To ensure that SSL verification happens use the following mode:
|
33
|
+
|
34
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
35
|
+
|
36
|
+
If the server certificate is invalid or context.ca_file is not set when verifying peers an OpenSSL::SSL::SSLError will be raised.
|
37
|
+
|
38
|
+
For more information on the impact of this issue, see the paper [The Most Dangerous Code in the World](https://www.cs.utexas.edu/~shmat/shmat_ccs12.pdf).
|
39
|
+
|
40
|
+
---
|
41
|
+
Back to [Warning Types](/docs/warning_types)
|
@@ -0,0 +1,33 @@
|
|
1
|
+
---
|
2
|
+
layout: page
|
3
|
+
title: "Unmaintained Dependencies"
|
4
|
+
date: 2024-01-24 16:01
|
5
|
+
comments: false
|
6
|
+
sharing: true
|
7
|
+
footer: true
|
8
|
+
---
|
9
|
+
|
10
|
+
Unmaintained or "end-of-life" dependencies can present security risks to your application.
|
11
|
+
|
12
|
+
When a dependency is no longer maintained, its developers may not release new versions with security patches for known
|
13
|
+
vulnerabilities. This means that any known vulnerabilities in the dependency remain unpatched, leaving your application open to attacks.
|
14
|
+
|
15
|
+
In addition to known vulnerabilities, older versions of software are likely to receive less scrutiny
|
16
|
+
are more likely to contain vulnerabilities that are not published and do not receive any public attention.
|
17
|
+
|
18
|
+
Maintained dependencies are also more likely to follow security best practices, such as using secure coding practices,
|
19
|
+
regularly testing for vulnerabilities, and providing timely security patches. Outdated dependencies may not follow these best practices, increasing the
|
20
|
+
risk of security vulnerabilities.
|
21
|
+
|
22
|
+
As a library ages, it is more likely to be completely abandoned or forgotten by its creator.
|
23
|
+
Abandoned libraries may become target for supply chain attacks, where the attacker takes over an old code repository or
|
24
|
+
an account on a package management server (such as RubyGems) and publishes a malicious version of the software.
|
25
|
+
|
26
|
+
## Ruby and Rails
|
27
|
+
|
28
|
+
Ruby versions are generally maintained for 3 years and 3 months after release. Check [the listing of maintenance branches](https://www.ruby-lang.org/en/downloads/branches/) for more information.
|
29
|
+
|
30
|
+
Rails is more complicated, but generally only the current series and the last of the previous series is supported. See the [Rails Maintenance Policy](https://guides.rubyonrails.org/maintenance_policy.html#security-issues).
|
31
|
+
|
32
|
+
---
|
33
|
+
Back to [Warning Types](/docs/warning_types)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
---
|
2
|
+
layout: page
|
3
|
+
title: "Unsafe Deserialization"
|
4
|
+
date: 2013-05-17 14:37
|
5
|
+
comments: false
|
6
|
+
sharing: true
|
7
|
+
footer: true
|
8
|
+
---
|
9
|
+
|
10
|
+
Objects in Ruby may be serialized to strings. The main method for doing so is the built-in `Marshal` class. The `YAML`, `JSON`, and `CSV` libraries also have methods for dumping Ruby objects into strings, and then creating objects from those strings.
|
11
|
+
|
12
|
+
Deserialization of arbitrary objects can lead to [remote code execution](/docs/warning_types/remote_code_execution), as was demonstrated with [CVE-2013-0156](https://groups.google.com/d/msg/rubyonrails-security/61bkgvnSGTQ/nehwjA8tQ8EJ).
|
13
|
+
|
14
|
+
Brakeman warns when loading user input with `Marshal`, `YAML`, or `CSV`. `JSON` is covered by the checks for [CVE-2013-0333](https://groups.google.com/d/msg/rubyonrails-security/1h2DR63ViGo/GOUVafeaF1IJ)
|
15
|
+
|
16
|
+
---
|
17
|
+
Back to [Warning Types](/docs/warning_types)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
---
|
2
|
+
layout: page
|
3
|
+
title: "Unscoped Find"
|
4
|
+
date: 2014-10-14 08:48
|
5
|
+
comments: false
|
6
|
+
sharing: true
|
7
|
+
footer: true
|
8
|
+
---
|
9
|
+
|
10
|
+
Unscoped `find` (and related methods) are a form of [Direct Object Reference](https://www.owasp.org/index.php/Top_10_2013-A4-Insecure_Direct_Object_References). Models which belong to another model should typically be accessed via a scoped query.
|
11
|
+
|
12
|
+
For example, if an `Account` belongs to a `User`, then this may be an unsafe unscoped find:
|
13
|
+
|
14
|
+
Account.find(params[:id])
|
15
|
+
|
16
|
+
Depending on the action, this could allow an attacker to access any account they wish.
|
17
|
+
|
18
|
+
Instead, it should be scoped to the currently logged-in user:
|
19
|
+
|
20
|
+
current_user = User.find(session[:user_id])
|
21
|
+
current_user.accounts.find(params[:id])
|
22
|
+
|
23
|
+
---
|
24
|
+
|
25
|
+
Back to [Warning Types](/docs/warning_types)
|