<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet href="/static/style.xsl" type="text/xsl"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">
  <channel>
    <title>Most recent entries from all</title>
    <link>https://vulnerability.circl.lu</link>
    <description>Contains only the most 10 recent entries.</description>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>python-feedgen</generator>
    <language>en</language>
    <lastBuildDate>Wed, 30 Sep 2026 06:34:36 +0000</lastBuildDate>
    <item>
      <title>CVE-2026-54696 — Ruby JSON: JSON generator heap buffer overflow when streaming to an IO</title>
      <link>https://vulnerability.circl.lu/vuln/cve-2026-54696</link>
      <description>&lt;p&gt;&lt;strong&gt;Affected:&lt;/strong&gt; ruby json&lt;/p&gt;
&lt;p&gt;Ruby JSON is a JSON implementation for Ruby. Versions 2.9.0 through 2.19.8 are vulnerable to heap buffer overflow when the JSON generator is provided with an oversized streamed object. When streaming to an IO JSON.dump(obj, io) and JSON::State#generate(obj, io) can write past the internal JSON generator buffer when a streamed object contains an
attacker-controlled string near 16 KB. Exploitation would result in a reliable process crash/denial of service. This issue has been fixed in version 2.19.9.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;&lt;strong&gt;Affected:&lt;/strong&gt; ruby json&lt;/p&gt;
&lt;p&gt;Ruby JSON is a JSON implementation for Ruby. Versions 2.9.0 through 2.19.8 are vulnerable to heap buffer overflow when the JSON generator is provided with an oversized streamed object. When streaming to an IO JSON.dump(obj, io) and JSON::State#generate(obj, io) can write past the internal JSON generator buffer when a streamed object contains an
attacker-controlled string near 16 KB. Exploitation would result in a reliable process crash/denial of service. This issue has been fixed in version 2.19.9.&lt;/p&gt;</content:encoded>
      <guid isPermaLink="false">https://vulnerability.circl.lu/vuln/cve-2026-54696</guid>
    </item>
    <item>
      <title>GHSA-x2f5-4prf-w687 — Ruby json: JSON generator heap buffer overflow when streaming to an IO</title>
      <link>https://vulnerability.circl.lu/vuln/ghsa-x2f5-4prf-w687</link>
      <description>&lt;p&gt;&lt;strong&gt;Affected:&lt;/strong&gt; RubyGems: json&lt;/p&gt;
&lt;p&gt;### Summary&lt;/p&gt;
&lt;p&gt;`JSON.dump(obj, io)` and `JSON::State#generate(obj, io)` can write past the
internal JSON generator buffer when a streamed object contains an
attacker-controlled string near 16 KB. The issue is a heap out-of-bounds write
in the IO-streaming path and is demonstrated as a reliable process crash /
denial of service.&lt;/p&gt;
&lt;p&gt;This was triaged on HackerOne as report #3785370. The issue was confirmed there
and I was asked to open it here.&lt;/p&gt;
&lt;p&gt;### Details&lt;/p&gt;
&lt;p&gt;Root cause is in `ext/json/fbuffer/fbuffer.h`, `fbuffer_do_inc_capa()`.&lt;/p&gt;
&lt;p&gt;On the IO path, the buffer is grown to `FBUFFER_IO_BUFFER_SIZE` (16383), but the
early return checks total capacity instead of remaining capacity:&lt;/p&gt;
&lt;p&gt;```c
if (RB_UNLIKELY(fb-&amp;gt;io)) {
    if (fb-&amp;gt;capa &amp;lt; FBUFFER_IO_BUFFER_SIZE) {
        fbuffer_realloc(fb, FBUFFER_IO_BUFFER_SIZE);
    } else {
        fbuffer_flush(fb);
    }&lt;/p&gt;
&lt;p&gt;if (RB_LIKELY(requested &amp;lt; fb-&amp;gt;capa)) {
        return;
    }
}
```&lt;/p&gt;
&lt;p&gt;If `fb-&amp;gt;len` already contains JSON syntax bytes, and a string flush has
`16383 - fb-&amp;gt;len &amp;lt;= requested &amp;lt; 16383`, this check returns even though there is
not enough space left. `fbuffer_append_reserved()` then writes past the buffer:&lt;/p&gt;
&lt;p&gt;```c
MEMCPY(fb-&amp;gt;ptr + fb-&amp;gt;len, newstr, char, len);
```&lt;/p&gt;
&lt;p&gt;The minimal fix is to compare against the remaining capacity:&lt;/p&gt;
&lt;p&gt;```diff
-        if (RB_LIKELY(requested &amp;lt; fb-&amp;gt;capa)) {
+        if (RB_LIKELY(requested &amp;lt;= fb-&amp;gt;capa - fb-&amp;gt;len)) {
             return;
         }
```&lt;/p&gt;
&lt;p&gt;### PoC&lt;/p&gt;
&lt;p&gt;```ruby
require &amp;#34;json&amp;#34;
require &amp;#34;stringio&amp;#34;&lt;/p&gt;
&lt;p&gt;io = StringIO.new…&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;&lt;strong&gt;Affected:&lt;/strong&gt; RubyGems: json&lt;/p&gt;
&lt;p&gt;### Summary&lt;/p&gt;
&lt;p&gt;`JSON.dump(obj, io)` and `JSON::State#generate(obj, io)` can write past the
internal JSON generator buffer when a streamed object contains an
attacker-controlled string near 16 KB. The issue is a heap out-of-bounds write
in the IO-streaming path and is demonstrated as a reliable process crash /
denial of service.&lt;/p&gt;
&lt;p&gt;This was triaged on HackerOne as report #3785370. The issue was confirmed there
and I was asked to open it here.&lt;/p&gt;
&lt;p&gt;### Details&lt;/p&gt;
&lt;p&gt;Root cause is in `ext/json/fbuffer/fbuffer.h`, `fbuffer_do_inc_capa()`.&lt;/p&gt;
&lt;p&gt;On the IO path, the buffer is grown to `FBUFFER_IO_BUFFER_SIZE` (16383), but the
early return checks total capacity instead of remaining capacity:&lt;/p&gt;
&lt;p&gt;```c
if (RB_UNLIKELY(fb-&amp;gt;io)) {
    if (fb-&amp;gt;capa &amp;lt; FBUFFER_IO_BUFFER_SIZE) {
        fbuffer_realloc(fb, FBUFFER_IO_BUFFER_SIZE);
    } else {
        fbuffer_flush(fb);
    }&lt;/p&gt;
&lt;p&gt;if (RB_LIKELY(requested &amp;lt; fb-&amp;gt;capa)) {
        return;
    }
}
```&lt;/p&gt;
&lt;p&gt;If `fb-&amp;gt;len` already contains JSON syntax bytes, and a string flush has
`16383 - fb-&amp;gt;len &amp;lt;= requested &amp;lt; 16383`, this check returns even though there is
not enough space left. `fbuffer_append_reserved()` then writes past the buffer:&lt;/p&gt;
&lt;p&gt;```c
MEMCPY(fb-&amp;gt;ptr + fb-&amp;gt;len, newstr, char, len);
```&lt;/p&gt;
&lt;p&gt;The minimal fix is to compare against the remaining capacity:&lt;/p&gt;
&lt;p&gt;```diff
-        if (RB_LIKELY(requested &amp;lt; fb-&amp;gt;capa)) {
+        if (RB_LIKELY(requested &amp;lt;= fb-&amp;gt;capa - fb-&amp;gt;len)) {
             return;
         }
```&lt;/p&gt;
&lt;p&gt;### PoC&lt;/p&gt;
&lt;p&gt;```ruby
require &amp;#34;json&amp;#34;
require &amp;#34;stringio&amp;#34;&lt;/p&gt;
&lt;p&gt;io = StringIO.new…&lt;/p&gt;</content:encoded>
      <guid isPermaLink="false">https://vulnerability.circl.lu/vuln/ghsa-x2f5-4prf-w687</guid>
    </item>
  </channel>
</rss>
