From 15cd91c71a57a0b84af620181a64b26d5aec8237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Trzci=C5=84ski?= Date: Mon, 15 Oct 2018 12:17:21 +0200 Subject: [PATCH] Make all legacy security reports to use raw format - This introduces and uses `:raw` format for all legacy reports, the ones that do not have yet proper parsers on Backend - Raw format is needed to make Frontend be able to parse reports, without the need of decompressing, - This also extends fixtures to seed security reports with database, even though parser code is part of EE --- app/models/ci/job_artifact.rb | 17 +- app/presenters/ci/build_runner_presenter.rb | 10 +- changelogs/unreleased/use-raw-file-format.yml | 5 + db/fixtures/development/14_pipelines.rb | 75 +- .../build/artifacts/adapters/gzip_stream.rb | 48 + .../ci/build/artifacts/adapters/raw_stream.rb | 27 + .../ci/build/artifacts/gzip_file_adapter.rb | 46 - spec/factories/ci/job_artifacts.rb | 4 +- .../security-reports/feature-branch.zip | Bin 0 -> 7163 bytes .../gl-container-scanning-report.json | 18 + .../feature-branch/gl-dast-report.json | 40 + .../gl-dependency-scanning-report.json | 46 + .../gl-license-management-report.json | 242 +++++ .../feature-branch/gl-sast-report.json | 944 ++++++++++++++++++ spec/fixtures/security-reports/master.zip | Bin 0 -> 6710 bytes .../master/gl-container-scanning-report.json | 18 + .../master/gl-dast-report.json | 40 + .../master/gl-dependency-scanning-report.json | 35 + .../master/gl-license-management-report.json | 150 +++ .../master/gl-sast-report.json | 944 ++++++++++++++++++ .../gzip_stream_spec.rb} | 2 +- .../artifacts/adapters/raw_stream_spec.rb | 47 + spec/models/ci/job_artifact_spec.rb | 8 + .../ci/build_runner_presenter_spec.rb | 28 +- 24 files changed, 2720 insertions(+), 74 deletions(-) create mode 100644 changelogs/unreleased/use-raw-file-format.yml create mode 100644 lib/gitlab/ci/build/artifacts/adapters/gzip_stream.rb create mode 100644 lib/gitlab/ci/build/artifacts/adapters/raw_stream.rb delete mode 100644 lib/gitlab/ci/build/artifacts/gzip_file_adapter.rb create mode 100644 spec/fixtures/security-reports/feature-branch.zip create mode 100644 spec/fixtures/security-reports/feature-branch/gl-container-scanning-report.json create mode 100644 spec/fixtures/security-reports/feature-branch/gl-dast-report.json create mode 100644 spec/fixtures/security-reports/feature-branch/gl-dependency-scanning-report.json create mode 100644 spec/fixtures/security-reports/feature-branch/gl-license-management-report.json create mode 100644 spec/fixtures/security-reports/feature-branch/gl-sast-report.json create mode 100644 spec/fixtures/security-reports/master.zip create mode 100644 spec/fixtures/security-reports/master/gl-container-scanning-report.json create mode 100644 spec/fixtures/security-reports/master/gl-dast-report.json create mode 100644 spec/fixtures/security-reports/master/gl-dependency-scanning-report.json create mode 100644 spec/fixtures/security-reports/master/gl-license-management-report.json create mode 100644 spec/fixtures/security-reports/master/gl-sast-report.json rename spec/lib/gitlab/ci/build/artifacts/{gzip_file_adapter_spec.rb => adapters/gzip_stream_spec.rb} (96%) create mode 100644 spec/lib/gitlab/ci/build/artifacts/adapters/raw_stream_spec.rb diff --git a/app/models/ci/job_artifact.rb b/app/models/ci/job_artifact.rb index cb73fc74bb6..2b28b702b05 100644 --- a/app/models/ci/job_artifact.rb +++ b/app/models/ci/job_artifact.rb @@ -27,11 +27,15 @@ module Ci metadata: :gzip, trace: :raw, junit: :gzip, - codequality: :gzip, - sast: :gzip, - dependency_scanning: :gzip, - container_scanning: :gzip, - dast: :gzip + + # All these file formats use `raw` as we need to store them uncompressed + # for Frontend to fetch the files and do analysis + # When they will be only used by backend, they can be `gzipped`. + codequality: :raw, + sast: :raw, + dependency_scanning: :raw, + container_scanning: :raw, + dast: :raw }.freeze belongs_to :project @@ -100,7 +104,8 @@ module Ci } FILE_FORMAT_ADAPTERS = { - gzip: Gitlab::Ci::Build::Artifacts::GzipFileAdapter + gzip: Gitlab::Ci::Build::Artifacts::Adapters::GzipStream, + raw: Gitlab::Ci::Build::Artifacts::Adapters::RawStream }.freeze def valid_file_format? diff --git a/app/presenters/ci/build_runner_presenter.rb b/app/presenters/ci/build_runner_presenter.rb index 880218e2727..300f85e1e9d 100644 --- a/app/presenters/ci/build_runner_presenter.rb +++ b/app/presenters/ci/build_runner_presenter.rb @@ -30,12 +30,12 @@ module Ci def create_reports(reports, expire_in:) return unless reports&.any? - reports.map do |k, v| + reports.map do |report_type, report_paths| { - artifact_type: k.to_sym, - artifact_format: :gzip, - name: ::Ci::JobArtifact::DEFAULT_FILE_NAMES[k.to_sym], - paths: v, + artifact_type: report_type.to_sym, + artifact_format: ::Ci::JobArtifact::TYPE_AND_FORMAT_PAIRS.fetch(report_type.to_sym), + name: ::Ci::JobArtifact::DEFAULT_FILE_NAMES.fetch(report_type.to_sym), + paths: report_paths, when: 'always', expire_in: expire_in } diff --git a/changelogs/unreleased/use-raw-file-format.yml b/changelogs/unreleased/use-raw-file-format.yml new file mode 100644 index 00000000000..d86db51fea4 --- /dev/null +++ b/changelogs/unreleased/use-raw-file-format.yml @@ -0,0 +1,5 @@ +--- +title: Make all legacy security reports to use raw format +merge_request: +author: +type: changed diff --git a/db/fixtures/development/14_pipelines.rb b/db/fixtures/development/14_pipelines.rb index 5535c4a14e5..5af77c49913 100644 --- a/db/fixtures/development/14_pipelines.rb +++ b/db/fixtures/development/14_pipelines.rb @@ -1,7 +1,7 @@ require './spec/support/sidekiq' class Gitlab::Seeder::Pipelines - STAGES = %w[build test deploy notify] + STAGES = %w[build test security deploy notify] BUILDS = [ # build stage { name: 'build:linux', stage: 'build', status: :success, @@ -31,6 +31,16 @@ class Gitlab::Seeder::Pipelines { name: 'spinach:osx', stage: 'test', status: :failed, allow_failure: true, queued_at: 8.hour.ago, started_at: 8.hour.ago, finished_at: 7.hour.ago }, + # security stage + { name: 'dast', stage: 'security', status: :success, + queued_at: 8.hour.ago, started_at: 8.hour.ago, finished_at: 7.hour.ago }, + { name: 'sast', stage: 'security', status: :success, + queued_at: 8.hour.ago, started_at: 8.hour.ago, finished_at: 7.hour.ago }, + { name: 'dependency_scanning', stage: 'security', status: :success, + queued_at: 8.hour.ago, started_at: 8.hour.ago, finished_at: 7.hour.ago }, + { name: 'container_scanning', stage: 'security', status: :success, + queued_at: 8.hour.ago, started_at: 8.hour.ago, finished_at: 7.hour.ago }, + # deploy stage { name: 'staging', stage: 'deploy', environment: 'staging', status_event: :success, options: { environment: { action: 'start', on_stop: 'stop staging' } }, @@ -108,6 +118,11 @@ class Gitlab::Seeder::Pipelines setup_artifacts(build) setup_test_reports(build) + if build.ref == build.project.default_branch + setup_security_reports_file(build) + else + setup_security_reports_legacy_archive(build) + end setup_build_log(build) build.project.environments. @@ -143,6 +158,55 @@ class Gitlab::Seeder::Pipelines end end + def setup_security_reports_file(build) + return unless build.stage == "security" + + # we have two sources: master and feature-branch + branch_name = build.ref == build.project.default_branch ? + 'master' : 'feature-branch' + + artifacts_cache_file(security_reports_path(branch_name, build.name)) do |file| + build.job_artifacts.build( + project: build.project, + file_type: build.name, + file_format: :raw, + file: file) + end + end + + def setup_security_reports_legacy_archive(build) + return unless build.stage == "security" + + # we have two sources: master and feature-branch + branch_name = build.ref == build.project.default_branch ? + 'master' : 'feature-branch' + + artifacts_cache_file(security_reports_archive_path(branch_name)) do |file| + build.job_artifacts.build( + project: build.project, + file_type: :archive, + file_format: :zip, + file: file) + end + + # assign dummy metadata + artifacts_cache_file(artifacts_metadata_path) do |file| + build.job_artifacts.build( + project: build.project, + file_type: :metadata, + file_format: :gzip, + file: file) + end + + build.options = { + artifacts: { + paths: [ + Ci::JobArtifact::DEFAULT_FILE_NAMES.fetch(build.name.to_sym) + ] + } + } + end + def setup_build_log(build) if %w(running success failed).include?(build.status) build.trace.set(FFaker::Lorem.paragraphs(6).join("\n\n")) @@ -190,6 +254,15 @@ class Gitlab::Seeder::Pipelines Rails.root + 'spec/fixtures/junit/junit.xml.gz' end + def security_reports_archive_path(branch) + Rails.root.join('spec', 'fixtures', 'security-reports', branch + '.zip') + end + + def security_reports_path(branch, name) + file_name = Ci::JobArtifact::DEFAULT_FILE_NAMES.fetch(name.to_sym) + Rails.root.join('spec', 'fixtures', 'security-reports', branch, file_name) + end + def artifacts_cache_file(file_path) file = Tempfile.new("artifacts") file.close diff --git a/lib/gitlab/ci/build/artifacts/adapters/gzip_stream.rb b/lib/gitlab/ci/build/artifacts/adapters/gzip_stream.rb new file mode 100644 index 00000000000..ee3647f24fd --- /dev/null +++ b/lib/gitlab/ci/build/artifacts/adapters/gzip_stream.rb @@ -0,0 +1,48 @@ +module Gitlab + module Ci + module Build + module Artifacts + module Adapters + class GzipStream + attr_reader :stream + + InvalidStreamError = Class.new(StandardError) + + def initialize(stream) + raise InvalidStreamError, "Stream is required" unless stream + + @stream = stream + end + + def each_blob + stream.seek(0) + + until stream.eof? + gzip(stream) do |gz| + yield gz.read, gz.orig_name + unused = gz.unused&.length.to_i + # pos has already reached to EOF at the moment + # We rewind the pos to the top of unused files + # to read next gzip stream, to support multistream archives + # https://golang.org/src/compress/gzip/gunzip.go#L117 + stream.seek(-unused, IO::SEEK_CUR) + end + end + end + + private + + def gzip(stream, &block) + gz = Zlib::GzipReader.new(stream) + yield(gz) + rescue Zlib::Error => e + raise InvalidStreamError, e.message + ensure + gz&.finish + end + end + end + end + end + end +end diff --git a/lib/gitlab/ci/build/artifacts/adapters/raw_stream.rb b/lib/gitlab/ci/build/artifacts/adapters/raw_stream.rb new file mode 100644 index 00000000000..fa6842cf36a --- /dev/null +++ b/lib/gitlab/ci/build/artifacts/adapters/raw_stream.rb @@ -0,0 +1,27 @@ +module Gitlab + module Ci + module Build + module Artifacts + module Adapters + class RawStream + attr_reader :stream + + InvalidStreamError = Class.new(StandardError) + + def initialize(stream) + raise InvalidStreamError, "Stream is required" unless stream + + @stream = stream + end + + def each_blob + stream.seek(0) + + yield(stream.read, 'raw') unless stream.eof? + end + end + end + end + end + end +end diff --git a/lib/gitlab/ci/build/artifacts/gzip_file_adapter.rb b/lib/gitlab/ci/build/artifacts/gzip_file_adapter.rb deleted file mode 100644 index 65f65cdce08..00000000000 --- a/lib/gitlab/ci/build/artifacts/gzip_file_adapter.rb +++ /dev/null @@ -1,46 +0,0 @@ -module Gitlab - module Ci - module Build - module Artifacts - class GzipFileAdapter - attr_reader :stream - - InvalidStreamError = Class.new(StandardError) - - def initialize(stream) - raise InvalidStreamError, "Stream is required" unless stream - - @stream = stream - end - - def each_blob - stream.seek(0) - - until stream.eof? - gzip(stream) do |gz| - yield gz.read, gz.orig_name - unused = gz.unused&.length.to_i - # pos has already reached to EOF at the moment - # We rewind the pos to the top of unused files - # to read next gzip stream, to support multistream archives - # https://golang.org/src/compress/gzip/gunzip.go#L117 - stream.seek(-unused, IO::SEEK_CUR) - end - end - end - - private - - def gzip(stream, &block) - gz = Zlib::GzipReader.new(stream) - yield(gz) - rescue Zlib::Error => e - raise InvalidStreamError, e.message - ensure - gz&.finish - end - end - end - end - end -end diff --git a/spec/factories/ci/job_artifacts.rb b/spec/factories/ci/job_artifacts.rb index e0aeadeecd7..2c76c22ba69 100644 --- a/spec/factories/ci/job_artifacts.rb +++ b/spec/factories/ci/job_artifacts.rb @@ -119,11 +119,11 @@ FactoryBot.define do trait :codequality do file_type :codequality - file_format :gzip + file_format :raw after(:build) do |artifact, evaluator| artifact.file = fixture_file_upload( - Rails.root.join('spec/fixtures/codequality/codequality.json.gz'), 'application/x-gzip') + Rails.root.join('spec/fixtures/codequality/codequality.json'), 'application/json') end end diff --git a/spec/fixtures/security-reports/feature-branch.zip b/spec/fixtures/security-reports/feature-branch.zip new file mode 100644 index 0000000000000000000000000000000000000000..730ce3dc5f8b3d7917eb66901cabd7e759f61fc3 GIT binary patch literal 7163 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 literal 0 HcmV?d00001 diff --git a/spec/fixtures/security-reports/feature-branch/gl-container-scanning-report.json b/spec/fixtures/security-reports/feature-branch/gl-container-scanning-report.json new file mode 100644 index 00000000000..9840382df6f --- /dev/null +++ b/spec/fixtures/security-reports/feature-branch/gl-container-scanning-report.json @@ -0,0 +1,18 @@ +{ + "image": "registry.gitlab.com/bikebilly/auto-devops-10-6/feature-branch:e7315ba964febb11bac8f5cd6ec433db8a3a1583", + "unapproved": [ + "CVE-2017-15650" + ], + "vulnerabilities": [ + { + "featurename": "musl", + "featureversion": "1.1.14-r15", + "vulnerability": "CVE-2017-15650", + "namespace": "alpine:v3.4", + "description": "", + "link": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-15650", + "severity": "Medium", + "fixedby": "1.1.14-r16" + } + ] +} diff --git a/spec/fixtures/security-reports/feature-branch/gl-dast-report.json b/spec/fixtures/security-reports/feature-branch/gl-dast-report.json new file mode 100644 index 00000000000..3a308bf047e --- /dev/null +++ b/spec/fixtures/security-reports/feature-branch/gl-dast-report.json @@ -0,0 +1,40 @@ +{ + "site": { + "alerts": [ + { + "sourceid": "3", + "wascid": "15", + "cweid": "16", + "reference": "

