Commit c46eaca91247ccf8e6fb3b691dad028e1b084ae3

Authored by Nigel Kukard
1 parent ee0e9830

More escaping

- Database name may contain characters which are not shell friendly
- Database password could contain the same
- While we at it there is no harm in escaping generated paths too
- Refactored 2-line system(command)

Signed-off-by: Nigel Kukard <nkukard@lbsd.net>
lib/backup/database.rb
1 require 'yaml' 1 require 'yaml'
  2 +require 'shellwords'
2 3
3 module Backup 4 module Backup
4 class Database 5 class Database
@@ -13,20 +14,20 @@ module Backup @@ -13,20 +14,20 @@ module Backup
13 def dump 14 def dump
14 case config["adapter"] 15 case config["adapter"]
15 when /^mysql/ then 16 when /^mysql/ then
16 - system("mysqldump #{mysql_args} #{config['database']} > #{db_file_name}") 17 + system("mysqldump #{mysql_args} #{Shellwords.shellescape(config['database'])} > #{Shellwords.shellescape(db_file_name)}")
17 when "postgresql" then 18 when "postgresql" then
18 pg_env 19 pg_env
19 - system("pg_dump #{config['database']} > #{db_file_name}") 20 + system("pg_dump #{Shellwords.shellescape(config['database'])} > #{db_file_name}")
20 end 21 end
21 end 22 end
22 23
23 def restore 24 def restore
24 case config["adapter"] 25 case config["adapter"]
25 when /^mysql/ then 26 when /^mysql/ then
26 - system("mysql #{mysql_args} #{config['database']} < #{db_file_name}") 27 + system("mysql #{mysql_args} #{Shellwords.shellescape(config['database'])} < #{db_file_name}")
27 when "postgresql" then 28 when "postgresql" then
28 pg_env 29 pg_env
29 - system("psql #{config['database']} -f #{db_file_name}") 30 + system("psql #{Shellwords.shellescape(config['database'])} -f #{Shellwords.shellescape(db_file_name)}")
30 end 31 end
31 end 32 end
32 33
@@ -45,7 +46,7 @@ module Backup @@ -45,7 +46,7 @@ module Backup
45 'encoding' => '--default-character-set', 46 'encoding' => '--default-character-set',
46 'password' => '--password' 47 'password' => '--password'
47 } 48 }
48 - args.map { |opt, arg| "#{arg}='#{config[opt]}'" if config[opt] }.compact.join(' ') 49 + args.map { |opt, arg| "#{arg}=#{Shellwords.shellescape(config[opt])}" if config[opt] }.compact.join(' ')
49 end 50 end
50 51
51 def pg_env 52 def pg_env
lib/backup/repository.rb
1 require 'yaml' 1 require 'yaml'
  2 +require 'shellwords'
2 3
3 module Backup 4 module Backup
4 class Repository 5 class Repository
@@ -18,7 +19,7 @@ module Backup @@ -18,7 +19,7 @@ module Backup
18 # Create namespace dir if missing 19 # Create namespace dir if missing
19 FileUtils.mkdir_p(File.join(backup_repos_path, project.namespace.path)) if project.namespace 20 FileUtils.mkdir_p(File.join(backup_repos_path, project.namespace.path)) if project.namespace
20 21
21 - if system("cd #{path_to_repo(project)} > /dev/null 2>&1 && git bundle create #{path_to_bundle(project)} --all > /dev/null 2>&1") 22 + if system("cd #{Shellwords.shellescape(path_to_repo(project))} > /dev/null 2>&1 && git bundle create #{Shellwords.shellescape(path_to_bundle(project))} --all > /dev/null 2>&1")
22 puts "[DONE]".green 23 puts "[DONE]".green
23 else 24 else
24 puts "[FAILED]".red 25 puts "[FAILED]".red
@@ -30,7 +31,7 @@ module Backup @@ -30,7 +31,7 @@ module Backup
30 print " * #{wiki.path_with_namespace} ... " 31 print " * #{wiki.path_with_namespace} ... "
31 if wiki.empty? 32 if wiki.empty?
32 puts " [SKIPPED]".cyan 33 puts " [SKIPPED]".cyan
33 - elsif system("cd #{path_to_repo(wiki)} > /dev/null 2>&1 && git bundle create #{path_to_bundle(wiki)} --all > /dev/null 2>&1") 34 + elsif system("cd #{Shellwords.shellescape(path_to_repo(wiki))} > /dev/null 2>&1 && git bundle create #{Shellwords.shellescape(path_to_bundle(wiki))} --all > /dev/null 2>&1")
34 puts " [DONE]".green 35 puts " [DONE]".green
35 else 36 else
36 puts " [FAILED]".red 37 puts " [FAILED]".red
@@ -53,7 +54,7 @@ module Backup @@ -53,7 +54,7 @@ module Backup
53 54
54 project.namespace.ensure_dir_exist if project.namespace 55 project.namespace.ensure_dir_exist if project.namespace
55 56
56 - if system("git clone --bare #{path_to_bundle(project)} #{path_to_repo(project)} > /dev/null 2>&1") 57 + if system("git clone --bare #{Shellwords.shellescape(path_to_bundle(project))} #{Shellwords.shellescape(path_to_repo(project))} > /dev/null 2>&1")
57 puts "[DONE]".green 58 puts "[DONE]".green
58 else 59 else
59 puts "[FAILED]".red 60 puts "[FAILED]".red
@@ -63,7 +64,7 @@ module Backup @@ -63,7 +64,7 @@ module Backup
63 64
64 if File.exists?(path_to_bundle(wiki)) 65 if File.exists?(path_to_bundle(wiki))
65 print " * #{wiki.path_with_namespace} ... " 66 print " * #{wiki.path_with_namespace} ... "
66 - if system("git clone --bare #{path_to_bundle(wiki)} #{path_to_repo(wiki)} > /dev/null 2>&1") 67 + if system("git clone --bare #{Shellwords.shellescape(path_to_bundle(wiki))} #{Shellwords.shellescape(path_to_repo(wiki))} > /dev/null 2>&1")
67 puts " [DONE]".green 68 puts " [DONE]".green
68 else 69 else
69 puts " [FAILED]".red 70 puts " [FAILED]".red
spec/models/gollum_wiki_spec.rb
1 require "spec_helper" 1 require "spec_helper"
  2 +require "shellwords"
