Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-05-12 00:09:17 +00:00
parent fdc26e021b
commit df8c8224ed
37 changed files with 7110 additions and 157 deletions

View File

@ -53,6 +53,7 @@
- ${TMP_TEST_FOLDER}/gitaly/run2/
- ${TMP_TEST_FOLDER}/gitaly/Makefile
- ${TMP_TEST_FOLDER}/gitaly/praefect.config.toml
- ${TMP_TEST_FOLDER}/gitaly/praefect-db.config.toml
- ${TMP_TEST_FOLDER}/gitaly/ruby/
policy: pull

View File

@ -25,6 +25,10 @@
.single-db-rspec:
extends: .single-db
.praefect-with-db:
variables:
GITALY_PRAEFECT_WITH_DB: '1'
.rspec-base:
extends:
- .rails-job-base
@ -192,6 +196,7 @@ setup-test-env:
- ${TMP_TEST_FOLDER}/gitaly/run2/
- ${TMP_TEST_FOLDER}/gitaly/Makefile
- ${TMP_TEST_FOLDER}/gitaly/praefect.config.toml
- ${TMP_TEST_FOLDER}/gitaly/praefect-db.config.toml
- ${TMP_TEST_FOLDER}/gitaly/ruby/
- ${TMP_TEST_FOLDER}/gitlab-elasticsearch-indexer/bin/gitlab-elasticsearch-indexer
- ${TMP_TEST_FOLDER}/gitlab-shell/
@ -262,6 +267,12 @@ rspec migration pg12 single-db:
- .single-db-rspec
- .rails:rules:single-db
rspec migration pg12 praefect:
extends:
- rspec migration pg12
- .praefect-with-db
- .rails:rules:praefect-with-db
rspec unit pg12:
extends:
- .rspec-base-pg12
@ -280,6 +291,12 @@ rspec unit pg12 single-db:
- .single-db-rspec
- .rails:rules:single-db
rspec unit pg12 praefect:
extends:
- rspec unit pg12
- .praefect-with-db
- .rails:rules:praefect-with-db
rspec integration pg12:
extends:
- .rspec-base-pg12
@ -298,6 +315,12 @@ rspec integration pg12 single-db:
- .single-db-rspec
- .rails:rules:single-db
rspec integration pg12 praefect:
extends:
- rspec integration pg12
- .praefect-with-db
- .rails:rules:praefect-with-db
rspec system pg12:
extends:
- .rspec-base-pg12
@ -318,6 +341,12 @@ rspec system pg12 single-db:
- .single-db-rspec
- .rails:rules:single-db
rspec system pg12 praefect:
extends:
- rspec system pg12
- .praefect-with-db
- .rails:rules:praefect-with-db
# Dedicated job to test DB library code against PG11.
# Note that these are already tested against PG12 in the `rspec unit pg12` / `rspec-ee unit pg12` jobs.
rspec db-library-code pg11:

View File

@ -961,6 +961,11 @@
changes: *db-patterns
- <<: *if-default-branch-schedule-nightly
.rails:rules:praefect-with-db:
rules:
- if: '$CI_MERGE_REQUEST_LABELS =~ /pipeline:run-praefect-with-db/'
allow_failure: true
.rails:rules:ee-and-foss-migration:
rules:
- <<: *if-fork-merge-request

View File

@ -322,12 +322,12 @@ module Ci
end
end
def archived_trace_exists?
def stored?
file&.file&.exists?
end
def self.archived_trace_exists_for?(job_id)
where(job_id: job_id).trace.take&.archived_trace_exists?
where(job_id: job_id).trace.take&.stored?
end
def self.max_artifact_size(type:, project:)

View File

@ -0,0 +1,16 @@
- name: "OAuth implicit grant" # the name of the feature being removed. Avoid the words `deprecation`, `deprecate`, `removal`, and `remove` in this field because these are implied.
announcement_milestone: "14.0" # The milestone when this feature was deprecated.
announcement_date: "2021-06-22" # The date of the milestone release when this feature was deprecated. This should almost always be the 22nd of a month (YYYY-MM-DD), unless you did an out of band blog post.
removal_milestone: "15.0" # The milestone when this feature is being removed.
removal_date: "2022-05-22" # This should almost always be the 22nd of a month (YYYY-MM-DD), the date of the milestone release when this feature will be removed.
breaking_change: true # Change to true if this removal is a breaking change.
reporter: hsutor # GitLab username of the person reporting the removal
body: | # Do not modify this line, instead modify the lines below.
The OAuth implicit grant authorization flow is no longer supported. Any applications that use OAuth implicit grant must switch to alternative [supported OAuth flows](https://docs.gitlab.com/ee/api/oauth2.html).
# The following items are not published on the docs page, but may be used in the future.
stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: # (optional) This is a link to the deprecation issue in GitLab
documentation_url: # (optional) This is a link to the current documentation page
image_url: # (optional) This is a link to a thumbnail image depicting the feature
video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg

View File

@ -0,0 +1,19 @@
# frozen_string_literal: true
class AddIndexToVulnerabilityFeedbackFindingUuid < Gitlab::Database::Migration[2.0]
disable_ddl_transaction!
INDEX_NAME = 'index_vulnerability_feedback_finding_uuid'
# We are indexing on UUID, a hash index should be smaller and faster
# details on https://gitlab.com/gitlab-org/gitlab/-/merge_requests/86808#note_943330140
# rubocop:disable Migration/HashIndex
def up
add_concurrent_index :vulnerability_feedback, :finding_uuid, using: :hash, name: INDEX_NAME
end
def down
remove_concurrent_index :vulnerability_feedback, :finding_uuid, using: :hash, name: INDEX_NAME
end
# rubocop:enable Migration/HashIndex
end

View File

@ -0,0 +1,11 @@
# frozen_string_literal: true
class RemoveDevopsAdoptionSecurityScanSucceededColumn < Gitlab::Database::Migration[2.0]
def up
remove_column :analytics_devops_adoption_snapshots, :security_scan_succeeded
end
def down
add_column :analytics_devops_adoption_snapshots, :security_scan_succeeded, :boolean
end
end

View File

@ -0,0 +1 @@
c8d61ae69828d0f234473092ea4a481e05aeffb61f777c5085836558f2fbe062

View File

@ -0,0 +1 @@
ddc86a14dbd512ee87654fa12fc2ef55f0f705341f628c2b26d0a80b6b2708a0

View File

@ -10800,7 +10800,6 @@ CREATE TABLE analytics_devops_adoption_snapshots (
runner_configured boolean NOT NULL,
pipeline_succeeded boolean NOT NULL,
deploy_succeeded boolean NOT NULL,
security_scan_succeeded boolean,
end_time timestamp with time zone NOT NULL,
total_projects_count integer,
code_owners_used_count integer,
@ -29546,6 +29545,8 @@ CREATE INDEX index_vulnerability_external_issue_links_on_author_id ON vulnerabil
CREATE INDEX index_vulnerability_external_issue_links_on_vulnerability_id ON vulnerability_external_issue_links USING btree (vulnerability_id);
CREATE INDEX index_vulnerability_feedback_finding_uuid ON vulnerability_feedback USING hash (finding_uuid);
CREATE INDEX index_vulnerability_feedback_on_author_id ON vulnerability_feedback USING btree (author_id);
CREATE INDEX index_vulnerability_feedback_on_comment_author_id ON vulnerability_feedback USING btree (comment_author_id);

View File

@ -132,13 +132,11 @@ Delete an event streaming destination by specifying an ID. Get the required ID b
streaming destinations.
```graphql
mutation{
mutation {
externalAuditEventDestinationDestroy(input: { id: destination }) {
errors
}
}
```
Destination is deleted if:

View File

@ -105,7 +105,7 @@ essentially makes it available on all levels:
- projects
Various traversal queries are already available on `Namespaces` to query the
group hierarchy. `Projects` represents the leaf nodes in the hierarchy, but with
group hierarchy. `Projects` represent the leaf nodes in the hierarchy, but with
the introduction of `ProjectNamespace`, these traversal queries can be used to
retrieve projects as well.

View File

@ -1436,10 +1436,15 @@ functionality is described.
| Only GitLab Premium SaaS and higher tiers (no self-managed instances) | `**(PREMIUM SAAS)**` |
| Only GitLab Ultimate SaaS (no self-managed instances) | `**(ULTIMATE SAAS)**` |
Topics that mention the `gitlab.rb` file are referring to
self-managed instances of GitLab. To prevent confusion, include the relevant `TIER SELF`
tier badge on the highest applicable heading level on
the page.
Topics that are only for instance administrators should be badged `<TIER> SELF`. Instance
administrator documentation often includes sections that mention:
- Changing the `gitlab.rb` or `gitlab.yml` files.
- Accessing the rails console or running Rake tasks.
- Doing things in the Admin Area.
These pages should also mention if the tasks can only be accomplished by an
instance administrator.
## Specific sections

View File

@ -371,3 +371,20 @@ the integration by using GDK:
```shell
curl --silent "http://localhost:9236/metrics" | grep go_find_all_tags
```
## Using Praefect in test
By default Praefect in test uses an in-memory election strategy. This strategy
is deprecated and no longer used in production. It mainly is kept for
unit-testing purposes.
A more modern election strategy requires a connection with a PostgreSQL
database. This behavior is disabled by default when running tests, but you can
enable it by setting `GITALY_PRAEFECT_WITH_DB=1` in your environment.
This requires you have PostgreSQL running, and you have the database created.
When you are using GDK, you can set it up with:
1. Start the database: `gdk start db`
1. Load the environment from GDK: `eval $(cd ../gitaly && gdk env)`
1. Create the database: `createdb --encoding=UTF8 --locale=C --echo praefect_test`

View File

@ -139,6 +139,16 @@ The issue for this removal is [GitLab-#350682](https://gitlab.com/gitlab-org/git
In GitLab 13.0, we introduced new project and design replication details routes in the Geo Admin UI. These routes are `/admin/geo/replication/projects` and `/admin/geo/replication/designs`. We kept the legacy routes and redirected them to the new routes. These legacy routes `/admin/geo/projects` and `/admin/geo/designs` have been removed in GitLab 15.0. Please update any bookmarks or scripts that may use the legacy routes.
### OAuth implicit grant
WARNING:
This feature was changed or removed in 15.0
as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#breaking-changes).
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
The OAuth implicit grant authorization flow is no longer supported. Any applications that use OAuth implicit grant must switch to alternative [supported OAuth flows](https://docs.gitlab.com/ee/api/oauth2.html).
### OAuth tokens without an expiration
WARNING:

View File

@ -225,8 +225,9 @@ container_scanning:
When you enable this feature, you may see [duplicate findings](../terminology/#duplicate-finding)
in the [Vulnerability Report](../vulnerability_report/)
if [Dependency Scanning](../dependency_scanning/)
is enabled for your project. This happens because GitLab can't automatically deduplicate the
findings reported by the two different analyzers.
is enabled for your project. This happens because GitLab can't automatically deduplicate findings
across different types of scanning tools. Please reference [this comparison](../dependency_scanning/#dependency-scanning-compared-to-container-scanning)
between GitLab Dependency Scanning and Container Scanning for more details on which types of dependencies are likely to be duplicated.
#### Available CI/CD variables

View File

@ -17,9 +17,11 @@ aspects of inspecting the items your code uses. These items typically include ap
dependencies that are almost always imported from external sources, rather than sourced from items
you wrote yourself.
## Dependency Scanning compared to Container Scanning
GitLab offers both Dependency Scanning and Container Scanning
to ensure coverage for all of these dependency types. To cover as much of your risk area as
possible, we encourage you to use all of our security scanners:
possible, we encourage you to use all of our security scanning tools:
- Dependency Scanning analyzes your project and tells you which software dependencies,
including upstream dependencies, have been included in your project, and what known
@ -41,6 +43,21 @@ possible, we encourage you to use all of our security scanners:
efforts to de-duplicate these findings can be tracked in
[this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/348655).
The following diagram summarizes which types of dependencies each scanning tool can detect:
| Feature | Dependency Scanning | Container Scanning |
| ----------------------------------------------------------- | ------------------- | ------------------ |
| Identify the manifest, lock file, or static file that introduced the dependency | :white_check_mark: | :x: |
| Development dependencies | :white_check_mark: | :x: |
| Dependencies in a lock file committed to your repository | :white_check_mark: | :white_check_mark: <sup>1</sup> |
| Binaries built by Go | :x: | :white_check_mark: <sup>2</sup> |
| Dynamically-linked language-specific dependencies installed by the Operating System | :x: | :white_check_mark: |
| Operating system dependencies | :x: | :white_check_mark: |
| Language-specific dependencies installed on the operating system (not built by your project) | :x: | :white_check_mark: |
1. Lock file must be present in the image to be detected.
1. Binary file must be present in the image to be detected.
## Overview
If you're using [GitLab CI/CD](../../../ci/index.md), you can use dependency scanning to analyze

View File

@ -69,17 +69,14 @@ can enable or disable a group wiki through the group settings.
To open group settings:
```markdown
1. On the top bar, select **Menu > Groups** and find your group.
1. On the left sidebar, select **Settings > General**.
1. Expand **Permissions and group features**.
```
In the wiki section, select one of these options:
- Enabled: Everyone who can access the group can access the wiki.
- Private: Only group members can access the wiki.
- Disabled: The wiki isn't accessible, and cannot be downloaded.
1. Scroll to **Wiki** and select one of these options:
- **Enabled**: Everyone who can access the group can access the wiki.
- **Private**: Only group members can access the wiki.
- **Disabled**: The wiki isn't accessible, and cannot be downloaded.
1. Select **Save changes**.
## Related topics

View File

@ -7,14 +7,14 @@ module Gitlab
module Validators
class SchemaValidator
SUPPORTED_VERSIONS = {
cluster_image_scanning: %w[14.0.4 14.0.5 14.0.6 14.1.0 14.1.1],
container_scanning: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1],
coverage_fuzzing: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1],
dast: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1],
api_fuzzing: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1],
dependency_scanning: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1],
sast: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1],
secret_detection: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1]
cluster_image_scanning: %w[14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2],
container_scanning: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2],
coverage_fuzzing: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2],
dast: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2],
api_fuzzing: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2],
dependency_scanning: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2],
sast: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2],
secret_detection: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2]
}.freeze
VERSIONS_TO_REMOVE_IN_16_0 = [].freeze

View File

@ -0,0 +1,977 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Report format for GitLab Cluster Image Scanning",
"description": "This schema provides the the report format for Cluster Image Scanning (https://docs.gitlab.com/ee/user/application_security/cluster_image_scanning/).",
"definitions": {
"detail_type": {
"oneOf": [
{
"$ref": "#/definitions/named_list"
},
{
"$ref": "#/definitions/list"
},
{
"$ref": "#/definitions/table"
},
{
"$ref": "#/definitions/text"
},
{
"$ref": "#/definitions/url"
},
{
"$ref": "#/definitions/code"
},
{
"$ref": "#/definitions/value"
},
{
"$ref": "#/definitions/diff"
},
{
"$ref": "#/definitions/markdown"
},
{
"$ref": "#/definitions/commit"
},
{
"$ref": "#/definitions/file_location"
},
{
"$ref": "#/definitions/module_location"
}
]
},
"text_value": {
"type": "string"
},
"named_field": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"$ref": "#/definitions/text_value",
"minLength": 1
},
"description": {
"$ref": "#/definitions/text_value"
}
}
},
"named_list": {
"type": "object",
"description": "An object with named and typed fields",
"required": [
"type",
"items"
],
"properties": {
"type": {
"const": "named-list"
},
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"allOf": [
{
"$ref": "#/definitions/named_field"
},
{
"$ref": "#/definitions/detail_type"
}
]
}
}
}
}
},
"list": {
"type": "object",
"description": "A list of typed fields",
"required": [
"type",
"items"
],
"properties": {
"type": {
"const": "list"
},
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
}
}
},
"table": {
"type": "object",
"description": "A table of typed fields",
"required": [
"type",
"rows"
],
"properties": {
"type": {
"const": "table"
},
"header": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
},
"rows": {
"type": "array",
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
}
}
}
},
"text": {
"type": "object",
"description": "Raw text",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "text"
},
"value": {
"$ref": "#/definitions/text_value"
}
}
},
"url": {
"type": "object",
"description": "A single URL",
"required": [
"type",
"href"
],
"properties": {
"type": {
"const": "url"
},
"text": {
"$ref": "#/definitions/text_value"
},
"href": {
"type": "string",
"minLength": 1,
"examples": [
"http://mysite.com"
]
}
}
},
"code": {
"type": "object",
"description": "A codeblock",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "code"
},
"value": {
"type": "string"
},
"lang": {
"type": "string",
"description": "A programming language"
}
}
},
"value": {
"type": "object",
"description": "A field that can store a range of types of value",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "value"
},
"value": {
"type": [
"number",
"string",
"boolean"
]
}
}
},
"diff": {
"type": "object",
"description": "A diff",
"required": [
"type",
"before",
"after"
],
"properties": {
"type": {
"const": "diff"
},
"before": {
"type": "string"
},
"after": {
"type": "string"
}
}
},
"markdown": {
"type": "object",
"description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "markdown"
},
"value": {
"$ref": "#/definitions/text_value",
"examples": [
"Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
]
}
}
},
"commit": {
"type": "object",
"description": "A commit/tag/branch within the GitLab project",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "commit"
},
"value": {
"type": "string",
"description": "The commit SHA",
"minLength": 1
}
}
},
"file_location": {
"type": "object",
"description": "A location within a file in the project",
"required": [
"type",
"file_name",
"line_start"
],
"properties": {
"type": {
"const": "file-location"
},
"file_name": {
"type": "string",
"minLength": 1
},
"line_start": {
"type": "integer"
},
"line_end": {
"type": "integer"
}
}
},
"module_location": {
"type": "object",
"description": "A location within a binary module of the form module+relative_offset",
"required": [
"type",
"module_name",
"offset"
],
"properties": {
"type": {
"const": "module-location"
},
"module_name": {
"type": "string",
"minLength": 1,
"examples": [
"compiled_binary"
]
},
"offset": {
"type": "integer",
"examples": [
100
]
}
}
}
},
"self": {
"version": "14.1.2"
},
"required": [
"version",
"vulnerabilities"
],
"additionalProperties": true,
"properties": {
"scan": {
"type": "object",
"required": [
"end_time",
"scanner",
"start_time",
"status",
"type"
],
"properties": {
"end_time": {
"type": "string",
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
"examples": [
"2020-01-28T03:26:02"
]
},
"messages": {
"type": "array",
"items": {
"type": "object",
"description": "Communication intended for the initiator of a scan.",
"required": [
"level",
"value"
],
"properties": {
"level": {
"type": "string",
"description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
"enum": [
"info",
"warn",
"fatal"
],
"examples": [
"info"
]
},
"value": {
"type": "string",
"description": "The message to communicate.",
"minLength": 1,
"examples": [
"Permission denied, scanning aborted"
]
}
}
}
},
"analyzer": {
"type": "object",
"description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
"required": [
"id",
"name",
"version",
"vendor"
],
"properties": {
"id": {
"type": "string",
"description": "Unique id that identifies the analyzer.",
"minLength": 1,
"examples": [
"gitlab-dast"
]
},
"name": {
"type": "string",
"description": "A human readable value that identifies the analyzer, not required to be unique.",
"minLength": 1,
"examples": [
"GitLab DAST"
]
},
"url": {
"type": "string",
"format": "uri",
"pattern": "^https?://.+",
"description": "A link to more information about the analyzer.",
"examples": [
"https://docs.gitlab.com/ee/user/application_security/dast"
]
},
"vendor": {
"description": "The vendor/maintainer of the analyzer.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The name of the vendor.",
"minLength": 1,
"examples": [
"GitLab"
]
}
}
},
"version": {
"type": "string",
"description": "The version of the analyzer.",
"minLength": 1,
"examples": [
"1.0.2"
]
}
}
},
"scanner": {
"type": "object",
"description": "Object defining the scanner used to perform the scan.",
"required": [
"id",
"name",
"version",
"vendor"
],
"properties": {
"id": {
"type": "string",
"description": "Unique id that identifies the scanner.",
"minLength": 1,
"examples": [
"my-sast-scanner"
]
},
"name": {
"type": "string",
"description": "A human readable value that identifies the scanner, not required to be unique.",
"minLength": 1,
"examples": [
"My SAST Scanner"
]
},
"url": {
"type": "string",
"description": "A link to more information about the scanner.",
"examples": [
"https://scanner.url"
]
},
"version": {
"type": "string",
"description": "The version of the scanner.",
"minLength": 1,
"examples": [
"1.0.2"
]
},
"vendor": {
"description": "The vendor/maintainer of the scanner.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The name of the vendor.",
"minLength": 1,
"examples": [
"GitLab"
]
}
}
}
}
},
"start_time": {
"type": "string",
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
"examples": [
"2020-02-14T16:01:59"
]
},
"status": {
"type": "string",
"description": "Result of the scan.",
"enum": [
"success",
"failure"
]
},
"type": {
"type": "string",
"description": "Type of the scan.",
"enum": [
"cluster_image_scanning"
]
}
}
},
"schema": {
"type": "string",
"description": "URI pointing to the validating security report schema.",
"format": "uri"
},
"version": {
"type": "string",
"description": "The version of the schema to which the JSON report conforms.",
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
},
"vulnerabilities": {
"type": "array",
"description": "Array of vulnerability objects.",
"items": {
"type": "object",
"description": "Describes the vulnerability using GitLab Flavored Markdown",
"required": [
"category",
"cve",
"identifiers",
"location",
"scanner"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
"examples": [
"642735a5-1425-428d-8d4e-3c854885a3c9"
]
},
"category": {
"type": "string",
"minLength": 1,
"description": "Describes where this vulnerability belongs (for example, SAST, Dependency Scanning, and so on)."
},
"name": {
"type": "string",
"description": "The name of the vulnerability. This must not include the finding's specific information."
},
"message": {
"type": "string",
"description": "A short text section that describes the vulnerability. This may include the finding's specific information."
},
"description": {
"type": "string",
"description": "A long text section describing the vulnerability more fully."
},
"cve": {
"type": "string",
"description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
},
"severity": {
"type": "string",
"description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
"enum": [
"Info",
"Unknown",
"Low",
"Medium",
"High",
"Critical"
]
},
"confidence": {
"type": "string",
"description": "How reliable the vulnerability's assessment is. Possible values are Ignore, Unknown, Experimental, Low, Medium, High, and Confirmed. Note that some analyzers may not report all these possible values.",
"enum": [
"Ignore",
"Unknown",
"Experimental",
"Low",
"Medium",
"High",
"Confirmed"
]
},
"solution": {
"type": "string",
"description": "Explanation of how to fix the vulnerability."
},
"scanner": {
"description": "Describes the scanner used to find this vulnerability.",
"type": "object",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "string",
"minLength": 1,
"description": "The scanner's ID, as a snake_case string."
},
"name": {
"type": "string",
"minLength": 1,
"description": "Human-readable name of the scanner."
}
}
},
"identifiers": {
"type": "array",
"minItems": 1,
"description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
"items": {
"type": "object",
"required": [
"type",
"name",
"value"
],
"properties": {
"type": {
"type": "string",
"description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
"minLength": 1
},
"name": {
"type": "string",
"description": "Human-readable name of the identifier.",
"minLength": 1
},
"url": {
"type": "string",
"description": "URL of the identifier's documentation.",
"format": "uri"
},
"value": {
"type": "string",
"description": "Value of the identifier, for matching purpose.",
"minLength": 1
}
}
}
},
"links": {
"type": "array",
"description": "An array of references to external documentation or articles that describe the vulnerability.",
"items": {
"type": "object",
"required": [
"url"
],
"properties": {
"name": {
"type": "string",
"description": "Name of the vulnerability details link."
},
"url": {
"type": "string",
"description": "URL of the vulnerability details document.",
"format": "uri"
}
}
}
},
"details": {
"$ref": "#/definitions/named_list/properties/items"
},
"tracking": {
"description": "Describes how this vulnerability should be tracked as the project changes.",
"oneOf": [
{
"description": "Declares that a series of items should be tracked using source-specific tracking methods.",
"required": [
"items"
],
"properties": {
"type": {
"const": "source"
},
"items": {
"type": "array",
"items": {
"description": "An item that should be tracked using source-specific tracking methods.",
"type": "object",
"required": [
"signatures"
],
"properties": {
"file": {
"type": "string",
"description": "Path to the file where the vulnerability is located."
},
"start_line": {
"type": "number",
"description": "The first line of the file that includes the vulnerability."
},
"end_line": {
"type": "number",
"description": "The last line of the file that includes the vulnerability."
},
"signatures": {
"type": "array",
"description": "An array of calculated tracking signatures for this tracking item.",
"minItems": 1,
"items": {
"description": "A calculated tracking signature value and metadata.",
"required": [
"algorithm",
"value"
],
"properties": {
"algorithm": {
"type": "string",
"description": "The algorithm used to generate the signature."
},
"value": {
"type": "string",
"description": "The result of this signature algorithm."
}
}
}
}
}
}
}
}
}
],
"properties": {
"type": {
"type": "string",
"description": "Each tracking type must declare its own type."
}
}
},
"flags": {
"description": "Flags that can be attached to vulnerabilities.",
"type": "array",
"items": {
"type": "object",
"description": "Informational flags identified and assigned to a vulnerability.",
"required": [
"type",
"origin",
"description"
],
"properties": {
"type": {
"type": "string",
"minLength": 1,
"description": "Result of the scan.",
"enum": [
"flagged-as-likely-false-positive"
]
},
"origin": {
"minLength": 1,
"description": "Tool that issued the flag.",
"type": "string"
},
"description": {
"minLength": 1,
"description": "What the flag is about.",
"type": "string"
}
}
}
},
"location": {
"type": "object",
"description": "Identifies the vulnerability's location.",
"required": [
"dependency",
"image",
"kubernetes_resource"
],
"properties": {
"dependency": {
"type": "object",
"description": "Describes the dependency of a project where the vulnerability is located.",
"properties": {
"package": {
"type": "object",
"description": "Provides information on the package where the vulnerability is located.",
"properties": {
"name": {
"type": "string",
"description": "Name of the package where the vulnerability is located."
}
}
},
"version": {
"type": "string",
"description": "Version of the vulnerable package."
},
"iid": {
"description": "ID that identifies the dependency in the scope of a dependency file.",
"type": "number"
},
"direct": {
"type": "boolean",
"description": "Tells whether this is a direct, top-level dependency of the scanned project."
},
"dependency_path": {
"type": "array",
"description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.",
"items": {
"type": "object",
"required": [
"iid"
],
"properties": {
"iid": {
"type": "number",
"description": "ID that is unique in the scope of a parent object, and specific to the resource type."
}
}
}
}
}
},
"operating_system": {
"type": "string",
"minLength": 1,
"maxLength": 255,
"description": "The operating system that contains the vulnerable package."
},
"image": {
"type": "string",
"minLength": 1,
"description": "The analyzed Docker image.",
"examples": [
"index.docker.io/library/nginx:1.21"
]
},
"kubernetes_resource": {
"type": "object",
"description": "The specific Kubernetes resource that was scanned.",
"required": [
"namespace",
"kind",
"name",
"container_name"
],
"properties": {
"namespace": {
"type": "string",
"minLength": 1,
"maxLength": 255,
"description": "The Kubernetes namespace the resource that had its image scanned.",
"examples": [
"default",
"staging",
"production"
]
},
"kind": {
"type": "string",
"minLength": 1,
"maxLength": 255,
"description": "The Kubernetes kind the resource that had its image scanned.",
"examples": [
"Deployment",
"DaemonSet"
]
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 255,
"description": "The name of the resource that had its image scanned.",
"examples": [
"nginx-ingress"
]
},
"container_name": {
"type": "string",
"minLength": 1,
"maxLength": 255,
"description": "The name of the container that had its image scanned.",
"examples": [
"nginx"
]
},
"agent_id": {
"type": "string",
"minLength": 1,
"maxLength": 255,
"description": "The GitLab ID of the Kubernetes Agent which performed the scan.",
"examples": [
"1234"
]
},
"cluster_id": {
"type": "string",
"minLength": 1,
"maxLength": 255,
"description": "The GitLab ID of the Kubernetes cluster when using cluster integration.",
"examples": [
"1234"
]
}
}
}
}
}
}
}
},
"remediations": {
"type": "array",
"description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
"items": {
"type": "object",
"required": [
"fixes",
"summary",
"diff"
],
"properties": {
"fixes": {
"type": "array",
"description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
"items": {
"type": "object",
"required": [
"cve"
],
"properties": {
"cve": {
"type": "string",
"description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
}
}
}
},
"summary": {
"type": "string",
"minLength": 1,
"description": "An overview of how the vulnerabilities were fixed."
},
"diff": {
"type": "string",
"minLength": 1,
"description": "A base64-encoded remediation code diff, compatible with git apply."
}
}
}
}
}
}

View File

@ -0,0 +1,911 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Report format for GitLab Container Scanning",
"description": "This schema provides the the report format for Container Scanning (https://docs.gitlab.com/ee/user/application_security/container_scanning).",
"definitions": {
"detail_type": {
"oneOf": [
{
"$ref": "#/definitions/named_list"
},
{
"$ref": "#/definitions/list"
},
{
"$ref": "#/definitions/table"
},
{
"$ref": "#/definitions/text"
},
{
"$ref": "#/definitions/url"
},
{
"$ref": "#/definitions/code"
},
{
"$ref": "#/definitions/value"
},
{
"$ref": "#/definitions/diff"
},
{
"$ref": "#/definitions/markdown"
},
{
"$ref": "#/definitions/commit"
},
{
"$ref": "#/definitions/file_location"
},
{
"$ref": "#/definitions/module_location"
}
]
},
"text_value": {
"type": "string"
},
"named_field": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"$ref": "#/definitions/text_value",
"minLength": 1
},
"description": {
"$ref": "#/definitions/text_value"
}
}
},
"named_list": {
"type": "object",
"description": "An object with named and typed fields",
"required": [
"type",
"items"
],
"properties": {
"type": {
"const": "named-list"
},
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"allOf": [
{
"$ref": "#/definitions/named_field"
},
{
"$ref": "#/definitions/detail_type"
}
]
}
}
}
}
},
"list": {
"type": "object",
"description": "A list of typed fields",
"required": [
"type",
"items"
],
"properties": {
"type": {
"const": "list"
},
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
}
}
},
"table": {
"type": "object",
"description": "A table of typed fields",
"required": [
"type",
"rows"
],
"properties": {
"type": {
"const": "table"
},
"header": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
},
"rows": {
"type": "array",
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
}
}
}
},
"text": {
"type": "object",
"description": "Raw text",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "text"
},
"value": {
"$ref": "#/definitions/text_value"
}
}
},
"url": {
"type": "object",
"description": "A single URL",
"required": [
"type",
"href"
],
"properties": {
"type": {
"const": "url"
},
"text": {
"$ref": "#/definitions/text_value"
},
"href": {
"type": "string",
"minLength": 1,
"examples": [
"http://mysite.com"
]
}
}
},
"code": {
"type": "object",
"description": "A codeblock",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "code"
},
"value": {
"type": "string"
},
"lang": {
"type": "string",
"description": "A programming language"
}
}
},
"value": {
"type": "object",
"description": "A field that can store a range of types of value",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "value"
},
"value": {
"type": [
"number",
"string",
"boolean"
]
}
}
},
"diff": {
"type": "object",
"description": "A diff",
"required": [
"type",
"before",
"after"
],
"properties": {
"type": {
"const": "diff"
},
"before": {
"type": "string"
},
"after": {
"type": "string"
}
}
},
"markdown": {
"type": "object",
"description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "markdown"
},
"value": {
"$ref": "#/definitions/text_value",
"examples": [
"Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
]
}
}
},
"commit": {
"type": "object",
"description": "A commit/tag/branch within the GitLab project",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "commit"
},
"value": {
"type": "string",
"description": "The commit SHA",
"minLength": 1
}
}
},
"file_location": {
"type": "object",
"description": "A location within a file in the project",
"required": [
"type",
"file_name",
"line_start"
],
"properties": {
"type": {
"const": "file-location"
},
"file_name": {
"type": "string",
"minLength": 1
},
"line_start": {
"type": "integer"
},
"line_end": {
"type": "integer"
}
}
},
"module_location": {
"type": "object",
"description": "A location within a binary module of the form module+relative_offset",
"required": [
"type",
"module_name",
"offset"
],
"properties": {
"type": {
"const": "module-location"
},
"module_name": {
"type": "string",
"minLength": 1,
"examples": [
"compiled_binary"
]
},
"offset": {
"type": "integer",
"examples": [
100
]
}
}
}
},
"self": {
"version": "14.1.2"
},
"required": [
"version",
"vulnerabilities"
],
"additionalProperties": true,
"properties": {
"scan": {
"type": "object",
"required": [
"end_time",
"scanner",
"start_time",
"status",
"type"
],
"properties": {
"end_time": {
"type": "string",
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
"examples": [
"2020-01-28T03:26:02"
]
},
"messages": {
"type": "array",
"items": {
"type": "object",
"description": "Communication intended for the initiator of a scan.",
"required": [
"level",
"value"
],
"properties": {
"level": {
"type": "string",
"description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
"enum": [
"info",
"warn",
"fatal"
],
"examples": [
"info"
]
},
"value": {
"type": "string",
"description": "The message to communicate.",
"minLength": 1,
"examples": [
"Permission denied, scanning aborted"
]
}
}
}
},
"analyzer": {
"type": "object",
"description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
"required": [
"id",
"name",
"version",
"vendor"
],
"properties": {
"id": {
"type": "string",
"description": "Unique id that identifies the analyzer.",
"minLength": 1,
"examples": [
"gitlab-dast"
]
},
"name": {
"type": "string",
"description": "A human readable value that identifies the analyzer, not required to be unique.",
"minLength": 1,
"examples": [
"GitLab DAST"
]
},
"url": {
"type": "string",
"format": "uri",
"pattern": "^https?://.+",
"description": "A link to more information about the analyzer.",
"examples": [
"https://docs.gitlab.com/ee/user/application_security/dast"
]
},
"vendor": {
"description": "The vendor/maintainer of the analyzer.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The name of the vendor.",
"minLength": 1,
"examples": [
"GitLab"
]
}
}
},
"version": {
"type": "string",
"description": "The version of the analyzer.",
"minLength": 1,
"examples": [
"1.0.2"
]
}
}
},
"scanner": {
"type": "object",
"description": "Object defining the scanner used to perform the scan.",
"required": [
"id",
"name",
"version",
"vendor"
],
"properties": {
"id": {
"type": "string",
"description": "Unique id that identifies the scanner.",
"minLength": 1,
"examples": [
"my-sast-scanner"
]
},
"name": {
"type": "string",
"description": "A human readable value that identifies the scanner, not required to be unique.",
"minLength": 1,
"examples": [
"My SAST Scanner"
]
},
"url": {
"type": "string",
"description": "A link to more information about the scanner.",
"examples": [
"https://scanner.url"
]
},
"version": {
"type": "string",
"description": "The version of the scanner.",
"minLength": 1,
"examples": [
"1.0.2"
]
},
"vendor": {
"description": "The vendor/maintainer of the scanner.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The name of the vendor.",
"minLength": 1,
"examples": [
"GitLab"
]
}
}
}
}
},
"start_time": {
"type": "string",
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
"examples": [
"2020-02-14T16:01:59"
]
},
"status": {
"type": "string",
"description": "Result of the scan.",
"enum": [
"success",
"failure"
]
},
"type": {
"type": "string",
"description": "Type of the scan.",
"enum": [
"container_scanning"
]
}
}
},
"schema": {
"type": "string",
"description": "URI pointing to the validating security report schema.",
"format": "uri"
},
"version": {
"type": "string",
"description": "The version of the schema to which the JSON report conforms.",
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
},
"vulnerabilities": {
"type": "array",
"description": "Array of vulnerability objects.",
"items": {
"type": "object",
"description": "Describes the vulnerability using GitLab Flavored Markdown",
"required": [
"category",
"cve",
"identifiers",
"location",
"scanner"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
"examples": [
"642735a5-1425-428d-8d4e-3c854885a3c9"
]
},
"category": {
"type": "string",
"minLength": 1,
"description": "Describes where this vulnerability belongs (for example, SAST, Dependency Scanning, and so on)."
},
"name": {
"type": "string",
"description": "The name of the vulnerability. This must not include the finding's specific information."
},
"message": {
"type": "string",
"description": "A short text section that describes the vulnerability. This may include the finding's specific information."
},
"description": {
"type": "string",
"description": "A long text section describing the vulnerability more fully."
},
"cve": {
"type": "string",
"description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
},
"severity": {
"type": "string",
"description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
"enum": [
"Info",
"Unknown",
"Low",
"Medium",
"High",
"Critical"
]
},
"confidence": {
"type": "string",
"description": "How reliable the vulnerability's assessment is. Possible values are Ignore, Unknown, Experimental, Low, Medium, High, and Confirmed. Note that some analyzers may not report all these possible values.",
"enum": [
"Ignore",
"Unknown",
"Experimental",
"Low",
"Medium",
"High",
"Confirmed"
]
},
"solution": {
"type": "string",
"description": "Explanation of how to fix the vulnerability."
},
"scanner": {
"description": "Describes the scanner used to find this vulnerability.",
"type": "object",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "string",
"minLength": 1,
"description": "The scanner's ID, as a snake_case string."
},
"name": {
"type": "string",
"minLength": 1,
"description": "Human-readable name of the scanner."
}
}
},
"identifiers": {
"type": "array",
"minItems": 1,
"description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
"items": {
"type": "object",
"required": [
"type",
"name",
"value"
],
"properties": {
"type": {
"type": "string",
"description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
"minLength": 1
},
"name": {
"type": "string",
"description": "Human-readable name of the identifier.",
"minLength": 1
},
"url": {
"type": "string",
"description": "URL of the identifier's documentation.",
"format": "uri"
},
"value": {
"type": "string",
"description": "Value of the identifier, for matching purpose.",
"minLength": 1
}
}
}
},
"links": {
"type": "array",
"description": "An array of references to external documentation or articles that describe the vulnerability.",
"items": {
"type": "object",
"required": [
"url"
],
"properties": {
"name": {
"type": "string",
"description": "Name of the vulnerability details link."
},
"url": {
"type": "string",
"description": "URL of the vulnerability details document.",
"format": "uri"
}
}
}
},
"details": {
"$ref": "#/definitions/named_list/properties/items"
},
"tracking": {
"description": "Describes how this vulnerability should be tracked as the project changes.",
"oneOf": [
{
"description": "Declares that a series of items should be tracked using source-specific tracking methods.",
"required": [
"items"
],
"properties": {
"type": {
"const": "source"
},
"items": {
"type": "array",
"items": {
"description": "An item that should be tracked using source-specific tracking methods.",
"type": "object",
"required": [
"signatures"
],
"properties": {
"file": {
"type": "string",
"description": "Path to the file where the vulnerability is located."
},
"start_line": {
"type": "number",
"description": "The first line of the file that includes the vulnerability."
},
"end_line": {
"type": "number",
"description": "The last line of the file that includes the vulnerability."
},
"signatures": {
"type": "array",
"description": "An array of calculated tracking signatures for this tracking item.",
"minItems": 1,
"items": {
"description": "A calculated tracking signature value and metadata.",
"required": [
"algorithm",
"value"
],
"properties": {
"algorithm": {
"type": "string",
"description": "The algorithm used to generate the signature."
},
"value": {
"type": "string",
"description": "The result of this signature algorithm."
}
}
}
}
}
}
}
}
}
],
"properties": {
"type": {
"type": "string",
"description": "Each tracking type must declare its own type."
}
}
},
"flags": {
"description": "Flags that can be attached to vulnerabilities.",
"type": "array",
"items": {
"type": "object",
"description": "Informational flags identified and assigned to a vulnerability.",
"required": [
"type",
"origin",
"description"
],
"properties": {
"type": {
"type": "string",
"minLength": 1,
"description": "Result of the scan.",
"enum": [
"flagged-as-likely-false-positive"
]
},
"origin": {
"minLength": 1,
"description": "Tool that issued the flag.",
"type": "string"
},
"description": {
"minLength": 1,
"description": "What the flag is about.",
"type": "string"
}
}
}
},
"location": {
"type": "object",
"description": "Identifies the vulnerability's location.",
"required": [
"dependency",
"operating_system",
"image"
],
"properties": {
"dependency": {
"type": "object",
"description": "Describes the dependency of a project where the vulnerability is located.",
"properties": {
"package": {
"type": "object",
"description": "Provides information on the package where the vulnerability is located.",
"properties": {
"name": {
"type": "string",
"description": "Name of the package where the vulnerability is located."
}
}
},
"version": {
"type": "string",
"description": "Version of the vulnerable package."
},
"iid": {
"description": "ID that identifies the dependency in the scope of a dependency file.",
"type": "number"
},
"direct": {
"type": "boolean",
"description": "Tells whether this is a direct, top-level dependency of the scanned project."
},
"dependency_path": {
"type": "array",
"description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.",
"items": {
"type": "object",
"required": [
"iid"
],
"properties": {
"iid": {
"type": "number",
"description": "ID that is unique in the scope of a parent object, and specific to the resource type."
}
}
}
}
}
},
"operating_system": {
"type": "string",
"minLength": 1,
"description": "The operating system that contains the vulnerable package."
},
"image": {
"type": "string",
"minLength": 1,
"pattern": "^[^:]+(:\\d+[^:]*)?:[^:]+$",
"description": "The analyzed Docker image."
},
"default_branch_image": {
"type": "string",
"maxLength": 255,
"pattern": "^[a-zA-Z0-9/_.-]+(:\\d+[a-zA-Z0-9/_.-]*)?:[a-zA-Z0-9_.-]+$",
"description": "The name of the image on the default branch."
}
}
}
}
}
},
"remediations": {
"type": "array",
"description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
"items": {
"type": "object",
"required": [
"fixes",
"summary",
"diff"
],
"properties": {
"fixes": {
"type": "array",
"description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
"items": {
"type": "object",
"required": [
"cve"
],
"properties": {
"cve": {
"type": "string",
"description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
}
}
}
},
"summary": {
"type": "string",
"minLength": 1,
"description": "An overview of how the vulnerabilities were fixed."
},
"diff": {
"type": "string",
"minLength": 1,
"description": "A base64-encoded remediation code diff, compatible with git apply."
}
}
}
}
}
}

View File

@ -0,0 +1,874 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Report format for GitLab Fuzz Testing",
"description": "This schema provides the report format for Coverage Guided Fuzz Testing (https://docs.gitlab.com/ee/user/application_security/coverage_fuzzing).",
"definitions": {
"detail_type": {
"oneOf": [
{
"$ref": "#/definitions/named_list"
},
{
"$ref": "#/definitions/list"
},
{
"$ref": "#/definitions/table"
},
{
"$ref": "#/definitions/text"
},
{
"$ref": "#/definitions/url"
},
{
"$ref": "#/definitions/code"
},
{
"$ref": "#/definitions/value"
},
{
"$ref": "#/definitions/diff"
},
{
"$ref": "#/definitions/markdown"
},
{
"$ref": "#/definitions/commit"
},
{
"$ref": "#/definitions/file_location"
},
{
"$ref": "#/definitions/module_location"
}
]
},
"text_value": {
"type": "string"
},
"named_field": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"$ref": "#/definitions/text_value",
"minLength": 1
},
"description": {
"$ref": "#/definitions/text_value"
}
}
},
"named_list": {
"type": "object",
"description": "An object with named and typed fields",
"required": [
"type",
"items"
],
"properties": {
"type": {
"const": "named-list"
},
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"allOf": [
{
"$ref": "#/definitions/named_field"
},
{
"$ref": "#/definitions/detail_type"
}
]
}
}
}
}
},
"list": {
"type": "object",
"description": "A list of typed fields",
"required": [
"type",
"items"
],
"properties": {
"type": {
"const": "list"
},
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
}
}
},
"table": {
"type": "object",
"description": "A table of typed fields",
"required": [
"type",
"rows"
],
"properties": {
"type": {
"const": "table"
},
"header": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
},
"rows": {
"type": "array",
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
}
}
}
},
"text": {
"type": "object",
"description": "Raw text",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "text"
},
"value": {
"$ref": "#/definitions/text_value"
}
}
},
"url": {
"type": "object",
"description": "A single URL",
"required": [
"type",
"href"
],
"properties": {
"type": {
"const": "url"
},
"text": {
"$ref": "#/definitions/text_value"
},
"href": {
"type": "string",
"minLength": 1,
"examples": [
"http://mysite.com"
]
}
}
},
"code": {
"type": "object",
"description": "A codeblock",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "code"
},
"value": {
"type": "string"
},
"lang": {
"type": "string",
"description": "A programming language"
}
}
},
"value": {
"type": "object",
"description": "A field that can store a range of types of value",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "value"
},
"value": {
"type": [
"number",
"string",
"boolean"
]
}
}
},
"diff": {
"type": "object",
"description": "A diff",
"required": [
"type",
"before",
"after"
],
"properties": {
"type": {
"const": "diff"
},
"before": {
"type": "string"
},
"after": {
"type": "string"
}
}
},
"markdown": {
"type": "object",
"description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "markdown"
},
"value": {
"$ref": "#/definitions/text_value",
"examples": [
"Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
]
}
}
},
"commit": {
"type": "object",
"description": "A commit/tag/branch within the GitLab project",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "commit"
},
"value": {
"type": "string",
"description": "The commit SHA",
"minLength": 1
}
}
},
"file_location": {
"type": "object",
"description": "A location within a file in the project",
"required": [
"type",
"file_name",
"line_start"
],
"properties": {
"type": {
"const": "file-location"
},
"file_name": {
"type": "string",
"minLength": 1
},
"line_start": {
"type": "integer"
},
"line_end": {
"type": "integer"
}
}
},
"module_location": {
"type": "object",
"description": "A location within a binary module of the form module+relative_offset",
"required": [
"type",
"module_name",
"offset"
],
"properties": {
"type": {
"const": "module-location"
},
"module_name": {
"type": "string",
"minLength": 1,
"examples": [
"compiled_binary"
]
},
"offset": {
"type": "integer",
"examples": [
100
]
}
}
}
},
"self": {
"version": "14.1.2"
},
"required": [
"version",
"vulnerabilities"
],
"additionalProperties": true,
"properties": {
"scan": {
"type": "object",
"required": [
"end_time",
"scanner",
"start_time",
"status",
"type"
],
"properties": {
"end_time": {
"type": "string",
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
"examples": [
"2020-01-28T03:26:02"
]
},
"messages": {
"type": "array",
"items": {
"type": "object",
"description": "Communication intended for the initiator of a scan.",
"required": [
"level",
"value"
],
"properties": {
"level": {
"type": "string",
"description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
"enum": [
"info",
"warn",
"fatal"
],
"examples": [
"info"
]
},
"value": {
"type": "string",
"description": "The message to communicate.",
"minLength": 1,
"examples": [
"Permission denied, scanning aborted"
]
}
}
}
},
"analyzer": {
"type": "object",
"description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
"required": [
"id",
"name",
"version",
"vendor"
],
"properties": {
"id": {
"type": "string",
"description": "Unique id that identifies the analyzer.",
"minLength": 1,
"examples": [
"gitlab-dast"
]
},
"name": {
"type": "string",
"description": "A human readable value that identifies the analyzer, not required to be unique.",
"minLength": 1,
"examples": [
"GitLab DAST"
]
},
"url": {
"type": "string",
"format": "uri",
"pattern": "^https?://.+",
"description": "A link to more information about the analyzer.",
"examples": [
"https://docs.gitlab.com/ee/user/application_security/dast"
]
},
"vendor": {
"description": "The vendor/maintainer of the analyzer.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The name of the vendor.",
"minLength": 1,
"examples": [
"GitLab"
]
}
}
},
"version": {
"type": "string",
"description": "The version of the analyzer.",
"minLength": 1,
"examples": [
"1.0.2"
]
}
}
},
"scanner": {
"type": "object",
"description": "Object defining the scanner used to perform the scan.",
"required": [
"id",
"name",
"version",
"vendor"
],
"properties": {
"id": {
"type": "string",
"description": "Unique id that identifies the scanner.",
"minLength": 1,
"examples": [
"my-sast-scanner"
]
},
"name": {
"type": "string",
"description": "A human readable value that identifies the scanner, not required to be unique.",
"minLength": 1,
"examples": [
"My SAST Scanner"
]
},
"url": {
"type": "string",
"description": "A link to more information about the scanner.",
"examples": [
"https://scanner.url"
]
},
"version": {
"type": "string",
"description": "The version of the scanner.",
"minLength": 1,
"examples": [
"1.0.2"
]
},
"vendor": {
"description": "The vendor/maintainer of the scanner.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The name of the vendor.",
"minLength": 1,
"examples": [
"GitLab"
]
}
}
}
}
},
"start_time": {
"type": "string",
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
"examples": [
"2020-02-14T16:01:59"
]
},
"status": {
"type": "string",
"description": "Result of the scan.",
"enum": [
"success",
"failure"
]
},
"type": {
"type": "string",
"description": "Type of the scan.",
"enum": [
"coverage_fuzzing"
]
}
}
},
"schema": {
"type": "string",
"description": "URI pointing to the validating security report schema.",
"format": "uri"
},
"version": {
"type": "string",
"description": "The version of the schema to which the JSON report conforms.",
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
},
"vulnerabilities": {
"type": "array",
"description": "Array of vulnerability objects.",
"items": {
"type": "object",
"description": "Describes the vulnerability using GitLab Flavored Markdown",
"required": [
"category",
"cve",
"identifiers",
"location",
"scanner"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
"examples": [
"642735a5-1425-428d-8d4e-3c854885a3c9"
]
},
"category": {
"type": "string",
"minLength": 1,
"description": "Describes where this vulnerability belongs (for example, SAST, Dependency Scanning, and so on)."
},
"name": {
"type": "string",
"description": "The name of the vulnerability. This must not include the finding's specific information."
},
"message": {
"type": "string",
"description": "A short text section that describes the vulnerability. This may include the finding's specific information."
},
"description": {
"type": "string",
"description": "A long text section describing the vulnerability more fully."
},
"cve": {
"type": "string",
"description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
},
"severity": {
"type": "string",
"description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
"enum": [
"Info",
"Unknown",
"Low",
"Medium",
"High",
"Critical"
]
},
"confidence": {
"type": "string",
"description": "How reliable the vulnerability's assessment is. Possible values are Ignore, Unknown, Experimental, Low, Medium, High, and Confirmed. Note that some analyzers may not report all these possible values.",
"enum": [
"Ignore",
"Unknown",
"Experimental",
"Low",
"Medium",
"High",
"Confirmed"
]
},
"solution": {
"type": "string",
"description": "Explanation of how to fix the vulnerability."
},
"scanner": {
"description": "Describes the scanner used to find this vulnerability.",
"type": "object",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "string",
"minLength": 1,
"description": "The scanner's ID, as a snake_case string."
},
"name": {
"type": "string",
"minLength": 1,
"description": "Human-readable name of the scanner."
}
}
},
"identifiers": {
"type": "array",
"minItems": 1,
"description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
"items": {
"type": "object",
"required": [
"type",
"name",
"value"
],
"properties": {
"type": {
"type": "string",
"description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
"minLength": 1
},
"name": {
"type": "string",
"description": "Human-readable name of the identifier.",
"minLength": 1
},
"url": {
"type": "string",
"description": "URL of the identifier's documentation.",
"format": "uri"
},
"value": {
"type": "string",
"description": "Value of the identifier, for matching purpose.",
"minLength": 1
}
}
}
},
"links": {
"type": "array",
"description": "An array of references to external documentation or articles that describe the vulnerability.",
"items": {
"type": "object",
"required": [
"url"
],
"properties": {
"name": {
"type": "string",
"description": "Name of the vulnerability details link."
},
"url": {
"type": "string",
"description": "URL of the vulnerability details document.",
"format": "uri"
}
}
}
},
"details": {
"$ref": "#/definitions/named_list/properties/items"
},
"tracking": {
"description": "Describes how this vulnerability should be tracked as the project changes.",
"oneOf": [
{
"description": "Declares that a series of items should be tracked using source-specific tracking methods.",
"required": [
"items"
],
"properties": {
"type": {
"const": "source"
},
"items": {
"type": "array",
"items": {
"description": "An item that should be tracked using source-specific tracking methods.",
"type": "object",
"required": [
"signatures"
],
"properties": {
"file": {
"type": "string",
"description": "Path to the file where the vulnerability is located."
},
"start_line": {
"type": "number",
"description": "The first line of the file that includes the vulnerability."
},
"end_line": {
"type": "number",
"description": "The last line of the file that includes the vulnerability."
},
"signatures": {
"type": "array",
"description": "An array of calculated tracking signatures for this tracking item.",
"minItems": 1,
"items": {
"description": "A calculated tracking signature value and metadata.",
"required": [
"algorithm",
"value"
],
"properties": {
"algorithm": {
"type": "string",
"description": "The algorithm used to generate the signature."
},
"value": {
"type": "string",
"description": "The result of this signature algorithm."
}
}
}
}
}
}
}
}
}
],
"properties": {
"type": {
"type": "string",
"description": "Each tracking type must declare its own type."
}
}
},
"flags": {
"description": "Flags that can be attached to vulnerabilities.",
"type": "array",
"items": {
"type": "object",
"description": "Informational flags identified and assigned to a vulnerability.",
"required": [
"type",
"origin",
"description"
],
"properties": {
"type": {
"type": "string",
"minLength": 1,
"description": "Result of the scan.",
"enum": [
"flagged-as-likely-false-positive"
]
},
"origin": {
"minLength": 1,
"description": "Tool that issued the flag.",
"type": "string"
},
"description": {
"minLength": 1,
"description": "What the flag is about.",
"type": "string"
}
}
}
},
"location": {
"description": "The location of the error",
"type": "object",
"properties": {
"crash_address": {
"type": "string",
"description": "The relative address in memory were the crash occurred.",
"examples": [
"0xabababab"
]
},
"stacktrace_snippet": {
"type": "string",
"description": "The stack trace recorded during fuzzing resulting the crash.",
"examples": [
"func_a+0xabcd\nfunc_b+0xabcc"
]
},
"crash_state": {
"type": "string",
"description": "Minimised and normalized crash stack-trace (called crash_state).",
"examples": [
"func_a+0xa\nfunc_b+0xb\nfunc_c+0xc"
]
},
"crash_type": {
"type": "string",
"description": "Type of the crash.",
"examples": [
"Heap-Buffer-overflow",
"Division-by-zero"
]
}
}
}
}
}
},
"remediations": {
"type": "array",
"description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
"items": {
"type": "object",
"required": [
"fixes",
"summary",
"diff"
],
"properties": {
"fixes": {
"type": "array",
"description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
"items": {
"type": "object",
"required": [
"cve"
],
"properties": {
"cve": {
"type": "string",
"description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
}
}
}
},
"summary": {
"type": "string",
"minLength": 1,
"description": "An overview of how the vulnerabilities were fixed."
},
"diff": {
"type": "string",
"minLength": 1,
"description": "A base64-encoded remediation code diff, compatible with git apply."
}
}
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,968 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Report format for GitLab Dependency Scanning",
"description": "This schema provides the the report format for Dependency Scanning analyzers (https://docs.gitlab.com/ee/user/application_security/dependency_scanning).",
"definitions": {
"detail_type": {
"oneOf": [
{
"$ref": "#/definitions/named_list"
},
{
"$ref": "#/definitions/list"
},
{
"$ref": "#/definitions/table"
},
{
"$ref": "#/definitions/text"
},
{
"$ref": "#/definitions/url"
},
{
"$ref": "#/definitions/code"
},
{
"$ref": "#/definitions/value"
},
{
"$ref": "#/definitions/diff"
},
{
"$ref": "#/definitions/markdown"
},
{
"$ref": "#/definitions/commit"
},
{
"$ref": "#/definitions/file_location"
},
{
"$ref": "#/definitions/module_location"
}
]
},
"text_value": {
"type": "string"
},
"named_field": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"$ref": "#/definitions/text_value",
"minLength": 1
},
"description": {
"$ref": "#/definitions/text_value"
}
}
},
"named_list": {
"type": "object",
"description": "An object with named and typed fields",
"required": [
"type",
"items"
],
"properties": {
"type": {
"const": "named-list"
},
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"allOf": [
{
"$ref": "#/definitions/named_field"
},
{
"$ref": "#/definitions/detail_type"
}
]
}
}
}
}
},
"list": {
"type": "object",
"description": "A list of typed fields",
"required": [
"type",
"items"
],
"properties": {
"type": {
"const": "list"
},
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
}
}
},
"table": {
"type": "object",
"description": "A table of typed fields",
"required": [
"type",
"rows"
],
"properties": {
"type": {
"const": "table"
},
"header": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
},
"rows": {
"type": "array",
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
}
}
}
},
"text": {
"type": "object",
"description": "Raw text",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "text"
},
"value": {
"$ref": "#/definitions/text_value"
}
}
},
"url": {
"type": "object",
"description": "A single URL",
"required": [
"type",
"href"
],
"properties": {
"type": {
"const": "url"
},
"text": {
"$ref": "#/definitions/text_value"
},
"href": {
"type": "string",
"minLength": 1,
"examples": [
"http://mysite.com"
]
}
}
},
"code": {
"type": "object",
"description": "A codeblock",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "code"
},
"value": {
"type": "string"
},
"lang": {
"type": "string",
"description": "A programming language"
}
}
},
"value": {
"type": "object",
"description": "A field that can store a range of types of value",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "value"
},
"value": {
"type": [
"number",
"string",
"boolean"
]
}
}
},
"diff": {
"type": "object",
"description": "A diff",
"required": [
"type",
"before",
"after"
],
"properties": {
"type": {
"const": "diff"
},
"before": {
"type": "string"
},
"after": {
"type": "string"
}
}
},
"markdown": {
"type": "object",
"description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "markdown"
},
"value": {
"$ref": "#/definitions/text_value",
"examples": [
"Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
]
}
}
},
"commit": {
"type": "object",
"description": "A commit/tag/branch within the GitLab project",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "commit"
},
"value": {
"type": "string",
"description": "The commit SHA",
"minLength": 1
}
}
},
"file_location": {
"type": "object",
"description": "A location within a file in the project",
"required": [
"type",
"file_name",
"line_start"
],
"properties": {
"type": {
"const": "file-location"
},
"file_name": {
"type": "string",
"minLength": 1
},
"line_start": {
"type": "integer"
},
"line_end": {
"type": "integer"
}
}
},
"module_location": {
"type": "object",
"description": "A location within a binary module of the form module+relative_offset",
"required": [
"type",
"module_name",
"offset"
],
"properties": {
"type": {
"const": "module-location"
},
"module_name": {
"type": "string",
"minLength": 1,
"examples": [
"compiled_binary"
]
},
"offset": {
"type": "integer",
"examples": [
100
]
}
}
}
},
"self": {
"version": "14.1.2"
},
"required": [
"dependency_files",
"version",
"vulnerabilities"
],
"additionalProperties": true,
"properties": {
"scan": {
"type": "object",
"required": [
"end_time",
"scanner",
"start_time",
"status",
"type"
],
"properties": {
"end_time": {
"type": "string",
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
"examples": [
"2020-01-28T03:26:02"
]
},
"messages": {
"type": "array",
"items": {
"type": "object",
"description": "Communication intended for the initiator of a scan.",
"required": [
"level",
"value"
],
"properties": {
"level": {
"type": "string",
"description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
"enum": [
"info",
"warn",
"fatal"
],
"examples": [
"info"
]
},
"value": {
"type": "string",
"description": "The message to communicate.",
"minLength": 1,
"examples": [
"Permission denied, scanning aborted"
]
}
}
}
},
"analyzer": {
"type": "object",
"description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
"required": [
"id",
"name",
"version",
"vendor"
],
"properties": {
"id": {
"type": "string",
"description": "Unique id that identifies the analyzer.",
"minLength": 1,
"examples": [
"gitlab-dast"
]
},
"name": {
"type": "string",
"description": "A human readable value that identifies the analyzer, not required to be unique.",
"minLength": 1,
"examples": [
"GitLab DAST"
]
},
"url": {
"type": "string",
"format": "uri",
"pattern": "^https?://.+",
"description": "A link to more information about the analyzer.",
"examples": [
"https://docs.gitlab.com/ee/user/application_security/dast"
]
},
"vendor": {
"description": "The vendor/maintainer of the analyzer.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The name of the vendor.",
"minLength": 1,
"examples": [
"GitLab"
]
}
}
},
"version": {
"type": "string",
"description": "The version of the analyzer.",
"minLength": 1,
"examples": [
"1.0.2"
]
}
}
},
"scanner": {
"type": "object",
"description": "Object defining the scanner used to perform the scan.",
"required": [
"id",
"name",
"version",
"vendor"
],
"properties": {
"id": {
"type": "string",
"description": "Unique id that identifies the scanner.",
"minLength": 1,
"examples": [
"my-sast-scanner"
]
},
"name": {
"type": "string",
"description": "A human readable value that identifies the scanner, not required to be unique.",
"minLength": 1,
"examples": [
"My SAST Scanner"
]
},
"url": {
"type": "string",
"description": "A link to more information about the scanner.",
"examples": [
"https://scanner.url"
]
},
"version": {
"type": "string",
"description": "The version of the scanner.",
"minLength": 1,
"examples": [
"1.0.2"
]
},
"vendor": {
"description": "The vendor/maintainer of the scanner.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The name of the vendor.",
"minLength": 1,
"examples": [
"GitLab"
]
}
}
}
}
},
"start_time": {
"type": "string",
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
"examples": [
"2020-02-14T16:01:59"
]
},
"status": {
"type": "string",
"description": "Result of the scan.",
"enum": [
"success",
"failure"
]
},
"type": {
"type": "string",
"description": "Type of the scan.",
"enum": [
"dependency_scanning"
]
}
}
},
"schema": {
"type": "string",
"description": "URI pointing to the validating security report schema.",
"format": "uri"
},
"version": {
"type": "string",
"description": "The version of the schema to which the JSON report conforms.",
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
},
"vulnerabilities": {
"type": "array",
"description": "Array of vulnerability objects.",
"items": {
"type": "object",
"description": "Describes the vulnerability using GitLab Flavored Markdown",
"required": [
"category",
"cve",
"identifiers",
"location",
"scanner"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
"examples": [
"642735a5-1425-428d-8d4e-3c854885a3c9"
]
},
"category": {
"type": "string",
"minLength": 1,
"description": "Describes where this vulnerability belongs (for example, SAST, Dependency Scanning, and so on)."
},
"name": {
"type": "string",
"description": "The name of the vulnerability. This must not include the finding's specific information."
},
"message": {
"type": "string",
"description": "A short text section that describes the vulnerability. This may include the finding's specific information."
},
"description": {
"type": "string",
"description": "A long text section describing the vulnerability more fully."
},
"cve": {
"type": "string",
"description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
},
"severity": {
"type": "string",
"description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
"enum": [
"Info",
"Unknown",
"Low",
"Medium",
"High",
"Critical"
]
},
"confidence": {
"type": "string",
"description": "How reliable the vulnerability's assessment is. Possible values are Ignore, Unknown, Experimental, Low, Medium, High, and Confirmed. Note that some analyzers may not report all these possible values.",
"enum": [
"Ignore",
"Unknown",
"Experimental",
"Low",
"Medium",
"High",
"Confirmed"
]
},
"solution": {
"type": "string",
"description": "Explanation of how to fix the vulnerability."
},
"scanner": {
"description": "Describes the scanner used to find this vulnerability.",
"type": "object",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "string",
"minLength": 1,
"description": "The scanner's ID, as a snake_case string."
},
"name": {
"type": "string",
"minLength": 1,
"description": "Human-readable name of the scanner."
}
}
},
"identifiers": {
"type": "array",
"minItems": 1,
"description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
"items": {
"type": "object",
"required": [
"type",
"name",
"value"
],
"properties": {
"type": {
"type": "string",
"description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
"minLength": 1
},
"name": {
"type": "string",
"description": "Human-readable name of the identifier.",
"minLength": 1
},
"url": {
"type": "string",
"description": "URL of the identifier's documentation.",
"format": "uri"
},
"value": {
"type": "string",
"description": "Value of the identifier, for matching purpose.",
"minLength": 1
}
}
}
},
"links": {
"type": "array",
"description": "An array of references to external documentation or articles that describe the vulnerability.",
"items": {
"type": "object",
"required": [
"url"
],
"properties": {
"name": {
"type": "string",
"description": "Name of the vulnerability details link."
},
"url": {
"type": "string",
"description": "URL of the vulnerability details document.",
"format": "uri"
}
}
}
},
"details": {
"$ref": "#/definitions/named_list/properties/items"
},
"tracking": {
"description": "Describes how this vulnerability should be tracked as the project changes.",
"oneOf": [
{
"description": "Declares that a series of items should be tracked using source-specific tracking methods.",
"required": [
"items"
],
"properties": {
"type": {
"const": "source"
},
"items": {
"type": "array",
"items": {
"description": "An item that should be tracked using source-specific tracking methods.",
"type": "object",
"required": [
"signatures"
],
"properties": {
"file": {
"type": "string",
"description": "Path to the file where the vulnerability is located."
},
"start_line": {
"type": "number",
"description": "The first line of the file that includes the vulnerability."
},
"end_line": {
"type": "number",
"description": "The last line of the file that includes the vulnerability."
},
"signatures": {
"type": "array",
"description": "An array of calculated tracking signatures for this tracking item.",
"minItems": 1,
"items": {
"description": "A calculated tracking signature value and metadata.",
"required": [
"algorithm",
"value"
],
"properties": {
"algorithm": {
"type": "string",
"description": "The algorithm used to generate the signature."
},
"value": {
"type": "string",
"description": "The result of this signature algorithm."
}
}
}
}
}
}
}
}
}
],
"properties": {
"type": {
"type": "string",
"description": "Each tracking type must declare its own type."
}
}
},
"flags": {
"description": "Flags that can be attached to vulnerabilities.",
"type": "array",
"items": {
"type": "object",
"description": "Informational flags identified and assigned to a vulnerability.",
"required": [
"type",
"origin",
"description"
],
"properties": {
"type": {
"type": "string",
"minLength": 1,
"description": "Result of the scan.",
"enum": [
"flagged-as-likely-false-positive"
]
},
"origin": {
"minLength": 1,
"description": "Tool that issued the flag.",
"type": "string"
},
"description": {
"minLength": 1,
"description": "What the flag is about.",
"type": "string"
}
}
}
},
"location": {
"type": "object",
"description": "Identifies the vulnerability's location.",
"required": [
"file",
"dependency"
],
"properties": {
"file": {
"type": "string",
"minLength": 1,
"description": "Path to the manifest or lock file where the dependency is declared (such as yarn.lock)."
},
"dependency": {
"type": "object",
"description": "Describes the dependency of a project where the vulnerability is located.",
"properties": {
"package": {
"type": "object",
"description": "Provides information on the package where the vulnerability is located.",
"properties": {
"name": {
"type": "string",
"description": "Name of the package where the vulnerability is located."
}
}
},
"version": {
"type": "string",
"description": "Version of the vulnerable package."
},
"iid": {
"description": "ID that identifies the dependency in the scope of a dependency file.",
"type": "number"
},
"direct": {
"type": "boolean",
"description": "Tells whether this is a direct, top-level dependency of the scanned project."
},
"dependency_path": {
"type": "array",
"description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.",
"items": {
"type": "object",
"required": [
"iid"
],
"properties": {
"iid": {
"type": "number",
"description": "ID that is unique in the scope of a parent object, and specific to the resource type."
}
}
}
}
}
}
}
}
}
}
},
"remediations": {
"type": "array",
"description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
"items": {
"type": "object",
"required": [
"fixes",
"summary",
"diff"
],
"properties": {
"fixes": {
"type": "array",
"description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
"items": {
"type": "object",
"required": [
"cve"
],
"properties": {
"cve": {
"type": "string",
"description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
}
}
}
},
"summary": {
"type": "string",
"minLength": 1,
"description": "An overview of how the vulnerabilities were fixed."
},
"diff": {
"type": "string",
"minLength": 1,
"description": "A base64-encoded remediation code diff, compatible with git apply."
}
}
}
},
"dependency_files": {
"type": "array",
"description": "List of dependency files identified in the project.",
"items": {
"type": "object",
"required": [
"path",
"package_manager",
"dependencies"
],
"properties": {
"path": {
"type": "string",
"minLength": 1
},
"package_manager": {
"type": "string",
"minLength": 1
},
"dependencies": {
"type": "array",
"items": {
"type": "object",
"description": "Describes the dependency of a project where the vulnerability is located.",
"properties": {
"package": {
"type": "object",
"description": "Provides information on the package where the vulnerability is located.",
"properties": {
"name": {
"type": "string",
"description": "Name of the package where the vulnerability is located."
}
}
},
"version": {
"type": "string",
"description": "Version of the vulnerable package."
},
"iid": {
"description": "ID that identifies the dependency in the scope of a dependency file.",
"type": "number"
},
"direct": {
"type": "boolean",
"description": "Tells whether this is a direct, top-level dependency of the scanned project."
},
"dependency_path": {
"type": "array",
"description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.",
"items": {
"type": "object",
"required": [
"iid"
],
"properties": {
"iid": {
"type": "number",
"description": "ID that is unique in the scope of a parent object, and specific to the resource type."
}
}
}
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,869 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Report format for GitLab SAST",
"description": "This schema provides the report format for Static Application Security Testing analyzers (https://docs.gitlab.com/ee/user/application_security/sast).",
"definitions": {
"detail_type": {
"oneOf": [
{
"$ref": "#/definitions/named_list"
},
{
"$ref": "#/definitions/list"
},
{
"$ref": "#/definitions/table"
},
{
"$ref": "#/definitions/text"
},
{
"$ref": "#/definitions/url"
},
{
"$ref": "#/definitions/code"
},
{
"$ref": "#/definitions/value"
},
{
"$ref": "#/definitions/diff"
},
{
"$ref": "#/definitions/markdown"
},
{
"$ref": "#/definitions/commit"
},
{
"$ref": "#/definitions/file_location"
},
{
"$ref": "#/definitions/module_location"
}
]
},
"text_value": {
"type": "string"
},
"named_field": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"$ref": "#/definitions/text_value",
"minLength": 1
},
"description": {
"$ref": "#/definitions/text_value"
}
}
},
"named_list": {
"type": "object",
"description": "An object with named and typed fields",
"required": [
"type",
"items"
],
"properties": {
"type": {
"const": "named-list"
},
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"allOf": [
{
"$ref": "#/definitions/named_field"
},
{
"$ref": "#/definitions/detail_type"
}
]
}
}
}
}
},
"list": {
"type": "object",
"description": "A list of typed fields",
"required": [
"type",
"items"
],
"properties": {
"type": {
"const": "list"
},
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
}
}
},
"table": {
"type": "object",
"description": "A table of typed fields",
"required": [
"type",
"rows"
],
"properties": {
"type": {
"const": "table"
},
"header": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
},
"rows": {
"type": "array",
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
}
}
}
},
"text": {
"type": "object",
"description": "Raw text",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "text"
},
"value": {
"$ref": "#/definitions/text_value"
}
}
},
"url": {
"type": "object",
"description": "A single URL",
"required": [
"type",
"href"
],
"properties": {
"type": {
"const": "url"
},
"text": {
"$ref": "#/definitions/text_value"
},
"href": {
"type": "string",
"minLength": 1,
"examples": [
"http://mysite.com"
]
}
}
},
"code": {
"type": "object",
"description": "A codeblock",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "code"
},
"value": {
"type": "string"
},
"lang": {
"type": "string",
"description": "A programming language"
}
}
},
"value": {
"type": "object",
"description": "A field that can store a range of types of value",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "value"
},
"value": {
"type": [
"number",
"string",
"boolean"
]
}
}
},
"diff": {
"type": "object",
"description": "A diff",
"required": [
"type",
"before",
"after"
],
"properties": {
"type": {
"const": "diff"
},
"before": {
"type": "string"
},
"after": {
"type": "string"
}
}
},
"markdown": {
"type": "object",
"description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "markdown"
},
"value": {
"$ref": "#/definitions/text_value",
"examples": [
"Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
]
}
}
},
"commit": {
"type": "object",
"description": "A commit/tag/branch within the GitLab project",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "commit"
},
"value": {
"type": "string",
"description": "The commit SHA",
"minLength": 1
}
}
},
"file_location": {
"type": "object",
"description": "A location within a file in the project",
"required": [
"type",
"file_name",
"line_start"
],
"properties": {
"type": {
"const": "file-location"
},
"file_name": {
"type": "string",
"minLength": 1
},
"line_start": {
"type": "integer"
},
"line_end": {
"type": "integer"
}
}
},
"module_location": {
"type": "object",
"description": "A location within a binary module of the form module+relative_offset",
"required": [
"type",
"module_name",
"offset"
],
"properties": {
"type": {
"const": "module-location"
},
"module_name": {
"type": "string",
"minLength": 1,
"examples": [
"compiled_binary"
]
},
"offset": {
"type": "integer",
"examples": [
100
]
}
}
}
},
"self": {
"version": "14.1.2"
},
"required": [
"version",
"vulnerabilities"
],
"additionalProperties": true,
"properties": {
"scan": {
"type": "object",
"required": [
"end_time",
"scanner",
"start_time",
"status",
"type"
],
"properties": {
"end_time": {
"type": "string",
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
"examples": [
"2020-01-28T03:26:02"
]
},
"messages": {
"type": "array",
"items": {
"type": "object",
"description": "Communication intended for the initiator of a scan.",
"required": [
"level",
"value"
],
"properties": {
"level": {
"type": "string",
"description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
"enum": [
"info",
"warn",
"fatal"
],
"examples": [
"info"
]
},
"value": {
"type": "string",
"description": "The message to communicate.",
"minLength": 1,
"examples": [
"Permission denied, scanning aborted"
]
}
}
}
},
"analyzer": {
"type": "object",
"description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
"required": [
"id",
"name",
"version",
"vendor"
],
"properties": {
"id": {
"type": "string",
"description": "Unique id that identifies the analyzer.",
"minLength": 1,
"examples": [
"gitlab-dast"
]
},
"name": {
"type": "string",
"description": "A human readable value that identifies the analyzer, not required to be unique.",
"minLength": 1,
"examples": [
"GitLab DAST"
]
},
"url": {
"type": "string",
"format": "uri",
"pattern": "^https?://.+",
"description": "A link to more information about the analyzer.",
"examples": [
"https://docs.gitlab.com/ee/user/application_security/dast"
]
},
"vendor": {
"description": "The vendor/maintainer of the analyzer.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The name of the vendor.",
"minLength": 1,
"examples": [
"GitLab"
]
}
}
},
"version": {
"type": "string",
"description": "The version of the analyzer.",
"minLength": 1,
"examples": [
"1.0.2"
]
}
}
},
"scanner": {
"type": "object",
"description": "Object defining the scanner used to perform the scan.",
"required": [
"id",
"name",
"version",
"vendor"
],
"properties": {
"id": {
"type": "string",
"description": "Unique id that identifies the scanner.",
"minLength": 1,
"examples": [
"my-sast-scanner"
]
},
"name": {
"type": "string",
"description": "A human readable value that identifies the scanner, not required to be unique.",
"minLength": 1,
"examples": [
"My SAST Scanner"
]
},
"url": {
"type": "string",
"description": "A link to more information about the scanner.",
"examples": [
"https://scanner.url"
]
},
"version": {
"type": "string",
"description": "The version of the scanner.",
"minLength": 1,
"examples": [
"1.0.2"
]
},
"vendor": {
"description": "The vendor/maintainer of the scanner.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The name of the vendor.",
"minLength": 1,
"examples": [
"GitLab"
]
}
}
}
}
},
"start_time": {
"type": "string",
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
"examples": [
"2020-02-14T16:01:59"
]
},
"status": {
"type": "string",
"description": "Result of the scan.",
"enum": [
"success",
"failure"
]
},
"type": {
"type": "string",
"description": "Type of the scan.",
"enum": [
"sast"
]
}
}
},
"schema": {
"type": "string",
"description": "URI pointing to the validating security report schema.",
"format": "uri"
},
"version": {
"type": "string",
"description": "The version of the schema to which the JSON report conforms.",
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
},
"vulnerabilities": {
"type": "array",
"description": "Array of vulnerability objects.",
"items": {
"type": "object",
"description": "Describes the vulnerability using GitLab Flavored Markdown",
"required": [
"category",
"cve",
"identifiers",
"location",
"scanner"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
"examples": [
"642735a5-1425-428d-8d4e-3c854885a3c9"
]
},
"category": {
"type": "string",
"minLength": 1,
"description": "Describes where this vulnerability belongs (for example, SAST, Dependency Scanning, and so on)."
},
"name": {
"type": "string",
"description": "The name of the vulnerability. This must not include the finding's specific information."
},
"message": {
"type": "string",
"description": "A short text section that describes the vulnerability. This may include the finding's specific information."
},
"description": {
"type": "string",
"description": "A long text section describing the vulnerability more fully."
},
"cve": {
"type": "string",
"description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
},
"severity": {
"type": "string",
"description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
"enum": [
"Info",
"Unknown",
"Low",
"Medium",
"High",
"Critical"
]
},
"confidence": {
"type": "string",
"description": "How reliable the vulnerability's assessment is. Possible values are Ignore, Unknown, Experimental, Low, Medium, High, and Confirmed. Note that some analyzers may not report all these possible values.",
"enum": [
"Ignore",
"Unknown",
"Experimental",
"Low",
"Medium",
"High",
"Confirmed"
]
},
"solution": {
"type": "string",
"description": "Explanation of how to fix the vulnerability."
},
"scanner": {
"description": "Describes the scanner used to find this vulnerability.",
"type": "object",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "string",
"minLength": 1,
"description": "The scanner's ID, as a snake_case string."
},
"name": {
"type": "string",
"minLength": 1,
"description": "Human-readable name of the scanner."
}
}
},
"identifiers": {
"type": "array",
"minItems": 1,
"description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
"items": {
"type": "object",
"required": [
"type",
"name",
"value"
],
"properties": {
"type": {
"type": "string",
"description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
"minLength": 1
},
"name": {
"type": "string",
"description": "Human-readable name of the identifier.",
"minLength": 1
},
"url": {
"type": "string",
"description": "URL of the identifier's documentation.",
"format": "uri"
},
"value": {
"type": "string",
"description": "Value of the identifier, for matching purpose.",
"minLength": 1
}
}
}
},
"links": {
"type": "array",
"description": "An array of references to external documentation or articles that describe the vulnerability.",
"items": {
"type": "object",
"required": [
"url"
],
"properties": {
"name": {
"type": "string",
"description": "Name of the vulnerability details link."
},
"url": {
"type": "string",
"description": "URL of the vulnerability details document.",
"format": "uri"
}
}
}
},
"details": {
"$ref": "#/definitions/named_list/properties/items"
},
"tracking": {
"description": "Describes how this vulnerability should be tracked as the project changes.",
"oneOf": [
{
"description": "Declares that a series of items should be tracked using source-specific tracking methods.",
"required": [
"items"
],
"properties": {
"type": {
"const": "source"
},
"items": {
"type": "array",
"items": {
"description": "An item that should be tracked using source-specific tracking methods.",
"type": "object",
"required": [
"signatures"
],
"properties": {
"file": {
"type": "string",
"description": "Path to the file where the vulnerability is located."
},
"start_line": {
"type": "number",
"description": "The first line of the file that includes the vulnerability."
},
"end_line": {
"type": "number",
"description": "The last line of the file that includes the vulnerability."
},
"signatures": {
"type": "array",
"description": "An array of calculated tracking signatures for this tracking item.",
"minItems": 1,
"items": {
"description": "A calculated tracking signature value and metadata.",
"required": [
"algorithm",
"value"
],
"properties": {
"algorithm": {
"type": "string",
"description": "The algorithm used to generate the signature."
},
"value": {
"type": "string",
"description": "The result of this signature algorithm."
}
}
}
}
}
}
}
}
}
],
"properties": {
"type": {
"type": "string",
"description": "Each tracking type must declare its own type."
}
}
},
"flags": {
"description": "Flags that can be attached to vulnerabilities.",
"type": "array",
"items": {
"type": "object",
"description": "Informational flags identified and assigned to a vulnerability.",
"required": [
"type",
"origin",
"description"
],
"properties": {
"type": {
"type": "string",
"minLength": 1,
"description": "Result of the scan.",
"enum": [
"flagged-as-likely-false-positive"
]
},
"origin": {
"minLength": 1,
"description": "Tool that issued the flag.",
"type": "string"
},
"description": {
"minLength": 1,
"description": "What the flag is about.",
"type": "string"
}
}
}
},
"location": {
"type": "object",
"description": "Identifies the vulnerability's location.",
"properties": {
"file": {
"type": "string",
"description": "Path to the file where the vulnerability is located."
},
"start_line": {
"type": "number",
"description": "The first line of the code affected by the vulnerability."
},
"end_line": {
"type": "number",
"description": "The last line of the code affected by the vulnerability."
},
"class": {
"type": "string",
"description": "Provides the name of the class where the vulnerability is located."
},
"method": {
"type": "string",
"description": "Provides the name of the method where the vulnerability is located."
}
}
},
"raw_source_code_extract": {
"type": "string",
"description": "Provides an unsanitized excerpt of the affected source code."
}
}
}
},
"remediations": {
"type": "array",
"description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
"items": {
"type": "object",
"required": [
"fixes",
"summary",
"diff"
],
"properties": {
"fixes": {
"type": "array",
"description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
"items": {
"type": "object",
"required": [
"cve"
],
"properties": {
"cve": {
"type": "string",
"description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
}
}
}
},
"summary": {
"type": "string",
"minLength": 1,
"description": "An overview of how the vulnerabilities were fixed."
},
"diff": {
"type": "string",
"minLength": 1,
"description": "A base64-encoded remediation code diff, compatible with git apply."
}
}
}
}
}
}

View File

@ -0,0 +1,892 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Report format for GitLab Secret Detection",
"description": "This schema provides the the report format for the Secret Detection analyzer (https://docs.gitlab.com/ee/user/application_security/secret_detection)",
"definitions": {
"detail_type": {
"oneOf": [
{
"$ref": "#/definitions/named_list"
},
{
"$ref": "#/definitions/list"
},
{
"$ref": "#/definitions/table"
},
{
"$ref": "#/definitions/text"
},
{
"$ref": "#/definitions/url"
},
{
"$ref": "#/definitions/code"
},
{
"$ref": "#/definitions/value"
},
{
"$ref": "#/definitions/diff"
},
{
"$ref": "#/definitions/markdown"
},
{
"$ref": "#/definitions/commit"
},
{
"$ref": "#/definitions/file_location"
},
{
"$ref": "#/definitions/module_location"
}
]
},
"text_value": {
"type": "string"
},
"named_field": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"$ref": "#/definitions/text_value",
"minLength": 1
},
"description": {
"$ref": "#/definitions/text_value"
}
}
},
"named_list": {
"type": "object",
"description": "An object with named and typed fields",
"required": [
"type",
"items"
],
"properties": {
"type": {
"const": "named-list"
},
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"allOf": [
{
"$ref": "#/definitions/named_field"
},
{
"$ref": "#/definitions/detail_type"
}
]
}
}
}
}
},
"list": {
"type": "object",
"description": "A list of typed fields",
"required": [
"type",
"items"
],
"properties": {
"type": {
"const": "list"
},
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
}
}
},
"table": {
"type": "object",
"description": "A table of typed fields",
"required": [
"type",
"rows"
],
"properties": {
"type": {
"const": "table"
},
"header": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
},
"rows": {
"type": "array",
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/detail_type"
}
}
}
}
},
"text": {
"type": "object",
"description": "Raw text",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "text"
},
"value": {
"$ref": "#/definitions/text_value"
}
}
},
"url": {
"type": "object",
"description": "A single URL",
"required": [
"type",
"href"
],
"properties": {
"type": {
"const": "url"
},
"text": {
"$ref": "#/definitions/text_value"
},
"href": {
"type": "string",
"minLength": 1,
"examples": [
"http://mysite.com"
]
}
}
},
"code": {
"type": "object",
"description": "A codeblock",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "code"
},
"value": {
"type": "string"
},
"lang": {
"type": "string",
"description": "A programming language"
}
}
},
"value": {
"type": "object",
"description": "A field that can store a range of types of value",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "value"
},
"value": {
"type": [
"number",
"string",
"boolean"
]
}
}
},
"diff": {
"type": "object",
"description": "A diff",
"required": [
"type",
"before",
"after"
],
"properties": {
"type": {
"const": "diff"
},
"before": {
"type": "string"
},
"after": {
"type": "string"
}
}
},
"markdown": {
"type": "object",
"description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "markdown"
},
"value": {
"$ref": "#/definitions/text_value",
"examples": [
"Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)"
]
}
}
},
"commit": {
"type": "object",
"description": "A commit/tag/branch within the GitLab project",
"required": [
"type",
"value"
],
"properties": {
"type": {
"const": "commit"
},
"value": {
"type": "string",
"description": "The commit SHA",
"minLength": 1
}
}
},
"file_location": {
"type": "object",
"description": "A location within a file in the project",
"required": [
"type",
"file_name",
"line_start"
],
"properties": {
"type": {
"const": "file-location"
},
"file_name": {
"type": "string",
"minLength": 1
},
"line_start": {
"type": "integer"
},
"line_end": {
"type": "integer"
}
}
},
"module_location": {
"type": "object",
"description": "A location within a binary module of the form module+relative_offset",
"required": [
"type",
"module_name",
"offset"
],
"properties": {
"type": {
"const": "module-location"
},
"module_name": {
"type": "string",
"minLength": 1,
"examples": [
"compiled_binary"
]
},
"offset": {
"type": "integer",
"examples": [
100
]
}
}
}
},
"self": {
"version": "14.1.2"
},
"required": [
"version",
"vulnerabilities"
],
"additionalProperties": true,
"properties": {
"scan": {
"type": "object",
"required": [
"end_time",
"scanner",
"start_time",
"status",
"type"
],
"properties": {
"end_time": {
"type": "string",
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
"examples": [
"2020-01-28T03:26:02"
]
},
"messages": {
"type": "array",
"items": {
"type": "object",
"description": "Communication intended for the initiator of a scan.",
"required": [
"level",
"value"
],
"properties": {
"level": {
"type": "string",
"description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
"enum": [
"info",
"warn",
"fatal"
],
"examples": [
"info"
]
},
"value": {
"type": "string",
"description": "The message to communicate.",
"minLength": 1,
"examples": [
"Permission denied, scanning aborted"
]
}
}
}
},
"analyzer": {
"type": "object",
"description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
"required": [
"id",
"name",
"version",
"vendor"
],
"properties": {
"id": {
"type": "string",
"description": "Unique id that identifies the analyzer.",
"minLength": 1,
"examples": [
"gitlab-dast"
]
},
"name": {
"type": "string",
"description": "A human readable value that identifies the analyzer, not required to be unique.",
"minLength": 1,
"examples": [
"GitLab DAST"
]
},
"url": {
"type": "string",
"format": "uri",
"pattern": "^https?://.+",
"description": "A link to more information about the analyzer.",
"examples": [
"https://docs.gitlab.com/ee/user/application_security/dast"
]
},
"vendor": {
"description": "The vendor/maintainer of the analyzer.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The name of the vendor.",
"minLength": 1,
"examples": [
"GitLab"
]
}
}
},
"version": {
"type": "string",
"description": "The version of the analyzer.",
"minLength": 1,
"examples": [
"1.0.2"
]
}
}
},
"scanner": {
"type": "object",
"description": "Object defining the scanner used to perform the scan.",
"required": [
"id",
"name",
"version",
"vendor"
],
"properties": {
"id": {
"type": "string",
"description": "Unique id that identifies the scanner.",
"minLength": 1,
"examples": [
"my-sast-scanner"
]
},
"name": {
"type": "string",
"description": "A human readable value that identifies the scanner, not required to be unique.",
"minLength": 1,
"examples": [
"My SAST Scanner"
]
},
"url": {
"type": "string",
"description": "A link to more information about the scanner.",
"examples": [
"https://scanner.url"
]
},
"version": {
"type": "string",
"description": "The version of the scanner.",
"minLength": 1,
"examples": [
"1.0.2"
]
},
"vendor": {
"description": "The vendor/maintainer of the scanner.",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "The name of the vendor.",
"minLength": 1,
"examples": [
"GitLab"
]
}
}
}
}
},
"start_time": {
"type": "string",
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
"examples": [
"2020-02-14T16:01:59"
]
},
"status": {
"type": "string",
"description": "Result of the scan.",
"enum": [
"success",
"failure"
]
},
"type": {
"type": "string",
"description": "Type of the scan.",
"enum": [
"secret_detection"
]
}
}
},
"schema": {
"type": "string",
"description": "URI pointing to the validating security report schema.",
"format": "uri"
},
"version": {
"type": "string",
"description": "The version of the schema to which the JSON report conforms.",
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
},
"vulnerabilities": {
"type": "array",
"description": "Array of vulnerability objects.",
"items": {
"type": "object",
"description": "Describes the vulnerability using GitLab Flavored Markdown",
"required": [
"category",
"cve",
"identifiers",
"location",
"scanner"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
"examples": [
"642735a5-1425-428d-8d4e-3c854885a3c9"
]
},
"category": {
"type": "string",
"minLength": 1,
"description": "Describes where this vulnerability belongs (for example, SAST, Dependency Scanning, and so on)."
},
"name": {
"type": "string",
"description": "The name of the vulnerability. This must not include the finding's specific information."
},
"message": {
"type": "string",
"description": "A short text section that describes the vulnerability. This may include the finding's specific information."
},
"description": {
"type": "string",
"description": "A long text section describing the vulnerability more fully."
},
"cve": {
"type": "string",
"description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
},
"severity": {
"type": "string",
"description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
"enum": [
"Info",
"Unknown",
"Low",
"Medium",
"High",
"Critical"
]
},
"confidence": {
"type": "string",
"description": "How reliable the vulnerability's assessment is. Possible values are Ignore, Unknown, Experimental, Low, Medium, High, and Confirmed. Note that some analyzers may not report all these possible values.",
"enum": [
"Ignore",
"Unknown",
"Experimental",
"Low",
"Medium",
"High",
"Confirmed"
]
},
"solution": {
"type": "string",
"description": "Explanation of how to fix the vulnerability."
},
"scanner": {
"description": "Describes the scanner used to find this vulnerability.",
"type": "object",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "string",
"minLength": 1,
"description": "The scanner's ID, as a snake_case string."
},
"name": {
"type": "string",
"minLength": 1,
"description": "Human-readable name of the scanner."
}
}
},
"identifiers": {
"type": "array",
"minItems": 1,
"description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
"items": {
"type": "object",
"required": [
"type",
"name",
"value"
],
"properties": {
"type": {
"type": "string",
"description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
"minLength": 1
},
"name": {
"type": "string",
"description": "Human-readable name of the identifier.",
"minLength": 1
},
"url": {
"type": "string",
"description": "URL of the identifier's documentation.",
"format": "uri"
},
"value": {
"type": "string",
"description": "Value of the identifier, for matching purpose.",
"minLength": 1
}
}
}
},
"links": {
"type": "array",
"description": "An array of references to external documentation or articles that describe the vulnerability.",
"items": {
"type": "object",
"required": [
"url"
],
"properties": {
"name": {
"type": "string",
"description": "Name of the vulnerability details link."
},
"url": {
"type": "string",
"description": "URL of the vulnerability details document.",
"format": "uri"
}
}
}
},
"details": {
"$ref": "#/definitions/named_list/properties/items"
},
"tracking": {
"description": "Describes how this vulnerability should be tracked as the project changes.",
"oneOf": [
{
"description": "Declares that a series of items should be tracked using source-specific tracking methods.",
"required": [
"items"
],
"properties": {
"type": {
"const": "source"
},
"items": {
"type": "array",
"items": {
"description": "An item that should be tracked using source-specific tracking methods.",
"type": "object",
"required": [
"signatures"
],
"properties": {
"file": {
"type": "string",
"description": "Path to the file where the vulnerability is located."
},
"start_line": {
"type": "number",
"description": "The first line of the file that includes the vulnerability."
},
"end_line": {
"type": "number",
"description": "The last line of the file that includes the vulnerability."
},
"signatures": {
"type": "array",
"description": "An array of calculated tracking signatures for this tracking item.",
"minItems": 1,
"items": {
"description": "A calculated tracking signature value and metadata.",
"required": [
"algorithm",
"value"
],
"properties": {
"algorithm": {
"type": "string",
"description": "The algorithm used to generate the signature."
},
"value": {
"type": "string",
"description": "The result of this signature algorithm."
}
}
}
}
}
}
}
}
}
],
"properties": {
"type": {
"type": "string",
"description": "Each tracking type must declare its own type."
}
}
},
"flags": {
"description": "Flags that can be attached to vulnerabilities.",
"type": "array",
"items": {
"type": "object",
"description": "Informational flags identified and assigned to a vulnerability.",
"required": [
"type",
"origin",
"description"
],
"properties": {
"type": {
"type": "string",
"minLength": 1,
"description": "Result of the scan.",
"enum": [
"flagged-as-likely-false-positive"
]
},
"origin": {
"minLength": 1,
"description": "Tool that issued the flag.",
"type": "string"
},
"description": {
"minLength": 1,
"description": "What the flag is about.",
"type": "string"
}
}
}
},
"location": {
"required": [
"commit"
],
"properties": {
"file": {
"type": "string",
"description": "Path to the file where the vulnerability is located"
},
"commit": {
"type": "object",
"description": "Represents the commit in which the vulnerability was detected",
"required": [
"sha"
],
"properties": {
"author": {
"type": "string"
},
"date": {
"type": "string"
},
"message": {
"type": "string"
},
"sha": {
"type": "string",
"minLength": 1
}
}
},
"start_line": {
"type": "number",
"description": "The first line of the code affected by the vulnerability"
},
"end_line": {
"type": "number",
"description": "The last line of the code affected by the vulnerability"
},
"class": {
"type": "string",
"description": "Provides the name of the class where the vulnerability is located"
},
"method": {
"type": "string",
"description": "Provides the name of the method where the vulnerability is located"
}
}
},
"raw_source_code_extract": {
"type": "string",
"description": "Provides an unsanitized excerpt of the affected source code."
}
}
}
},
"remediations": {
"type": "array",
"description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
"items": {
"type": "object",
"required": [
"fixes",
"summary",
"diff"
],
"properties": {
"fixes": {
"type": "array",
"description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
"items": {
"type": "object",
"required": [
"cve"
],
"properties": {
"cve": {
"type": "string",
"description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
}
}
}
},
"summary": {
"type": "string",
"minLength": 1,
"description": "An overview of how the vulnerabilities were fixed."
},
"diff": {
"type": "string",
"minLength": 1,
"description": "A base64-encoded remediation code diff, compatible with git apply."
}
}
}
}
}
}

View File

@ -219,9 +219,7 @@ module Gitlab
end
def archived?
# TODO check checksum to ensure archive completed successfully
# See https://gitlab.com/gitlab-org/gitlab/-/issues/259619
trace_artifact&.archived_trace_exists?
trace_artifact&.stored?
end
def destroy_any_orphan_trace_data!

View File

@ -149,28 +149,47 @@ module Gitlab
module Praefect
extend Gitlab::SetupHelper
class << self
def configuration_toml(gitaly_dir, _, _)
def configuration_toml(gitaly_dir, _storage_paths, options)
raise 'This configuration is only intended for test' unless Rails.env.test?
nodes = [{ storage: 'default', address: "unix:#{gitaly_dir}/gitaly.socket", primary: true, token: 'secret' }]
second_storage_nodes = [{ storage: 'test_second_storage', address: "unix:#{gitaly_dir}/gitaly2.socket", primary: true, token: 'secret' }]
storages = [{ name: 'default', node: nodes }, { name: 'test_second_storage', node: second_storage_nodes }]
failover = { enabled: false, election_strategy: 'local' }
config = {
i_understand_my_election_strategy_is_unsupported_and_will_be_removed_without_warning: true,
socket_path: "#{gitaly_dir}/praefect.socket",
memory_queue_enabled: true,
virtual_storage: storages,
failover: failover
token: 'secret'
}
config[:token] = 'secret' if Rails.env.test?
if options[:per_repository]
failover = { enabled: true, election_strategy: 'per_repository' }
database = { host: options.fetch(:pghost),
port: options.fetch(:pgport).to_i,
user: options.fetch(:pguser),
dbname: options.fetch(:dbname, 'praefect_test') }
config.merge!(database: database,
failover: failover)
else
failover = { enabled: false, election_strategy: 'local' }
config.merge!(
i_understand_my_election_strategy_is_unsupported_and_will_be_removed_without_warning: true,
memory_queue_enabled: true,
failover: failover
)
end
TomlRB.dump(config)
end
private
def get_config_path(dir, _)
File.join(dir, 'praefect.config.toml')
def get_config_path(dir, options)
config_filename = options[:config_filename] || 'praefect.config.toml'
File.join(dir, config_filename)
end
end
end

View File

@ -1,53 +0,0 @@
# frozen_string_literal: true
require 'set'
require_relative '../../migration_helpers'
module RuboCop
module Cop
module Migration
# Cop that prevents the use of hash indexes in database migrations
class HashIndex < RuboCop::Cop::Cop
include MigrationHelpers
MSG = 'hash indexes should be avoided at all costs since they are not ' \
'recorded in the PostgreSQL WAL, you should use a btree index instead'
NAMES = Set.new([:add_index, :index, :add_concurrent_index]).freeze
def on_send(node)
return unless in_migration?(node)
name = node.children[1]
return unless NAMES.include?(name)
opts = node.children.last
return unless opts && opts.type == :hash
opts.each_node(:pair) do |pair|
next unless hash_key_type(pair) == :sym &&
hash_key_name(pair) == :using
if hash_key_value(pair).to_s == 'hash'
add_offense(pair, location: :expression)
end
end
end
def hash_key_type(pair)
pair.children[0].type
end
def hash_key_name(pair)
pair.children[0].children[0]
end
def hash_key_value(pair)
pair.children[1].children[0]
end
end
end
end
end

View File

@ -11,6 +11,9 @@ class GitalyTestSpawn
def run
install_gitaly_gems
# Run Praefect migrations
setup_praefect
# Optionally specify the path to the gitaly config toml as first argument.
# Used by workhorse in test.
spawn_gitaly(ARGV[0])

