|
| 1 | +--- |
| 2 | +gem: rack |
| 3 | +cve: 2018-16471 |
| 4 | +url: https://groups.google.com/forum/#!topic/ruby-security-ann/NAalCee8n6o |
| 5 | +title: Possible XSS vulnerability in Rack |
| 6 | +date: 2018-11-05 |
| 7 | + |
| 8 | +description: | |
| 9 | + There is a possible vulnerability in Rack. This vulnerability has been |
| 10 | + assigned the CVE identifier CVE-2018-16471. |
| 11 | +
|
| 12 | + Versions Affected: All. |
| 13 | + Not affected: None. |
| 14 | + Fixed Versions: 2.0.6, 1.6.11 |
| 15 | +
|
| 16 | + Impact |
| 17 | + ------ |
| 18 | + There is a possible XSS vulnerability in Rack. Carefully crafted requests can |
| 19 | + impact the data returned by the `scheme` method on `Rack::Request`. |
| 20 | + Applications that expect the scheme to be limited to "http" or "https" and do |
| 21 | + not escape the return value could be vulnerable to an XSS attack. |
| 22 | +
|
| 23 | + Vulnerable code looks something like this: |
| 24 | +
|
| 25 | + ``` |
| 26 | + <%= request.scheme.html_safe %> |
| 27 | + ``` |
| 28 | +
|
| 29 | + Note that applications using the normal escaping mechanisms provided by Rails |
| 30 | + may not impacted, but applications that bypass the escaping mechanisms, or do |
| 31 | + not use them may be vulnerable. |
| 32 | +
|
| 33 | + All users running an affected release should either upgrade or use one of the |
| 34 | + workarounds immediately. |
| 35 | +
|
| 36 | + Releases |
| 37 | + -------- |
| 38 | + The 2.0.6 and 1.6.11 releases are available at the normal locations. |
| 39 | +
|
| 40 | + Workarounds |
| 41 | + ----------- |
| 42 | + The following monkey patch can be applied to work around this issue: |
| 43 | +
|
| 44 | + ``` |
| 45 | + require "rack" |
| 46 | + require "rack/request" |
| 47 | +
|
| 48 | + class Rack::Request |
| 49 | + SCHEME_WHITELIST = %w(https http).freeze |
| 50 | +
|
| 51 | + def scheme |
| 52 | + if get_header(Rack::HTTPS) == 'on' |
| 53 | + 'https' |
| 54 | + elsif get_header(HTTP_X_FORWARDED_SSL) == 'on' |
| 55 | + 'https' |
| 56 | + elsif forwarded_scheme |
| 57 | + forwarded_scheme |
| 58 | + else |
| 59 | + get_header(Rack::RACK_URL_SCHEME) |
| 60 | + end |
| 61 | + end |
| 62 | +
|
| 63 | + def forwarded_scheme |
| 64 | + scheme_headers = [ |
| 65 | + get_header(HTTP_X_FORWARDED_SCHEME), |
| 66 | + get_header(HTTP_X_FORWARDED_PROTO).to_s.split(',')[0] |
| 67 | + ] |
| 68 | +
|
| 69 | + scheme_headers.each do |header| |
| 70 | + return header if SCHEME_WHITELIST.include?(header) |
| 71 | + end |
| 72 | +
|
| 73 | + nil |
| 74 | + end |
| 75 | + end |
| 76 | + ``` |
| 77 | +
|
| 78 | +patched_versions: |
| 79 | + - "~> 1.6.11" |
| 80 | + - ">= 2.0.6" |
0 commit comments