2 3
3 describe GollumWiki do 4 describe GollumWiki do
4 5
5 def create_temp_repo(path) 6 def create_temp_repo(path)
6 FileUtils.mkdir_p path 7 FileUtils.mkdir_p path
7 - command = "git init --quiet #{path};"  
8 - system(command) 8 + system("git init --quiet #{Shellwords.shellescape(path)}")
9 end 9 end
10 10
11 def remove_temp_repo(path) 11 def remove_temp_repo(path)
spec/models/wiki_page_spec.rb
1 require "spec_helper" 1 require "spec_helper"
  2 +require "shellwords"
2 3
3 describe WikiPage do 4 describe WikiPage do
4 5
5 def create_temp_repo(path) 6 def create_temp_repo(path)
6 FileUtils.mkdir_p path 7 FileUtils.mkdir_p path
7 - command = "git init --quiet #{path};"  
8 - system(command) 8 + system("git init --quiet #{Shellwords.shellescape(path)}")
9 end 9 end
10 10
11 def remove_temp_repo(path) 11 def remove_temp_repo(path)
spec/support/test_env.rb
1 require 'rspec/mocks' 1 require 'rspec/mocks'
  2 +require 'shellwords'
2 3
3 module TestEnv 4 module TestEnv
4 extend self 5 extend self
@@ -102,7 +103,7 @@ module TestEnv @@ -102,7 +103,7 @@ module TestEnv
102 repo = repo(namespace, name) 103 repo = repo(namespace, name)
103 104
104 # Symlink tmp/repositories/gitlabhq to tmp/test-git-base-path/gitlabhq 105 # Symlink tmp/repositories/gitlabhq to tmp/test-git-base-path/gitlabhq
105 - system("ln -s -f #{seed_repo_path()} #{repo}") 106 + system("ln -s -f #{Shellwords.shellescape(seed_repo_path())} #{Shellwords.shellescape(repo)}")
106 create_satellite(repo, namespace, name) 107 create_satellite(repo, namespace, name)
107 end 108 end
108 109
@@ -166,12 +167,11 @@ module TestEnv @@ -166,12 +167,11 @@ module TestEnv
166 # Symlink tmp/satellite/gitlabhq to tmp/test-git-base-path/satellite/gitlabhq, create the directory if it doesn't exist already 167 # Symlink tmp/satellite/gitlabhq to tmp/test-git-base-path/satellite/gitlabhq, create the directory if it doesn't exist already
167 satellite_dir = File.dirname(satellite_repo) 168 satellite_dir = File.dirname(satellite_repo)
168 FileUtils.mkdir_p(satellite_dir) unless File.exists?(satellite_dir) 169 FileUtils.mkdir_p(satellite_dir) unless File.exists?(satellite_dir)
169 - system("ln -s -f #{seed_satellite_path} #{satellite_repo}") 170 + system("ln -s -f #{Shellwords.shellescape(seed_satellite_path)} #{Shellwords.shellescape(satellite_repo)}")
170 end 171 end
171 172
172 def create_temp_repo(path) 173 def create_temp_repo(path)
173 FileUtils.mkdir_p path 174 FileUtils.mkdir_p path
174 - command = "git init --quiet --bare #{path};"  
175 - system(command) 175 + system("git init --quiet --bare #{Shellwords.shellescape(path)}")
176 end 176 end
177 end 177 end