CVE-2017-16792: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: Stored cross-site scripting (XSS) vulnerability in "geminabox" (Gem in a Box) before 0.13.10 allows attackers to inject arbitrary web script via the "homepage" value of a ".gemspec" file, related to views/gem.erb and views/index.erb.
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: 2017-11-13T09:29Z
Repository: https://github.com/geminabox/geminabox
Language: Ruby
Files changed: lib/geminabox/server.rb, views/gem.erb, views/index.erb
Commit date: 2017-11-13 10:24:54 +0900
Commit message: Fix CVE-2017-16792 - Stored XSS

Reject Javascript Link

Diff: diff --git a/lib/geminabox/server.rb b/lib/geminabox/server.rb
index a004367..04ae5c8 100644
--- a/lib/geminabox/server.rb
+++ b/lib/geminabox/server.rb
@@ -305,10 +305,19 @@ HTML
     def combined_gem_list
       GemListMerge.from(local_gem_list, remote_gem_list)
     end
 
     helpers do
+      def href(text)
+        escaped_text = Rack::Utils.escape_html(text)
+        if escaped_text.start_with?('http://') || escaped_text.start_with?('https://')
+          escaped_text
+        else
+          '#'
+        end
+      end
+
       def h(text)
         Rack::Utils.escape_html(text)
       end
 
       def spec_for(gem_name, version, platform = default_platform)
diff --git a/views/gem.erb b/views/gem.erb
index 6517c2b..f38274a 100644
--- a/views/gem.erb
+++ b/views/gem.erb
@@ -25,11 +25,11 @@
         <% newest_gem = versions.newest %>
         <% if spec = spec_for(name, newest_gem.number, newest_gem.platform) %>
           <%= spec.description %>
           <br/>
           <span class="author">– <%= spec.authors.map do |author|
-            "<a href='#{h(spec.homepage)}'>#{author}</a>"
+            "<a href='#{href(spec.homepage)}'>#{author}</a>"
           end.join(', ') %></span>
         <% end %>
         </p>
       </div>
 
diff --git a/views/index.erb b/views/index.erb
index 2948f15..8e89c53 100644
--- a/views/index.erb
+++ b/views/index.erb
@@ -44,11 +44,11 @@
             <% newest_gem = versions.newest %>
             <% if spec = spec_for(name, newest_gem.number, newest_gem.platform) %>
               <%= spec.description %>
               <br/>
               <span class="author">– <%= spec.authors.map do |author|
-                "<a href='#{h(spec.homepage)}'>#{author}</a>"
+                "<a href='#{href(spec.homepage)}'>#{author}</a>"
               end.join(', ') %></span>
             <% end %>
           </p>
         </div>
 

Vulnerable code:             "<a href='#{h(spec.homepage)}'>#{author}</a>"
                "<a href='#{h(spec.homepage)}'>#{author}</a>"
Fixed code:       def href(text)
        escaped_text = Rack::Utils.escape_html(text)
        if escaped_text.start_with?('http://') || escaped_text.start_with?('https://')
          escaped_text
        else
          '#'
        end
      end

            "<a href='#{href(spec.homepage)}'>#{author}</a>"
                "<a href='#{href(spec.homepage)}'>#{author}</a>"