SECURITYHIGHCVE-2026-105221

CVE-2026-105221: gist RubyGem Disables TLS Certificate Validation, Exposing GitHub OAuth Tokens

The gist RubyGem before 6.1.0 sets VERIFY_NONE on every HTTPS connection, letting on-path attackers intercept GitHub API traffic and steal OAuth tokens.

Dylan H.

Security Team

October 5, 2026
7 min read
CVE-2026-105221: gist RubyGem Disables TLS Certificate Validation, Exposing GitHub OAuth Tokens

Affected Products

  • gist RubyGem before 6.1.0

Overview

A certificate-validation flaw has been disclosed in gist, the popular Ruby command-line client for creating and managing GitHub Gists (defunkt/gist). Tracked as CVE-2026-105221 with a CVSS 3.1 score of 7.4 (High) and a CVSS 4.0 score of 9.1, the flaw lives in the http_connection method inside lib/gist.rb, which explicitly sets OpenSSL's verification mode to VERIFY_NONE on every outbound HTTPS connection the tool makes to the GitHub API.

With certificate verification disabled, the gist CLI will accept any TLS certificate presented during the handshake — self-signed, expired, or issued for an entirely different hostname — and still establish what it believes is a secure connection. An on-path (man-in-the-middle) attacker positioned between a user and GitHub's infrastructure — on a malicious Wi-Fi network, a compromised proxy, or a poisoned DNS/ARP path — can intercept, read, and modify all traffic the gem sends and receives, including the OAuth access token gist uses to authenticate to the GitHub API.


Technical Details

FieldValue
CVE IDCVE-2026-105221
SeverityHigh (CVSS 3.1: 7.4, CVSS 4.0: 9.1)
CVSS 3.1 VectorCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N
CWECWE-295 — Improper Certificate Validation
Attack VectorNetwork (requires on-path / MITM position)
AuthenticationNone Required
Privileges RequiredNone
User InteractionNone
ImpactConfidentiality and Integrity (no availability impact)
Affected Versionsgist RubyGem ≥ 4.0.0, ≤ 6.0.x (before 6.1.0)
Fixed Version6.1.0
AssignerVulnCheck
Published2026-10-04

How It Works

The gist gem builds its own HTTP client wrapper around Ruby's Net::HTTP for every call it makes to the GitHub API — authenticating, uploading gist content, listing gists, and so on. Inside http_connection in lib/gist.rb (lines 466–468 in the 6.0.0 release), the client configures its Net::HTTP object's verify_mode as:

http.verify_mode = OpenSSL::SSL::VERIFY_NONE

VERIFY_NONE tells OpenSSL to skip the entire certificate-chain and hostname-validation process. The TLS handshake still negotiates encryption, so traffic looks protected — there's no browser-style warning, no connection failure, nothing a user would notice — but the client never confirms it is actually talking to api.github.com. An attacker who can position themselves on the network path (hostile public Wi-Fi, a compromised corporate proxy, ARP/DNS spoofing on a LAN, or a malicious exit node) can present a trivially self-signed certificate for api.github.com and the gem will accept it without complaint.

According to public reporting on the issue history, this setting did not start out malicious — it traces back to an old GitHub issue where a user hit a certificate verify failed error (commonly caused by a missing or outdated local CA bundle) and the workaround suggested at the time was to swap VERIFY_PEER for VERIFY_NONE. That workaround was apparently folded into the gem itself and shipped as the permanent default for every subsequent release through 6.0.x, rather than being limited to a documented escape hatch for broken CA bundles.

Because gist handles the OAuth token used to authenticate to the GitHub API on the user's behalf, an attacker sitting on the connection can:

  • Capture the OAuth token from the Authorization header on any request the CLI makes
  • Read the content of gists being created, fetched, or listed in that session
  • Modify responses or requests in transit, for example tampering with gist content being uploaded, or returning forged API responses to the CLI

Any captured OAuth token can then be replayed directly against the GitHub API, independent of the vulnerable gem, until the token is revoked — extending the impact well beyond the single intercepted session.


Impact Assessment

Impact AreaDescription
Credential TheftOAuth tokens sent by the gist CLI can be captured in cleartext by an on-path attacker and reused against the GitHub API outside the victim's machine
Data ExposurePrivate gist content transmitted during create/read/update operations can be read by the attacker, even though the connection appears encrypted
Data IntegrityAn attacker able to intercept traffic can tamper with gist content or API responses before they reach the client or GitHub
Scope of ExposureEvery call the gem makes — not just login — is affected, since VERIFY_NONE is set unconditionally for all HTTPS connections http_connection opens
Detection DifficultyNo TLS error, warning, or failed connection is surfaced to the user; the interception is silent by design
Exploitation StatusNot listed in the CISA Known Exploited Vulnerabilities (KEV) catalog; no public proof-of-concept observed as of publication

The realistic exploitation scenario requires the attacker to already hold an on-path position relative to the victim's network traffic — this is not a remote, internet-wide exploit. That said, the gist CLI is commonly run from laptops on untrusted networks (coffee shops, conference Wi-Fi, hotel networks, shared or compromised corporate proxies), which are exactly the conditions under which on-path attacks are most practical and least likely to be noticed.


Mitigation

Immediate Actions

  • Upgrade to gist RubyGem 6.1.0 or later immediately: gem update gist, or update the Gemfile/gemspec pin and run bundle update gist
  • Revoke and regenerate the OAuth token gist uses (stored by the gem for GitHub API access) if the tool has been used on any untrusted network while running a pre-6.1.0 version
  • Audit CI/CD pipelines and dev containers that invoke gist programmatically — any automated job calling the gem over a network path you don't fully control carries the same exposure
  • If upgrading is not immediately possible, avoid running gist on untrusted networks (public Wi-Fi, unmanaged VPNs, shared proxies) until patched

Detection Opportunities

  • Review GitHub account security logs / audit log for OAuth token usage from unexpected IP addresses or locations around periods when gist was used on an untrusted network
  • Network defenders can look for TLS handshakes to api.github.com with anomalous or self-signed certificates in proxy/TLS-inspection logs — a sign that interception succeeded against a vulnerable client
  • Check installed gem versions across developer workstations and build agents: gem list gist -a to confirm no host is still running a version earlier than 6.1.0

Defence-in-Depth

  • Pin and regularly audit third-party CLI tooling dependencies (Gemfile.lock, gem list) as part of routine developer-environment hygiene, not just application dependencies
  • Where feasible, run developer tooling that handles credentials (OAuth tokens, API keys) through a VPN or trusted network egress rather than directly on untrusted Wi-Fi
  • Treat any gem, script, or tool that wraps its own HTTP/TLS client (instead of relying on a vetted library's defaults) as higher risk — custom verify_mode handling is a recurring source of exactly this class of bug
  • Consider short-lived or fine-grained GitHub personal access tokens over long-lived OAuth tokens where your workflow allows it, to limit the blast radius of any future credential interception

Discovery & Disclosure

CVE-2026-105221 was assigned by VulnCheck and published on 2026-10-04. Public reporting has not identified a named individual discoverer for this issue, and as of publication the vulnerability is not listed in the CISA KEV catalog with no public proof-of-concept exploit observed. The fix landed in the defunkt/gist repository in commit 07ccc1a6d46e9d36f0e85d0b1c5d795890ae6bcf, which removes the hardcoded VERIFY_NONE setting and restores standard certificate verification, released as part of gist 6.1.0. The issue is also referenced against the project's existing GitHub Issue #373.


References