mirror of
https://git.yoctoproject.org/poky
synced 2026-04-19 06:32:13 +02:00
ruby/cgi-gem: CVE-2021-33621 HTTP response splitting in CGI
Upstream-Status: Backport from 64c5045c0a
(From OE-Core rev: dfe4a2b601e094e2922b671f6cf73ff6a91f061f)
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
This commit is contained in:
committed by
Steve Sakoman
parent
32da5ee951
commit
91feb9b975
139
meta/recipes-devtools/ruby/ruby/CVE-2021-33621.patch
Normal file
139
meta/recipes-devtools/ruby/ruby/CVE-2021-33621.patch
Normal file
@@ -0,0 +1,139 @@
|
||||
From 64c5045c0a6b84fdb938a8465a0890e5f7162708 Mon Sep 17 00:00:00 2001
|
||||
From: Yusuke Endoh <mame@ruby-lang.org>
|
||||
Date: Tue, 22 Nov 2022 10:49:27 +0900
|
||||
Subject: [PATCH] Prevent CRLF injection
|
||||
|
||||
Throw a RuntimeError if the HTTP response header contains CR or LF to
|
||||
prevent HTTP response splitting.
|
||||
|
||||
https://hackerone.com/reports/1204695
|
||||
|
||||
Upstream-Status: Backport [https://github.com/ruby/cgi/commit/64c5045c0a6b84fdb938a8465a0890e5f7162708]
|
||||
CVE: CVE-2021-33621
|
||||
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
|
||||
---
|
||||
lib/cgi/core.rb | 45 +++++++++++++++++++++++--------------
|
||||
test/cgi/test_cgi_header.rb | 8 +++++++
|
||||
2 files changed, 36 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/lib/cgi/core.rb b/lib/cgi/core.rb
|
||||
index bec76e0..62e6068 100644
|
||||
--- a/lib/cgi/core.rb
|
||||
+++ b/lib/cgi/core.rb
|
||||
@@ -188,17 +188,28 @@ class CGI
|
||||
# Using #header with the HTML5 tag maker will create a <header> element.
|
||||
alias :header :http_header
|
||||
|
||||
+ def _no_crlf_check(str)
|
||||
+ if str
|
||||
+ str = str.to_s
|
||||
+ raise "A HTTP status or header field must not include CR and LF" if str =~ /[\r\n]/
|
||||
+ str
|
||||
+ else
|
||||
+ nil
|
||||
+ end
|
||||
+ end
|
||||
+ private :_no_crlf_check
|
||||
+
|
||||
def _header_for_string(content_type) #:nodoc:
|
||||
buf = ''.dup
|
||||
if nph?()
|
||||
- buf << "#{$CGI_ENV['SERVER_PROTOCOL'] || 'HTTP/1.0'} 200 OK#{EOL}"
|
||||
+ buf << "#{_no_crlf_check($CGI_ENV['SERVER_PROTOCOL']) || 'HTTP/1.0'} 200 OK#{EOL}"
|
||||
buf << "Date: #{CGI.rfc1123_date(Time.now)}#{EOL}"
|
||||
- buf << "Server: #{$CGI_ENV['SERVER_SOFTWARE']}#{EOL}"
|
||||
+ buf << "Server: #{_no_crlf_check($CGI_ENV['SERVER_SOFTWARE'])}#{EOL}"
|
||||
buf << "Connection: close#{EOL}"
|
||||
end
|
||||
- buf << "Content-Type: #{content_type}#{EOL}"
|
||||
+ buf << "Content-Type: #{_no_crlf_check(content_type)}#{EOL}"
|
||||
if @output_cookies
|
||||
- @output_cookies.each {|cookie| buf << "Set-Cookie: #{cookie}#{EOL}" }
|
||||
+ @output_cookies.each {|cookie| buf << "Set-Cookie: #{_no_crlf_check(cookie)}#{EOL}" }
|
||||
end
|
||||
return buf
|
||||
end # _header_for_string
|
||||
@@ -213,9 +224,9 @@ class CGI
|
||||
## NPH
|
||||
options.delete('nph') if defined?(MOD_RUBY)
|
||||
if options.delete('nph') || nph?()
|
||||
- protocol = $CGI_ENV['SERVER_PROTOCOL'] || 'HTTP/1.0'
|
||||
+ protocol = _no_crlf_check($CGI_ENV['SERVER_PROTOCOL']) || 'HTTP/1.0'
|
||||
status = options.delete('status')
|
||||
- status = HTTP_STATUS[status] || status || '200 OK'
|
||||
+ status = HTTP_STATUS[status] || _no_crlf_check(status) || '200 OK'
|
||||
buf << "#{protocol} #{status}#{EOL}"
|
||||
buf << "Date: #{CGI.rfc1123_date(Time.now)}#{EOL}"
|
||||
options['server'] ||= $CGI_ENV['SERVER_SOFTWARE'] || ''
|
||||
@@ -223,38 +234,38 @@ class CGI
|
||||
end
|
||||
## common headers
|
||||
status = options.delete('status')
|
||||
- buf << "Status: #{HTTP_STATUS[status] || status}#{EOL}" if status
|
||||
+ buf << "Status: #{HTTP_STATUS[status] || _no_crlf_check(status)}#{EOL}" if status
|
||||
server = options.delete('server')
|
||||
- buf << "Server: #{server}#{EOL}" if server
|
||||
+ buf << "Server: #{_no_crlf_check(server)}#{EOL}" if server
|
||||
connection = options.delete('connection')
|
||||
- buf << "Connection: #{connection}#{EOL}" if connection
|
||||
+ buf << "Connection: #{_no_crlf_check(connection)}#{EOL}" if connection
|
||||
type = options.delete('type')
|
||||
- buf << "Content-Type: #{type}#{EOL}" #if type
|
||||
+ buf << "Content-Type: #{_no_crlf_check(type)}#{EOL}" #if type
|
||||
length = options.delete('length')
|
||||
- buf << "Content-Length: #{length}#{EOL}" if length
|
||||
+ buf << "Content-Length: #{_no_crlf_check(length)}#{EOL}" if length
|
||||
language = options.delete('language')
|
||||
- buf << "Content-Language: #{language}#{EOL}" if language
|
||||
+ buf << "Content-Language: #{_no_crlf_check(language)}#{EOL}" if language
|
||||
expires = options.delete('expires')
|
||||
buf << "Expires: #{CGI.rfc1123_date(expires)}#{EOL}" if expires
|
||||
## cookie
|
||||
if cookie = options.delete('cookie')
|
||||
case cookie
|
||||
when String, Cookie
|
||||
- buf << "Set-Cookie: #{cookie}#{EOL}"
|
||||
+ buf << "Set-Cookie: #{_no_crlf_check(cookie)}#{EOL}"
|
||||
when Array
|
||||
arr = cookie
|
||||
- arr.each {|c| buf << "Set-Cookie: #{c}#{EOL}" }
|
||||
+ arr.each {|c| buf << "Set-Cookie: #{_no_crlf_check(c)}#{EOL}" }
|
||||
when Hash
|
||||
hash = cookie
|
||||
- hash.each_value {|c| buf << "Set-Cookie: #{c}#{EOL}" }
|
||||
+ hash.each_value {|c| buf << "Set-Cookie: #{_no_crlf_check(c)}#{EOL}" }
|
||||
end
|
||||
end
|
||||
if @output_cookies
|
||||
- @output_cookies.each {|c| buf << "Set-Cookie: #{c}#{EOL}" }
|
||||
+ @output_cookies.each {|c| buf << "Set-Cookie: #{_no_crlf_check(c)}#{EOL}" }
|
||||
end
|
||||
## other headers
|
||||
options.each do |key, value|
|
||||
- buf << "#{key}: #{value}#{EOL}"
|
||||
+ buf << "#{_no_crlf_check(key)}: #{_no_crlf_check(value)}#{EOL}"
|
||||
end
|
||||
return buf
|
||||
end # _header_for_hash
|
||||
diff --git a/test/cgi/test_cgi_header.rb b/test/cgi/test_cgi_header.rb
|
||||
index bab2d03..ec2f4de 100644
|
||||
--- a/test/cgi/test_cgi_header.rb
|
||||
+++ b/test/cgi/test_cgi_header.rb
|
||||
@@ -176,6 +176,14 @@ class CGIHeaderTest < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
|
||||
+ def test_cgi_http_header_crlf_injection
|
||||
+ cgi = CGI.new
|
||||
+ assert_raise(RuntimeError) { cgi.http_header("text/xhtml\r\nBOO") }
|
||||
+ assert_raise(RuntimeError) { cgi.http_header("type" => "text/xhtml\r\nBOO") }
|
||||
+ assert_raise(RuntimeError) { cgi.http_header("status" => "200 OK\r\nBOO") }
|
||||
+ assert_raise(RuntimeError) { cgi.http_header("location" => "text/xhtml\r\nBOO") }
|
||||
+ end
|
||||
+
|
||||
|
||||
instance_methods.each do |method|
|
||||
private method if method =~ /^test_(.*)/ && $1 != ENV['TEST']
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -8,6 +8,7 @@ SRC_URI += " \
|
||||
file://0001-Modify-shebang-of-libexec-y2racc-and-libexec-racc2y.patch \
|
||||
file://0001-template-Makefile.in-do-not-write-host-cross-cc-item.patch \
|
||||
file://CVE-2023-28756.patch \
|
||||
file://CVE-2021-33621.patch \
|
||||
"
|
||||
|
||||
SRC_URI[md5sum] = "f972fb0cce662966bec10d5c5f32d042"
|
||||
|
||||
Reference in New Issue
Block a user