Commit 51062bbd authored by Stan Hu's avatar Stan Hu

Merge branch '335372-add-fields-to-the-pipelinesecurityreportfinding-graphql-type' into 'master'

Add fields to the PipelineSecurityReportFinding GraphQL type

See merge request gitlab-org/gitlab!75001
parents 58d5d171 732f134e
......@@ -8656,6 +8656,18 @@ Describes a rule for who can approve merge requests.
| <a id="approvalruletype"></a>`type` | [`ApprovalRuleType`](#approvalruletype) | Type of the rule. |
| <a id="approvalruleusers"></a>`users` | [`UserCoreConnection`](#usercoreconnection) | List of users added as approvers for the rule. (see [Connections](#connections)) |
### `AssetType`
Represents a vulnerability asset type.
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="assettypename"></a>`name` | [`String!`](#string) | Name of the asset. |
| <a id="assettypetype"></a>`type` | [`String!`](#string) | Type of the asset. |
| <a id="assettypeurl"></a>`url` | [`String!`](#string) | URL of the asset. |
### `AwardEmoji`
An emoji awarded by a user.
......@@ -13475,10 +13487,13 @@ Represents vulnerability finding of a security report on the pipeline.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="pipelinesecurityreportfindingassets"></a>`assets` | [`[AssetType!]`](#assettype) | List of assets associated with the vulnerability. |
| <a id="pipelinesecurityreportfindingconfidence"></a>`confidence` | [`String`](#string) | Type of the security report that found the vulnerability. |
| <a id="pipelinesecurityreportfindingdescription"></a>`description` | [`String`](#string) | Description of the vulnerability finding. |
| <a id="pipelinesecurityreportfindingevidence"></a>`evidence` | [`VulnerabilityEvidence`](#vulnerabilityevidence) | Evidence for the vulnerability. |
| <a id="pipelinesecurityreportfindingfalsepositive"></a>`falsePositive` | [`Boolean`](#boolean) | Indicates whether the vulnerability is a false positive. |
| <a id="pipelinesecurityreportfindingidentifiers"></a>`identifiers` | [`[VulnerabilityIdentifier!]!`](#vulnerabilityidentifier) | Identifiers of the vulnerabilit finding. |
| <a id="pipelinesecurityreportfindingidentifiers"></a>`identifiers` | [`[VulnerabilityIdentifier!]!`](#vulnerabilityidentifier) | Identifiers of the vulnerability finding. |
| <a id="pipelinesecurityreportfindinglinks"></a>`links` | [`[VulnerabilityLink!]`](#vulnerabilitylink) | List of links associated with the vulnerability. |
| <a id="pipelinesecurityreportfindinglocation"></a>`location` | [`VulnerabilityLocation`](#vulnerabilitylocation) | Location metadata for the vulnerability. Its fields depend on the type of security scan that found the vulnerability. |
| <a id="pipelinesecurityreportfindingname"></a>`name` | [`String`](#string) | Name of the vulnerability finding. |
| <a id="pipelinesecurityreportfindingproject"></a>`project` | [`Project`](#project) | Project on which the vulnerability finding was found. |
......@@ -13488,6 +13503,7 @@ Represents vulnerability finding of a security report on the pipeline.
| <a id="pipelinesecurityreportfindingseverity"></a>`severity` | [`VulnerabilitySeverity`](#vulnerabilityseverity) | Severity of the vulnerability finding. |
| <a id="pipelinesecurityreportfindingsolution"></a>`solution` | [`String`](#string) | URL to the vulnerability's details page. |
| <a id="pipelinesecurityreportfindingstate"></a>`state` | [`VulnerabilityState`](#vulnerabilitystate) | Finding status. |
| <a id="pipelinesecurityreportfindingtitle"></a>`title` | [`String`](#string) | Title of the vulnerability finding. |
| <a id="pipelinesecurityreportfindinguuid"></a>`uuid` | [`String`](#string) | Name of the vulnerability finding. |
### `Project`
......@@ -16348,6 +16364,44 @@ Represents the vulnerability details URL field.
| <a id="vulnerabilitydetailurlname"></a>`name` | [`String`](#string) | Name of the field. |
| <a id="vulnerabilitydetailurltext"></a>`text` | [`String`](#string) | Text of the URL. |
### `VulnerabilityEvidence`
Represents a Vulnerability Evidence.
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="vulnerabilityevidencerequest"></a>`request` | [`VulnerabilityRequest`](#vulnerabilityrequest) | HTTP request of the Vulnerability Evidence. |
| <a id="vulnerabilityevidenceresponse"></a>`response` | [`VulnerabilityResponse`](#vulnerabilityresponse) | HTTP response of the Vulnerability Evidence. |
| <a id="vulnerabilityevidencesource"></a>`source` | [`VulnerabilityEvidenceSource`](#vulnerabilityevidencesource) | Source of the Vulnerability Evidence. |
| <a id="vulnerabilityevidencesummary"></a>`summary` | [`String`](#string) | Summary of the Vulnerability Evidence. |
| <a id="vulnerabilityevidencesupportingmessages"></a>`supportingMessages` | [`[VulnerabilityEvidenceSupportingMessage!]`](#vulnerabilityevidencesupportingmessage) | Supporting messages of the Vulnerability Evidence. |
### `VulnerabilityEvidenceSource`
Represents a vulnerability evidence.
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="vulnerabilityevidencesourceidentifier"></a>`identifier` | [`String!`](#string) | ID of the Vulnerability Evidence Source. |
| <a id="vulnerabilityevidencesourcename"></a>`name` | [`String!`](#string) | Name of the Vulnerability Evidence Source. |
| <a id="vulnerabilityevidencesourceurl"></a>`url` | [`String`](#string) | URL of the Vulnerability Evidence Source. |
### `VulnerabilityEvidenceSupportingMessage`
Represents a vulnerability evidence supporting message.
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="vulnerabilityevidencesupportingmessagename"></a>`name` | [`String!`](#string) | Name of the vulnerability supporting message. |
| <a id="vulnerabilityevidencesupportingmessagerequest"></a>`request` | [`VulnerabilityRequest`](#vulnerabilityrequest) | HTTP request of the vulnerability evidence supporting message. |
| <a id="vulnerabilityevidencesupportingmessageresponse"></a>`response` | [`VulnerabilityResponse`](#vulnerabilityresponse) | HTTP response of the vulnerability evidence supporting message. |
### `VulnerabilityExternalIssueLink`
Represents an external issue link of a vulnerability.
......@@ -16430,8 +16484,11 @@ Represents the location of a vulnerability found by a Coverage Fuzzing scan.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="vulnerabilitylocationcoveragefuzzingblobpath"></a>`blobPath` | [`String`](#string) | Blob path to the vulnerable file. |
| <a id="vulnerabilitylocationcoveragefuzzingcrashaddress"></a>`crashAddress` | [`String`](#string) | Relative address in memory were the crash occurred. |
| <a id="vulnerabilitylocationcoveragefuzzingcrashtype"></a>`crashType` | [`String`](#string) | Type of the crash. |
| <a id="vulnerabilitylocationcoveragefuzzingendline"></a>`endLine` | [`String`](#string) | Number of the last relevant line in the vulnerable file. |
| <a id="vulnerabilitylocationcoveragefuzzingfile"></a>`file` | [`String`](#string) | Path to the vulnerable file. |
| <a id="vulnerabilitylocationcoveragefuzzingstacktracesnippet"></a>`stacktraceSnippet` | [`String`](#string) | Stack trace recorded during fuzzing resulting the crash. |
| <a id="vulnerabilitylocationcoveragefuzzingstartline"></a>`startLine` | [`String`](#string) | Number of the first relevant line in the vulnerable file. |
| <a id="vulnerabilitylocationcoveragefuzzingvulnerableclass"></a>`vulnerableClass` | [`String`](#string) | Class containing the vulnerability. |
| <a id="vulnerabilitylocationcoveragefuzzingvulnerablemethod"></a>`vulnerableMethod` | [`String`](#string) | Method containing the vulnerability. |
......@@ -16519,6 +16576,43 @@ Check permissions for the current user on a vulnerability.
| <a id="vulnerabilitypermissionsreadvulnerabilityfeedback"></a>`readVulnerabilityFeedback` | [`Boolean!`](#boolean) | Indicates the user can perform `read_vulnerability_feedback` on this resource. |
| <a id="vulnerabilitypermissionsupdatevulnerabilityfeedback"></a>`updateVulnerabilityFeedback` | [`Boolean!`](#boolean) | Indicates the user can perform `update_vulnerability_feedback` on this resource. |
### `VulnerabilityRequest`
Represents a Vulnerability Request.
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="vulnerabilityrequestbody"></a>`body` | [`String`](#string) | Body of the Vulnerability Request. |
| <a id="vulnerabilityrequestheaders"></a>`headers` | [`[VulnerabilityRequestResponseHeader!]!`](#vulnerabilityrequestresponseheader) | HTTP headers of the Vulnerability Request. |
| <a id="vulnerabilityrequestmethod"></a>`method` | [`String`](#string) | Method of the Vulnerability Request. |
| <a id="vulnerabilityrequesturl"></a>`url` | [`String`](#string) | URL of the Vulnerability Request. |
### `VulnerabilityRequestResponseHeader`
Represents a Vulnerability Request/Response Header.
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="vulnerabilityrequestresponseheadername"></a>`name` | [`String`](#string) | Name of the Vulnerability Request/Response Header. |
| <a id="vulnerabilityrequestresponseheadervalue"></a>`value` | [`String`](#string) | Value of the Vulnerability Request/Response Header. |
### `VulnerabilityResponse`
Represents a Vulnerability Response.
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="vulnerabilityresponsebody"></a>`body` | [`String`](#string) | Body of the Vulnerability Response. |
| <a id="vulnerabilityresponseheaders"></a>`headers` | [`[VulnerabilityRequestResponseHeader!]!`](#vulnerabilityrequestresponseheader) | HTTP headers of the Vulnerability Response. |
| <a id="vulnerabilityresponsereasonphrase"></a>`reasonPhrase` | [`String`](#string) | Reason Phrase of the Vulnerability Response. |
| <a id="vulnerabilityresponsestatuscode"></a>`statusCode` | [`Int`](#int) | Status Code of the Vulnerability Response. |
### `VulnerabilityScanner`
Represents a vulnerability scanner.
......@@ -13,11 +13,18 @@ module Types
null: true,
description: 'Type of the security report that found the vulnerability finding.'
# TODO: deprecate the `name` field because it's been replaced by the `title` field
# See https://gitlab.com/gitlab-org/gitlab/-/issues/346335
field :name,
type: GraphQL::Types::String,
null: true,
description: 'Name of the vulnerability finding.'
field :title,
type: GraphQL::Types::String,
null: true,
description: 'Title of the vulnerability finding.', method: :name
field :severity,
type: VulnerabilitySeverityEnum,
null: true,
......@@ -34,6 +41,19 @@ module Types
description: 'Indicates whether the vulnerability is a false positive.',
resolver_method: :false_positive?
field :links, [::Types::Vulnerabilities::LinkType],
null: true,
description: 'List of links associated with the vulnerability.'
field :assets, [::Types::Vulnerabilities::AssetType],
null: true,
description: 'List of assets associated with the vulnerability.'
field :evidence,
type: VulnerabilityEvidenceType,
null: true,
description: 'Evidence for the vulnerability.'
field :scanner,
type: VulnerabilityScannerType,
null: true,
......@@ -42,7 +62,7 @@ module Types
field :identifiers,
type: [VulnerabilityIdentifierType],
null: false,
description: 'Identifiers of the vulnerabilit finding.'
description: 'Identifiers of the vulnerability finding.'
field :project_fingerprint,
type: GraphQL::Types::String,
......
# frozen_string_literal: true
module Types
module Vulnerabilities
# rubocop: disable Graphql/AuthorizeTypes
class AssetType < BaseObject
graphql_name 'AssetType'
description 'Represents a vulnerability asset type.'
field :name, GraphQL::Types::String, null: false,
description: 'Name of the asset.'
field :type, GraphQL::Types::String, null: false,
description: 'Type of the asset.'
field :url, GraphQL::Types::String, null: false,
description: 'URL of the asset.'
end
end
# rubocop: enable Graphql/AuthorizeTypes
end
# frozen_string_literal: true
module Types
# rubocop: disable Graphql/AuthorizeTypes
class VulnerabilityEvidenceSourceType < BaseObject
graphql_name 'VulnerabilityEvidenceSource'
description 'Represents a vulnerability evidence'
field :identifier, GraphQL::Types::String, null: false,
description: 'ID of the Vulnerability Evidence Source.', method: :id
field :name, GraphQL::Types::String, null: false,
description: 'Name of the Vulnerability Evidence Source.'
field :url, GraphQL::Types::String, null: true,
description: 'URL of the Vulnerability Evidence Source.'
end
# rubocop: enable Graphql/AuthorizeTypes
end
# frozen_string_literal: true
module Types
# rubocop: disable Graphql/AuthorizeTypes
class VulnerabilityEvidenceSupportingMessageType < BaseObject
graphql_name 'VulnerabilityEvidenceSupportingMessage'
description 'Represents a vulnerability evidence supporting message'
field :name, GraphQL::Types::String, null: false,
description: 'Name of the vulnerability supporting message.'
field :request, VulnerabilityRequestType, null: true,
description: 'HTTP request of the vulnerability evidence supporting message.'
field :response, VulnerabilityResponseType, null: true,
description: 'HTTP response of the vulnerability evidence supporting message.'
end
# rubocop: enable Graphql/AuthorizeTypes
end
# frozen_string_literal: true
module Types
# rubocop: disable Graphql/AuthorizeTypes
class VulnerabilityEvidenceType < BaseObject
graphql_name 'VulnerabilityEvidence'
description 'Represents a Vulnerability Evidence'
field :summary, GraphQL::Types::String, null: true,
description: 'Summary of the Vulnerability Evidence.'
field :supporting_messages, [VulnerabilityEvidenceSupportingMessageType], null: true,
description: 'Supporting messages of the Vulnerability Evidence.'
field :source, VulnerabilityEvidenceSourceType, null: true,
description: 'Source of the Vulnerability Evidence.'
field :request, VulnerabilityRequestType, null: true,
description: 'HTTP request of the Vulnerability Evidence.'
field :response, VulnerabilityResponseType, null: true,
description: 'HTTP response of the Vulnerability Evidence.'
end
# rubocop: enable Graphql/AuthorizeTypes
end
......@@ -26,6 +26,15 @@ module Types
field :blob_path, GraphQL::Types::String, null: true,
description: 'Blob path to the vulnerable file.'
field :crash_type, GraphQL::Types::String, null: true,
description: 'Type of the crash.'
field :crash_address, GraphQL::Types::String, null: true,
description: 'Relative address in memory were the crash occurred.'
field :stacktrace_snippet, GraphQL::Types::String, null: true,
description: 'Stack trace recorded during fuzzing resulting the crash.'
end
end
end
# frozen_string_literal: true
module Types
# rubocop: disable Graphql/AuthorizeTypes
class VulnerabilityRequestResponseHeaderType < BaseObject
graphql_name 'VulnerabilityRequestResponseHeader'
description 'Represents a Vulnerability Request/Response Header'
field :name, GraphQL::Types::String, null: true,
description: 'Name of the Vulnerability Request/Response Header.'
field :value, GraphQL::Types::String, null: true,
description: 'Value of the Vulnerability Request/Response Header.'
end
# rubocop: enable Graphql/AuthorizeTypes
end
# frozen_string_literal: true
module Types
# rubocop: disable Graphql/AuthorizeTypes
class VulnerabilityRequestType < BaseObject
graphql_name 'VulnerabilityRequest'
description 'Represents a Vulnerability Request'
field :body, GraphQL::Types::String, null: true,
description: 'Body of the Vulnerability Request.'
# GraphQL Ruby has the following bug https://github.com/rmosolgo/graphql-ruby/issues/3944 which prevents
# using the `hash_key` attribute if the source field is named `method`. We can work around this by using
# the `resolver_method` instead, however, there's a rubocop rule which forces us to use the `hash_key`
# method, so we need to disable this rule until the previously mentioned bug is fixed.
field :method, GraphQL::Types::String, null: true, # rubocop: disable GraphQL/FieldHashKey
description: 'Method of the Vulnerability Request.',
# this is necessary to avoid the error "VulnerabilityRequest's `field :method` conflicts with a built-in method"
resolver_method: :resolve_method
field :url, GraphQL::Types::String, null: true,
description: 'URL of the Vulnerability Request.'
field :headers, [VulnerabilityRequestResponseHeaderType], null: false,
description: 'HTTP headers of the Vulnerability Request.'
def resolve_method
object[:method]
end
end
# rubocop: enable Graphql/AuthorizeTypes
end
# frozen_string_literal: true
module Types
# rubocop: disable Graphql/AuthorizeTypes
class VulnerabilityResponseType < BaseObject
graphql_name 'VulnerabilityResponse'
description 'Represents a Vulnerability Response'
field :body, GraphQL::Types::String, null: true,
description: 'Body of the Vulnerability Response.'
field :status_code, GraphQL::Types::Int, null: true,
description: 'Status Code of the Vulnerability Response.'
field :reason_phrase, GraphQL::Types::String, null: true,
description: 'Reason Phrase of the Vulnerability Response.'
field :headers, [VulnerabilityRequestResponseHeaderType], null: false,
description: 'HTTP headers of the Vulnerability Response.'
end
# rubocop: enable Graphql/AuthorizeTypes
end
......@@ -42,7 +42,8 @@
"evidence": {
"source": {
"id": "assert:CORS - Bad 'Origin' value",
"name": "CORS - Bad 'Origin' value"
"name": "CORS - Bad 'Origin' value",
"url": "https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSMissingAllowOrigin"
},
"summary": "The Origin header was changed to an invalid value of http://peachapisecurity.com and the response contained an Access-Control-Allow-Origin header which included this invalid Origin, indicating that the CORS configuration on the server is overly permissive.\n\n\n",
"request": {
......
{
"version": "v1.0.8",
"regression": false,
"exit_code": -1,
"vulnerabilities": [
{
"category": "coverage_fuzzing",
"message": "Heap-buffer-overflow\nREAD 1",
"description": "Heap-buffer-overflow\nREAD 1",
"severity": "Critical",
"stacktrace_snippet": "INFO: Seed: 3415817494\nINFO: Loaded 1 modules (7 inline 8-bit counters): 7 [0x10eee2470, 0x10eee2477), \nINFO: Loaded 1 PC tables (7 PCs): 7 [0x10eee2478,0x10eee24e8), \nINFO: 5 files found in corpus\nINFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes\nINFO: seed corpus: files: 5 min: 1b max: 4b total: 14b rss: 26Mb\n#6\tINITED cov: 7 ft: 7 corp: 5/14b exec/s: 0 rss: 26Mb\n=================================================================\n==43405==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000001573 at pc 0x00010eea205a bp 0x7ffee0d5e090 sp 0x7ffee0d5e088\nREAD of size 1 at 0x602000001573 thread T0\n #0 0x10eea2059 in FuzzMe(unsigned char const*, unsigned long) fuzz_me.cc:9\n #1 0x10eea20ba in LLVMFuzzerTestOneInput fuzz_me.cc:13\n #2 0x10eebe020 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) FuzzerLoop.cpp:556\n #3 0x10eebd765 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) FuzzerLoop.cpp:470\n #4 0x10eebf966 in fuzzer::Fuzzer::MutateAndTestOne() FuzzerLoop.cpp:698\n #5 0x10eec0665 in fuzzer::Fuzzer::Loop(std::__1::vector\u003cfuzzer::SizedFile, fuzzer::fuzzer_allocator\u003cfuzzer::SizedFile\u003e \u003e\u0026) FuzzerLoop.cpp:830\n #6 0x10eead0cd in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) FuzzerDriver.cpp:829\n #7 0x10eedaf82 in main FuzzerMain.cpp:19\n #8 0x7fff684fecc8 in start+0x0 (libdyld.dylib:x86_64+0x1acc8)\n\n0x602000001573 is located 0 bytes to the right of 3-byte region [0x602000001570,0x602000001573)\nallocated by thread T0 here:\n #0 0x10ef92cfd in wrap__Znam+0x7d (libclang_rt.asan_osx_dynamic.dylib:x86_64+0x50cfd)\n #1 0x10eebdf31 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) FuzzerLoop.cpp:541\n #2 0x10eebd765 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) FuzzerLoop.cpp:470\n #3 0x10eebf966 in fuzzer::Fuzzer::MutateAndTestOne() FuzzerLoop.cpp:698\n #4 0x10eec0665 in fuzzer::Fuzzer::Loop(std::__1::vector\u003cfuzzer::SizedFile, fuzzer::fuzzer_allocator\u003cfuzzer::SizedFile\u003e \u003e\u0026) FuzzerLoop.cpp:830\n #5 0x10eead0cd in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) FuzzerDriver.cpp:829\n #6 0x10eedaf82 in main FuzzerMain.cpp:19\n #7 0x7fff684fecc8 in start+0x0 (libdyld.dylib:x86_64+0x1acc8)\n\nSUMMARY: AddressSanitizer: heap-buffer-overflow fuzz_me.cc:9 in FuzzMe(unsigned char const*, unsigned long)\nShadow bytes around the buggy address:\n 0x1c0400000250: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa\n 0x1c0400000260: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa\n 0x1c0400000270: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa\n 0x1c0400000280: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa\n 0x1c0400000290: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa\n=\u003e0x1c04000002a0: fa fa fd fa fa fa fd fa fa fa fd fa fa fa[03]fa\n 0x1c04000002b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa\n 0x1c04000002c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa\n 0x1c04000002d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa\n 0x1c04000002e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa\n 0x1c04000002f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa\nShadow byte legend (one shadow byte represents 8 application bytes):\n Addressable: 00\n Partially addressable: 01 02 03 04 05 06 07 \n Heap left redzone: fa\n Freed heap region: fd\n Stack left redzone: f1\n Stack mid redzone: f2\n Stack right redzone: f3\n Stack after return: f5\n Stack use after scope: f8\n Global redzone: f9\n Global init order: f6\n Poisoned by user: f7\n Container overflow: fc\n Array cookie: ac\n Intra object redzone: bb\n ASan internal: fe\n Left alloca redzone: ca\n Right alloca redzone: cb\n Shadow gap: cc\n==43405==ABORTING\nMS: 1 EraseBytes-; base unit: de3a753d4f1def197604865d76dba888d6aefc71\n0x46,0x55,0x5a,\nFUZ\nartifact_prefix='./crashes/'; Test unit written to ./crashes/crash-0eb8e4ed029b774d80f2b66408203801cb982a60\nBase64: RlVa\nstat::number_of_executed_units: 122\nstat::average_exec_per_sec: 0\nstat::new_units_added: 0\nstat::slowest_unit_time_sec: 0\nstat::peak_rss_mb: 28",
"scanner": {
"id": "libFuzzer",
"name": "libFuzzer"
},
"location": {
"crash_address": "0x602000001573",
"crash_state": "FuzzMe\nstart\nstart+0x0\n\n",
"crash_type": "Heap-buffer-overflow\nREAD 1"
},
"tool": "libFuzzer"
"version": "3.0",
"vulnerabilities": [
{
"id": "0e9148e513ed08ee1973cc149e939ef260cbfa1d7d2242760377c5749b953ddd",
"category": "coverage_fuzzing",
"name": "name",
"message": "Heap-buffer-overflow\nREAD 1",
"cve": "",
"severity": "Critical",
"scanner": {
"id": "libfuzzer",
"name": "libfuzzer"
},
"location": {
"crash_address": "0x602000001573",
"crash_type": "Heap-buffer-overflow\nREAD 1",
"crash_state": "FuzzMe\nstart\nstart+0x0\n\n",
"stacktrace_snippet": "INFO: Seed: 3415817494\nINFO: Loaded 1 modules"
},
"identifiers": [
{
"type": "cwe",
"name": "Heap-buffer-overflow\nREAD 1",
"value": "Heap-buffer-overflow\nREAD 1"
}
]
}
],
"remediations": [],
"scan": {
"scanner": {
"id": "libfuzzer",
"name": "libfuzzer",
"url": "https://docs.gitlab.com/ee/user/application_security/coverage_fuzzing",
"vendor": {
"name": "GitLab"
},
"version": "v2.0.46"
},
"type": "coverage_fuzzing",
"start_time": "2020-11-10T09:02:02",
"end_time": "2020-11-10T09:02:04",
"status": "success"
}
]
}
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe GitlabSchema.types['AssetType'] do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
let_it_be(:pipeline) { create(:ee_ci_pipeline, :with_api_fuzzing_report, project: project) }
before do
stub_licensed_features(api_fuzzing: true, security_dashboard: true)
project.add_developer(user)
end
let(:fields) do
%i[name type url]
end
subject { GitlabSchema.execute(query, context: { current_user: user }).as_json }
specify { expect(described_class.graphql_name).to eq('AssetType') }
it { expect(described_class).to have_graphql_fields(fields) }
describe 'checking field contents' do
let(:query) do
%(
query {
project(fullPath: "#{project.full_path}") {
pipeline(iid: "#{pipeline.iid}") {
securityReportFindings {
nodes {
title
assets {
name
type
url
}
}
}
}
}
}
)
end
it 'checks the contents of the assets field' do
vulnerabilities = subject.dig('data', 'project', 'pipeline', 'securityReportFindings', 'nodes')
vulnerability = vulnerabilities.find { |v| v['title'] == "CORS misconfiguration at 'http://127.0.0.1:7777/api/users'" }
asset = vulnerability['assets'].first
expect(asset).to eq({
"name" => "Test Postman Collection",
"type" => "postman",
"url" => "http://localhost/test.collection"
})
end
end
end
......@@ -10,10 +10,14 @@ RSpec.describe GitlabSchema.types['PipelineSecurityReportFinding'] do
let(:fields) do
%i[report_type
name
title
severity
confidence
scanner
identifiers
links
assets
evidence
project_fingerprint
uuid
project
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe GitlabSchema.types['VulnerabilityEvidenceSource'] do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
let_it_be(:pipeline) { create(:ee_ci_pipeline, :with_api_fuzzing_report, project: project) }
before do
stub_licensed_features(api_fuzzing: true, security_dashboard: true)
project.add_developer(user)
end
let(:fields) do
%i[identifier name url]
end
subject { GitlabSchema.execute(query, context: { current_user: user }).as_json }
specify { expect(described_class.graphql_name).to eq('VulnerabilityEvidenceSource') }
it { expect(described_class).to have_graphql_fields(fields) }
describe 'checking field contents' do
let(:query) do
%(
query {
project(fullPath: "#{project.full_path}") {
pipeline(iid: "#{pipeline.iid}") {
securityReportFindings {
nodes {
title
evidence {
source {
identifier
name
url
}
}
}
}
}
}
}
)
end
it 'checks the contents of the evidence.source field' do
vulnerabilities = subject.dig('data', 'project', 'pipeline', 'securityReportFindings', 'nodes')
vulnerability = vulnerabilities.find { |v| v['title'] == "CORS misconfiguration at 'http://127.0.0.1:7777/api/users'" }
source = vulnerability['evidence']['source']
expect(source['name']).to eq("CORS - Bad 'Origin' value")
expect(source['identifier']).to eq("assert:CORS - Bad 'Origin' value")
expect(source['url']).to eq("https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSMissingAllowOrigin")
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe GitlabSchema.types['VulnerabilityEvidenceSupportingMessage'] do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
let_it_be(:pipeline) { create(:ee_ci_pipeline, :with_api_fuzzing_report, project: project) }
before do
stub_licensed_features(api_fuzzing: true, security_dashboard: true)
project.add_developer(user)
end
let(:fields) do
%i[name request response]
end
subject { GitlabSchema.execute(query, context: { current_user: user }).as_json }
specify { expect(described_class.graphql_name).to eq('VulnerabilityEvidenceSupportingMessage') }
it { expect(described_class).to have_graphql_fields(fields) }
describe 'checking field contents' do
let(:query) do
%(
query {
project(fullPath: "#{project.full_path}") {
pipeline(iid: "#{pipeline.iid}") {
securityReportFindings {
nodes {
title
evidence {
supportingMessages {
name
}
}
}
}
}
}
}
)
end
it 'checks the contents of the evidence.suportingMessages array' do
vulnerabilities = subject.dig('data', 'project', 'pipeline', 'securityReportFindings', 'nodes')
vulnerability = vulnerabilities.find { |v| v['title'] == "CORS misconfiguration at 'http://127.0.0.1:7777/api/users'" }
supporting_message = vulnerability['evidence']['supportingMessages'].find { |m| m['name'] == 'Recorded' }
expect(supporting_message['name']).to eq('Recorded')
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe GitlabSchema.types['VulnerabilityEvidence'] do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
let_it_be(:pipeline) { create(:ee_ci_pipeline, :with_api_fuzzing_report, project: project) }
before do
stub_licensed_features(api_fuzzing: true, security_dashboard: true)
project.add_developer(user)
end
let(:fields) do
%i[summary supporting_messages source request response]
end
subject { GitlabSchema.execute(query, context: { current_user: user }).as_json }
specify { expect(described_class.graphql_name).to eq('VulnerabilityEvidence') }
it { expect(described_class).to have_graphql_fields(fields) }
describe 'checking field contents' do
let(:query) do
%(
query {
project(fullPath: "#{project.full_path}") {
pipeline(iid: "#{pipeline.iid}") {
securityReportFindings {
nodes {
title
evidence {
summary
}
}
}
}
}
}
)
end
it 'checks the contents of the evidence.summary field' do
vulnerabilities = subject.dig('data', 'project', 'pipeline', 'securityReportFindings', 'nodes')
vulnerability = vulnerabilities.find { |v| v['title'] == "CORS misconfiguration at 'http://127.0.0.1:7777/api/users'" }
expect(vulnerability['evidence']['summary']).to eq("The Origin header was changed to an invalid value of http://peachapisecurity.com and the response contained an Access-Control-Allow-Origin header which included this invalid Origin, indicating that the CORS configuration on the server is overly permissive.\n\n\n")
end
end
end
......@@ -3,6 +3,16 @@
require 'spec_helper'
RSpec.describe GitlabSchema.types['VulnerabilityLocationCoverageFuzzing'] do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
let_it_be(:pipeline) { create(:ee_ci_pipeline, :with_coverage_fuzzing_report, project: project) }
before do
stub_licensed_features(coverage_fuzzing: true, security_dashboard: true)
project.add_developer(user)
end
it do
expect(described_class).to have_graphql_fields(
:vulnerable_class,
......@@ -10,7 +20,46 @@ RSpec.describe GitlabSchema.types['VulnerabilityLocationCoverageFuzzing'] do
:file,
:vulnerable_method,
:start_line,
:blob_path
:blob_path,
:crash_type,
:crash_address,
:stacktrace_snippet
)
end
subject { GitlabSchema.execute(query, context: { current_user: user }).as_json }
specify { expect(described_class.graphql_name).to eq('VulnerabilityLocationCoverageFuzzing') }
describe 'checking field contents' do
let(:query) do
%(
query {
project(fullPath: "#{project.full_path}") {
pipeline(iid: "#{pipeline.iid}") {
securityReportFindings {
nodes {
location {
... on VulnerabilityLocationCoverageFuzzing {
crashType
crashAddress
stacktraceSnippet
}
}
}
}
}
}
}
)
end
it 'checks the contents of the VulnerabilityLocationCoverageFuzzing fields' do
vulnerability = subject.dig('data', 'project', 'pipeline', 'securityReportFindings', 'nodes').first
expect(vulnerability['location']['crashType']).to eq("Heap-buffer-overflow\nREAD 1")
expect(vulnerability['location']['crashAddress']).to eq("0x602000001573")
expect(vulnerability['location']['stacktraceSnippet']).to eq("INFO: Seed: 3415817494\nINFO: Loaded 1 modules")
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe GitlabSchema.types['VulnerabilityRequestResponseHeader'] do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
let_it_be(:pipeline) { create(:ee_ci_pipeline, :with_api_fuzzing_report, project: project) }
before do
stub_licensed_features(api_fuzzing: true, security_dashboard: true)
project.add_developer(user)
end
let(:fields) do
%i[name value]
end
subject { GitlabSchema.execute(query, context: { current_user: user }).as_json }
specify { expect(described_class.graphql_name).to eq('VulnerabilityRequestResponseHeader') }
it { expect(described_class).to have_graphql_fields(fields) }
describe 'checking field contents' do
before do
vulnerabilities = subject.dig('data', 'project', 'pipeline', 'securityReportFindings', 'nodes')
@vulnerability = vulnerabilities.find { |v| v['title'] == "CORS misconfiguration at 'http://127.0.0.1:7777/api/users'" }
end
context 'evidence.request.headers fields' do
let(:query) do
%(
query {
project(fullPath: "#{project.full_path}") {
pipeline(iid: "#{pipeline.iid}") {
securityReportFindings {
nodes {
title
evidence {
request {
headers {
name
value
}
}
}
}
}
}
}
}
)
end
it 'checks the contents of the fields' do
headers = @vulnerability['evidence']['request']['headers']
expect(headers.length).to eq(11)
expect(headers.first).to eq({ 'name' => 'Host', 'value' => '127.0.0.1:7777' })
end
end
context 'evidence.response.headers fields' do
let(:query) do
%(
query {
project(fullPath: "#{project.full_path}") {
pipeline(iid: "#{pipeline.iid}") {
securityReportFindings {
nodes {
title
evidence {
response {
headers {
name
value
}
}
}
}
}
}
}
}
)
end
it 'checks the contents of the fields' do
headers = @vulnerability['evidence']['response']['headers']
expect(headers.length).to eq(7)
expect(headers.first).to eq({ 'name' => 'Server', 'value' => 'TwistedWeb/20.3.0' })
end
end
context 'evidence.supportingMessages[].request.headers fields' do
let(:query) do
%(
query {
project(fullPath: "#{project.full_path}") {
pipeline(iid: "#{pipeline.iid}") {
securityReportFindings {
nodes {
title
evidence {
supportingMessages {
name
request {
headers {
name
value
}
}
}
}
}
}
}
}
}
)
end
it 'checks the contents of the fields' do
request = @vulnerability['evidence']['supportingMessages'].find { |m| m['name'] == 'Recorded' }['request']
expect(request['headers'].first).to eq({
"name" => "Host",
"value" => "127.0.0.1:7777"
})
expect(request['headers'].length).to eq(9)
end
end
context 'evidence.supportingMessages[].response.headers fields' do
let(:query) do
%(
query {
project(fullPath: "#{project.full_path}") {
pipeline(iid: "#{pipeline.iid}") {
securityReportFindings {
nodes {
title
evidence {
supportingMessages {
name
response {
headers {
name
value
}
}
}
}
}
}
}
}
}
)
end
it 'checks the contents of the fields' do
response = @vulnerability['evidence']['supportingMessages'].find { |m| m['name'] == 'Recorded' }['response']
expect(response['headers'].first).to eq({
"name" => "Server",
"value" => "TwistedWeb/20.3.0"
})
expect(response['headers'].length).to eq(6)
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe GitlabSchema.types['VulnerabilityRequest'] do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
let_it_be(:pipeline) { create(:ee_ci_pipeline, :with_api_fuzzing_report, project: project) }
before do
stub_licensed_features(api_fuzzing: true, security_dashboard: true)
project.add_developer(user)
end
let(:fields) do
%i[body method url headers]
end
subject { GitlabSchema.execute(query, context: { current_user: user }).as_json }
specify { expect(described_class.graphql_name).to eq('VulnerabilityRequest') }
it { expect(described_class).to have_graphql_fields(fields) }
describe 'checking field contents' do
before do
vulnerabilities = subject.dig('data', 'project', 'pipeline', 'securityReportFindings', 'nodes')
@vulnerability = vulnerabilities.find { |v| v['title'] == "CORS misconfiguration at 'http://127.0.0.1:7777/api/users'" }
end
context 'evidence.request fields' do
let(:query) do
%(
query {
project(fullPath: "#{project.full_path}") {
pipeline(iid: "#{pipeline.iid}") {
securityReportFindings {
nodes {
title
evidence {
request {
body
method
url
headers {
name
value
}
}
}
}
}
}
}
}
)
end
it 'checks the contents of the fields' do
request = @vulnerability['evidence']['request']
expect(request['headers'].first).to eq({ 'name' => 'Host', 'value' => '127.0.0.1:7777' })
expect(request['method']).to eq('GET')
expect(request['url']).to eq('http://127.0.0.1:7777/api/users')
expect(request['body']).to be_empty
end
end
context 'evidence.supportingMessages[].request fields' do
let(:query) do
%(
query {
project(fullPath: "#{project.full_path}") {
pipeline(iid: "#{pipeline.iid}") {
securityReportFindings {
nodes {
title
evidence {
supportingMessages {
name
request {
method
url
body
headers {
name
value
}
}
}
}
}
}
}
}
}
)
end
it 'checks the contents of the fields' do
request = @vulnerability['evidence']['supportingMessages'].find { |m| m['name'] == 'Recorded' }['request']
expect(request['headers'].first).to eq({
"name" => "Host",
"value" => "127.0.0.1:7777"
})
expect(request['method']).to eq('GET')
expect(request['url']).to eq('http://127.0.0.1:7777/api/users')
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe GitlabSchema.types['VulnerabilityResponse'] do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
let_it_be(:pipeline) { create(:ee_ci_pipeline, :with_api_fuzzing_report, project: project) }
before do
stub_licensed_features(api_fuzzing: true, security_dashboard: true)
project.add_developer(user)
end
let(:fields) do
%i[body status_code reason_phrase headers]
end
subject { GitlabSchema.execute(query, context: { current_user: user }).as_json }
specify { expect(described_class.graphql_name).to eq('VulnerabilityResponse') }
it { expect(described_class).to have_graphql_fields(fields) }
describe 'checking field contents' do
before do
vulnerabilities = subject.dig('data', 'project', 'pipeline', 'securityReportFindings', 'nodes')
@vulnerability = vulnerabilities.find { |v| v['title'] == "CORS misconfiguration at 'http://127.0.0.1:7777/api/users'" }
end
context 'evidence.response fields' do
let(:query) do
%(
query {
project(fullPath: "#{project.full_path}") {
pipeline(iid: "#{pipeline.iid}") {
securityReportFindings {
nodes {
title
evidence {
response {
body
statusCode
reasonPhrase
headers {
name
value
}
}
}
}
}
}
}
}
)
end
it 'checks the contents of the fields' do
response = @vulnerability['evidence']['response']
expect(response['reasonPhrase']).to eq('OK')
expect(response['statusCode']).to eq(200)
expect(response['body']).to eq('[{"user_id":1,"user":"admin","first":"Joe","last":"Smith","password":"Password!"}]')
expect(response['headers'].first).to eq({ 'name' => 'Server', 'value' => 'TwistedWeb/20.3.0' })
end
end
context 'evidence.supportingMessages[].response fields' do
let(:query) do
%(
query {
project(fullPath: "#{project.full_path}") {
pipeline(iid: "#{pipeline.iid}") {
securityReportFindings {
nodes {
title
evidence {
supportingMessages {
name
response {
body
statusCode
reasonPhrase
headers {
name
value
}
}
}
}
}
}
}
}
}
)
end
it 'checks the contents of the fields' do
response = @vulnerability['evidence']['supportingMessages'].find { |m| m['name'] == 'Recorded' }['response']
expect(response['reasonPhrase']).to eq('OK')
expect(response['statusCode']).to eq(200)
expect(response['body']).to eq('[{"user_id":1,"user":"admin","first":"Joe","last":"Smith","password":"Password!"}]')
expect(response['headers'].first).to eq({
"name" => "Server",
"value" => "TwistedWeb/20.3.0"
})
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment