diff --git a/ee/app/assets/javascripts/pages/projects/security/vulnerabilities/new/index.js b/ee/app/assets/javascripts/pages/projects/security/vulnerabilities/new/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..5cb420a65f77e78aa766d9890eb9bc408bfacc9c
--- /dev/null
+++ b/ee/app/assets/javascripts/pages/projects/security/vulnerabilities/new/index.js
@@ -0,0 +1,3 @@
+import initNewVulnerability from 'ee/vulnerabilities/new_vulnerability_init';
+
+initNewVulnerability(document.getElementById('js-vulnerability-new'));
diff --git a/ee/app/assets/javascripts/vulnerabilities/components/new_vulnerability/new_vulnerability.vue b/ee/app/assets/javascripts/vulnerabilities/components/new_vulnerability/new_vulnerability.vue
new file mode 100644
index 0000000000000000000000000000000000000000..d73b7f053b72d88df08520b85ea37852fd674f07
--- /dev/null
+++ b/ee/app/assets/javascripts/vulnerabilities/components/new_vulnerability/new_vulnerability.vue
@@ -0,0 +1,25 @@
+<script>
+import { s__ } from '~/locale';
+
+export default {
+  i18n: {
+    title: s__('VulnerabilityManagement|Add vulnerability finding'),
+    description: s__(
+      'VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report.',
+    ),
+  },
+};
+</script>
+
+<template>
+  <div>
+    <header class="gl-my-4 gl-border-b-gray-100 gl-border-b-solid gl-border-b-1">
+      <h2 class="gl-mt-0 gl-mb-3">
+        {{ $options.i18n.title }}
+      </h2>
+      <p data-testid="page-description">
+        {{ $options.i18n.description }}
+      </p>
+    </header>
+  </div>
+</template>
diff --git a/ee/app/assets/javascripts/vulnerabilities/new_vulnerability_init.js b/ee/app/assets/javascripts/vulnerabilities/new_vulnerability_init.js
new file mode 100644
index 0000000000000000000000000000000000000000..7defd24afeefe50b14c9dac86d953c7207ddecd3
--- /dev/null
+++ b/ee/app/assets/javascripts/vulnerabilities/new_vulnerability_init.js
@@ -0,0 +1,18 @@
+import Vue from 'vue';
+import apolloProvider from 'ee/security_dashboard/graphql/provider';
+import App from 'ee/vulnerabilities/components/new_vulnerability/new_vulnerability.vue';
+
+export default (el) => {
+  if (!el) {
+    return null;
+  }
+
+  return new Vue({
+    el,
+    apolloProvider,
+    render: (h) =>
+      h(App, {
+        props: {},
+      }),
+  });
+};
diff --git a/ee/app/controllers/projects/security/vulnerabilities_controller.rb b/ee/app/controllers/projects/security/vulnerabilities_controller.rb
index 83e6a22e92c013321abe4dfa4c5e232acca7f2b0..aade28d590cea85b8c3d36345960849d1bca6b77 100644
--- a/ee/app/controllers/projects/security/vulnerabilities_controller.rb
+++ b/ee/app/controllers/projects/security/vulnerabilities_controller.rb
@@ -12,7 +12,8 @@ class VulnerabilitiesController < Projects::ApplicationController
         push_frontend_feature_flag(:create_vulnerability_jira_issue_via_graphql, @project, default_enabled: :yaml)
       end
 
-      before_action :vulnerability, except: :index
+      before_action :vulnerability, except: [:index, :new]
+      before_action :authorize_create_vulnerability!, only: :new
 
       alias_method :vulnerable, :project
 
diff --git a/ee/app/views/projects/security/vulnerabilities/new.html.haml b/ee/app/views/projects/security/vulnerabilities/new.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..c90fdb68de8684ea3ce3ea07b3dca107e5e6b877
--- /dev/null
+++ b/ee/app/views/projects/security/vulnerabilities/new.html.haml
@@ -0,0 +1,7 @@
+- @content_class = "limit-container-width" unless fluid_layout
+- add_to_breadcrumbs _("Vulnerability Report"), project_security_vulnerability_report_index_path(@project)
+- breadcrumb_title _("Add vulnerability finding")
+- page_title _("Add vulnerability finding")
+- add_page_specific_style 'page_bundles/security_dashboard'
+
+#js-vulnerability-new
diff --git a/ee/config/routes/project.rb b/ee/config/routes/project.rb
index f777499500b9f61b4afaf42ca846590b70b09081..43ce78e6f73a5e1b5d101bd5353f316b3eb53d2e 100644
--- a/ee/config/routes/project.rb
+++ b/ee/config/routes/project.rb
@@ -76,7 +76,7 @@
 
           resources :scanned_resources, only: [:index]
 
