Commit f090135f authored by Kamil Trzciński's avatar Kamil Trzciński

Support new report syntax for common vulnerabilities

The new reports are always a top-level Hash with explicit `version:`
field. Old reports that are Arrays are converted to Hash representation
with indication what version is being used.

This MR also removes other reports and uses one common set of fixtures
for all test types.
parent 2efc19f8
......@@ -8,10 +8,11 @@ module Gitlab
SecurityReportParserError = Class.new(Gitlab::Ci::Parsers::ParserError)
def parse!(json_data, report)
vulnerabilities = JSON.parse!(json_data)
report_data = parse_report(json_data)
raise SecurityReportParserError, "Invalid report format" unless report_data.is_a?(Hash)
vulnerabilities.each do |vulnerability|
create_vulnerability(report, vulnerability)
report_data["vulnerabilities"].each do |vulnerability|
create_vulnerability(report, vulnerability, report_data["version"])
end
rescue JSON::ParserError
raise SecurityReportParserError, 'JSON parsing failed'
......@@ -22,7 +23,11 @@ module Gitlab
protected
def create_vulnerability(report, data)
def parse_report(json_data)
JSON.parse!(json_data)
end
def create_vulnerability(report, data, version)
scanner = create_scanner(report, data['scanner'] || mutate_scanner_tool(data['tool']))
identifiers = create_identifiers(report, data['identifiers'])
......@@ -38,9 +43,7 @@ module Gitlab
scanner: scanner,
identifiers: identifiers,
raw_metadata: data.to_json,
# Version is hardcoded here untill provided in the report.
# See https://gitlab.com/gitlab-org/gitlab-ee/issues/8025
metadata_version: metadata_version(data)
metadata_version: version
)
end
......
......@@ -5,14 +5,28 @@ module Gitlab
module Parsers
module Security
class DependencyScanning < Common
extend ::Gitlab::Utils::Override
DEPRECATED_REPORT_VERSION = "1.3".freeze
private
def metadata_version(vulnerability)
'1.3'
override :parse_report
def parse_report(json_data)
report = super
if report.is_a?(Array)
report = {
"version" => DEPRECATED_REPORT_VERSION,
"vulnerabilities" => report
}
end
report
end
def generate_location_fingerprint(location)
Digest::SHA1.hexdigest("#{location['file']}:#{location['dependency']['package']['name']}")
Digest::SHA1.hexdigest("#{location['file']}:#{location.dig('dependency', 'package', 'name')}")
end
end
end
......
......@@ -5,10 +5,24 @@ module Gitlab
module Parsers
module Security
class Sast < Common
extend ::Gitlab::Utils::Override
DEPRECATED_REPORT_VERSION = "1.2".freeze
private
def metadata_version(vulnerability)
'1.2'
override :parse_report
def parse_report(json_data)
report = super
if report.is_a?(Array)
report = {
"version" => DEPRECATED_REPORT_VERSION,
"vulnerabilities" => report
}
end
report
end
def generate_location_fingerprint(location)
......
......@@ -29,15 +29,9 @@ FactoryBot.define do
end
end
trait :license_management_report do
trait :license_management_feature_branch do
after(:build) do |build|
build.job_artifacts << create(:ee_ci_job_artifact, :license_management_report, job: build)
end
end
trait :license_management_report_2 do
after(:build) do |build|
build.job_artifacts << create(:ee_ci_job_artifact, :license_management_report_2, job: build)
build.job_artifacts << create(:ee_ci_job_artifact, :license_management_feature_branch, job: build)
end
end
......
......@@ -8,7 +8,17 @@ FactoryBot.define do
after(:build) do |artifact, evaluator|
artifact.file = fixture_file_upload(
Rails.root.join('ee/spec/fixtures/reports/security/sast.json'), 'application/json')
Rails.root.join('spec/fixtures/security-reports/master/gl-sast-report.json'), 'text/plain')
end
end
trait :sast_deprecated do
file_type :sast
file_format :raw
after(:build) do |artifact, evaluator|
artifact.file = fixture_file_upload(
Rails.root.join('spec/fixtures/security-reports/deprecated/gl-sast-report.json'), 'text/plain')
end
end
......@@ -18,27 +28,27 @@ FactoryBot.define do
after(:build) do |artifact, evaluator|
artifact.file = fixture_file_upload(
Rails.root.join('ee/spec/fixtures/reports/security/sast_with_corrupted_data.json'), 'application/json')
Rails.root.join('spec/fixtures/trace/sample_trace'), 'application/json')
end
end
trait :license_management_report do
trait :license_management do
file_type :license_management
file_format :raw
after(:build) do |artifact, evaluator|
artifact.file = fixture_file_upload(
Rails.root.join('ee/spec/fixtures/license_management/report.json'), 'application/json')
Rails.root.join('spec/fixtures/security-reports/master/gl-license-management-report.json'), 'application/json')
end
end
trait :license_management_report_2 do
trait :license_management_feature_branch do
file_type :license_management
file_format :raw
after(:build) do |artifact, evaluator|
artifact.file = fixture_file_upload(
Rails.root.join('ee/spec/fixtures/license_management/report2.json'), 'application/json')
Rails.root.join('spec/fixtures/security-reports/feature-branch/gl-license-management-report.json'), 'application/json')
end
end
......@@ -48,7 +58,7 @@ FactoryBot.define do
after(:build) do |artifact, evaluator|
artifact.file = fixture_file_upload(
Rails.root.join('ee/spec/fixtures/license_management/report_with_corrupted_data.json'), 'application/json')
Rails.root.join('spec/fixtures/trace/sample_trace'), 'application/json')
end
end
......@@ -82,6 +92,16 @@ FactoryBot.define do
end
end
trait :dependency_scanning_deprecated do
file_format :raw
file_type :dependency_scanning
after(:build) do |artifact, _|
artifact.file = fixture_file_upload(
Rails.root.join('spec/fixtures/security-reports/deprecated/gl-dependency-scanning-report.json'), 'text/plain')
end
end
trait :container_scanning do
file_format :raw
file_type :container_scanning
......
......@@ -11,15 +11,15 @@ FactoryBot.define do
status :success
after(:build) do |pipeline, evaluator|
pipeline.builds << build(:ee_ci_build, :license_management_report, pipeline: pipeline, project: pipeline.project)
pipeline.builds << build(:ee_ci_build, :license_management, pipeline: pipeline, project: pipeline.project)
end
end
trait :with_license_management_report_2 do
trait :with_license_management_feature_branch do
status :success
after(:build) do |pipeline, evaluator|
pipeline.builds << build(:ee_ci_build, :license_management_report_2, pipeline: pipeline, project: pipeline.project)
pipeline.builds << build(:ee_ci_build, :license_management_feature_branch, pipeline: pipeline, project: pipeline.project)
end
end
......
This diff is collapsed.
{
"licenses": [
{
"count": 1,
"name": "WTFPL"
},
{
"count": 1,
"name": "MIT"
}
],
"dependencies": [
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "actioncable",
"url": "http://rubyonrails.org",
"description": "WebSocket framework for Rails.",
"pathes": [
"."
]
}
},
{
"license": {
"name": "WTFPL",
"url": "http://www.wtfpl.net/"
},
"dependency": {
"name": "wtfpl_init",
"url": "https://rubygems.org/gems/wtfpl_init",
"description": "Download WTFPL license file and rename to LICENSE.md or something",
"pathes": [
"."
]
}
}
]
}
[
{
"category": "sast",
"name": "Cipher with no integrity",
"message": "Cipher with no integrity",
"description": "The cipher does not provide data integrity",
"cve": "e6449b89335daf53c0db4c0219bc1634:CIPHER_INTEGRITY",
"severity": "Medium",
"confidence": "High",
"location": {
"file": "maven/src/main/java/com/gitlab/security_products/tests/App.java",
"start_line": 29,
"end_line": 29,
"class": "com.gitlab.security_products.tests.App",
"method": "insecureCypher"
},
"scanner": {
"id": "find_sec_bugs",
"name": "Find Security Bugs"
},
"identifiers": [
{
"type": "find_sec_bugs_type",
"name": "Find Security Bugs-CIPHER_INTEGRITY",
"value": "CIPHER_INTEGRITY",
"url": "https://find-sec-bugs.github.io/bugs.htm#CIPHER_INTEGRITY"
},
{
"type": "cwe",
"name": "CWE-353",
"value": "353",
"url": "https://cwe.mitre.org/data/definitions/353.html"
}
],
"priority": "Medium",
"file": "maven/src/main/java/com/gitlab/security_products/tests/App.java",
"line": 29,
"url": "https://find-sec-bugs.github.io/bugs.htm#CIPHER_INTEGRITY",
"tool": "find_sec_bugs"
},
{
"category": "sast",
"message": "Use of insecure MD2, MD4, or MD5 hash function.",
"cve": "python/imports/imports-aliases.py:cb203b465dffb0cb3a8e8bd8910b84b93b0a5995a938e4b903dbb0cd6ffa1254:B303",
"severity": "Medium",
"confidence": "High",
"location": {
"file": "python/imports/imports-aliases.py",
"start_line": 11,
"end_line": 11
},
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B303",
"value": "B303"
},
{
"type": "cwe",
"name": "CWE-353",
"value": "353",
"url": "https://cwe.mitre.org/data/definitions/353.html"
}
],
"priority": "Medium",
"file": "python/imports/imports-aliases.py",
"line": 11,
"tool": "bandit"
},
{
"category": "sast",
"name": "Unescaped parameter value",
"message": "Unescaped parameter value",
"cve": "26b8b0ad586712d41ac6877e2292c6da7aa4760078add7fd23edf5b7a1bcb699",
"confidence": "High",
"location": {
"file": "rails5/app/views/widget/show.html.erb",
"start_line": 1
},
"scanner": {
"id": "brakeman",
"name": "Brakeman"
},
"identifiers": [
{
"type": "brakeman_warning_code",
"name": "Brakeman Warning Code 2",
"value": "2",
"url": "https://brakemanscanner.org/docs/warning_types/cross-site_scripting/"
}
],
"file": "rails5/app/views/widget/show.html.erb",
"line": 1,
"url": "https://brakemanscanner.org/docs/warning_types/cross-site_scripting/",
"tool": "brakeman"
}
]
......@@ -9,7 +9,7 @@ describe Gitlab::Ci::Parsers::LicenseManagement::LicenseManagement do
let(:report) { Gitlab::Ci::Reports::LicenseManagement::Report.new }
context 'when data is a JSON license management report' do
let(:data) { File.read(Rails.root.join('ee/spec/fixtures/license_management/report.json')) }
let(:data) { File.read(Rails.root.join('spec/fixtures/security-reports/master/gl-license-management-report.json')) }
it 'parses without error' do
expect { subject }.not_to raise_error
......
......@@ -10,24 +10,30 @@ describe Gitlab::Ci::Parsers::Security::DependencyScanning do
let(:report) { Gitlab::Ci::Reports::Security::Report.new(artifact.file_type) }
let(:parser) { described_class.new }
before do
artifact.each_blob do |blob|
parser.parse!(blob, report)
where(report_format: %i(dependency_scanning dependency_scanning_deprecated))
with_them do
let(:artifact) { create(:ee_ci_job_artifact, report_format) }
before do
artifact.each_blob do |blob|
parser.parse!(blob, report)
end
end
end
it "parses all identifiers and occurrences" do
expect(report.occurrences.length).to eq(4)
expect(report.identifiers.length).to eq(7)
expect(report.scanners.length).to eq(2)
end
it "parses all identifiers and occurrences" do
expect(report.occurrences.length).to eq(4)
expect(report.identifiers.length).to eq(7)
expect(report.scanners.length).to eq(2)
end
it "generates expected location fingerprint" do
expect(report.occurrences.first[:location_fingerprint]).to eq('2773f8cc955346ab1f756b94aa310db8e17c0944')
end
it "generates expected location fingerprint" do
expect(report.occurrences.first[:location_fingerprint]).to eq('2773f8cc955346ab1f756b94aa310db8e17c0944')
end
it "generates expected metadata_version" do
expect(report.occurrences.first[:metadata_version]).to eq('1.3')
it "generates expected metadata_version" do
expect(report.occurrences.first[:metadata_version]).to eq('1.3')
end
end
end
end
......@@ -6,28 +6,33 @@ describe Gitlab::Ci::Parsers::Security::Sast do
describe '#parse!' do
let(:project) { artifact.project }
let(:pipeline) { artifact.job.pipeline }
let(:artifact) { create(:ee_ci_job_artifact, :sast) }
let(:report) { Gitlab::Ci::Reports::Security::Report.new(artifact.file_type) }
let(:parser) { described_class.new }
before do
artifact.each_blob do |blob|
parser.parse!(blob, report)
where(report_format: %i(sast sast_deprecated))
with_them do
let(:artifact) { create(:ee_ci_job_artifact, report_format) }
before do
artifact.each_blob do |blob|
parser.parse!(blob, report)
end
end
end
it "parses all identifiers and occurrences" do
expect(report.occurrences.length).to eq(3)
expect(report.identifiers.length).to eq(4)
expect(report.scanners.length).to eq(3)
end
it "parses all identifiers and occurrences" do
expect(report.occurrences.length).to eq(33)
expect(report.identifiers.length).to eq(14)
expect(report.scanners.length).to eq(3)
end
it "generates expected location fingerprint" do
expect(report.occurrences.first[:location_fingerprint]).to eq('6b6bb283d43cc510d7d1e73e2882b3652cb34bd5')
end
it "generates expected location fingerprint" do
expect(report.occurrences.first[:location_fingerprint]).to eq('d869ba3f0b3347eb2749135a437dc07c8ae0f420')
end
it "generates expected metadata_version" do
expect(report.occurrences.first[:metadata_version]).to eq('1.2')
it "generates expected metadata_version" do
expect(report.occurrences.first[:metadata_version]).to eq('1.2')
end
end
end
end
......@@ -167,7 +167,7 @@ describe Ci::Build do
it 'parses blobs and add the results to the report' do
subject
expect(security_reports.get_report('sast').occurrences.size).to eq(3)
expect(security_reports.get_report('sast').occurrences.size).to eq(33)
end
end
......@@ -180,7 +180,7 @@ describe Ci::Build do
it 'parses blobs and add the results to the reports' do
subject
expect(security_reports.get_report('sast').occurrences.size).to eq(3)
expect(security_reports.get_report('sast').occurrences.size).to eq(33)
expect(security_reports.get_report('dependency_scanning').occurrences.size).to eq(4)
end
end
......@@ -236,7 +236,7 @@ describe Ci::Build do
context 'when build has a license management report' do
context 'when there is a license management report' do
before do
create(:ee_ci_job_artifact, :license_management_report, job: job, project: job.project)
create(:ee_ci_job_artifact, :license_management, job: job, project: job.project)
end
it 'parses blobs and add the results to the report' do
......
......@@ -239,7 +239,7 @@ describe Ci::Pipeline do
it 'returns security reports with collected data grouped as expected' do
expect(subject.reports.keys).to contain_exactly('sast', 'dependency_scanning')
expect(subject.get_report('sast').occurrences.size).to eq(6)
expect(subject.get_report('sast').occurrences.size).to eq(66)
expect(subject.get_report('dependency_scanning').occurrences.size).to eq(4)
end
......@@ -247,7 +247,7 @@ describe Ci::Pipeline do
let(:build_sast_1) { create(:ci_build, :retried, name: 'sast_1', pipeline: pipeline, project: project) }
it 'does not take retried builds into account' do
expect(subject.get_report('sast').occurrences.size).to eq(3)
expect(subject.get_report('sast').occurrences.size).to eq(33)
expect(subject.get_report('dependency_scanning').occurrences.size).to eq(4)
end
end
......@@ -322,7 +322,7 @@ describe Ci::Pipeline do
context 'when pipeline has builds with license_management reports' do
before do
create(:ee_ci_build, :license_management_report, pipeline: pipeline, project: project)
create(:ee_ci_build, :license_management, pipeline: pipeline, project: project)
end
context 'when pipeline status is running' do
......@@ -350,7 +350,7 @@ describe Ci::Pipeline do
context 'when retried build has license management reports' do
before do
create(:ee_ci_build, :retried, :license_management_report, pipeline: pipeline, project: project)
create(:ee_ci_build, :retried, :license_management, pipeline: pipeline, project: project)
end
let(:pipeline) { create(:ci_pipeline, :success, project: project) }
......@@ -367,14 +367,13 @@ describe Ci::Pipeline do
let!(:build_2) { create(:ci_build, :success, name: 'license_management2', pipeline: pipeline, project: project) }
before do
create(:ee_ci_job_artifact, :license_management_report, job: build_1, project: project)
create(:ee_ci_job_artifact, :license_management_report_2, job: build_2, project: project)
create(:ee_ci_job_artifact, :license_management, job: build_1, project: project)
create(:ee_ci_job_artifact, :license_management_feature_branch, job: build_2, project: project)
end
it 'returns a license management report with collected data' do
expect(subject.licenses.count).to be(5)
expect(subject.licenses.any? { |license| license.name == 'WTFPL' } ).to be_truthy
expect(subject.licenses.any? { |license| license.name == 'MIT' } ).to be_truthy
expect(subject.licenses.count).to eq(5)
expect(subject.licenses.map(&:name)).to include('WTFPL', 'MIT')
end
context 'when builds are retried' do
......@@ -382,14 +381,14 @@ describe Ci::Pipeline do
let!(:build_2) { create(:ci_build, :retried, :success, name: 'license_management2', pipeline: pipeline, project: project) }
it 'does not take retried builds into account' do
expect(subject.licenses.count).to be(0)
expect(subject.licenses).to be_empty
end
end
end
context 'when pipeline does not have any builds with license management reports' do
it 'returns an empty license management report' do
expect(subject.licenses.count).to be(0)
expect(subject.licenses).to be_empty
end
end
end
......
......@@ -7,7 +7,7 @@ describe EE::Ci::JobArtifact do
subject { Ci::JobArtifact.license_management_reports }
context 'when there is a license management report' do
let!(:artifact) { create(:ee_ci_job_artifact, :license_management_report) }
let!(:artifact) { create(:ee_ci_job_artifact, :license_management) }
it { is_expected.to eq([artifact]) }
end
......
......@@ -15,32 +15,32 @@ describe Ci::CompareLicenseManagementReportsService do
it 'reports new licenses' do
expect(subject[:status]).to eq(:parsed)
expect(subject[:data]['new_licenses'].count).to be(4)
expect(subject[:data]['new_licenses'].any? { |license| license['name'] == 'MIT' } ).to be_truthy
expect(subject[:data]['new_licenses'].count).to eq(4)
expect(subject[:data]['new_licenses']).to include(a_hash_including('name' => 'MIT'))
end
end
context 'when base and head pipelines have test reports' do
let!(:base_pipeline) { create(:ee_ci_pipeline, :with_license_management_report, project: project) }
let!(:head_pipeline) { create(:ee_ci_pipeline, :with_license_management_report_2, project: project) }
let!(:head_pipeline) { create(:ee_ci_pipeline, :with_license_management_feature_branch, project: project) }
it 'reports status as parsed' do
expect(subject[:status]).to eq(:parsed)
end
it 'reports new licenses' do
expect(subject[:data]['new_licenses'].count).to be(1)
expect(subject[:data]['new_licenses'][0]['name']).to eq('WTFPL')
expect(subject[:data]['new_licenses'].count).to eq(1)
expect(subject[:data]['new_licenses']).to include(a_hash_including('name' => 'WTFPL'))
end
it 'reports existing licenses' do
expect(subject[:data]['existing_licenses'].count).to be(1)
expect(subject[:data]['existing_licenses'][0]['name']).to eq('MIT')
expect(subject[:data]['existing_licenses'].count).to eq(1)
expect(subject[:data]['existing_licenses']).to include(a_hash_including('name' => 'MIT'))
end
it 'reports removed licenses' do
expect(subject[:data]['removed_licenses'].count).to be(3)
expect(subject[:data]['removed_licenses'].any? { |license| license['name'] == 'New BSD' } ).to be_truthy
expect(subject[:data]['removed_licenses'].count).to eq(3)
expect(subject[:data]['removed_licenses']).to include(a_hash_including('name' => 'New BSD'))
end
end
......
......@@ -18,7 +18,7 @@ describe Security::StoreReportService, '#execute' do
using RSpec::Parameterized::TableSyntax
where(:case_name, :report_type, :scanners, :identifiers, :occurrences, :occurrence_identifiers, :occurrence_pipelines) do
'with SAST report' | :sast | 3 | 4 | 3 | 5 | 3
'with SAST report' | :sast | 3 | 14 | 33 | 35 | 33
'with Dependency Scanning report' | :dependency_scanning | 2 | 7 | 4 | 7 | 4
end
......@@ -46,8 +46,8 @@ describe Security::StoreReportService, '#execute' do
end
context 'with existing data from previous pipeline' do
let(:scanner) { create(:vulnerabilities_scanner, project: project, external_id: 'find_sec_bugs', name: 'existing_name') }
let(:identifier) { create(:vulnerabilities_identifier, project: project, fingerprint: 'f5724386167705667ae25a1390c0a516020690ba') }
let(:scanner) { create(:vulnerabilities_scanner, project: project, external_id: 'bandit', name: 'Bandit') }
let(:identifier) { create(:vulnerabilities_identifier, project: project, fingerprint: 'e6dd15eda2137be0034977a85b300a94a4f243a3') }
let!(:new_artifact) { create(:ee_ci_job_artifact, :sast, job: new_build) }
let(:new_build) { create(:ci_build, pipeline: new_pipeline) }
let(:new_pipeline) { create(:ci_pipeline, project: project) }
......@@ -61,7 +61,7 @@ describe Security::StoreReportService, '#execute' do
primary_identifier: identifier,
scanner: scanner,
project: project,
location_fingerprint: '6b6bb283d43cc510d7d1e73e2882b3652cb34bd5')
location_fingerprint: 'd869ba3f0b3347eb2749135a437dc07c8ae0f420')
end
subject { described_class.new(new_pipeline, new_report).execute }
......@@ -71,15 +71,15 @@ describe Security::StoreReportService, '#execute' do
end
it 'inserts only new identifiers and reuse existing ones' do
expect { subject }.to change { Vulnerabilities::Identifier.count }.by(3)
expect { subject }.to change { Vulnerabilities::Identifier.count }.by(13)
end
it 'inserts only new occurrences and reuse existing ones' do
expect { subject }.to change { Vulnerabilities::Occurrence.count }.by(2)
expect { subject }.to change { Vulnerabilities::Occurrence.count }.by(32)
end
it 'inserts all occurrence pipelines (join model) for this new pipeline' do
expect { subject }.to change { Vulnerabilities::OccurrencePipeline.where(pipeline: new_pipeline).count }.by(3)
expect { subject }.to change { Vulnerabilities::OccurrencePipeline.where(pipeline: new_pipeline).count }.by(33)
end
end
......
[
{
"category": "dependency_scanning",
"name": "io.netty/netty - CVE-2014-3488",
"message": "DoS by CPU exhaustion when using malicious SSL packets",
"cve": "app/pom.xml:io.netty/netty@3.9.1.Final:CVE-2014-3488",
"severity": "Unknown",
"solution": "Upgrade to the latest version",
"scanner": {
"id": "gemnasium",
"name": "Gemnasium"
},
"location": {
"file": "app/pom.xml",
"dependency": {
"package": {
"name": "io.netty/netty"
},
"version": "3.9.1.Final"
}
},
"identifiers": [
{
"type": "gemnasium",
"name": "Gemnasium-d1bf36d9-9f07-46cd-9cfc-8675338ada8f",
"value": "d1bf36d9-9f07-46cd-9cfc-8675338ada8f",
"url": "https://deps.sec.gitlab.com/packages/maven/io.netty/netty/versions/3.9.1.Final/advisories"
},
{
"type": "cve",
"name": "CVE-2014-3488",
"value": "CVE-2014-3488",
"url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-3488"
}
],
"links": [
{
"url": "https://bugzilla.redhat.com/CVE-2014-3488"
},
{
"url": "http://netty.io/news/2014/06/11/3.html"
},
{
"url": "https://github.com/netty/netty/issues/2562"
}
],
"priority": "Unknown",
"file": "app/pom.xml",
"url": "https://bugzilla.redhat.com/CVE-2014-3488",
"tool": "gemnasium"
},
{
"category": "dependency_scanning",
"name": "Django - CVE-2017-12794",
"message": "Possible XSS in traceback section of technical 500 debug page",
"cve": "app/requirements.txt:Django@1.11.3:CVE-2017-12794",
"severity": "Unknown",
"solution": "Upgrade to latest version or apply patch.",
"scanner": {
"id": "gemnasium",
"name": "Gemnasium"
},
"location": {
"file": "app/requirements.txt",
"dependency": {
"package": {
"name": "Django"
},
"version": "1.11.3"
}
},
"identifiers": [
{
"type": "gemnasium",
"name": "Gemnasium-6162a015-8635-4a15-8d7c-dc9321db366f",
"value": "6162a015-8635-4a15-8d7c-dc9321db366f",
"url": "https://deps.sec.gitlab.com/packages/pypi/Django/versions/1.11.3/advisories"
},
{
"type": "cve",
"name": "CVE-2017-12794",
"value": "CVE-2017-12794",
"url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-12794"
}
],
"links": [
{
"url": "https://www.djangoproject.com/weblog/2017/sep/05/security-releases/"
}
],
"priority": "Unknown",
"file": "app/requirements.txt",
"url": "https://www.djangoproject.com/weblog/2017/sep/05/security-releases/",
"tool": "gemnasium"
},
{
"category": "dependency_scanning",
"name": "nokogiri - USN-3424-1",
"message": "Vulnerabilities in libxml2",
"cve": "rails/Gemfile.lock:nokogiri@1.8.0:USN-3424-1",
"severity": "Unknown",
"solution": "Upgrade to latest version.",
"scanner": {
"id": "gemnasium",
"name": "Gemnasium"
},
"location": {
"file": "rails/Gemfile.lock",
"dependency": {
"package": {
"name": "nokogiri"
},
"version": "1.8.0"
}
},
"identifiers": [
{
"type": "gemnasium",
"name": "Gemnasium-06565b64-486d-4326-b906-890d9915804d",
"value": "06565b64-486d-4326-b906-890d9915804d",
"url": "https://deps.sec.gitlab.com/packages/gem/nokogiri/versions/1.8.0/advisories"
},
{
"type": "usn",
"name": "USN-3424-1",
"value": "USN-3424-1",
"url": "https://usn.ubuntu.com/3424-1/"
}
],
"links": [
{
"url": "https://github.com/sparklemotion/nokogiri/issues/1673"
}
],
"priority": "Unknown",
"file": "rails/Gemfile.lock",
"url": "https://github.com/sparklemotion/nokogiri/issues/1673",
"tool": "gemnasium"
},
{
"category": "dependency_scanning",
"name": "ffi - CVE-2018-1000201",
"message": "ruby-ffi DDL loading issue on Windows OS",
"cve": "ffi:1.9.18:CVE-2018-1000201",
"severity": "High",
"solution": "upgrade to \u003e= 1.9.24",
"scanner": {
"id": "bundler_audit",
"name": "bundler-audit"
},
"location": {
"file": "sast-sample-rails/Gemfile.lock",
"dependency": {
"package": {
"name": "ffi"
},
"version": "1.9.18"
}
},
"identifiers": [
{
"type": "cve",
"name": "CVE-2018-1000201",
"value": "CVE-2018-1000201",
"url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-1000201"
}
],
"links": [
{
"url": "https://github.com/ffi/ffi/releases/tag/1.9.24"
}
],
"priority": "High",
"file": "sast-sample-rails/Gemfile.lock",
"url": "https://github.com/ffi/ffi/releases/tag/1.9.24",
"tool": "bundler_audit"
}
]
This diff is collapsed.
{
"licenses": [
{
"count": 13,
"name": "MIT"
},
{
"count": 2,
"name": "New BSD"
"count": 1,
"name": "WTFPL"
},
{
"count": 1,
"name": "LGPL"
"name": "MIT"
}
],
"dependencies": [
......@@ -20,107 +16,9 @@
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "bundler",
"url": "http://bundler.io",
"description": "The best way to manage your application's dependencies",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "concurrent-ruby",
"url": "http://www.concurrent-ruby.com",
"description": "Modern concurrency tools for Ruby. Inspired by Erlang, Clojure, Scala, Haskell, F#, C#, Java, and classic concurrency patterns.",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "connection_pool",
"url": "https://github.com/mperham/connection_pool",
"description": "Generic connection pool for Ruby",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "mini_portile2",
"url": "http://github.com/flavorjones/mini_portile",
"description": "Simplistic port-like solution for developers",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "mustermann",
"url": "https://github.com/sinatra/mustermann",
"description": "Your personal string matching expert.",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "nokogiri",
"url": "http://nokogiri.org",
"description": "Nokogiri (鋸) is an HTML, XML, SAX, and Reader parser",
"pathes": [
"."
]
}
},
{
"license": {
"name": "New BSD",
"url": "http://opensource.org/licenses/BSD-3-Clause"
},
"dependency": {
"name": "pg",
"url": "https://bitbucket.org/ged/ruby-pg",
"description": "Pg is the Ruby interface to the {PostgreSQL RDBMS}[http://www.postgresql.org/]",
"pathes": [
"."
]
}
},
{
"license": {
"name": "New BSD",
"url": "http://opensource.org/licenses/BSD-3-Clause"
},
"dependency": {
"name": "puma",
"url": "http://puma.io",
"description": "Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server for Ruby/Rack applications",
"name": "actioncable",
"url": "http://rubyonrails.org",
"description": "WebSocket framework for Rails.",
"pathes": [
"."
]
......@@ -128,111 +26,13 @@
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "rack",
"url": "https://rack.github.io/",
"description": "a modular Ruby webserver interface",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "rack-protection",
"url": "http://github.com/sinatra/sinatra/tree/master/rack-protection",
"description": "Protect against typical web attacks, works with all Rack apps, including Rails.",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "redis",
"url": "https://github.com/redis/redis-rb",
"description": "A Ruby client library for Redis",
"pathes": [
"."
]
}
},
{
"license": {
"name": "LGPL",
"url": "http://www.gnu.org/licenses/lgpl.txt"
},
"dependency": {
"name": "sidekiq",
"url": "http://sidekiq.org",
"description": "Simple, efficient background processing for Ruby",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "sinatra",
"url": "http://www.sinatrarb.com/",
"description": "Classy web-development dressed in a DSL",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "slim",
"url": "http://slim-lang.com/",
"description": "Slim is a template language.",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "temple",
"url": "https://github.com/judofyr/temple",
"description": "Template compilation framework in Ruby",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
"name": "WTFPL",
"url": "http://www.wtfpl.net/"
},
"dependency": {
"name": "tilt",
"url": "http://github.com/rtomayko/tilt/",
"description": "Generic interface to multiple Ruby template engines",
"name": "wtfpl_init",
"url": "https://rubygems.org/gems/wtfpl_init",
"description": "Download WTFPL license file and rename to LICENSE.md or something",
"pathes": [
"."
]
......
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