Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-61696

CVE-2026-61696: Forem Stored XSS Vulnerability

CVE-2026-61696 is a stored XSS vulnerability in Forem that allows attackers to execute arbitrary JavaScript in administrator browsers through unsanitized feedback messages. This article covers technical details, impact, and mitigation.

Published:

CVE-2026-61696 Overview

CVE-2026-61696 is a stored cross-site scripting (XSS) vulnerability in Forem, an open source platform for building online communities. The flaw exists in the FeedbackMessagesController, which is publicly accessible and accepts abuse reports without authentication. An unauthenticated attacker can submit a crafted feedback_message[message] value along with an offender_id parameter. The malicious payload is stored without sanitization and later rendered using raw(feedback_message.message) in app/views/admin/feedback_messages/_feedback_message.html.erb. When an administrator views the abuse report, arbitrary JavaScript executes in their browser session.

Critical Impact

Unauthenticated attackers can execute arbitrary JavaScript in an administrator's browser, exposing sensitive in-page data, abusing CSRF tokens, or performing administrative actions in the victim's session.

Affected Products

  • Forem versions prior to commit 92eacd16a82cf9007ba8e16a2258b42e3b53ca9c
  • Self-hosted Forem community instances
  • DEV Community-derived deployments running vulnerable Forem builds

Discovery Timeline

  • 2026-08-18 - CVE-2026-61696 published to NVD
  • 2026-08-18 - Last updated in NVD database

Technical Details for CVE-2026-61696

Vulnerability Analysis

The vulnerability is a stored XSS classified under [CWE-74] (Improper Neutralization of Special Elements in Output). Forem's FeedbackMessagesController skips CSRF verification and requires no authorization, exposing the endpoint to any unauthenticated client on the network. The controller previously included offender_id in its allowed parameters list, which triggered the vulnerable rendering path in the administrative view.

When an administrator opens the abuse report in /admin/feedback_messages, the partial _feedback_message.html.erb calls raw(feedback_message.message) to render the attacker-supplied string. Because raw bypasses Rails' default HTML escaping, any <script> tag or event handler embedded in the message executes with the administrator's session context.

Root Cause

The root cause is unsafe output rendering combined with an over-permissive public input surface. The administrative partial trusts stored feedback content and passes it directly to raw, and the public controller accepted offender_id from unauthenticated submitters, making the vulnerable admin view reachable via user-controlled data.

Attack Vector

An unauthenticated attacker submits a POST request to the public feedback endpoint containing a malicious script payload in feedback_message[message] and any value in offender_id. The payload is persisted to the database. When an administrator later reviews the abuse report queue, the script runs in their authenticated browser context and can steal CSRF tokens, invoke administrative APIs, or exfiltrate sensitive DOM content.

ruby
 class FeedbackMessagesController < ApplicationController
   # No authorization required for entirely public controller
   skip_before_action :verify_authenticity_token
-  FEEDBACK_ALLOWED_PARAMS = %i[message feedback_type category reported_url offender_id].freeze
+  FEEDBACK_ALLOWED_PARAMS = %i[message feedback_type category reported_url].freeze
 
   def create
     flash.clear

Source: GitHub Commit 92eacd1 — the patch removes offender_id from user-controlled parameters so the vulnerable admin rendering path is no longer reachable by unauthenticated input.

ruby
   CATEGORIES = ["spam", "other", "rude or vulgar", "harassment", "bug", "listings"].freeze
   STATUSES = %w[Open Invalid Resolved].freeze
 
-  before_save :determine_reported_from_url
+  before_save :determine_reported_from_url, :assign_offender_from_reported
 
   def self.reporter_uniqueness_msg
     I18n.t("models.feedback_message.reported")

Source: GitHub Commit 92eacd1 — the model now derives offender server-side from the reported URL rather than trusting attacker input.

Detection Methods for CVE-2026-61696

Indicators of Compromise

  • POST requests to /feedback_messages containing HTML tags, <script>, onerror=, or javascript: substrings in the message field.
  • Feedback records in the database whose message column contains script tags, event handlers, or encoded JavaScript.
  • Unexpected outbound requests from administrator browsers to attacker-controlled domains shortly after visiting /admin/feedback_messages.
  • Administrative actions (user bans, role changes, content deletions) originating from admin sessions without corresponding UI navigation logs.

Detection Strategies

  • Inspect application logs for POST requests to the feedback endpoint that include payload signatures common to XSS (<script, onload=, onerror=, document.cookie).
  • Run a database query against the feedback messages table to identify stored entries containing HTML or script markup.
  • Correlate admin session activity with feedback-message page views to identify anomalous CSRF-token-authenticated calls.

Monitoring Recommendations

  • Enable a Content Security Policy (CSP) in report-only mode on /admin/feedback_messages and alert on script-src violations.
  • Ingest Rails application and web server access logs into a centralized SIEM and tag traffic to FeedbackMessagesController#create.
  • Monitor administrator accounts for privileged API calls that occur within seconds of loading the abuse report views.

How to Mitigate CVE-2026-61696

Immediate Actions Required

  • Upgrade Forem to a build that includes commit 92eacd16a82cf9007ba8e16a2258b42e3b53ca9c or later.
  • Audit the feedback messages table for stored payloads containing HTML or JavaScript and purge malicious entries before administrators view the queue.
  • Rotate administrator session cookies and API tokens if you suspect a payload was viewed prior to patching.

Patch Information

The issue is fixed in Forem commit 92eacd16a82cf9007ba8e16a2258b42e3b53ca9c. The patch removes offender_id from FEEDBACK_ALLOWED_PARAMS in app/controllers/feedback_messages_controller.rb and adds an assign_offender_from_reported callback in app/models/feedback_message.rb so the offender is derived server-side. See the GitHub Security Advisory GHSA-4463-499m-94mx for full details.

Workarounds

  • Temporarily restrict access to /admin/feedback_messages at the web server or load balancer until the patch is applied.
  • Deploy a strict Content Security Policy that disallows inline scripts on admin routes to blunt payload execution.
  • Apply a WAF rule that blocks POST requests to /feedback_messages containing <script, onerror=, or javascript: substrings in the message parameter.
bash
# Example WAF rule to block obvious XSS payloads on the public feedback endpoint
SecRule REQUEST_URI "@streq /feedback_messages" \
  "chain,phase:2,deny,status:403,id:1026616960,msg:'CVE-2026-61696 XSS payload blocked'"
  SecRule ARGS:feedback_message[message] "@rx (?i)(<script|onerror=|onload=|javascript:)" "t:none"

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.