http://msdn.microsoft.com/en-us/library/ie/gg622941%28v=vs.85%29.aspx

https://www.owasp.org/index.php/List_of_useful_HTTP_headers

", + "otherinfo": "

This issue still applies to error type pages (401, 403, 500, etc) as those pages are often still affected by injection issues, in which case there is still concern for browsers sniffing pages away from their actual content type.

At \"High\" threshold this scanner will not alert on client or server error responses.

", + "solution": "

Ensure that the application/web server sets the Content-Type header appropriately, and that it sets the X-Content-Type-Options header to 'nosniff' for all web pages.

If possible, ensure that the end user uses a standards-compliant and modern web browser that does not perform MIME-sniffing at all, or that can be directed by the web application/web server to not perform MIME-sniffing.

", + "count": "2", + "pluginid": "10021", + "alert": "X-Content-Type-Options Header Missing", + "name": "X-Content-Type-Options Header Missing", + "riskcode": "1", + "confidence": "2", + "riskdesc": "Low (Medium)", + "desc": "

The Anti-MIME-Sniffing header X-Content-Type-Options was not set to 'nosniff'. This allows older versions of Internet Explorer and Chrome to perform MIME-sniffing on the response body, potentially causing the response body to be interpreted and displayed as a content type other than the declared content type. Current (early 2014) and legacy versions of Firefox will use the declared content type (if one is set), rather than performing MIME-sniffing.

", + "instances": [ + { + "param": "X-Content-Type-Options", + "method": "GET", + "uri": "http://bikebilly-spring-auto-devops-review-feature-br-3y2gpb.35.192.176.43.xip.io" + }, + { + "param": "X-Content-Type-Options", + "method": "GET", + "uri": "http://bikebilly-spring-auto-devops-review-feature-br-3y2gpb.35.192.176.43.xip.io/" + } + ] + } + ], + "@ssl": "false", + "@port": "80", + "@host": "bikebilly-spring-auto-devops-review-feature-br-3y2gpb.35.192.176.43.xip.io", + "@name": "http://bikebilly-spring-auto-devops-review-feature-br-3y2gpb.35.192.176.43.xip.io" + }, + "@generated": "Fri, 13 Apr 2018 09:22:01", + "@version": "2.7.0" +} diff --git a/spec/fixtures/security-reports/feature-branch/gl-dependency-scanning-report.json b/spec/fixtures/security-reports/feature-branch/gl-dependency-scanning-report.json new file mode 100644 index 00000000000..4b47e259c0f --- /dev/null +++ b/spec/fixtures/security-reports/feature-branch/gl-dependency-scanning-report.json @@ -0,0 +1,46 @@ +[ + { + "priority": "Unknown", + "file": "pom.xml", + "cve": "CVE-2012-4387", + "url": "http://struts.apache.org/docs/s2-011.html", + "message": "Long parameter name DoS for org.apache.struts/struts2-core", + "tools": [ + "gemnasium" + ], + "tool": "gemnasium" + }, + { + "priority": "Unknown", + "file": "pom.xml", + "cve": "CVE-2013-1966", + "url": "http://struts.apache.org/docs/s2-014.html", + "message": "Remote command execution due to flaw in the includeParams attribute of URL and Anchor tags for org.apache.struts/struts2-core", + "tools": [ + "gemnasium" + ], + "tool": "gemnasium" + }, + { + "priority": "Unknown", + "file": "pom.xml", + "cve": "CVE-2013-2115", + "url": "http://struts.apache.org/docs/s2-014.html", + "message": "Remote command execution due to flaw in the includeParams attribute of URL and Anchor tags for org.apache.struts/struts2-core", + "tools": [ + "gemnasium" + ], + "tool": "gemnasium" + }, + { + "priority": "Unknown", + "file": "pom.xml", + "cve": "CVE-2013-2134", + "url": "http://struts.apache.org/docs/s2-015.html", + "message": "Arbitrary OGNL code execution via unsanitized wildcard matching for org.apache.struts/struts2-core", + "tools": [ + "gemnasium" + ], + "tool": "gemnasium" + } +] diff --git a/spec/fixtures/security-reports/feature-branch/gl-license-management-report.json b/spec/fixtures/security-reports/feature-branch/gl-license-management-report.json new file mode 100644 index 00000000000..c1d20fa02fa --- /dev/null +++ b/spec/fixtures/security-reports/feature-branch/gl-license-management-report.json @@ -0,0 +1,242 @@ +{ + "licenses": [ + { + "count": 13, + "name": "MIT" + }, + { + "count": 2, + "name": "New BSD" + }, + { + "count": 1, + "name": "LGPL" + } + ], + "dependencies": [ + { + "license": { + "name": "MIT", + "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", + "pathes": [ + "." + ] + } + }, + { + "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" + }, + "dependency": { + "name": "tilt", + "url": "http://github.com/rtomayko/tilt/", + "description": "Generic interface to multiple Ruby template engines", + "pathes": [ + "." + ] + } + } + ] +} diff --git a/spec/fixtures/security-reports/feature-branch/gl-sast-report.json b/spec/fixtures/security-reports/feature-branch/gl-sast-report.json new file mode 100644 index 00000000000..a85b9be8b5f --- /dev/null +++ b/spec/fixtures/security-reports/feature-branch/gl-sast-report.json @@ -0,0 +1,944 @@ +[ + { + "category": "sast", + "message": "Probable insecure usage of temp file/directory.", + "cve": "python/hardcoded/hardcoded-tmp.py:52865813c884a507be1f152d654245af34aba8a391626d01f1ab6d3f52ec8779:B108", + "severity": "Medium", + "confidence": "Medium", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/hardcoded/hardcoded-tmp.py", + "start_line": 1, + "end_line": 1 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B108", + "value": "B108", + "url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html" + } + ], + "priority": "Medium", + "file": "python/hardcoded/hardcoded-tmp.py", + "line": 1, + "url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html", + "tool": "bandit" + }, + { + "category": "sast", + "name": "Predictable pseudorandom number generator", + "message": "Predictable pseudorandom number generator", + "cve": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy:47:PREDICTABLE_RANDOM", + "severity": "Medium", + "confidence": "Medium", + "scanner": { + "id": "find_sec_bugs", + "name": "Find Security Bugs" + }, + "location": { + "file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy", + "start_line": 47, + "end_line": 47, + "class": "com.gitlab.security_products.tests.App", + "method": "generateSecretToken2" + }, + "identifiers": [ + { + "type": "find_sec_bugs_type", + "name": "Find Security Bugs-PREDICTABLE_RANDOM", + "value": "PREDICTABLE_RANDOM", + "url": "https://find-sec-bugs.github.io/bugs.htm#PREDICTABLE_RANDOM" + } + ], + "priority": "Medium", + "file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy", + "line": 47, + "url": "https://find-sec-bugs.github.io/bugs.htm#PREDICTABLE_RANDOM", + "tool": "find_sec_bugs" + }, + { + "category": "sast", + "name": "Predictable pseudorandom number generator", + "message": "Predictable pseudorandom number generator", + "cve": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy:41:PREDICTABLE_RANDOM", + "severity": "Medium", + "confidence": "Medium", + "scanner": { + "id": "find_sec_bugs", + "name": "Find Security Bugs" + }, + "location": { + "file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy", + "start_line": 41, + "end_line": 41, + "class": "com.gitlab.security_products.tests.App", + "method": "generateSecretToken1" + }, + "identifiers": [ + { + "type": "find_sec_bugs_type", + "name": "Find Security Bugs-PREDICTABLE_RANDOM", + "value": "PREDICTABLE_RANDOM", + "url": "https://find-sec-bugs.github.io/bugs.htm#PREDICTABLE_RANDOM" + } + ], + "priority": "Medium", + "file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy", + "line": 41, + "url": "https://find-sec-bugs.github.io/bugs.htm#PREDICTABLE_RANDOM", + "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", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-aliases.py", + "start_line": 11, + "end_line": 11 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B303", + "value": "B303" + } + ], + "priority": "Medium", + "file": "python/imports/imports-aliases.py", + "line": 11, + "tool": "bandit" + }, + { + "category": "sast", + "message": "Use of insecure MD2, MD4, or MD5 hash function.", + "cve": "python/imports/imports-aliases.py:a7173c43ae66bd07466632d819d450e0071e02dbf782763640d1092981f9631b:B303", + "severity": "Medium", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-aliases.py", + "start_line": 12, + "end_line": 12 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B303", + "value": "B303" + } + ], + "priority": "Medium", + "file": "python/imports/imports-aliases.py", + "line": 12, + "tool": "bandit" + }, + { + "category": "sast", + "message": "Use of insecure MD2, MD4, or MD5 hash function.", + "cve": "python/imports/imports-aliases.py:017017b77deb0b8369b6065947833eeea752a92ec8a700db590fece3e934cf0d:B303", + "severity": "Medium", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-aliases.py", + "start_line": 13, + "end_line": 13 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B303", + "value": "B303" + } + ], + "priority": "Medium", + "file": "python/imports/imports-aliases.py", + "line": 13, + "tool": "bandit" + }, + { + "category": "sast", + "message": "Use of insecure MD2, MD4, or MD5 hash function.", + "cve": "python/imports/imports-aliases.py:45fc8c53aea7b84f06bc4e590cc667678d6073c4c8a1d471177ca2146fb22db2:B303", + "severity": "Medium", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-aliases.py", + "start_line": 14, + "end_line": 14 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B303", + "value": "B303" + } + ], + "priority": "Medium", + "file": "python/imports/imports-aliases.py", + "line": 14, + "tool": "bandit" + }, + { + "category": "sast", + "message": "Pickle library appears to be in use, possible security issue.", + "cve": "python/imports/imports-aliases.py:5f200d47291e7bbd8352db23019b85453ca048dd98ea0c291260fa7d009963a4:B301", + "severity": "Medium", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-aliases.py", + "start_line": 15, + "end_line": 15 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B301", + "value": "B301" + } + ], + "priority": "Medium", + "file": "python/imports/imports-aliases.py", + "line": 15, + "tool": "bandit" + }, + { + "category": "sast", + "name": "ECB mode is insecure", + "message": "ECB mode is insecure", + "cve": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy:29:ECB_MODE", + "severity": "Medium", + "confidence": "High", + "scanner": { + "id": "find_sec_bugs", + "name": "Find Security Bugs" + }, + "location": { + "file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy", + "start_line": 29, + "end_line": 29, + "class": "com.gitlab.security_products.tests.App", + "method": "insecureCypher" + }, + "identifiers": [ + { + "type": "find_sec_bugs_type", + "name": "Find Security Bugs-ECB_MODE", + "value": "ECB_MODE", + "url": "https://find-sec-bugs.github.io/bugs.htm#ECB_MODE" + } + ], + "priority": "Medium", + "file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy", + "line": 29, + "url": "https://find-sec-bugs.github.io/bugs.htm#ECB_MODE", + "tool": "find_sec_bugs" + }, + { + "category": "sast", + "name": "Cipher with no integrity", + "message": "Cipher with no integrity", + "cve": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy:29:CIPHER_INTEGRITY", + "severity": "Medium", + "confidence": "High", + "scanner": { + "id": "find_sec_bugs", + "name": "Find Security Bugs" + }, + "location": { + "file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy", + "start_line": 29, + "end_line": 29, + "class": "com.gitlab.security_products.tests.App", + "method": "insecureCypher" + }, + "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" + } + ], + "priority": "Medium", + "file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy", + "line": 29, + "url": "https://find-sec-bugs.github.io/bugs.htm#CIPHER_INTEGRITY", + "tool": "find_sec_bugs" + }, + { + "category": "sast", + "message": "Probable insecure usage of temp file/directory.", + "cve": "python/hardcoded/hardcoded-tmp.py:63dd4d626855555b816985d82c4614a790462a0a3ada89dc58eb97f9c50f3077:B108", + "severity": "Medium", + "confidence": "Medium", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/hardcoded/hardcoded-tmp.py", + "start_line": 14, + "end_line": 14 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B108", + "value": "B108", + "url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html" + } + ], + "priority": "Medium", + "file": "python/hardcoded/hardcoded-tmp.py", + "line": 14, + "url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html", + "tool": "bandit" + }, + { + "category": "sast", + "message": "Probable insecure usage of temp file/directory.", + "cve": "python/hardcoded/hardcoded-tmp.py:4ad6d4c40a8c263fc265f3384724014e0a4f8dd6200af83e51ff120420038031:B108", + "severity": "Medium", + "confidence": "Medium", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/hardcoded/hardcoded-tmp.py", + "start_line": 10, + "end_line": 10 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B108", + "value": "B108", + "url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html" + } + ], + "priority": "Medium", + "file": "python/hardcoded/hardcoded-tmp.py", + "line": 10, + "url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html", + "tool": "bandit" + }, + { + "category": "sast", + "message": "Consider possible security implications associated with Popen module.", + "cve": "python/imports/imports-aliases.py:2c3e1fa1e54c3c6646e8bcfaee2518153c6799b77587ff8d9a7b0631f6d34785:B404", + "severity": "Low", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-aliases.py", + "start_line": 1, + "end_line": 1 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B404", + "value": "B404" + } + ], + "priority": "Low", + "file": "python/imports/imports-aliases.py", + "line": 1, + "tool": "bandit" + }, + { + "category": "sast", + "message": "Consider possible security implications associated with pickle module.", + "cve": "python/imports/imports.py:af58d07f6ad519ef5287fcae65bf1a6999448a1a3a8bc1ac2a11daa80d0b96bf:B403", + "severity": "Low", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports.py", + "start_line": 2, + "end_line": 2 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B403", + "value": "B403" + } + ], + "priority": "Low", + "file": "python/imports/imports.py", + "line": 2, + "tool": "bandit" + }, + { + "category": "sast", + "message": "Consider possible security implications associated with subprocess module.", + "cve": "python/imports/imports.py:8de9bc98029d212db530785a5f6780cfa663548746ff228ab8fa96c5bb82f089:B404", + "severity": "Low", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports.py", + "start_line": 4, + "end_line": 4 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B404", + "value": "B404" + } + ], + "priority": "Low", + "file": "python/imports/imports.py", + "line": 4, + "tool": "bandit" + }, + { + "category": "sast", + "message": "Possible hardcoded password: 'blerg'", + "cve": "python/hardcoded/hardcoded-passwords.py:97c30f1d76d2a88913e3ce9ae74087874d740f87de8af697a9c455f01119f633:B106", + "severity": "Low", + "confidence": "Medium", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/hardcoded/hardcoded-passwords.py", + "start_line": 22, + "end_line": 22 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B106", + "value": "B106", + "url": "https://docs.openstack.org/bandit/latest/plugins/b106_hardcoded_password_funcarg.html" + } + ], + "priority": "Low", + "file": "python/hardcoded/hardcoded-passwords.py", + "line": 22, + "url": "https://docs.openstack.org/bandit/latest/plugins/b106_hardcoded_password_funcarg.html", + "tool": "bandit" + }, + { + "category": "sast", + "message": "Possible hardcoded password: 'root'", + "cve": "python/hardcoded/hardcoded-passwords.py:7431c73a0bc16d94ece2a2e75ef38f302574d42c37ac0c3c38ad0b3bf8a59f10:B105", + "severity": "Low", + "confidence": "Medium", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/hardcoded/hardcoded-passwords.py", + "start_line": 5, + "end_line": 5 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B105", + "value": "B105", + "url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html" + } + ], + "priority": "Low", + "file": "python/hardcoded/hardcoded-passwords.py", + "line": 5, + "url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html", + "tool": "bandit" + }, + { + "category": "sast", + "message": "Possible hardcoded password: ''", + "cve": "python/hardcoded/hardcoded-passwords.py:d2d1857c27caedd49c57bfbcdc23afcc92bd66a22701fcdc632869aab4ca73ee:B105", + "severity": "Low", + "confidence": "Medium", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/hardcoded/hardcoded-passwords.py", + "start_line": 9, + "end_line": 9 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B105", + "value": "B105", + "url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html" + } + ], + "priority": "Low", + "file": "python/hardcoded/hardcoded-passwords.py", + "line": 9, + "url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html", + "tool": "bandit" + }, + { + "category": "sast", + "message": "Possible hardcoded password: 'ajklawejrkl42348swfgkg'", + "cve": "python/hardcoded/hardcoded-passwords.py:fb3866215a61393a5c9c32a3b60e2058171a23219c353f722cbd3567acab21d2:B105", + "severity": "Low", + "confidence": "Medium", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/hardcoded/hardcoded-passwords.py", + "start_line": 13, + "end_line": 13 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B105", + "value": "B105", + "url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html" + } + ], + "priority": "Low", + "file": "python/hardcoded/hardcoded-passwords.py", + "line": 13, + "url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html", + "tool": "bandit" + }, + { + "category": "sast", + "message": "Possible hardcoded password: 'blerg'", + "cve": "python/hardcoded/hardcoded-passwords.py:63c62a8b7e1e5224439bd26b28030585ac48741e28ca64561a6071080c560a5f:B105", + "severity": "Low", + "confidence": "Medium", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/hardcoded/hardcoded-passwords.py", + "start_line": 23, + "end_line": 23 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B105", + "value": "B105", + "url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html" + } + ], + "priority": "Low", + "file": "python/hardcoded/hardcoded-passwords.py", + "line": 23, + "url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html", + "tool": "bandit" + }, + { + "category": "sast", + "message": "Possible hardcoded password: 'blerg'", + "cve": "python/hardcoded/hardcoded-passwords.py:4311b06d08df8fa58229b341c531da8e1a31ec4520597bdff920cd5c098d86f9:B105", + "severity": "Low", + "confidence": "Medium", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/hardcoded/hardcoded-passwords.py", + "start_line": 24, + "end_line": 24 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B105", + "value": "B105", + "url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html" + } + ], + "priority": "Low", + "file": "python/hardcoded/hardcoded-passwords.py", + "line": 24, + "url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html", + "tool": "bandit" + }, + { + "category": "sast", + "message": "Consider possible security implications associated with subprocess module.", + "cve": "python/imports/imports-function.py:5858400c2f39047787702de44d03361ef8d954c9d14bd54ee1c2bef9e6a7df93:B404", + "severity": "Low", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-function.py", + "start_line": 4, + "end_line": 4 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B404", + "value": "B404" + } + ], + "priority": "Low", + "file": "python/imports/imports-function.py", + "line": 4, + "tool": "bandit" + }, + { + "category": "sast", + "message": "Consider possible security implications associated with pickle module.", + "cve": "python/imports/imports-function.py:dbda3cf4190279d30e0aad7dd137eca11272b0b225e8af4e8bf39682da67d956:B403", + "severity": "Low", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-function.py", + "start_line": 2, + "end_line": 2 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B403", + "value": "B403" + } + ], + "priority": "Low", + "file": "python/imports/imports-function.py", + "line": 2, + "tool": "bandit" + }, + { + "category": "sast", + "message": "Consider possible security implications associated with Popen module.", + "cve": "python/imports/imports-from.py:eb8a0db9cd1a8c1ab39a77e6025021b1261cc2a0b026b2f4a11fca4e0636d8dd:B404", + "severity": "Low", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-from.py", + "start_line": 7, + "end_line": 7 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B404", + "value": "B404" + } + ], + "priority": "Low", + "file": "python/imports/imports-from.py", + "line": 7, + "tool": "bandit" + }, + { + "category": "sast", + "message": "subprocess call with shell=True seems safe, but may be changed in the future, consider rewriting without shell", + "cve": "python/imports/imports-aliases.py:f99f9721e27537fbcb6699a4cf39c6740d6234d2c6f06cfc2d9ea977313c483d:B602", + "severity": "Low", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-aliases.py", + "start_line": 9, + "end_line": 9 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B602", + "value": "B602", + "url": "https://docs.openstack.org/bandit/latest/plugins/b602_subprocess_popen_with_shell_equals_true.html" + } + ], + "priority": "Low", + "file": "python/imports/imports-aliases.py", + "line": 9, + "url": "https://docs.openstack.org/bandit/latest/plugins/b602_subprocess_popen_with_shell_equals_true.html", + "tool": "bandit" + }, + { + "category": "sast", + "message": "Consider possible security implications associated with subprocess module.", + "cve": "python/imports/imports-from.py:332a12ab1146698f614a905ce6a6a5401497a12281aef200e80522711c69dcf4:B404", + "severity": "Low", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-from.py", + "start_line": 6, + "end_line": 6 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B404", + "value": "B404" + } + ], + "priority": "Low", + "file": "python/imports/imports-from.py", + "line": 6, + "tool": "bandit" + }, + { + "category": "sast", + "message": "Consider possible security implications associated with Popen module.", + "cve": "python/imports/imports-from.py:0a48de4a3d5348853a03666cb574697e3982998355e7a095a798bd02a5947276:B404", + "severity": "Low", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-from.py", + "start_line": 1, + "end_line": 2 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B404", + "value": "B404" + } + ], + "priority": "Low", + "file": "python/imports/imports-from.py", + "line": 1, + "tool": "bandit" + }, + { + "category": "sast", + "message": "Consider possible security implications associated with pickle module.", + "cve": "python/imports/imports-aliases.py:51b71661dff994bde3529639a727a678c8f5c4c96f00d300913f6d5be1bbdf26:B403", + "severity": "Low", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-aliases.py", + "start_line": 7, + "end_line": 8 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B403", + "value": "B403" + } + ], + "priority": "Low", + "file": "python/imports/imports-aliases.py", + "line": 7, + "tool": "bandit" + }, + { + "category": "sast", + "message": "Consider possible security implications associated with loads module.", + "cve": "python/imports/imports-aliases.py:6ff02aeb3149c01ab68484d794a94f58d5d3e3bb0d58557ef4153644ea68ea54:B403", + "severity": "Low", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-aliases.py", + "start_line": 6, + "end_line": 6 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B403", + "value": "B403" + } + ], + "priority": "Low", + "file": "python/imports/imports-aliases.py", + "line": 6, + "tool": "bandit" + }, + { + "category": "sast", + "message": "Statically-sized arrays can be improperly restricted, leading to potential overflows or other issues (CWE-119!/CWE-120)", + "cve": "c/subdir/utils.c:b466873101951fe96e1332f6728eb7010acbbd5dfc3b65d7d53571d091a06d9e:CWE-119!/CWE-120", + "confidence": "Low", + "solution": "Perform bounds checking, use functions that limit length, or ensure that the size is larger than the maximum possible length", + "scanner": { + "id": "flawfinder", + "name": "Flawfinder" + }, + "location": { + "file": "c/subdir/utils.c", + "start_line": 4 + }, + "identifiers": [ + { + "type": "cwe", + "name": "CWE-119", + "value": "119", + "url": "https://cwe.mitre.org/data/definitions/119.html" + }, + { + "type": "cwe", + "name": "CWE-120", + "value": "120", + "url": "https://cwe.mitre.org/data/definitions/120.html" + } + ], + "file": "c/subdir/utils.c", + "line": 4, + "url": "https://cwe.mitre.org/data/definitions/119.html", + "tool": "flawfinder" + }, + { + "category": "sast", + "message": "Check when opening files - can an attacker redirect it (via symlinks), force the opening of special file type (e.g., device files), move things around to create a race condition, control its ancestors, or change its contents? (CWE-362)", + "cve": "c/subdir/utils.c:bab681140fcc8fc3085b6bba74081b44ea145c1c98b5e70cf19ace2417d30770:CWE-362", + "confidence": "Low", + "scanner": { + "id": "flawfinder", + "name": "Flawfinder" + }, + "location": { + "file": "c/subdir/utils.c", + "start_line": 8 + }, + "identifiers": [ + { + "type": "cwe", + "name": "CWE-362", + "value": "362", + "url": "https://cwe.mitre.org/data/definitions/362.html" + } + ], + "file": "c/subdir/utils.c", + "line": 8, + "url": "https://cwe.mitre.org/data/definitions/362.html", + "tool": "flawfinder" + }, + { + "category": "sast", + "message": "Statically-sized arrays can be improperly restricted, leading to potential overflows or other issues (CWE-119!/CWE-120)", + "cve": "cplusplus/src/hello.cpp:c8c6dd0afdae6814194cf0930b719f757ab7b379cf8f261e7f4f9f2f323a818a:CWE-119!/CWE-120", + "confidence": "Low", + "solution": "Perform bounds checking, use functions that limit length, or ensure that the size is larger than the maximum possible length", + "scanner": { + "id": "flawfinder", + "name": "Flawfinder" + }, + "location": { + "file": "cplusplus/src/hello.cpp", + "start_line": 6 + }, + "identifiers": [ + { + "type": "cwe", + "name": "CWE-119", + "value": "119", + "url": "https://cwe.mitre.org/data/definitions/119.html" + }, + { + "type": "cwe", + "name": "CWE-120", + "value": "120", + "url": "https://cwe.mitre.org/data/definitions/120.html" + } + ], + "file": "cplusplus/src/hello.cpp", + "line": 6, + "url": "https://cwe.mitre.org/data/definitions/119.html", + "tool": "flawfinder" + }, + { + "category": "sast", + "message": "Does not check for buffer overflows when copying to destination [MS-banned] (CWE-120)", + "cve": "cplusplus/src/hello.cpp:331c04062c4fe0c7c486f66f59e82ad146ab33cdd76ae757ca41f392d568cbd0:CWE-120", + "confidence": "Low", + "solution": "Consider using snprintf, strcpy_s, or strlcpy (warning: strncpy easily misused)", + "scanner": { + "id": "flawfinder", + "name": "Flawfinder" + }, + "location": { + "file": "cplusplus/src/hello.cpp", + "start_line": 7 + }, + "identifiers": [ + { + "type": "cwe", + "name": "CWE-120", + "value": "120", + "url": "https://cwe.mitre.org/data/definitions/120.html" + } + ], + "file": "cplusplus/src/hello.cpp", + "line": 7, + "url": "https://cwe.mitre.org/data/definitions/120.html", + "tool": "flawfinder" + } +] diff --git a/spec/fixtures/security-reports/master.zip b/spec/fixtures/security-reports/master.zip new file mode 100644 index 0000000000000000000000000000000000000000..4684aecb738db3cdf456879463820f5cdedc167e GIT binary patch literal 6710 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 Vx)L7#?@f5W&f{P1=K1sW{{vB$HeLV# literal 0 HcmV?d00001 diff --git a/spec/fixtures/security-reports/master/gl-container-scanning-report.json b/spec/fixtures/security-reports/master/gl-container-scanning-report.json new file mode 100644 index 00000000000..500c19e3abb --- /dev/null +++ b/spec/fixtures/security-reports/master/gl-container-scanning-report.json @@ -0,0 +1,18 @@ +{ + "image": "registry.gitlab.com/bikebilly/auto-devops-10-6/feature-branch:e7315ba964febb11bac8f5cd6ec433db8a3a1583", + "unapproved": [ + "CVE-2017-15651" + ], + "vulnerabilities": [ + { + "featurename": "musl", + "featureversion": "1.1.14-r15", + "vulnerability": "CVE-2017-15651", + "namespace": "alpine:v3.4", + "description": "", + "link": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-15651", + "severity": "Medium", + "fixedby": "1.1.14-r16" + } + ] +} diff --git a/spec/fixtures/security-reports/master/gl-dast-report.json b/spec/fixtures/security-reports/master/gl-dast-report.json new file mode 100644 index 00000000000..3a308bf047e --- /dev/null +++ b/spec/fixtures/security-reports/master/gl-dast-report.json @@ -0,0 +1,40 @@ +{ + "site": { + "alerts": [ + { + "sourceid": "3", + "wascid": "15", + "cweid": "16", + "reference": "