-          resources :vulnerabilities, only: [:show] do
+          resources :vulnerabilities, only: [:show, :new] do
             member do
               get :discussions, format: :json
             end
diff --git a/ee/spec/controllers/projects/security/vulnerabilities_controller_spec.rb b/ee/spec/controllers/projects/security/vulnerabilities_controller_spec.rb
index af91a0a582a041e70c0d9c6b6d715731700df806..5bbed9dc9b7cfd89ca3a0c4c4745240ab9840ed3 100644
--- a/ee/spec/controllers/projects/security/vulnerabilities_controller_spec.rb
+++ b/ee/spec/controllers/projects/security/vulnerabilities_controller_spec.rb
@@ -15,6 +15,34 @@
     sign_in(user)
   end
 
+  describe 'GET #new' do
+    let(:request_new_vulnerability_page) { get :new, params: { namespace_id: project.namespace, project_id: project } }
+
+    include_context '"Security & Compliance" permissions' do
+      let(:valid_request) { request_new_vulnerability_page }
+    end
+
+    it 'renders the add new finding page' do
+      request_new_vulnerability_page
+
+      expect(response).to have_gitlab_http_status(:ok)
+    end
+
+    context 'when user can not create vulnerability' do
+      before do
+        guest = create(:user)
+        project.add_guest(guest)
+        sign_in(guest)
+      end
+
+      it 'renders a 403' do
+        request_new_vulnerability_page
+
+        expect(response).to have_gitlab_http_status(:forbidden)
+      end
+    end
+  end
+
   describe 'GET #show' do
     let_it_be(:pipeline) { create(:ci_pipeline, sha: project.commit.id, project: project, user: user) }
     let_it_be(:vulnerability) { create(:vulnerability, project: project) }
diff --git a/ee/spec/frontend/vulnerabilities/new_vulnerability/new_vulnerability_spec.js b/ee/spec/frontend/vulnerabilities/new_vulnerability/new_vulnerability_spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..08ff7b31b5361eefe1d21a584a7f818c4abfac77
--- /dev/null
+++ b/ee/spec/frontend/vulnerabilities/new_vulnerability/new_vulnerability_spec.js
@@ -0,0 +1,27 @@
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import NewVulnerability from 'ee/vulnerabilities/components/new_vulnerability/new_vulnerability.vue';
+
+describe('New vulnerability component', () => {
+  let wrapper;
+
+  const createWrapper = () => {
+    return shallowMountExtended(NewVulnerability, {});
+  };
+
+  beforeEach(() => {
+    wrapper = createWrapper();
+  });
+
+  afterEach(() => {
+    wrapper.destroy();
+  });
+
+  it('should render the page title and description', () => {
+    expect(wrapper.findByRole('heading', { name: 'Add vulnerability finding' }).exists()).toBe(
+      true,
+    );
+    expect(wrapper.findByTestId('page-description').text()).toBe(
+      'Manually add a vulnerability entry into the vulnerability report.',
+    );
+  });
+});
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index afd39e9cfa5321737a8ff0baf963c605709f3a8f..f87833e829d6560d84b4e9bc04296cd7dcd4eae8 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -2133,6 +2133,9 @@ msgstr ""
 msgid "Add variable"
 msgstr ""
 
+msgid "Add vulnerability finding"
+msgstr ""
+
 msgid "Add webhook"
 msgstr ""
 
@@ -38397,6 +38400,9 @@ msgstr ""
 msgid "VulnerabilityManagement|A true-positive and will fix"
 msgstr ""
 
+msgid "VulnerabilityManagement|Add vulnerability finding"
+msgstr ""
+
 msgid "VulnerabilityManagement|Change status"
 msgstr ""
 
@@ -38412,6 +38418,9 @@ msgstr ""
 msgid "VulnerabilityManagement|Fetching linked Jira issues"
 msgstr ""
 
+msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
+msgstr ""
+
 msgid "VulnerabilityManagement|Needs triage"
 msgstr ""