View File

@ -53,6 +53,7 @@ require 'omniauth'
require 'omniauth-github'
require 'etc'
require_dependency File.expand_path('../lib/gitlab/access', __dir__)
require_dependency File.expand_path('../lib/gitlab/utils', __dir__)
require_dependency File.expand_path('../config/initializers/1_settings', __dir__)

View File

@ -61,9 +61,14 @@ function setup_db_user_only() {
source scripts/create_postgres_user.sh
}
function setup_db_praefect() {
createdb -h postgres -U postgres --encoding=UTF8 --echo praefect_test
}
function setup_db() {
run_timed_command "setup_db_user_only"
run_timed_command_with_metric "bundle exec rake db:drop db:create db:structure:load db:migrate gitlab:db:setup_ee" "setup_db"
run_timed_command "setup_db_praefect"
}
function install_api_client_dependencies_with_apk() {

View File

@ -413,7 +413,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
let(:expected_errors) do
[
"Version 12.37.0 for report type dast is unsupported, supported versions for this report type are: 14.0.0, 14.0.1, 14.0.2, 14.0.3, 14.0.4, 14.0.5, 14.0.6, 14.1.0, 14.1.1"
"Version 12.37.0 for report type dast is unsupported, supported versions for this report type are: 14.0.0, 14.0.1, 14.0.2, 14.0.3, 14.0.4, 14.0.5, 14.0.6, 14.1.0, 14.1.1, 14.1.2"
]
end
@ -429,7 +429,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
let(:expected_errors) do
[
"Version 12.37.0 for report type dast is unsupported, supported versions for this report type are: 14.0.0, 14.0.1, 14.0.2, 14.0.3, 14.0.4, 14.0.5, 14.0.6, 14.1.0, 14.1.1",
"Version 12.37.0 for report type dast is unsupported, supported versions for this report type are: 14.0.0, 14.0.1, 14.0.2, 14.0.3, 14.0.4, 14.0.5, 14.0.6, 14.1.0, 14.1.1, 14.1.2",
"root is missing required keys: vulnerabilities"
]
end
@ -513,7 +513,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
let(:report_version) { described_class::DEPRECATED_VERSIONS[report_type].last }
let(:expected_deprecation_warnings) do
[
"Version V2.7.0 for report type dast has been deprecated, supported versions for this report type are: 14.0.0, 14.0.1, 14.0.2, 14.0.3, 14.0.4, 14.0.5, 14.0.6, 14.1.0, 14.1.1"
"Version V2.7.0 for report type dast has been deprecated, supported versions for this report type are: 14.0.0, 14.0.1, 14.0.2, 14.0.3, 14.0.4, 14.0.5, 14.0.6, 14.1.0, 14.1.1, 14.1.2"
]
end
@ -721,7 +721,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
let(:expected_warnings) do
[
"Version 12.37.0 for report type dast is unsupported, supported versions for this report type are: 14.0.0, 14.0.1, 14.0.2, 14.0.3, 14.0.4, 14.0.5, 14.0.6, 14.1.0, 14.1.1"
"Version 12.37.0 for report type dast is unsupported, supported versions for this report type are: 14.0.0, 14.0.1, 14.0.2, 14.0.3, 14.0.4, 14.0.5, 14.0.6, 14.1.0, 14.1.1, 14.1.2"
]
end
@ -737,7 +737,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
let(:expected_warnings) do
[
"Version 12.37.0 for report type dast is unsupported, supported versions for this report type are: 14.0.0, 14.0.1, 14.0.2, 14.0.3, 14.0.4, 14.0.5, 14.0.6, 14.1.0, 14.1.1",
"Version 12.37.0 for report type dast is unsupported, supported versions for this report type are: 14.0.0, 14.0.1, 14.0.2, 14.0.3, 14.0.4, 14.0.5, 14.0.6, 14.1.0, 14.1.1, 14.1.2",
"root is missing required keys: vulnerabilities"
]
end

View File

@ -0,0 +1,79 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::SetupHelper::Praefect do
describe '.configuration_toml' do
let(:opt_per_repo) do
{ per_repository: true,
pghost: 'my-host',
pgport: 555432,
pguser: 'me' }
end
it 'defaults to in memory queue' do
toml = described_class.configuration_toml('/here', nil, {})
expect(toml).to match(/i_understand_my_election_strategy_is_unsupported_and_will_be_removed_without_warning/)
expect(toml).to match(/memory_queue_enabled = true/)
expect(toml).to match(/election_strategy = "local"/)
expect(toml).not_to match(/\[database\]/)
end
it 'provides database details if wanted' do
toml = described_class.configuration_toml('/here', nil, opt_per_repo)
expect(toml).not_to match(/i_understand_my_election_strategy_is_unsupported_and_will_be_removed_without_warning/)
expect(toml).not_to match(/memory_queue_enabled = true/)
expect(toml).to match(/\[database\]/)
expect(toml).to match(/election_strategy = "per_repository"/)
end
%i[pghost pgport pguser].each do |pg_key|
it "fails when #{pg_key} is missing" do
opt = opt_per_repo.dup
opt.delete(pg_key)
expect do
described_class.configuration_toml('/here', nil, opt)
end.to raise_error(KeyError)
end
it "uses the provided #{pg_key}" do
toml = described_class.configuration_toml('/here', nil, opt_per_repo)
expect(toml).to match(/#{pg_key.to_s.delete_prefix('pg')} = "?#{opt_per_repo[pg_key]}"?/)
end
end
it 'defaults to praefect_test if dbname is missing' do
toml = described_class.configuration_toml('/here', nil, opt_per_repo)
expect(toml).to match(/dbname = "praefect_test"/)
end
it 'uses the provided dbname' do
opt = opt_per_repo.merge(dbname: 'my_db')
toml = described_class.configuration_toml('/here', nil, opt)
expect(toml).to match(/dbname = "my_db"/)
end
end
describe '.get_config_path' do
it 'defaults to praefect.config.toml' do
expect(described_class).to receive(:generate_configuration).with(anything, '/tmp/praefect.config.toml', anything)
described_class.create_configuration('/tmp', {})
end
it 'takes the provided config_filename' do
opt = { config_filename: 'yo.toml' }
expect(described_class).to receive(:generate_configuration).with(anything, '/tmp/yo.toml', anything)
described_class.create_configuration('/tmp', {}, options: opt)
end
end
end

View File

@ -206,8 +206,8 @@ RSpec.describe Ci::JobArtifact do
end
end
describe '#archived_trace_exists?' do
subject { artifact.archived_trace_exists? }
describe '#stored?' do
subject { artifact.stored? }
context 'when the file exists' do
it { is_expected.to be_truthy }

View File

@ -1,47 +0,0 @@
# frozen_string_literal: true
require 'fast_spec_helper'
require_relative '../../../../rubocop/cop/migration/hash_index'
RSpec.describe RuboCop::Cop::Migration::HashIndex do
subject(:cop) { described_class.new }
context 'when in migration' do
before do
allow(cop).to receive(:in_migration?).and_return(true)
end
it 'registers an offense when creating a hash index' do
expect_offense(<<~RUBY)
def change
add_index :table, :column, using: :hash
^^^^^^^^^^^^ hash indexes should be avoided at all costs[...]
end
RUBY
end
it 'registers an offense when creating a concurrent hash index' do
expect_offense(<<~RUBY)
def change
add_concurrent_index :table, :column, using: :hash
^^^^^^^^^^^^ hash indexes should be avoided at all costs[...]
end
RUBY
end
it 'registers an offense when creating a hash index using t.index' do
expect_offense(<<~RUBY)
def change
t.index :table, :column, using: :hash
^^^^^^^^^^^^ hash indexes should be avoided at all costs[...]
end
RUBY
end
end
context 'when outside of migration' do
it 'registers no offense' do
expect_no_offenses('def change; index :table, :column, using: :hash; end')
end
end
end

View File

@ -106,12 +106,14 @@ module GitalySetup
Gitlab.config.repositories.storages[REPOS_STORAGE].legacy_disk_path
end
def service_binary(service)
def service_cmd(service, toml = nil)
toml ||= config_path(service)
case service
when :gitaly, :gitaly2
'gitaly'
[File.join(tmp_tests_gitaly_bin_dir, 'gitaly'), toml]
when :praefect
'praefect'
[File.join(tmp_tests_gitaly_bin_dir, 'praefect'), '-config', toml]
end
end
@ -136,14 +138,18 @@ module GitalySetup
end
def start_praefect
start(:praefect)
if ENV['GITALY_PRAEFECT_WITH_DB']
LOGGER.debug 'Starting Praefect with database election strategy'
start(:praefect, File.join(tmp_tests_gitaly_dir, 'praefect-db.config.toml'))
else
LOGGER.debug 'Starting Praefect with in-memory election strategy'
start(:praefect)
end
end
def start(service, toml = nil)
toml ||= config_path(service)
args = ["#{tmp_tests_gitaly_bin_dir}/#{service_binary(service)}"]
args.push("-config") if service == :praefect
args.push(toml)
args = service_cmd(service, toml)
# Ensure user configuration does not affect Git
# Context: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58776#note_547613780
@ -277,7 +283,42 @@ module GitalySetup
config_filename: "gitaly2.config.toml"
}
)
Gitlab::SetupHelper::Praefect.create_configuration(gitaly_dir, { 'praefect' => repos_path }, force: true)
# In CI we need to pre-generate both config files.
# For local testing we'll create the correct file on-demand.
if ENV['CI'] || ENV['GITALY_PRAEFECT_WITH_DB'].nil?
Gitlab::SetupHelper::Praefect.create_configuration(
gitaly_dir,
{ 'praefect' => repos_path },
force: true
)
end
if ENV['CI'] || ENV['GITALY_PRAEFECT_WITH_DB']
Gitlab::SetupHelper::Praefect.create_configuration(
gitaly_dir,
{ 'praefect' => repos_path },
force: true,
options: {
per_repository: true,
config_filename: 'praefect-db.config.toml',
pghost: ENV['CI'] ? 'postgres' : ENV.fetch('PGHOST'),
pgport: ENV['CI'] ? 5432 : ENV.fetch('PGPORT').to_i,
pguser: ENV['CI'] ? 'postgres' : ENV.fetch('USER')
}
)
end
# In CI no database is running when Gitaly is set up
# so scripts/gitaly-test-spawn will take care of it instead.
setup_praefect unless ENV['CI']
end
def setup_praefect
return unless ENV['GITALY_PRAEFECT_WITH_DB']
migrate_cmd = service_cmd(:praefect, File.join(tmp_tests_gitaly_dir, 'praefect-db.config.toml')) + ['sql-migrate']
system(env, *migrate_cmd, [:out, :err] => 'log/praefect-test.log')
end
def socket_path(service)
@ -330,7 +371,7 @@ module GitalySetup
message += "- The `praefect` binary does not exist: #{praefect_binary}\n" unless File.exist?(praefect_binary)
message += "- The `git` binary does not exist: #{git_binary}\n" unless File.exist?(git_binary)
message += "\nCheck log/gitaly-test.log for errors.\n"
message += "\nCheck log/gitaly-test.log & log/praefect-test.log for errors.\n"
unless ENV['CI']
message += "\nIf binaries are missing, try running `make -C tmp/tests/gitaly all WITH_BUNDLED_GIT=YesPlease`.\n"