Skip to content

Commit 9430185

Browse files
SECURITY: Improve theme git import (#12694)
1 parent 0afcf9e commit 9430185

File tree

3 files changed

+19
-1
lines changed

3 files changed

+19
-1
lines changed

config/locales/server.en.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ en:
7474
about_json_values: "about.json contains invalid values: %{errors}"
7575
modifier_values: "about.json modifiers contain invalid values: %{errors}"
7676
git: "Error cloning git repository, access is denied or repository is not found"
77+
git_ref_not_found: "Unable to checkout git reference: %{ref}"
7778
unpack_failed: "Failed to unpack file"
7879
file_too_big: "The uncompressed file is too big."
7980
unknown_file_type: "The file you uploaded does not appear to be a valid Discourse theme."

lib/theme_store/git_importer.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,16 @@ def import!
2525
end
2626
if version = Discourse.find_compatible_git_resource(@temp_folder)
2727
Discourse::Utils.execute_command(chdir: @temp_folder) do |runner|
28-
return runner.exec("git cat-file -e #{version} || git fetch --depth 1 $(git rev-parse --symbolic-full-name @{upstream} | awk -F '/' '{print $3}') #{version}; git reset --hard #{version}")
28+
begin
29+
runner.exec "git", "cat-file", "-e", version
30+
rescue RuntimeError => e
31+
tracking_ref = runner.exec "git", "rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{upstream}"
32+
remote_name = tracking_ref.split("/", 2)[0]
33+
runner.exec "git", "fetch", "--depth", "1", remote_name, "#{version}:#{version}"
34+
end
35+
runner.exec "git", "reset", "--hard", version
36+
rescue RuntimeError
37+
raise RemoteTheme::ImportError.new(I18n.t("themes.import_error.git_ref_not_found", ref: version))
2938
end
3039
end
3140
end

lib/version.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ def self.find_compatible_resource(version_list, version = ::Discourse::VERSION::
5454
checkout_version = target
5555
end
5656

57+
return if checkout_version.nil?
58+
59+
begin
60+
Discourse::Utils.execute_command "git", "check-ref-format", "--allow-onelevel", checkout_version
61+
rescue RuntimeError
62+
raise InvalidVersionListError, "Invalid ref name: #{checkout_version}"
63+
end
64+
5765
checkout_version
5866
end
5967

0 commit comments

Comments
 (0)