CVE-2021-25969: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: In Camaleon CMS application, versions 0.0.1 to 2.6.0 are vulnerable to stored XSS, that allows an unauthenticated attacker to store malicious scripts in the comments section of the post. These scripts are executed in a victim’s browser when they open the page containing the malicious comment.
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: 6.1
Published: 2021-10-20T12:15Z
Repository: https://github.com/owen2345/camaleon-cms
Language: Ruby
Files changed: app/apps/themes/default/views/partials/_comments_list.html.erb, app/helpers/camaleon_cms/comment_helper.rb, app/views/camaleon_cms/default_theme/partials/_comments_list.html.erb, app/views/camaleon_cms/default_theme/partials/_comments_list2.html.erb
Commit date: 2021-10-11 23:52:00 -0500
Commit message: Sanitize comments

Diff: diff --git a/app/apps/themes/default/views/partials/_comments_list.html.erb b/app/apps/themes/default/views/partials/_comments_list.html.erb
index dae5b025..fe5fe80c 100644
--- a/app/apps/themes/default/views/partials/_comments_list.html.erb
+++ b/app/apps/themes/default/views/partials/_comments_list.html.erb
@@ -9,12 +9,12 @@
             <div class="panel panel-default">
                 <div class="panel-heading">
                     <strong class="<%= (children.present?)? "pull-right" : "" %>"><%= user.the_name %></strong> <small class="text-muted <%= (children.present?)? "" : "pull-right" %>"><%= comment.decorate.the_created_at %></small>
                 </div>
                 <div class="panel-body">
-                    <%= raw comment.content %>
+                    <%= comment.content %>
                 </div><!-- /panel-body -->
             </div><!-- /panel panel-default -->
         </div><!-- /col-sm-5 -->
     </div>
     <%= render partial: "partials/comments_list", locals: { comments: comment.children.approveds, children: "present" }  if comment.children.present? %>
-<% end %>
\ No newline at end of file
+<% end %>
diff --git a/app/helpers/camaleon_cms/comment_helper.rb b/app/helpers/camaleon_cms/comment_helper.rb
index a8bf78cb..93207beb 100644
--- a/app/helpers/camaleon_cms/comment_helper.rb
+++ b/app/helpers/camaleon_cms/comment_helper.rb
@@ -23,11 +23,11 @@ module CamaleonCms::CommentHelper
                  <div class='media-left'>
                     <a href='#{author.the_admin_profile_url}'>#{image_tag author.the_avatar, class: 'media-object', style: 'width: 64px; height: 64px;'}</a>
                  </div>
                  <div class='media-body'>
                     <h4 class='media-heading'>#{author.the_name} <small>#{comment.the_created_at}</small> <span class='label label-#{labels[comment.approved]} pull-right'>#{t("camaleon_cms.admin.comments.message.#{comment.approved}")}</span></h4>
-                    <div class='comment_content'>#{comment.content}</div>
+                    <div class='comment_content'>#{sanitize comment.content}</div>
                     <div class='comment_actions'>
                         <div class='pull-left'>
                             <a href='#{cama_admin_post_comment_answer_path(@post.id, comment.id)}' data-comment-id='#{comment.id}' title='#{t('camaleon_cms.admin.comments.tooltip.reply_comment')}' class='btn btn-info reply btn-xs ajax_modal'><span class='fa fa-mail-reply'></span></a>
                             #{link_to raw('<i class="fa fa-trash-o"></i>'), { action: :destroy, id: comment.id }, method: :delete, data: { confirm: t('camaleon_cms.admin.message.delete') }, class: "btn btn-danger btn-xs cama_ajax_request", title: "#{t('camaleon_cms.admin.comments.tooltip.delete_comment')}" }
                         </div>
diff --git a/app/views/camaleon_cms/default_theme/partials/_comments_list.html.erb b/app/views/camaleon_cms/default_theme/partials/_comments_list.html.erb
index 15b512c5..6b1702c0 100644
--- a/app/views/camaleon_cms/default_theme/partials/_comments_list.html.erb
+++ b/app/views/camaleon_cms/default_theme/partials/_comments_list.html.erb
@@ -10,12 +10,12 @@
             <div class="panel panel-default">
                 <div class="panel-heading">
                     <strong class=""><%= link_to(user.the_name, user.the_url) %></strong> <small class="text-muted pull-right"><%= comment.decorate.the_created_at %></small>
                 </div>
                 <div class="panel-body">
-                    <%= raw comment.content %>
+                    <%= comment.content %>
                 </div><!-- /panel-body -->
             </div><!-- /panel panel-default -->
         </div><!-- /col-sm-5 -->
     </div>
     <%= render partial: "partials/comments_list", locals: { comments: comment.children.approveds, children: "present" }  if comment.children.present? %>
-<% end %>
\ No newline at end of file
+<% end %>
diff --git a/app/views/camaleon_cms/default_theme/partials/_comments_list2.html.erb b/app/views/camaleon_cms/default_theme/partials/_comments_list2.html.erb
index 1b53ef92..5e7923e2 100644
--- a/app/views/camaleon_cms/default_theme/partials/_comments_list2.html.erb
+++ b/app/views/camaleon_cms/default_theme/partials/_comments_list2.html.erb
@@ -4,11 +4,11 @@
             <div class="media-left">
                 <%= link_to(image_tag(user.the_avatar, class: "media-object", style: 'width: 64px;'), user.the_url) %>
             </div>
             <div class="media-body">
                 <h4 class="media-heading"><%= link_to(user.the_name, user.the_url) %> <small class="pull-right"><%= comment.decorate.the_created_at %></small></h4>
-                <div><%= raw comment.content %></div>
+                <div><%= comment.content %></div>
                 <% comment.children.approveds.each do |answer| user2 = answer.comment_user.decorate %>
                     <div class="media">
                         <div class="media-left">
                             <%= link_to(image_tag(user2.the_avatar, class: "media-object", style: 'width: 64px;'), user2.the_url) %>
                         </div>
@@ -19,6 +19,6 @@
                     </div>
                 <% end %>
             </div>
         </li>
     <% end %>
-</ul>
\ No newline at end of file
+</ul>

Vulnerable code:                     <%= raw comment.content %>
<% end %>
                    <div class='comment_content'>#{comment.content}</div>
                    <%= raw comment.content %>
<% end %>
                <div><%= raw comment.content %></div>
</ul>
Fixed code:                     <%= comment.content %>
<% end %>
                    <div class='comment_content'>#{sanitize comment.content}</div>
                    <%= comment.content %>
<% end %>
                <div><%= comment.content %></div>
</ul>