http://msdn.microsoft.com/en-us/library/ie/gg622941%28v=vs.85%29.aspx

https://www.owasp.org/index.php/List_of_useful_HTTP_headers

", + "otherinfo": "

This issue still applies to error type pages (401, 403, 500, etc) as those pages are often still affected by injection issues, in which case there is still concern for browsers sniffing pages away from their actual content type.

At \"High\" threshold this scanner will not alert on client or server error responses.

", + "solution": "

Ensure that the application/web server sets the Content-Type header appropriately, and that it sets the X-Content-Type-Options header to 'nosniff' for all web pages.

If possible, ensure that the end user uses a standards-compliant and modern web browser that does not perform MIME-sniffing at all, or that can be directed by the web application/web server to not perform MIME-sniffing.

", + "count": "2", + "pluginid": "10021", + "alert": "X-Content-Type-Options Header Missing", + "name": "X-Content-Type-Options Header Missing", + "riskcode": "1", + "confidence": "2", + "riskdesc": "Low (Medium)", + "desc": "

The Anti-MIME-Sniffing header X-Content-Type-Options was not set to 'nosniff'. This allows older versions of Internet Explorer and Chrome to perform MIME-sniffing on the response body, potentially causing the response body to be interpreted and displayed as a content type other than the declared content type. Current (early 2014) and legacy versions of Firefox will use the declared content type (if one is set), rather than performing MIME-sniffing.

", + "instances": [ + { + "param": "X-Content-Type-Options", + "method": "GET", + "uri": "http://bikebilly-spring-auto-devops-review-feature-br-3y2gpb.35.192.176.43.xip.io" + }, + { + "param": "X-Content-Type-Options", + "method": "GET", + "uri": "http://bikebilly-spring-auto-devops-review-feature-br-3y2gpb.35.192.176.43.xip.io/" + } + ] + } + ], + "@ssl": "false", + "@port": "80", + "@host": "bikebilly-spring-auto-devops-review-feature-br-3y2gpb.35.192.176.43.xip.io", + "@name": "http://bikebilly-spring-auto-devops-review-feature-br-3y2gpb.35.192.176.43.xip.io" + }, + "@generated": "Fri, 13 Apr 2018 09:22:01", + "@version": "2.7.0" +} diff --git a/spec/fixtures/security-reports/master/gl-dependency-scanning-report.json b/spec/fixtures/security-reports/master/gl-dependency-scanning-report.json new file mode 100644 index 00000000000..b4e4e8e7dd5 --- /dev/null +++ b/spec/fixtures/security-reports/master/gl-dependency-scanning-report.json @@ -0,0 +1,35 @@ +[ + { + "priority": "Unknown", + "file": "pom.xml", + "cve": "CVE-2012-4386", + "url": "http://struts.apache.org/docs/s2-010.html", + "message": "CSRF protection bypass for org.apache.struts/struts2-core", + "tools": [ + "gemnasium" + ], + "tool": "gemnasium" + }, + { + "priority": "Unknown", + "file": "pom.xml", + "cve": "CVE-2012-4387", + "url": "http://struts.apache.org/docs/s2-011.html", + "message": "Long parameter name DoS for org.apache.struts/struts2-core", + "tools": [ + "gemnasium" + ], + "tool": "gemnasium" + }, + { + "priority": "Unknown", + "file": "pom.xml", + "cve": "CVE-2013-1966", + "url": "http://struts.apache.org/docs/s2-014.html", + "message": "Remote command execution due to flaw in the includeParams attribute of URL and Anchor tags for org.apache.struts/struts2-core", + "tools": [ + "gemnasium" + ], + "tool": "gemnasium" + } +] diff --git a/spec/fixtures/security-reports/master/gl-license-management-report.json b/spec/fixtures/security-reports/master/gl-license-management-report.json new file mode 100644 index 00000000000..fe91e4fb7ee --- /dev/null +++ b/spec/fixtures/security-reports/master/gl-license-management-report.json @@ -0,0 +1,150 @@ +{ + "licenses": [ + { + "count": 10, + "name": "MIT" + } + ], + "dependencies": [ + { + "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": "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": "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" + }, + "dependency": { + "name": "tilt", + "url": "http://github.com/rtomayko/tilt/", + "description": "Generic interface to multiple Ruby template engines", + "pathes": [ + "." + ] + } + } + ] +} diff --git a/spec/fixtures/security-reports/master/gl-sast-report.json b/spec/fixtures/security-reports/master/gl-sast-report.json new file mode 100644 index 00000000000..a85b9be8b5f --- /dev/null +++ b/spec/fixtures/security-reports/master/gl-sast-report.json @@ -0,0 +1,944 @@ +[ + { + "category": "sast", + "message": "Probable insecure usage of temp file/directory.", + "cve": "python/hardcoded/hardcoded-tmp.py:52865813c884a507be1f152d654245af34aba8a391626d01f1ab6d3f52ec8779:B108", + "severity": "Medium", + "confidence": "Medium", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/hardcoded/hardcoded-tmp.py", + "start_line": 1, + "end_line": 1 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B108", + "value": "B108", + "url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html" + } + ], + "priority": "Medium", + "file": "python/hardcoded/hardcoded-tmp.py", + "line": 1, + "url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html", + "tool": "bandit" + }, + { + "category": "sast", + "name": "Predictable pseudorandom number generator", + "message": "Predictable pseudorandom number generator", + "cve": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy:47:PREDICTABLE_RANDOM", + "severity": "Medium", + "confidence": "Medium", + "scanner": { + "id": "find_sec_bugs", + "name": "Find Security Bugs" + }, + "location": { + "file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy", + "start_line": 47, + "end_line": 47, + "class": "com.gitlab.security_products.tests.App", + "method": "generateSecretToken2" + }, + "identifiers": [ + { + "type": "find_sec_bugs_type", + "name": "Find Security Bugs-PREDICTABLE_RANDOM", + "value": "PREDICTABLE_RANDOM", + "url": "https://find-sec-bugs.github.io/bugs.htm#PREDICTABLE_RANDOM" + } + ], + "priority": "Medium", + "file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy", + "line": 47, + "url": "https://find-sec-bugs.github.io/bugs.htm#PREDICTABLE_RANDOM", + "tool": "find_sec_bugs" + }, + { + "category": "sast", + "name": "Predictable pseudorandom number generator", + "message": "Predictable pseudorandom number generator", + "cve": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy:41:PREDICTABLE_RANDOM", + "severity": "Medium", + "confidence": "Medium", + "scanner": { + "id": "find_sec_bugs", + "name": "Find Security Bugs" + }, + "location": { + "file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy", + "start_line": 41, + "end_line": 41, + "class": "com.gitlab.security_products.tests.App", + "method": "generateSecretToken1" + }, + "identifiers": [ + { + "type": "find_sec_bugs_type", + "name": "Find Security Bugs-PREDICTABLE_RANDOM", + "value": "PREDICTABLE_RANDOM", + "url": "https://find-sec-bugs.github.io/bugs.htm#PREDICTABLE_RANDOM" + } + ], + "priority": "Medium", + "file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy", + "line": 41, + "url": "https://find-sec-bugs.github.io/bugs.htm#PREDICTABLE_RANDOM", + "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", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-aliases.py", + "start_line": 11, + "end_line": 11 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B303", + "value": "B303" + } + ], + "priority": "Medium", + "file": "python/imports/imports-aliases.py", + "line": 11, + "tool": "bandit" + }, + { + "category": "sast", + "message": "Use of insecure MD2, MD4, or MD5 hash function.", + "cve": "python/imports/imports-aliases.py:a7173c43ae66bd07466632d819d450e0071e02dbf782763640d1092981f9631b:B303", + "severity": "Medium", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-aliases.py", + "start_line": 12, + "end_line": 12 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B303", + "value": "B303" + } + ], + "priority": "Medium", + "file": "python/imports/imports-aliases.py", + "line": 12, + "tool": "bandit" + }, + { + "category": "sast", + "message": "Use of insecure MD2, MD4, or MD5 hash function.", + "cve": "python/imports/imports-aliases.py:017017b77deb0b8369b6065947833eeea752a92ec8a700db590fece3e934cf0d:B303", + "severity": "Medium", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-aliases.py", + "start_line": 13, + "end_line": 13 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B303", + "value": "B303" + } + ], + "priority": "Medium", + "file": "python/imports/imports-aliases.py", + "line": 13, + "tool": "bandit" + }, + { + "category": "sast", + "message": "Use of insecure MD2, MD4, or MD5 hash function.", + "cve": "python/imports/imports-aliases.py:45fc8c53aea7b84f06bc4e590cc667678d6073c4c8a1d471177ca2146fb22db2:B303", + "severity": "Medium", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-aliases.py", + "start_line": 14, + "end_line": 14 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B303", + "value": "B303" + } + ], + "priority": "Medium", + "file": "python/imports/imports-aliases.py", + "line": 14, + "tool": "bandit" + }, + { + "category": "sast", + "message": "Pickle library appears to be in use, possible security issue.", + "cve": "python/imports/imports-aliases.py:5f200d47291e7bbd8352db23019b85453ca048dd98ea0c291260fa7d009963a4:B301", + "severity": "Medium", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-aliases.py", + "start_line": 15, + "end_line": 15 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B301", + "value": "B301" + } + ], + "priority": "Medium", + "file": "python/imports/imports-aliases.py", + "line": 15, + "tool": "bandit" + }, + { + "category": "sast", + "name": "ECB mode is insecure", + "message": "ECB mode is insecure", + "cve": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy:29:ECB_MODE", + "severity": "Medium", + "confidence": "High", + "scanner": { + "id": "find_sec_bugs", + "name": "Find Security Bugs" + }, + "location": { + "file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy", + "start_line": 29, + "end_line": 29, + "class": "com.gitlab.security_products.tests.App", + "method": "insecureCypher" + }, + "identifiers": [ + { + "type": "find_sec_bugs_type", + "name": "Find Security Bugs-ECB_MODE", + "value": "ECB_MODE", + "url": "https://find-sec-bugs.github.io/bugs.htm#ECB_MODE" + } + ], + "priority": "Medium", + "file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy", + "line": 29, + "url": "https://find-sec-bugs.github.io/bugs.htm#ECB_MODE", + "tool": "find_sec_bugs" + }, + { + "category": "sast", + "name": "Cipher with no integrity", + "message": "Cipher with no integrity", + "cve": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy:29:CIPHER_INTEGRITY", + "severity": "Medium", + "confidence": "High", + "scanner": { + "id": "find_sec_bugs", + "name": "Find Security Bugs" + }, + "location": { + "file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy", + "start_line": 29, + "end_line": 29, + "class": "com.gitlab.security_products.tests.App", + "method": "insecureCypher" + }, + "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" + } + ], + "priority": "Medium", + "file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy", + "line": 29, + "url": "https://find-sec-bugs.github.io/bugs.htm#CIPHER_INTEGRITY", + "tool": "find_sec_bugs" + }, + { + "category": "sast", + "message": "Probable insecure usage of temp file/directory.", + "cve": "python/hardcoded/hardcoded-tmp.py:63dd4d626855555b816985d82c4614a790462a0a3ada89dc58eb97f9c50f3077:B108", + "severity": "Medium", + "confidence": "Medium", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/hardcoded/hardcoded-tmp.py", + "start_line": 14, + "end_line": 14 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B108", + "value": "B108", + "url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html" + } + ], + "priority": "Medium", + "file": "python/hardcoded/hardcoded-tmp.py", + "line": 14, + "url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html", + "tool": "bandit" + }, + { + "category": "sast", + "message": "Probable insecure usage of temp file/directory.", + "cve": "python/hardcoded/hardcoded-tmp.py:4ad6d4c40a8c263fc265f3384724014e0a4f8dd6200af83e51ff120420038031:B108", + "severity": "Medium", + "confidence": "Medium", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/hardcoded/hardcoded-tmp.py", + "start_line": 10, + "end_line": 10 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B108", + "value": "B108", + "url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html" + } + ], + "priority": "Medium", + "file": "python/hardcoded/hardcoded-tmp.py", + "line": 10, + "url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html", + "tool": "bandit" + }, + { + "category": "sast", + "message": "Consider possible security implications associated with Popen module.", + "cve": "python/imports/imports-aliases.py:2c3e1fa1e54c3c6646e8bcfaee2518153c6799b77587ff8d9a7b0631f6d34785:B404", + "severity": "Low", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-aliases.py", + "start_line": 1, + "end_line": 1 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B404", + "value": "B404" + } + ], + "priority": "Low", + "file": "python/imports/imports-aliases.py", + "line": 1, + "tool": "bandit" + }, + { + "category": "sast", + "message": "Consider possible security implications associated with pickle module.", + "cve": "python/imports/imports.py:af58d07f6ad519ef5287fcae65bf1a6999448a1a3a8bc1ac2a11daa80d0b96bf:B403", + "severity": "Low", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports.py", + "start_line": 2, + "end_line": 2 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B403", + "value": "B403" + } + ], + "priority": "Low", + "file": "python/imports/imports.py", + "line": 2, + "tool": "bandit" + }, + { + "category": "sast", + "message": "Consider possible security implications associated with subprocess module.", + "cve": "python/imports/imports.py:8de9bc98029d212db530785a5f6780cfa663548746ff228ab8fa96c5bb82f089:B404", + "severity": "Low", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports.py", + "start_line": 4, + "end_line": 4 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B404", + "value": "B404" + } + ], + "priority": "Low", + "file": "python/imports/imports.py", + "line": 4, + "tool": "bandit" + }, + { + "category": "sast", + "message": "Possible hardcoded password: 'blerg'", + "cve": "python/hardcoded/hardcoded-passwords.py:97c30f1d76d2a88913e3ce9ae74087874d740f87de8af697a9c455f01119f633:B106", + "severity": "Low", + "confidence": "Medium", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/hardcoded/hardcoded-passwords.py", + "start_line": 22, + "end_line": 22 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B106", + "value": "B106", + "url": "https://docs.openstack.org/bandit/latest/plugins/b106_hardcoded_password_funcarg.html" + } + ], + "priority": "Low", + "file": "python/hardcoded/hardcoded-passwords.py", + "line": 22, + "url": "https://docs.openstack.org/bandit/latest/plugins/b106_hardcoded_password_funcarg.html", + "tool": "bandit" + }, + { + "category": "sast", + "message": "Possible hardcoded password: 'root'", + "cve": "python/hardcoded/hardcoded-passwords.py:7431c73a0bc16d94ece2a2e75ef38f302574d42c37ac0c3c38ad0b3bf8a59f10:B105", + "severity": "Low", + "confidence": "Medium", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/hardcoded/hardcoded-passwords.py", + "start_line": 5, + "end_line": 5 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B105", + "value": "B105", + "url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html" + } + ], + "priority": "Low", + "file": "python/hardcoded/hardcoded-passwords.py", + "line": 5, + "url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html", + "tool": "bandit" + }, + { + "category": "sast", + "message": "Possible hardcoded password: ''", + "cve": "python/hardcoded/hardcoded-passwords.py:d2d1857c27caedd49c57bfbcdc23afcc92bd66a22701fcdc632869aab4ca73ee:B105", + "severity": "Low", + "confidence": "Medium", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/hardcoded/hardcoded-passwords.py", + "start_line": 9, + "end_line": 9 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B105", + "value": "B105", + "url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html" + } + ], + "priority": "Low", + "file": "python/hardcoded/hardcoded-passwords.py", + "line": 9, + "url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html", + "tool": "bandit" + }, + { + "category": "sast", + "message": "Possible hardcoded password: 'ajklawejrkl42348swfgkg'", + "cve": "python/hardcoded/hardcoded-passwords.py:fb3866215a61393a5c9c32a3b60e2058171a23219c353f722cbd3567acab21d2:B105", + "severity": "Low", + "confidence": "Medium", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/hardcoded/hardcoded-passwords.py", + "start_line": 13, + "end_line": 13 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B105", + "value": "B105", + "url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html" + } + ], + "priority": "Low", + "file": "python/hardcoded/hardcoded-passwords.py", + "line": 13, + "url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html", + "tool": "bandit" + }, + { + "category": "sast", + "message": "Possible hardcoded password: 'blerg'", + "cve": "python/hardcoded/hardcoded-passwords.py:63c62a8b7e1e5224439bd26b28030585ac48741e28ca64561a6071080c560a5f:B105", + "severity": "Low", + "confidence": "Medium", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/hardcoded/hardcoded-passwords.py", + "start_line": 23, + "end_line": 23 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B105", + "value": "B105", + "url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html" + } + ], + "priority": "Low", + "file": "python/hardcoded/hardcoded-passwords.py", + "line": 23, + "url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html", + "tool": "bandit" + }, + { + "category": "sast", + "message": "Possible hardcoded password: 'blerg'", + "cve": "python/hardcoded/hardcoded-passwords.py:4311b06d08df8fa58229b341c531da8e1a31ec4520597bdff920cd5c098d86f9:B105", + "severity": "Low", + "confidence": "Medium", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/hardcoded/hardcoded-passwords.py", + "start_line": 24, + "end_line": 24 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B105", + "value": "B105", + "url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html" + } + ], + "priority": "Low", + "file": "python/hardcoded/hardcoded-passwords.py", + "line": 24, + "url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html", + "tool": "bandit" + }, + { + "category": "sast", + "message": "Consider possible security implications associated with subprocess module.", + "cve": "python/imports/imports-function.py:5858400c2f39047787702de44d03361ef8d954c9d14bd54ee1c2bef9e6a7df93:B404", + "severity": "Low", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-function.py", + "start_line": 4, + "end_line": 4 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B404", + "value": "B404" + } + ], + "priority": "Low", + "file": "python/imports/imports-function.py", + "line": 4, + "tool": "bandit" + }, + { + "category": "sast", + "message": "Consider possible security implications associated with pickle module.", + "cve": "python/imports/imports-function.py:dbda3cf4190279d30e0aad7dd137eca11272b0b225e8af4e8bf39682da67d956:B403", + "severity": "Low", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-function.py", + "start_line": 2, + "end_line": 2 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B403", + "value": "B403" + } + ], + "priority": "Low", + "file": "python/imports/imports-function.py", + "line": 2, + "tool": "bandit" + }, + { + "category": "sast", + "message": "Consider possible security implications associated with Popen module.", + "cve": "python/imports/imports-from.py:eb8a0db9cd1a8c1ab39a77e6025021b1261cc2a0b026b2f4a11fca4e0636d8dd:B404", + "severity": "Low", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-from.py", + "start_line": 7, + "end_line": 7 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B404", + "value": "B404" + } + ], + "priority": "Low", + "file": "python/imports/imports-from.py", + "line": 7, + "tool": "bandit" + }, + { + "category": "sast", + "message": "subprocess call with shell=True seems safe, but may be changed in the future, consider rewriting without shell", + "cve": "python/imports/imports-aliases.py:f99f9721e27537fbcb6699a4cf39c6740d6234d2c6f06cfc2d9ea977313c483d:B602", + "severity": "Low", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-aliases.py", + "start_line": 9, + "end_line": 9 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B602", + "value": "B602", + "url": "https://docs.openstack.org/bandit/latest/plugins/b602_subprocess_popen_with_shell_equals_true.html" + } + ], + "priority": "Low", + "file": "python/imports/imports-aliases.py", + "line": 9, + "url": "https://docs.openstack.org/bandit/latest/plugins/b602_subprocess_popen_with_shell_equals_true.html", + "tool": "bandit" + }, + { + "category": "sast", + "message": "Consider possible security implications associated with subprocess module.", + "cve": "python/imports/imports-from.py:332a12ab1146698f614a905ce6a6a5401497a12281aef200e80522711c69dcf4:B404", + "severity": "Low", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-from.py", + "start_line": 6, + "end_line": 6 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B404", + "value": "B404" + } + ], + "priority": "Low", + "file": "python/imports/imports-from.py", + "line": 6, + "tool": "bandit" + }, + { + "category": "sast", + "message": "Consider possible security implications associated with Popen module.", + "cve": "python/imports/imports-from.py:0a48de4a3d5348853a03666cb574697e3982998355e7a095a798bd02a5947276:B404", + "severity": "Low", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-from.py", + "start_line": 1, + "end_line": 2 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B404", + "value": "B404" + } + ], + "priority": "Low", + "file": "python/imports/imports-from.py", + "line": 1, + "tool": "bandit" + }, + { + "category": "sast", + "message": "Consider possible security implications associated with pickle module.", + "cve": "python/imports/imports-aliases.py:51b71661dff994bde3529639a727a678c8f5c4c96f00d300913f6d5be1bbdf26:B403", + "severity": "Low", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-aliases.py", + "start_line": 7, + "end_line": 8 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B403", + "value": "B403" + } + ], + "priority": "Low", + "file": "python/imports/imports-aliases.py", + "line": 7, + "tool": "bandit" + }, + { + "category": "sast", + "message": "Consider possible security implications associated with loads module.", + "cve": "python/imports/imports-aliases.py:6ff02aeb3149c01ab68484d794a94f58d5d3e3bb0d58557ef4153644ea68ea54:B403", + "severity": "Low", + "confidence": "High", + "scanner": { + "id": "bandit", + "name": "Bandit" + }, + "location": { + "file": "python/imports/imports-aliases.py", + "start_line": 6, + "end_line": 6 + }, + "identifiers": [ + { + "type": "bandit_test_id", + "name": "Bandit Test ID B403", + "value": "B403" + } + ], + "priority": "Low", + "file": "python/imports/imports-aliases.py", + "line": 6, + "tool": "bandit" + }, + { + "category": "sast", + "message": "Statically-sized arrays can be improperly restricted, leading to potential overflows or other issues (CWE-119!/CWE-120)", + "cve": "c/subdir/utils.c:b466873101951fe96e1332f6728eb7010acbbd5dfc3b65d7d53571d091a06d9e:CWE-119!/CWE-120", + "confidence": "Low", + "solution": "Perform bounds checking, use functions that limit length, or ensure that the size is larger than the maximum possible length", + "scanner": { + "id": "flawfinder", + "name": "Flawfinder" + }, + "location": { + "file": "c/subdir/utils.c", + "start_line": 4 + }, + "identifiers": [ + { + "type": "cwe", + "name": "CWE-119", + "value": "119", + "url": "https://cwe.mitre.org/data/definitions/119.html" + }, + { + "type": "cwe", + "name": "CWE-120", + "value": "120", + "url": "https://cwe.mitre.org/data/definitions/120.html" + } + ], + "file": "c/subdir/utils.c", + "line": 4, + "url": "https://cwe.mitre.org/data/definitions/119.html", + "tool": "flawfinder" + }, + { + "category": "sast", + "message": "Check when opening files - can an attacker redirect it (via symlinks), force the opening of special file type (e.g., device files), move things around to create a race condition, control its ancestors, or change its contents? (CWE-362)", + "cve": "c/subdir/utils.c:bab681140fcc8fc3085b6bba74081b44ea145c1c98b5e70cf19ace2417d30770:CWE-362", + "confidence": "Low", + "scanner": { + "id": "flawfinder", + "name": "Flawfinder" + }, + "location": { + "file": "c/subdir/utils.c", + "start_line": 8 + }, + "identifiers": [ + { + "type": "cwe", + "name": "CWE-362", + "value": "362", + "url": "https://cwe.mitre.org/data/definitions/362.html" + } + ], + "file": "c/subdir/utils.c", + "line": 8, + "url": "https://cwe.mitre.org/data/definitions/362.html", + "tool": "flawfinder" + }, + { + "category": "sast", + "message": "Statically-sized arrays can be improperly restricted, leading to potential overflows or other issues (CWE-119!/CWE-120)", + "cve": "cplusplus/src/hello.cpp:c8c6dd0afdae6814194cf0930b719f757ab7b379cf8f261e7f4f9f2f323a818a:CWE-119!/CWE-120", + "confidence": "Low", + "solution": "Perform bounds checking, use functions that limit length, or ensure that the size is larger than the maximum possible length", + "scanner": { + "id": "flawfinder", + "name": "Flawfinder" + }, + "location": { + "file": "cplusplus/src/hello.cpp", + "start_line": 6 + }, + "identifiers": [ + { + "type": "cwe", + "name": "CWE-119", + "value": "119", + "url": "https://cwe.mitre.org/data/definitions/119.html" + }, + { + "type": "cwe", + "name": "CWE-120", + "value": "120", + "url": "https://cwe.mitre.org/data/definitions/120.html" + } + ], + "file": "cplusplus/src/hello.cpp", + "line": 6, + "url": "https://cwe.mitre.org/data/definitions/119.html", + "tool": "flawfinder" + }, + { + "category": "sast", + "message": "Does not check for buffer overflows when copying to destination [MS-banned] (CWE-120)", + "cve": "cplusplus/src/hello.cpp:331c04062c4fe0c7c486f66f59e82ad146ab33cdd76ae757ca41f392d568cbd0:CWE-120", + "confidence": "Low", + "solution": "Consider using snprintf, strcpy_s, or strlcpy (warning: strncpy easily misused)", + "scanner": { + "id": "flawfinder", + "name": "Flawfinder" + }, + "location": { + "file": "cplusplus/src/hello.cpp", + "start_line": 7 + }, + "identifiers": [ + { + "type": "cwe", + "name": "CWE-120", + "value": "120", + "url": "https://cwe.mitre.org/data/definitions/120.html" + } + ], + "file": "cplusplus/src/hello.cpp", + "line": 7, + "url": "https://cwe.mitre.org/data/definitions/120.html", + "tool": "flawfinder" + } +] diff --git a/spec/lib/gitlab/ci/build/artifacts/gzip_file_adapter_spec.rb b/spec/lib/gitlab/ci/build/artifacts/adapters/gzip_stream_spec.rb similarity index 96% rename from spec/lib/gitlab/ci/build/artifacts/gzip_file_adapter_spec.rb rename to spec/lib/gitlab/ci/build/artifacts/adapters/gzip_stream_spec.rb index 384329dda18..987c6b37aaa 100644 --- a/spec/lib/gitlab/ci/build/artifacts/gzip_file_adapter_spec.rb +++ b/spec/lib/gitlab/ci/build/artifacts/adapters/gzip_stream_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Gitlab::Ci::Build::Artifacts::GzipFileAdapter do +describe Gitlab::Ci::Build::Artifacts::Adapters::GzipStream do describe '#initialize' do context 'when stream is passed' do let(:stream) { File.open(expand_fixture_path('junit/junit.xml.gz'), 'rb') } diff --git a/spec/lib/gitlab/ci/build/artifacts/adapters/raw_stream_spec.rb b/spec/lib/gitlab/ci/build/artifacts/adapters/raw_stream_spec.rb new file mode 100644 index 00000000000..ec2dd724b45 --- /dev/null +++ b/spec/lib/gitlab/ci/build/artifacts/adapters/raw_stream_spec.rb @@ -0,0 +1,47 @@ +require 'spec_helper' + +describe Gitlab::Ci::Build::Artifacts::Adapters::RawStream do + describe '#initialize' do + context 'when stream is passed' do + let(:stream) { File.open(expand_fixture_path('junit/junit.xml'), 'rb') } + + it 'initialized' do + expect { described_class.new(stream) }.not_to raise_error + end + end + + context 'when stream is not passed' do + let(:stream) { nil } + + it 'raises an error' do + expect { described_class.new(stream) }.to raise_error(described_class::InvalidStreamError) + end + end + end + + describe '#each_blob' do + let(:adapter) { described_class.new(stream) } + + context 'when file is not empty' do + let(:stream) { File.open(expand_fixture_path('junit/junit.xml'), 'rb') } + + it 'iterates content' do + expect { |b| adapter.each_blob(&b) } + .to yield_with_args(fixture_file('junit/junit.xml'), 'raw') + end + end + + context 'when file is empty' do + let(:stream) { Tempfile.new } + + after do + stream.unlink + end + + it 'does not iterate content' do + expect { |b| adapter.each_blob(&b) } + .not_to yield_control + end + end + end +end diff --git a/spec/models/ci/job_artifact_spec.rb b/spec/models/ci/job_artifact_spec.rb index 85fad77a242..fb5bec4108a 100644 --- a/spec/models/ci/job_artifact_spec.rb +++ b/spec/models/ci/job_artifact_spec.rb @@ -194,6 +194,14 @@ describe Ci::JobArtifact do end end + context 'when file format is raw' do + let(:artifact) { build(:ci_job_artifact, :codequality, file_format: :raw) } + + it 'iterates blob once' do + expect { |b| artifact.each_blob(&b) }.to yield_control.once + end + end + context 'when there are no adapters for the file format' do let(:artifact) { build(:ci_job_artifact, :junit, file_format: :zip) } diff --git a/spec/presenters/ci/build_runner_presenter_spec.rb b/spec/presenters/ci/build_runner_presenter_spec.rb index a42d1f3d399..170e0ac5717 100644 --- a/spec/presenters/ci/build_runner_presenter_spec.rb +++ b/spec/presenters/ci/build_runner_presenter_spec.rb @@ -40,21 +40,23 @@ describe Ci::BuildRunnerPresenter do context "with reports" do Ci::JobArtifact::DEFAULT_FILE_NAMES.each do |file_type, filename| - let(:report) { { "#{file_type}": [filename] } } - let(:build) { create(:ci_build, options: { artifacts: { reports: report } } ) } + context file_type.to_s do + let(:report) { { "#{file_type}": [filename] } } + let(:build) { create(:ci_build, options: { artifacts: { reports: report } } ) } - let(:report_expectation) do - { - name: filename, - artifact_type: :"#{file_type}", - artifact_format: :gzip, - paths: [filename], - when: 'always' - } - end + let(:report_expectation) do + { + name: filename, + artifact_type: :"#{file_type}", + artifact_format: Ci::JobArtifact::TYPE_AND_FORMAT_PAIRS.fetch(file_type), + paths: [filename], + when: 'always' + } + end - it 'presents correct hash' do - expect(presenter.artifacts.first).to include(report_expectation) + it 'presents correct hash' do + expect(presenter.artifacts.first).to include(report_expectation) + end end end end