CVE-2023-34103: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: Avo is an open source ruby on rails admin panel creation framework. In affected versions some avo fields are vulnerable to Cross Site Scripting (XSS) when rendering html based content. Attackers do need form edit privilege in order to successfully exploit this vulnerability, but the results are stored and no specific timing is required. This issue has been addressed in commit `7891c01e` which is expected to be included in the next release of avo. Users are advised to configure CSP headers for their application and to limit untrusted user access as a mitigation.
CWE description: The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
CVSS v3 base score: 5.4
Published: 2023-06-05T23:15Z
Repository: https://github.com/avo-hq/avo
Language: Ruby
Files changed: app/components/avo/alert_component.html.erb, app/components/avo/field_wrapper_component.html.erb, app/components/avo/fields/common/heading_component.html.erb, app/components/avo/fields/trix_field/edit_component.html.erb, app/components/avo/fields/trix_field/show_component.html.erb, app/components/avo/index/field_wrapper_component.html.erb
Commit date: 2023-06-05 23:38:42 +0300
Commit message: Merge pull request from GHSA-5cr9-5jx3-2g39


Diff: diff --git a/app/components/avo/alert_component.html.erb b/app/components/avo/alert_component.html.erb
index 6f840454..be55c147 100644
--- a/app/components/avo/alert_component.html.erb
+++ b/app/components/avo/alert_component.html.erb
@@ -8,11 +8,11 @@
       <div class="flex items-center min-h-full">
         <%= helpers.svg icon, class: "h-6" %>
       </div>
       <div class="ml-3 w-0 flex-1 pt-0.5">
         <p class="text-sm leading-5 font-semibold">
-          <%== message %>
+          <%= sanitize message %>
         </p>
       </div>
       <div class="ml-4 flex-shrink-0 flex items-center">
         <button data-action="alert#close" class="inline-flex text-white focus:outline-none focus:text-gray-300 transition ease-in-out duration-150">
           <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
diff --git a/app/components/avo/field_wrapper_component.html.erb b/app/components/avo/field_wrapper_component.html.erb
index df4d809a..992a4165 100644
--- a/app/components/avo/field_wrapper_component.html.erb
+++ b/app/components/avo/field_wrapper_component.html.erb
@@ -22,15 +22,15 @@
         <%= content %>
         <% if record.present? and record.errors.include? field.id %>
           <div class="text-red-600 mt-2 text-sm"><%= record.errors.full_messages_for(field.id).to_sentence %></div>
         <% end %>
         <% if help.present? %>
-          <div class="text-gray-600 mt-2 text-sm"><%== help %></div>
+          <div class="text-gray-600 mt-2 text-sm"><%= sanitize help %></div>
         <% end %>
       <% end %>
     </div>
   </div>
   <% if params[:avo_debug].present? %>
     <!-- Raw value: -->
-    <!-- <%== field.value.inspect %> -->
+    <!-- <%= sanitize field.value.inspect %> -->
   <% end %>
 <% end %>
diff --git a/app/components/avo/fields/common/heading_component.html.erb b/app/components/avo/fields/common/heading_component.html.erb
index 726853f1..3685e99b 100644
--- a/app/components/avo/fields/common/heading_component.html.erb
+++ b/app/components/avo/fields/common/heading_component.html.erb
@@ -1,11 +1,11 @@
 <div class="flex items-start py-1 leading-tight bg-gray-100 text-gray-500 text-xs">
   <div class="py-2 px-6 h-full w-full">
     <% if empty %>
     <% elsif value.present? %>
       <% if as_html %>
-        <%== value %>
+        <%= sanitize value %>
       <% else %>
         <div class="font-semibold uppercase"><%= value %></div>
       <% end %>
     <% else %>
       —
diff --git a/app/components/avo/fields/trix_field/edit_component.html.erb b/app/components/avo/fields/trix_field/edit_component.html.erb
index ecc8186b..5bd32074 100644
--- a/app/components/avo/fields/trix_field/edit_component.html.erb
+++ b/app/components/avo/fields/trix_field/edit_component.html.erb
@@ -18,11 +18,11 @@
         "trix-field-target": "editor",
         **@field.get_html(:data, view: view, element: :input)
       },
       input: trix_id,
       placeholder: @field.placeholder do %>
-      <%== @field.value %>
+      <%= sanitize @field.value %>
     <% end %>
     <%= @form.text_area @field.id,
       class: classes("w-full hidden"),
       data: @field.get_html(:data, view: view, element: :input),
       disabled: disabled?,
diff --git a/app/components/avo/fields/trix_field/show_component.html.erb b/app/components/avo/fields/trix_field/show_component.html.erb
index bb6067dc..847cbe51 100644
--- a/app/components/avo/fields/trix_field/show_component.html.erb
+++ b/app/components/avo/fields/trix_field/show_component.html.erb
@@ -6,9 +6,9 @@
   <div data-controller="hidden-input">
     <% unless @field.always_show %>
       <%= link_to t('avo.show_content'), 'javascript:void(0);', class: 'font-bold inline-block', data: { action: 'click->hidden-input#showContent' } %>
     <% end %>
     <div class="<%= content_classes %> " data-hidden-input-target="content">
-      <%== @field.value %>
+      <%= sanitize @field.value %>
     </div>
   </div>
 <% end %>
diff --git a/app/components/avo/index/field_wrapper_component.html.erb b/app/components/avo/index/field_wrapper_component.html.erb
index 7f1123a6..fd5868f2 100644
--- a/app/components/avo/index/field_wrapper_component.html.erb
+++ b/app/components/avo/index/field_wrapper_component.html.erb
@@ -17,8 +17,8 @@
       <%= content %>
     <% end %>
   <% end %>
   <% if params[:avo_debug].present? %>
     <!-- Raw value: -->
-    <!-- <%== @field.value.inspect %> -->
+    <!-- <%= sanitize @field.value.inspect %> -->
   <% end %>
 <% end %>

Vulnerable code:           <%== message %>
          <div class="text-gray-600 mt-2 text-sm"><%== help %></div>
    <!-- <%== field.value.inspect %> -->
        <%== value %>
      <%== @field.value %>
      <%== @field.value %>
    <!-- <%== @field.value.inspect %> -->
Fixed code:           <%= sanitize message %>
          <div class="text-gray-600 mt-2 text-sm"><%= sanitize help %></div>
    <!-- <%= sanitize field.value.inspect %> -->
        <%= sanitize value %>
      <%= sanitize @field.value %>
      <%= sanitize @field.value %>
    <!-- <%= sanitize @field.value.inspect %> -->