Feature #21258
closedRetire CGI library from Ruby 3.5
Description
I would like to retire CGI library from Ruby 3.5.0 release. It means CGI is not promoted bundled gems. The users need to run gem install cgi after Ruby 3.5 if they want to use CGI library.
Background¶
I handled two CVEs related CGI library at https://www.ruby-lang.org/en/news/2025/02/26/security-advisories/
We shouldn't spend our time to maintain CGI library in the future because CGI is old protocol. In fact, Perl 5.22.0 removed CGI.pm at 2015, Python 3.13 also removed cgi at Nov 2024.
Problem¶
CGI is not using widely today. But cgi/escape is core feature in Ruby ecosystem. erb, net-http and bundler depend CGI.escape/CGI.unescape. And CGI.escapeHTML, CGI.escapeURIComponent are used at that libraries.
Solution¶
- We keep only
cgi/escapefeature in Ruby. The current CGI library is removed and dependcgi-utilgem. - We migrate
cgi/escapeto other class/module. The current CGI library andcgi/escapeare removed. - 2 + We provide
cgi-utilgem for migration with deprecated warning at Ruby 3.5. In next year, we will removecgi-utilgem.
The new class/module location is diffcult. I discussed that with some Ruby core member.
-
URI.escape/unescape:URI.escapeis migrated toURI::RFC2396_PARSER.escapeat Ruby 3.4. The newURI.escapeis confusing name with historical reason. -
URI::Util.escape: It seems okay...?
I think URI or related name are good place for that because other language provide that under the url libraries:
Python:
import urllib.parse
urllib.parse.quote()
Java:
import java.net.URLEncoder;
URLEncoder.encode()
Go:
import "net/url"
url.QueryEscape()
Migration plan¶
If Idea 2 is accepted and decide new location, We provide dummy module and method for cgi/escape. That dummy module call new method and warn about deprecating cgi/escape.
Updated by soutaro (Soutaro Matsumoto) 7 months ago
I like the idea of deprecating CGI and moving the escape/unescape methods!
JavaScript calls the features "hello".encode_uri_component, so can we call it String#encode_uri_component?
(I don't think this is the way we should go, but I believe it's better than CGI.escape.)
The straightforward name would be URI.escape, but I understand that it's difficult for historical reason.
Updated by kou (Kouhei Sutou) 7 months ago
URI.encode (not escape)?
Updated by jeremyevans0 (Jeremy Evans) 7 months ago
I am in favor of retiring cgi and keeping cgi/escape feature. Of the two options, I prefer option 1 (keep only cgi/escape feature in Ruby). It is the more backwards compatible option, and I do not think the benefits of using a new module outweigh the backwards compatibility costs.
Updated by hsbt (Hiroshi SHIBATA) 7 months ago
@kou (Kouhei Sutou) +1, @tompng (tomoya ishida) suggest URI.escape_query_param. I prefer these approachs.
@jeremyevans0 (Jeremy Evans) I understood your concerns. But we need to keep looking for descriptive and meaningful module/class for the new Ruby users.
Updated by tompng (tomoya ishida) 7 months ago
CGI.escape_uri_component and URI.encode_uri_component are almost the same except * and ~.
CGI.escape and URI.encode_www_form_component are also almost the same except * and ~.
Do we really need to properly use these four methods? If not, I think URI already have enough encode methods for two purpose.
I suggested URI.escape_query_param but now I think something like URI.encode_www_form_component_cgi_style would be more descriptive. Long naming is good if we don't recommend it over URI.encode_www_form_component.
| Method/Function | Spec |
|---|---|
| CGI.escape_uri_component | RFC3986 |
| CGI.escape | www-form-urlencoded version of CGI.escape_uri_component. I think this gem-cgi-style spec doesn't have a name. |
| URI.encode_uri_component | uri-component version of URI.encode_www_form_component |
| URI.encode_www_form_component | https://url.spec.whatwg.org/#application-x-www-form-urlencoded-percent-encode-set |
| JavaScript: encodeURIComponent | https://url.spec.whatwg.org/#component-percent-encode-set |
Updated by hsbt (Hiroshi SHIBATA) 6 months ago
- Description updated (diff)
Updated by hsbt (Hiroshi SHIBATA) 6 months ago
- Status changed from Open to Assigned
- Assignee set to hsbt (Hiroshi SHIBATA)
We discussed this in devmeeting.
We decided the followings:
- To remove
cgilibrary withoutCGI.escape*andCGI.unescape*methods.- It includes
escapeURIComponent,unescapeURIComponent,escapeHTML,unescapeHTML,escapeElement,unescapeElement
- It includes
- Make to load them with
cgi/escapeinstead ofcgi/util. - Keep
cgi/escapein the future.- Renaming or moving them to another class/module is another discussion.
- Provide warning and fallback wrapper by
cgi.rbandcgi/util.rb. It helps the users who usedcgiorcgi/utilfor likeCGI.escapemethods.
We are not sure we should publich cgi-escape gem now. I tried to remove cgi library without cgi-escape gem at https://github.com/ruby/ruby/pull/13275
Updated by MSP-Greg (Greg L) 6 months ago
With recent commits, it seems that a cgi.gemspec is not created.
erb.gemspec shows it as a dependency?
Updated by byroot (Jean Boussier) 6 months ago
It means CGI is not promoted bundled gems.
Is there a reason to skip this step?
For previous extractions we could rely on warnings to keep track of gems that need to be updated while continue to test ruby-head, with this immediate extraction lots of CI are broken all across the ecosystem and going back to passing build will take a long time.
Updated by getajobmike (Mike Perham) 6 months ago
CGI may be an "old" protocol but that maturity brings stability. It means I don't need to run an app server process (like puma) at all. I don't need to worry about open ports, memory leaks, resource leaks, connection pooling, etc. It's extremely reliable and requires zero maintenance from me.
I have no problem pulling in the gem. If you need someone to help maintain it, I would be happy to help.
Updated by hsbt (Hiroshi SHIBATA) 5 months ago
- Status changed from Assigned to Closed
I released cgi-0.5.0 that has same interface with ruby-head
https://github.com/ruby/cgi/releases/tag/v0.5.0
Is there a reason to skip this step?
The bundled gems are still shipped with Ruby package, so we may make an announcement as we did with https://www.ruby-lang.org/en/news/2025/04/28/dos-net-imap-cve-2025-43857/, and it may also be necessary to bump a bundled version. I would like to leave that security work of CGI immediately.
FYI: I'm a heavy user of CGI library. I'm maintaining CGI application like https://github.com/tdiary/tdiary-core/ and use it every day.