diff --git a/app/controllers/admin/backups_controller.rb b/app/controllers/admin/backups_controller.rb
index b085dc81f68..6222fc2b088 100644
--- a/app/controllers/admin/backups_controller.rb
+++ b/app/controllers/admin/backups_controller.rb
@@ -119,6 +119,7 @@ class Admin::BackupsController < Admin::AdminController
 
     return render status: 415, text: I18n.t("backup.backup_file_should_be_tar_gz") unless /\.(tar\.gz|t?gz)$/i =~ filename
     return render status: 415, text: I18n.t("backup.not_enough_space_on_disk")     unless has_enough_space_on_disk?(total_size)
+    return render status: 415, text: I18n.t("backup.invalid_filename") unless !!(/^[a-zA-Z0-9\.-_]+$/ =~ filename)
 
     file               = params.fetch(:file)
     identifier         = params.fetch(:resumableIdentifier)
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index c9ba20b69de..09554bb945a 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -140,6 +140,7 @@ en:
     operation_already_running: "An operation is currently running. Can't start a new job right now."
     backup_file_should_be_tar_gz: "The backup file should be a .tar.gz archive."
     not_enough_space_on_disk: "There is not enough space on disk to upload this backup."
+    invalid_filename: "The backup filename contains invalid characters. Valid characters are a-z 0-9 . - _."
 
   not_logged_in: "You need to be logged in to do that."
   not_found: "The requested URL or resource could not be found."
diff --git a/spec/controllers/admin/backups_controller_spec.rb b/spec/controllers/admin/backups_controller_spec.rb
index 82b9e69dd53..dc44007ca3e 100644
--- a/spec/controllers/admin/backups_controller_spec.rb
+++ b/spec/controllers/admin/backups_controller_spec.rb
@@ -194,6 +194,35 @@ describe Admin::BackupsController do
 
     end
 
+    describe "#upload_backup_chunk" do
+      describe "when filename contains invalid characters" do
+        it "should raise an error" do
+          ['灰色.tar.gz', '; echo \'haha\'.tar.gz'].each do |invalid_filename|
+            xhr :post, :upload_backup_chunk, resumableFilename: invalid_filename, resumableTotalSize: '1'
+
+            expect(response.status).to eq(415)
+            expect(response.body).to eq(I18n.t('backup.invalid_filename'))
+          end
+        end
+      end
+
+      describe "when filename is valid" do
+        it "should upload the file successfully" do
+          xhr :post, :upload_backup_chunk,
+            resumableFilename: 'test.tar.gz',
+            resumableTotalSize: '1',
+            resumableIdentifier: 'test',
+            resumableChunkNumber: '1',
+            resumableChunkSize: '1',
+            resumableCurrentChunkSize: '1',
+            file: fixture_file_upload(Tempfile.new)
+
+          expect(response.status).to eq(200)
+          expect(response.body).to eq("")
+        end
+      end
+    end
+
   end
 
 end