diff --git a/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_report/vulnerability_report_header.vue b/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_report/vulnerability_report_header.vue
index 62ac836d21a104a83cd3256aede1917cf29aaeb0..3c697e2bd2e9abdaf02c5e5652d1158f7674867b 100644
--- a/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_report/vulnerability_report_header.vue
+++ b/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_report/vulnerability_report_header.vue
@@ -51,7 +51,10 @@ export default {
       <gl-button v-if="shouldShowNewVulnerabilityButton" :href="newVulnerabilityPath" icon="plus">
         {{ $options.i18n.submitVulnerability }}
       </gl-button>
-      <csv-export-button :class="shouldShowNewVulnerabilityButton ? 'gl-ml-4' : 'gl-ml-auto'" />
+      <csv-export-button
+        data-qa-selector="export_vulnerabilities_button"
+        :class="shouldShowNewVulnerabilityButton ? 'gl-ml-4' : 'gl-ml-auto'"
+      />
     </div>
   </header>
 </template>
diff --git a/qa/qa/ee/page/project/secure/security_dashboard.rb b/qa/qa/ee/page/project/secure/security_dashboard.rb
index a8f4b7b390624eb2a104fb8282695ee2b589440c..e27e1ed8dd7c9604372a9cfaf32144437c915b9d 100644
--- a/qa/qa/ee/page/project/secure/security_dashboard.rb
+++ b/qa/qa/ee/page/project/secure/security_dashboard.rb
@@ -20,6 +20,10 @@ class SecurityDashboard < QA::Page::Base
               element :change_status_button
             end
 
+            view 'ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_report/vulnerability_report_header.vue' do
+              element :export_vulnerabilities_button
+            end
+
             def has_vulnerability?(description:)
               has_element?(:vulnerability, vulnerability_description: description)
             end
@@ -55,6 +59,10 @@ def has_remediated_badge?(vulnerability_name)
             def has_issue_created_icon?(vulnerability_name)
               has_element?(:vulnerability_issue_created_badge_content, badge_description: vulnerability_name)
             end
+
+            def export_vulnerabilities_to_csv
+              click_element(:export_vulnerabilities_button)
+            end
           end
         end
       end
diff --git a/qa/qa/runtime/browser.rb b/qa/qa/runtime/browser.rb
index af1a4e06473753ef86c0e6a5ba9b4fe5edffb056..faf2023f7c2399c8eb59aeaa92eac8e31cea645f 100644
--- a/qa/qa/runtime/browser.rb
+++ b/qa/qa/runtime/browser.rb
@@ -96,12 +96,11 @@ def self.configure!
             capabilities['goog:chromeOptions'][:args] << 'disable-dev-shm-usage' if QA::Runtime::Env.disable_dev_shm?
 
             # Set chrome default download path
-            if QA::Runtime::Env.chrome_default_download_path
-              capabilities['goog:chromeOptions'][:prefs] = {
-                'download.default_directory' => File.expand_path(QA::Runtime::Env.chrome_default_download_path),
-                'download.prompt_for_download' => false
-              }
-            end
+
+            capabilities['goog:chromeOptions'][:prefs] = {
+              'download.default_directory' => File.expand_path(QA::Runtime::Env.chrome_default_download_path),
+              'download.prompt_for_download' => false
+            }
 
             # Specify the user-agent to allow challenges to be bypassed
             # See https://gitlab.com/gitlab-com/gl-infra/infrastructure/-/issues/11938
diff --git a/qa/qa/runtime/env.rb b/qa/qa/runtime/env.rb
index b2a5890e960f8dfbb892e571218ecfd0be4f10d0..346d40780fd1a4f1f877fb8f017e83c8bca528cf 100644
--- a/qa/qa/runtime/env.rb
+++ b/qa/qa/runtime/env.rb
@@ -495,7 +495,7 @@ def allow_local_requests?
       end
 
       def chrome_default_download_path
-        ENV['DEFAULT_CHROME_DOWNLOAD_PATH']
+        ENV['DEFAULT_CHROME_DOWNLOAD_PATH'] || Dir.tmpdir
       end
 
       private
diff --git a/qa/qa/specs/features/ee/browser_ui/10_govern/export_vulnerability_report_spec.rb b/qa/qa/specs/features/ee/browser_ui/10_govern/export_vulnerability_report_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8a23caebd0f9b45f490de40f638c986d0041ed23
--- /dev/null
+++ b/qa/qa/specs/features/ee/browser_ui/10_govern/export_vulnerability_report_spec.rb
@@ -0,0 +1,77 @@
+# frozen_string_literal: true
+
+module QA
+  RSpec.describe 'Govern', product_group: :threat_insights do
+    describe 'Vulnerability report in a project' do
+      let!(:project) do
+        Resource::Project.fabricate_via_api! do |project|
+          project.name = 'project-export-vulnerability-report'
+          project.description = 'Project to check export vulnerability report feature'
+          project.initialize_with_readme = true
+        end
+      end
+
+      let(:vuln_severity) { :HIGH }
+
+      let(:download_dir) { QA::Runtime::Env.chrome_default_download_path }
+
+      let(:vulnerabilities) do
+        { "Elves vulnerability": "Pale skin and pointy ears",
+          "Dwarves vulnerability": "Short, but stern and tough",
+          "Men vulnerability": "Good and bad, greedy and selfless",
+          "Orcs vulnerability": "Faithful to the dark lord",
+          "CVE-2017-18269 in glibc": "Short description to match in specs" }
+      end
+
+      let!(:vulnerability_report) do
+        vulnerabilities.each do |name, description|
+          QA::EE::Resource::VulnerabilityItem.fabricate_via_api! do |vulnerability|
+            vulnerability.id = project.id
+            vulnerability.severity = vuln_severity
+            vulnerability.name = name
+            vulnerability.description = description
+          end
+        end
+      end
+
+      let(:vulnerability_name) { "CVE-2017-18269 in glibc" }
+      let(:vulnerability_description) { "Short description to match in specs" }
+
+      before do
+        Flow::Login.sign_in
+        project.visit!
+      end
+
+      it 'can export vulnerability report to csv',
+         testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/384370' do
+        Page::Project::Menu.perform(&:click_on_vulnerability_report)
+
+        EE::Page::Project::Secure::SecurityDashboard.perform do |security_dashboard|
+          expect(security_dashboard).to have_vulnerability(description: vulnerability_name)
+          security_dashboard.export_vulnerabilities_to_csv
+        end
+        file_name = get_exported_csv_filename
+        validate_csv(file_name)
+      end
+
+      def get_exported_csv_filename
+        csv_file = nil
+        file_name_glob = "#{project.full_path.split('/').join('-')}_vulnerabilities"
+        Support::Waiter.wait_until(max_duration: 20, sleep_interval: 1,
+                                   message: "Waiting for vulnerabilities csv export") do
+          csv_file = Dir["#{download_dir}/*"].find { |file| file =~ /#{file_name_glob}.*csv/ }
+        end
+
+        csv_file
+      end
+
+      def validate_csv(file_name)
+        vulnerabilities_from_csv = []
+        CSV.foreach(file_name, headers: true) do |row|
+          vulnerabilities_from_csv << [row['Vulnerability'], row['Details']]
+        end
+        expect(vulnerabilities.stringify_keys.to_a).to match_array vulnerabilities_from_csv
+      end
+    end
+  end
+end