CVE-2011-3178: Improper Control of Generation of Code ('Code Injection') (CWE-94)
value: In the web ui of the openbuildservice before 2.3.0 a code injection of the project rebuildtimes statistics could be used by authorized attackers to execute shellcode.
CWE description: The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.
CVSS v3 base score: 8.8
Published: 2018-03-20T18:29Z
Repository: https://github.com/openSUSE/open-build-service
Language: Ruby
Files changed: src/webui/app/controllers/project_controller.rb
Commit date: 2011-09-02 14:50:54 +0200
Commit message: [webui] check the value of the scheduler parameter

Diff: diff --git a/src/webui/app/controllers/project_controller.rb b/src/webui/app/controllers/project_controller.rb
index 5aed60fa3..9d97ae762 100644
--- a/src/webui/app/controllers/project_controller.rb
+++ b/src/webui/app/controllers/project_controller.rb
@@ -455,10 +455,15 @@ class ProjectController < ApplicationController
     load_packages_mainpage 
     @repository = params[:repository]
     @arch = params[:arch]
     @hosts = begin Integer(params[:hosts] || '40') rescue 40 end
     @scheduler = params[:scheduler] || 'needed'
+    unless ["fifo", "lifo", "random", "btime", "needed", "neededb", "longest_data", "longested_triedread", "longest"].include? @scheduler
+      flash[:error] = "Invalid scheduler type, check mkdiststats docu - aehm, source"
+      redirect_to :action => :show, :project => @project
+      return
+    end
     bdep = find_cached(BuilddepInfo, :project => @project.name, :repository => @repository, :arch => @arch)
     jobs = find_cached(Jobhislist , :project => @project.name, :repository => @repository, :arch => @arch, 
             :limit => @packages.each.size * 3, :code => ['succeeded', 'unchanged'])
     unless bdep and jobs
       flash[:error] = "Could not collect infos about repository #{@repository}/#{@arch}"
@@ -471,13 +476,20 @@ class ProjectController < ApplicationController
     f.close
     f = File.open(indir + "/_jobhistory.xml", 'w')
     f.write(jobs.dump_xml)
     f.close
     outdir = Dir.mktmpdir
-    cmd="perl ./mkdiststats '--srcdir=#{indir}' '--destdir=#{outdir}' --outfmt=xml #{@project.name}/#{@repository}/#{@arch} --width=910 --buildhosts=#{@hosts} --scheduler=#{@scheduler}"
-    logger.debug "cd #{RAILS_ROOT}/vendor/diststats && #{cmd}"
-    system("cd #{RAILS_ROOT}/vendor/diststats && #{cmd}")
+    logger.debug "cd #{RAILS_ROOT}/vendor/diststats && perl ./mkdiststats --srcdir=#{indir} --destdir=#{outdir} 
+             --outfmt=xml #{@project.name}/#{@repository}/#{@arch} --width=910
+             --buildhosts=#{@hosts} --scheduler=#{@scheduler}"
+    fork do
+      Dir.chdir("#{RAILS_ROOT}/vendor/diststats")
+      system("perl", "./mkdiststats", "--srcdir=#{indir}", "--destdir=#{outdir}", 
+             "--outfmt=xml", "#{@project.name}/#{@repository}/#{@arch}", "--width=910",
+             "--buildhosts=#{@hosts}", "--scheduler=#{@scheduler}")
+    end
+    Process.wait
     f=File.open(outdir + "/rebuild.png")
     png=f.read
     f.close 
     @pngkey = Digest::MD5.hexdigest( params.to_s )
     Rails.cache.write("rebuild-%s.png" % @pngkey, png)

Vulnerable code:     cmd="perl ./mkdiststats '--srcdir=#{indir}' '--destdir=#{outdir}' --outfmt=xml #{@project.name}/#{@repository}/#{@arch} --width=910 --buildhosts=#{@hosts} --scheduler=#{@scheduler}"
    logger.debug "cd #{RAILS_ROOT}/vendor/diststats && #{cmd}"
    system("cd #{RAILS_ROOT}/vendor/diststats && #{cmd}")
Fixed code:     unless ["fifo", "lifo", "random", "btime", "needed", "neededb", "longest_data", "longested_triedread", "longest"].include? @scheduler
      flash[:error] = "Invalid scheduler type, check mkdiststats docu - aehm, source"
      redirect_to :action => :show, :project => @project
      return
    end
    logger.debug "cd #{RAILS_ROOT}/vendor/diststats && perl ./mkdiststats --srcdir=#{indir} --destdir=#{outdir} 
             --outfmt=xml #{@project.name}/#{@repository}/#{@arch} --width=910
             --buildhosts=#{@hosts} --scheduler=#{@scheduler}"
    fork do
      Dir.chdir("#{RAILS_ROOT}/vendor/diststats")
      system("perl", "./mkdiststats", "--srcdir=#{indir}", "--destdir=#{outdir}", 
             "--outfmt=xml", "#{@project.name}/#{@repository}/#{@arch}", "--width=910",
             "--buildhosts=#{@hosts}", "--scheduler=#{@scheduler}")
    end
    Process.wait