Commit cc0c4563 authored by James Lopez's avatar James Lopez

Merge branch 'add_scanned_resources_to_security_report_summary_223672' into 'master'

Add scanned resources to security report

See merge request gitlab-org/gitlab!35695
parents 0b213b0d a68b5371
......@@ -11310,6 +11310,56 @@ type RunDASTScanPayload {
pipelineUrl: String
}
"""
Represents a resource scanned by a security scan
"""
type ScannedResource {
"""
The HTTP request method used to access the URL
"""
requestMethod: String
"""
The URL scanned by the scanner
"""
url: String
}
"""
The connection type for ScannedResource.
"""
type ScannedResourceConnection {
"""
A list of edges.
"""
edges: [ScannedResourceEdge]
"""
A list of nodes.
"""
nodes: [ScannedResource]
"""
Information to aid in pagination.
"""
pageInfo: PageInfo!
}
"""
An edge in a connection.
"""
type ScannedResourceEdge {
"""
A cursor for use in pagination.
"""
cursor: String!
"""
The item at the end of the edge.
"""
node: ScannedResource
}
"""
Represents summary of a security report
"""
......@@ -11349,6 +11399,31 @@ type SecurityReportSummary {
Represents a section of a summary of a security report
"""
type SecurityReportSummarySection {
"""
A list of the first 20 scanned resources
"""
scannedResources(
"""
Returns the elements in the list that come after the specified cursor.
"""
after: String
"""
Returns the elements in the list that come before the specified cursor.
"""
before: String
"""
Returns the first _n_ elements from the list.
"""
first: Int
"""
Returns the last _n_ elements from the list.
"""
last: Int
): ScannedResourceConnection
"""
Total number of scanned resources
"""
......
......@@ -33217,6 +33217,159 @@
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "ScannedResource",
"description": "Represents a resource scanned by a security scan",
"fields": [
{
"name": "requestMethod",
"description": "The HTTP request method used to access the URL",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "url",
"description": "The URL scanned by the scanner",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "ScannedResourceConnection",
"description": "The connection type for ScannedResource.",
"fields": [
{
"name": "edges",
"description": "A list of edges.",
"args": [
],
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "ScannedResourceEdge",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "nodes",
"description": "A list of nodes.",
"args": [
],
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "ScannedResource",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "pageInfo",
"description": "Information to aid in pagination.",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "PageInfo",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "ScannedResourceEdge",
"description": "An edge in a connection.",
"fields": [
{
"name": "cursor",
"description": "A cursor for use in pagination.",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "node",
"description": "The item at the end of the edge.",
"args": [
],
"type": {
"kind": "OBJECT",
"name": "ScannedResource",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "SecurityReportSummary",
......@@ -33319,6 +33472,59 @@
"name": "SecurityReportSummarySection",
"description": "Represents a section of a summary of a security report",
"fields": [
{
"name": "scannedResources",
"description": "A list of the first 20 scanned resources",
"args": [
{
"name": "after",
"description": "Returns the elements in the list that come after the specified cursor.",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "before",
"description": "Returns the elements in the list that come before the specified cursor.",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "first",
"description": "Returns the first _n_ elements from the list.",
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
},
{
"name": "last",
"description": "Returns the last _n_ elements from the list.",
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "ScannedResourceConnection",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "scannedResourcesCount",
"description": "Total number of scanned resources",
......@@ -1637,6 +1637,15 @@ Autogenerated return type of RunDASTScan
| `errors` | String! => Array | Errors encountered during execution of the mutation. |
| `pipelineUrl` | String | URL of the pipeline that was created. |
## ScannedResource
Represents a resource scanned by a security scan
| Name | Type | Description |
| --- | ---- | ---------- |
| `requestMethod` | String | The HTTP request method used to access the URL |
| `url` | String | The URL scanned by the scanner |
## SecurityReportSummary
Represents summary of a security report
......
# frozen_string_literal: true
module Types
# rubocop: disable Graphql/AuthorizeTypes
class ScannedResourceType < BaseObject
graphql_name 'ScannedResource'
description 'Represents a resource scanned by a security scan'
field :url, GraphQL::STRING_TYPE, null: true, description: 'The URL scanned by the scanner'
field :request_method, GraphQL::STRING_TYPE, null: true, description: 'The HTTP request method used to access the URL'
end
end
......@@ -8,5 +8,6 @@ module Types
field :vulnerabilities_count, GraphQL::INT_TYPE, null: true, description: 'Total number of vulnerabilities'
field :scanned_resources_count, GraphQL::INT_TYPE, null: true, description: 'Total number of scanned resources'
field :scanned_resources, ::Types::ScannedResourceType.connection_type, null: true, description: 'A list of the first 20 scanned resources'
end
end
......@@ -28,6 +28,8 @@ module Security
response[:vulnerabilities_count] = vulnerability_counts[report_type.to_s]
when :scanned_resources_count
response[:scanned_resources_count] = scanned_resources_counts[report_type.to_s]
when :scanned_resources
response[:scanned_resources] = scanned_resources[report_type.to_s]
end
end
end
......@@ -37,6 +39,13 @@ module Security
@report_types_for_summary_type[summary_type].map(&:to_s)
end
def scanned_resources
strong_memoize(:scanned_resources) do
scanned_resources_limit = 20
::Security::ScannedResourcesService.new(@pipeline, requested_report_types(:scanned_resources), scanned_resources_limit).execute
end
end
def vulnerability_counts
strong_memoize(:vulnerability_counts) do
::Security::VulnerabilityCountingService.new(@pipeline, requested_report_types(:vulnerabilities_count)).execute
......
# frozen_string_literal: true
module Security
# Service for getting the scanned resources for
# an array of report types within a pipeline
#
class ScannedResourcesService
# @param [Ci::Pipeline] pipeline
# @param Array[Symbol] report_types Summary report types. Valid values are members of Vulnerabilities::Occurrence::REPORT_TYPES
# @param [Int] The maximum number of scanned resources to return
def initialize(pipeline, report_types, limit = nil)
@pipeline = pipeline
@report_types = report_types
@limit = limit
end
def execute
reports = @pipeline&.security_reports&.reports || {}
@report_types.each_with_object({}) do |type, acc|
scanned_resources = reports[type]&.scanned_resources || []
scanned_resources = scanned_resources.first(@limit) if @limit
acc[type] = scanned_resources.map do |resource|
{
'request_method' => resource['method'],
'url' => resource['url']
}
end
end
end
end
end
---
title: Add scanned resources to security report
merge_request: 35695
author:
type: added
......@@ -109,6 +109,16 @@ FactoryBot.define do
end
end
trait :dast_large_scanned_resources_field do
file_format { :raw }
file_type { :dast }
after(:build) do |artifact, _|
artifact.file = fixture_file_upload(
Rails.root.join('ee/spec/fixtures/security_reports/master/gl-dast-large-scanned-resources.json'), 'application/json')
end
end
trait :low_severity_dast_report do
file_format { :raw }
file_type { :dast }
......
{
"@generated": "Fri, 13 Apr 2018 09:22:01",
"@version": "2.7.0",
"scan": {
"scanned_resources": [
{
"method": "GET",
"type": "url",
"url": "http://nginx"
},
{
"method": "GET",
"type": "url",
"url": "http://nginx/"
},
{
"method": "GET",
"type": "url",
"url": "http://nginx/1"
},
{
"method": "GET",
"type": "url",
"url": "http://nginx/2"
},
{
"method": "GET",
"type": "url",
"url": "http://nginx/3"
},
{
"method": "GET",
"type": "url",
"url": "http://nginx/4"
},
{
"method": "GET",
"type": "url",
"url": "http://nginx/5"
},
{
"method": "GET",
"type": "url",
"url": "http://nginx/6"
},
{
"method": "GET",
"type": "url",
"url": "http://nginx/7"
},
{
"method": "GET",
"type": "url",
"url": "http://nginx/8"
},
{
"method": "GET",
"type": "url",
"url": "http://nginx/9"
},
{
"method": "GET",
"type": "url",
"url": "http://nginx/10"
},
{
"method": "GET",
"type": "url",
"url": "http://nginx/11"
},
{
"method": "GET",
"type": "url",
"url": "http://nginx/12"
},
{
"method": "GET",
"type": "url",
"url": "http://nginx/13"
},
{
"method": "GET",
"type": "url",
"url": "http://nginx/14"
},
{
"method": "GET",
"type": "url",
"url": "http://nginx/15"
},
{
"method": "GET",
"type": "url",
"url": "http://nginx/16"
},
{
"method": "GET",
"type": "url",
"url": "http://nginx/17"
},
{
"method": "GET",
"type": "url",
"url": "http://nginx/18"
},
{
"method": "GET",
"type": "url",
"url": "http://nginx/19"
},
{
"method": "GET",
"type": "url",
"url": "http://nginx/20"
},
{
"method": "GET",
"type": "url",
"url": "http://nginx/21"
},
{
"method": "POST",
"type": "url",
"url": "http://nginx/myform"
},
{
"method": "GET",
"type": "url",
"url": "http://nginx/robots.txt"
},
{
"method": "GET",
"type": "url",
"url": "http://nginx/sitemap.xml"
}
]
},
"site": [
{
"@host": "goat",
"@name": "http://goat:8080",
"@port": "8080",
"@ssl": "false",
"alerts": [
{
"alert": "Anti CSRF Tokens Scanner",
"confidence": "2",
"count": "4",
"cweid": "352",
"desc": "<p>A cross-site request forgery is an attack that involves forcing a victim to send an HTTP request to a target destination without their knowledge or intent in order to perform an action as the victim. The underlying cause is application functionality using predictable URL/form actions in a repeatable way. The nature of the attack is that CSRF exploits the trust that a web site has for a user. By contrast, cross-site scripting (XSS) exploits the trust that a user has for a web site. Like XSS, CSRF attacks are not necessarily cross-site, but they can be. Cross-site request forgery is also known as CSRF, XSRF, one-click attack, session riding, confused deputy, and sea surf.</p><p></p><p>CSRF attacks are effective in a number of situations, including:</p><p> * The victim has an active session on the target site.</p><p> * The victim is authenticated via HTTP auth on the target site.</p><p> * The victim is on the same local network as the target site.</p><p></p><p>CSRF has primarily been used to perform an action against a target site using the victim's privileges, but recent techniques have been discovered to disclose information by gaining access to the response. The risk of information disclosure is dramatically increased when the target site is vulnerable to XSS, because XSS can be used as a platform for CSRF, allowing the attack to operate within the bounds of the same-origin policy.</p>",
"instances": [
{
"attack": "",
"evidence": "<form method=\"POST\" style=\"width: 200px;\" action=\"/WebGoat/login\">",
"method": "GET",
"param": "",
"uri": "http://goat:8080/WebGoat/login"
},
{
"attack": "",
"evidence": "<form method=\"POST\" style=\"width: 200px;\" action=\"/WebGoat/login\">",
"method": "GET",
"param": "",
"uri": "http://goat:8080/WebGoat/login?error"
},
{
"attack": "",
"evidence": "<form class=\"form-horizontal\" action=\"/WebGoat/register.mvc\" method=\"POST\">",
"method": "POST",
"param": "",
"uri": "http://goat:8080/WebGoat/register.mvc"
},
{
"attack": "",
"evidence": "<form class=\"form-horizontal\" action=\"/WebGoat/register.mvc\" method=\"POST\">",
"method": "GET",
"param": "",
"uri": "http://goat:8080/WebGoat/registration"
}
],
"name": "Anti CSRF Tokens Scanner",
"otherinfo": "",
"pluginid": "20012",
"reference": "<p>http://projects.webappsec.org/Cross-Site-Request-Forgery</p><p>http://cwe.mitre.org/data/definitions/352.html</p>",
"riskcode": "3",
"riskdesc": "High (Medium)",
"solution": "<p>Phase: Architecture and Design</p><p>Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid.</p><p>For example, use anti-CSRF packages such as the OWASP CSRFGuard.</p><p></p><p>Phase: Implementation</p><p>Ensure that your application is free of cross-site scripting issues, because most CSRF defenses can be bypassed using attacker-controlled script.</p><p></p><p>Phase: Architecture and Design</p><p>Generate a unique nonce for each form, place the nonce into the form, and verify the nonce upon receipt of the form. Be sure that the nonce is not predictable (CWE-330).</p><p>Note that this can be bypassed using XSS.</p><p></p><p>Identify especially dangerous operations. When the user performs a dangerous operation, send a separate confirmation request to ensure that the user intended to perform that operation.</p><p>Note that this can be bypassed using XSS.</p><p></p><p>Use the ESAPI Session Management control.</p><p>This control includes a component for CSRF.</p><p></p><p>Do not use the GET method for any request that triggers a state change.</p><p></p><p>Phase: Implementation</p><p>Check the HTTP Referer header to see if the request originated from an expected page. This could break legitimate functionality, because users or proxies may have disabled sending the Referer for privacy reasons.</p>",
"sourceid": "1",
"wascid": "9"
},
{
"alert": "Absence of Anti-CSRF Tokens",
"confidence": "2",
"count": "4",
"cweid": "352",
"desc": "<p>No Anti-CSRF tokens were found in a HTML submission form.</p><p>A cross-site request forgery is an attack that involves forcing a victim to send an HTTP request to a target destination without their knowledge or intent in order to perform an action as the victim. The underlying cause is application functionality using predictable URL/form actions in a repeatable way. The nature of the attack is that CSRF exploits the trust that a web site has for a user. By contrast, cross-site scripting (XSS) exploits the trust that a user has for a web site. Like XSS, CSRF attacks are not necessarily cross-site, but they can be. Cross-site request forgery is also known as CSRF, XSRF, one-click attack, session riding, confused deputy, and sea surf.</p><p></p><p>CSRF attacks are effective in a number of situations, including:</p><p> * The victim has an active session on the target site.</p><p> * The victim is authenticated via HTTP auth on the target site.</p><p> * The victim is on the same local network as the target site.</p><p></p><p>CSRF has primarily been used to perform an action against a target site using the victim's privileges, but recent techniques have been discovered to disclose information by gaining access to the response. The risk of information disclosure is dramatically increased when the target site is vulnerable to XSS, because XSS can be used as a platform for CSRF, allowing the attack to operate within the bounds of the same-origin policy.</p>",
"instances": [
{
"attack": "",
"evidence": "<form method=\"POST\" style=\"width: 200px;\" action=\"/WebGoat/login\">",
"method": "GET",
"param": "",
"uri": "http://goat:8080/WebGoat/login"
},
{
"attack": "",
"evidence": "<form method=\"POST\" style=\"width: 200px;\" action=\"/WebGoat/login\">",
"method": "GET",
"param": "",
"uri": "http://goat:8080/WebGoat/login?error"
},
{
"attack": "",
"evidence": "<form class=\"form-horizontal\" action=\"/WebGoat/register.mvc\" method=\"POST\">",
"method": "POST",
"param": "",
"uri": "http://goat:8080/WebGoat/register.mvc"
},
{
"attack": "",
"evidence": "<form class=\"form-horizontal\" action=\"/WebGoat/register.mvc\" method=\"POST\">",
"method": "GET",
"param": "",
"uri": "http://goat:8080/WebGoat/registration"
}
],
"name": "Absence of Anti-CSRF Tokens",
"otherinfo": "<p>No known Anti-CSRF token [anticsrf, CSRFToken, __RequestVerificationToken, csrfmiddlewaretoken, authenticity_token, OWASP_CSRFTOKEN, anoncsrf, csrf_token, _csrf, _csrfSecret] was found in the following HTML form: [Form 1: \"exampleInputEmail1\" \"exampleInputPassword1\" ].</p>",
"pluginid": "10202",
"reference": "<p>http://projects.webappsec.org/Cross-Site-Request-Forgery</p><p>http://cwe.mitre.org/data/definitions/352.html</p>",
"riskcode": "1",
"riskdesc": "Low (Medium)",
"solution": "<p>Phase: Architecture and Design</p><p>Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid.</p><p>For example, use anti-CSRF packages such as the OWASP CSRFGuard.</p><p></p><p>Phase: Implementation</p><p>Ensure that your application is free of cross-site scripting issues, because most CSRF defenses can be bypassed using attacker-controlled script.</p><p></p><p>Phase: Architecture and Design</p><p>Generate a unique nonce for each form, place the nonce into the form, and verify the nonce upon receipt of the form. Be sure that the nonce is not predictable (CWE-330).</p><p>Note that this can be bypassed using XSS.</p><p></p><p>Identify especially dangerous operations. When the user performs a dangerous operation, send a separate confirmation request to ensure that the user intended to perform that operation.</p><p>Note that this can be bypassed using XSS.</p><p></p><p>Use the ESAPI Session Management control.</p><p>This control includes a component for CSRF.</p><p></p><p>Do not use the GET method for any request that triggers a state change.</p><p></p><p>Phase: Implementation</p><p>Check the HTTP Referer header to see if the request originated from an expected page. This could break legitimate functionality, because users or proxies may have disabled sending the Referer for privacy reasons.</p>",
"sourceid": "3",
"wascid": "9"
},
{
"alert": "Cookie No HttpOnly Flag",
"confidence": "2",
"count": "2",
"cweid": "16",
"desc": "<p>A cookie has been set without the HttpOnly flag, which means that the cookie can be accessed by JavaScript. If a malicious script can be run on this page then the cookie will be accessible and can be transmitted to another site. If this is a session cookie then session hijacking may be possible.</p>",
"instances": [
{
"attack": "",
"evidence": "Set-Cookie: JSESSIONID",
"method": "GET",
"param": "JSESSIONID",
"uri": "http://goat:8080/WebGoat/login?logout"
},
{
"attack": "",
"evidence": "Set-Cookie: JSESSIONID",
"method": "GET",
"param": "JSESSIONID",
"uri": "http://goat:8080/WebGoat/logout"
}
],
"name": "Cookie No HttpOnly Flag",
"otherinfo": "",
"pluginid": "10010",
"reference": "<p>http://www.owasp.org/index.php/HttpOnly</p>",
"riskcode": "1",
"riskdesc": "Low (Medium)",
"solution": "<p>Ensure that the HttpOnly flag is set for all cookies.</p>",
"sourceid": "3",
"wascid": "13"
},
{
"alert": "Cookie Without SameSite Attribute",
"confidence": "2",
"count": "2",
"cweid": "16",
"desc": "<p>A cookie has been set without the SameSite attribute, which means that the cookie can be sent as a result of a 'cross-site' request. The SameSite attribute is an effective counter measure to cross-site request forgery, cross-site script inclusion, and timing attacks.</p>",
"instances": [
{
"attack": "",
"evidence": "Set-Cookie: JSESSIONID",
"method": "GET",
"param": "JSESSIONID",
"uri": "http://goat:8080/WebGoat/login?logout"
},
{
"attack": "",
"evidence": "Set-Cookie: JSESSIONID",
"method": "GET",
"param": "JSESSIONID",
"uri": "http://goat:8080/WebGoat/logout"
}
],
"name": "Cookie Without SameSite Attribute",
"otherinfo": "",
"pluginid": "10054",
"reference": "<p>https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site</p>",
"riskcode": "1",
"riskdesc": "Low (Medium)",
"solution": "<p>Ensure that the SameSite attribute is set to either 'lax' or ideally 'strict' for all cookies.</p>",
"sourceid": "3",
"wascid": "13"
},
{
"alert": "Charset Mismatch (Header Versus Meta Content-Type Charset)",
"confidence": "1",
"count": "1",
"cweid": "16",
"desc": "<p>This check identifies responses where the HTTP Content-Type header declares a charset different from the charset defined by the body of the HTML or XML. When there's a charset mismatch between the HTTP header and content body Web browsers can be forced into an undesirable content-sniffing mode to determine the content's correct character set.</p><p></p><p>An attacker could manipulate content on the page to be interpreted in an encoding of their choice. For example, if an attacker can control content at the beginning of the page, they could inject script using UTF-7 encoded text and manipulate some browsers into interpreting that text.</p>",
"instances": [
{
"attack": "",
"evidence": "",
"method": "GET",
"param": "",
"uri": "http://goat:8080/WebGoat/start.mvc"
}
],
"name": "Charset Mismatch (Header Versus Meta Content-Type Charset)",
"otherinfo": "<p>There was a charset mismatch between the HTTP Header and the META content-type encoding declarations: [UTF-8] and [ISO-8859-1] do not match.</p>",
"pluginid": "90011",
"reference": "<p>http://code.google.com/p/browsersec/wiki/Part2#Character_set_handling_and_detection</p>",
"riskcode": "0",
"riskdesc": "Informational (Low)",
"solution": "<p>Force UTF-8 for all text content in both the HTTP header and meta tags in HTML or encoding declarations in XML.</p>",
"sourceid": "3",
"wascid": "15"
},
{
"alert": "Information Disclosure - Suspicious Comments",
"confidence": "2",
"count": "4",
"cweid": "200",
"desc": "<p>The response appears to contain suspicious comments which may help an attacker.</p>",
"instances": [
{
"attack": "",
"evidence": "",
"method": "GET",
"param": "",
"uri": "http://goat:8080/WebGoat/js/html5shiv.js"
},
{
"attack": "",
"evidence": "",
"method": "GET",
"param": "",
"uri": "http://goat:8080/WebGoat/js/modernizr-2.6.2.min.js"
},
{
"attack": "",
"evidence": "",
"method": "GET",
"param": "",
"uri": "http://goat:8080/WebGoat/js/respond.min.js"
},
{
"attack": "",
"evidence": "",
"method": "GET",
"param": "",
"uri": "http://goat:8080/WebGoat/start.mvc"
}
],
"name": "Information Disclosure - Suspicious Comments",
"otherinfo": "<p><!--<button type=\"button\" id=\"admin-button\" class=\"btn btn-default right_nav_button\" title=\"Administrator\">--></p><p><!--<button type=\"button\" id=\"user-management\" class=\"btn btn-default right_nav_button\"--></p><p><!--title=\"User management\">--></p><p></p>",
"pluginid": "10027",
"reference": "<p></p>",
"riskcode": "0",
"riskdesc": "Informational (Medium)",
"solution": "<p>Remove all comments that return information that may help an attacker and fix any underlying problems they refer to.</p>",
"sourceid": "3",
"wascid": "13"
},
{
"alert": "Loosely Scoped Cookie",
"confidence": "1",
"count": "2",
"cweid": "565",
"desc": "<p>Cookies can be scoped by domain or path. This check is only concerned with domain scope.The domain scope applied to a cookie determines which domains can access it. For example, a cookie can be scoped strictly to a subdomain e.g. www.nottrusted.com, or loosely scoped to a parent domain e.g. nottrusted.com. In the latter case, any subdomain of nottrusted.com can access the cookie. Loosely scoped cookies are common in mega-applications like google.com and live.com. Cookies set from a subdomain like app.foo.bar are transmitted only to that domain by the browser. However, cookies scoped to a parent-level domain may be transmitted to the parent, or any subdomain of the parent.</p>",
"instances": [
{
"attack": "",
"evidence": "",
"method": "GET",
"param": "",
"uri": "http://goat:8080/WebGoat/login?logout"
},
{
"attack": "",
"evidence": "",
"method": "GET",
"param": "",
"uri": "http://goat:8080/WebGoat/logout"
}
],
"name": "Loosely Scoped Cookie",
"otherinfo": "<p>The origin domain used for comparison was: </p><p>goat</p><p>JSESSIONID=78EC2C9D7CE583610DCC7826EE416D7F</p><p></p>",
"pluginid": "90033",
"reference": "<p>https://tools.ietf.org/html/rfc6265#section-4.1</p><p>https://www.owasp.org/index.php/Testing_for_cookies_attributes_(OTG-SESS-002)</p><p>http://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_cookies</p>",
"riskcode": "0",
"riskdesc": "Informational (Low)",
"solution": "<p>Always scope cookies to a FQDN (Fully Qualified Domain Name).</p>",
"sourceid": "3",
"wascid": "15"
},
{
"alert": "Timestamp Disclosure - Unix",
"confidence": "1",
"count": "5",
"cweid": "200",
"desc": "<p>A timestamp was disclosed by the application/web server - Unix</p>",
"instances": [
{
"attack": "",
"evidence": "00000000",
"method": "GET",
"param": "",
"uri": "http://goat:8080/WebGoat/plugins/bootstrap/css/bootstrap.min.css"
},
{
"attack": "",
"evidence": "33333333",
"method": "GET",
"param": "",
"uri": "http://goat:8080/WebGoat/plugins/bootstrap/css/bootstrap.min.css"
},
{
"attack": "",
"evidence": "42857143",
"method": "GET",
"param": "",
"uri": "http://goat:8080/WebGoat/plugins/bootstrap/css/bootstrap.min.css"
},
{
"attack": "",
"evidence": "80000000",
"method": "GET",
"param": "",
"uri": "http://goat:8080/WebGoat/plugins/bootstrap/css/bootstrap.min.css"
},
{
"attack": "",
"evidence": "66666667",
"method": "GET",
"param": "",
"uri": "http://goat:8080/WebGoat/plugins/bootstrap/css/bootstrap.min.css"
}
],
"name": "Timestamp Disclosure - Unix",
"otherinfo": "<p>00000000, which evaluates to: 1970-01-01 00:00:00</p>",
"pluginid": "10096",
"reference": "<p>https://www.owasp.org/index.php/Top_10_2013-A6-Sensitive_Data_Exposure</p><p>http://projects.webappsec.org/w/page/13246936/Information%20Leakage</p>",
"riskcode": "0",
"riskdesc": "Informational (Low)",
"solution": "<p>Manually confirm that the timestamp data is not sensitive, and that the data cannot be aggregated to disclose exploitable patterns.</p>",
"sourceid": "3",
"wascid": "13"
}
]
}
],
"spider": {
"progress": "100",
"result": {
"urlsInScope": [
{
"method": "GET",
"processed": "false",
"reasonNotProcessed": "Not Text",
"statusCode": "404",
"statusReason": "",
"url": "http://goat:8080/"
},
{
"method": "GET",
"processed": "true",
"reasonNotProcessed": "",
"statusCode": "302",
"statusReason": "",
"url": "http://goat:8080/WebGoat/"
},
{
"method": "GET",
"processed": "true",
"reasonNotProcessed": "",
"statusCode": "302",
"statusReason": "",
"url": "http://goat:8080/WebGoat/attack"
},
{
"method": "GET",
"processed": "true",
"reasonNotProcessed": "",
"statusCode": "200",
"statusReason": "",
"url": "http://goat:8080/WebGoat/css/animate.css"
},
{
"method": "GET",
"processed": "true",
"reasonNotProcessed": "",
"statusCode": "200",
"statusReason": "",
"url": "http://goat:8080/WebGoat/css/coderay.css"
},
{
"method": "GET",
"processed": "true",
"reasonNotProcessed": "",
"statusCode": "200",
"statusReason": "",
"url": "http://goat:8080/WebGoat/css/font-awesome.min.css"
},
{
"method": "GET",
"processed": "true",
"reasonNotProcessed": "",
"statusCode": "200",
"statusReason": "",
"url": "http://goat:8080/WebGoat/css/lessons.css"
},
{
"method": "GET",
"processed": "true",
"reasonNotProcessed": "",
"statusCode": "200",
"statusReason": "",
"url": "http://goat:8080/WebGoat/css/main.css"
},
{
"method": "GET",
"processed": "true",
"reasonNotProcessed": "",
"statusCode": "404",
"statusReason": "",
"url": "http://goat:8080/WebGoat/images/favicon.ico"
},
{
"method": "GET",
"processed": "true",
"reasonNotProcessed": "",
"statusCode": "200",
"statusReason": "",
"url": "http://goat:8080/WebGoat/js/html5shiv.js"
},
{
"method": "GET",
"processed": "true",
"reasonNotProcessed": "",
"statusCode": "200",
"statusReason": "",
"url": "http://goat:8080/WebGoat/js/libs/require.min.js"
},
{
"method": "GET",
"processed": "true",
"reasonNotProcessed": "",
"statusCode": "200",
"statusReason": "",
"url": "http://goat:8080/WebGoat/js/modernizr-2.6.2.min.js"
},
{
"method": "GET",
"processed": "true",
"reasonNotProcessed": "",
"statusCode": "200",
"statusReason": "",
"url": "http://goat:8080/WebGoat/js/respond.min.js"
},
{
"method": "GET",
"processed": "true",
"reasonNotProcessed": "",
"statusCode": "200",
"statusReason": "",
"url": "http://goat:8080/WebGoat/login"
},
{
"method": "POST",
"processed": "true",
"reasonNotProcessed": "",
"statusCode": "302",
"statusReason": "",
"url": "http://goat:8080/WebGoat/login"
},
{
"method": "GET",
"processed": "false",
"reasonNotProcessed": "Max Depth",
"statusCode": "200",
"statusReason": "",
"url": "http://goat:8080/WebGoat/login?error"
},
{
"method": "GET",
"processed": "true",
"reasonNotProcessed": "",
"statusCode": "302",
"statusReason": "",
"url": "http://goat:8080/WebGoat/login?logout"
},
{
"method": "GET",
"processed": "true",
"reasonNotProcessed": "",
"statusCode": "302",
"statusReason": "",
"url": "http://goat:8080/WebGoat/logout"
},
{
"method": "GET",
"processed": "true",
"reasonNotProcessed": "",
"statusCode": "200",
"statusReason": "",
"url": "http://goat:8080/WebGoat/plugins/bootstrap/css/bootstrap.min.css"
},
{
"method": "POST",
"processed": "false",
"reasonNotProcessed": "Max Depth",
"statusCode": "200",
"statusReason": "",
"url": "http://goat:8080/WebGoat/register.mvc"
},
{
"method": "GET",
"processed": "true",
"reasonNotProcessed": "",
"statusCode": "200",
"statusReason": "",
"url": "http://goat:8080/WebGoat/registration"
},
{
"method": "GET",
"processed": "true",
"reasonNotProcessed": "",
"statusCode": "200",
"statusReason": "",
"url": "http://goat:8080/WebGoat/start.mvc"
},
{
"method": "GET",
"processed": "true",
"reasonNotProcessed": "",
"statusCode": "302",
"statusReason": "",
"url": "http://goat:8080/WebGoat/welcome.mvc"
},
{
"method": "GET",
"processed": "true",
"reasonNotProcessed": "",
"statusCode": "302",
"statusReason": "",
"url": "http://goat:8080/WebGoat"
},
{
"method": "GET",
"processed": "true",
"reasonNotProcessed": "",
"statusCode": "404",
"statusReason": "",
"url": "http://goat:8080/robots.txt"
},
{
"method": "GET",
"processed": "true",
"reasonNotProcessed": "",
"statusCode": "404",
"statusReason": "",
"url": "http://goat:8080/sitemap.xml"
},
{
"method": "GET",
"processed": "false",
"reasonNotProcessed": "Not Text",
"statusCode": "404",
"statusReason": "",
"url": "http://goat:8080"
}
],
"urlsIoError": [],
"urlsOutOfScope": [
"http://daneden.me/animate",
"http://fontawesome.io/",
"http://fontawesome.io/license",
"http://getbootstrap.com/",
"https://github.com/nickpettit/glide",
"https://github.com/twbs/bootstrap/blob/master/LICENSE"
]
},
"state": "FINISHED"
},
"version": "2.5",
"vulnerabilities": [
{
"category": "dast",
"confidence": "medium",
"cve": "20012",
"description": "A cross-site request forgery is an attack that involves forcing a victim to send an HTTP request to a target destination without their knowledge or intent in order to perform an action as the victim. The underlying cause is application functionality using predictable URL/form actions in a repeatable way. The nature of the attack is that CSRF exploits the trust that a web site has for a user. By contrast, cross-site scripting (XSS) exploits the trust that a user has for a web site. Like XSS, CSRF attacks are not necessarily cross-site, but they can be. Cross-site request forgery is also known as CSRF, XSRF, one-click attack, session riding, confused deputy, and sea surf. CSRF attacks are effective in a number of situations, including: * The victim has an active session on the target site. * The victim is authenticated via HTTP auth on the target site. * The victim is on the same local network as the target site. CSRF has primarily been used to perform an action against a target site using the victim's privileges, but recent techniques have been discovered to disclose information by gaining access to the response. The risk of information disclosure is dramatically increased when the target site is vulnerable to XSS, because XSS can be used as a platform for CSRF, allowing the attack to operate within the bounds of the same-origin policy.",
"identifiers": [
{
"name": "Anti CSRF Tokens Scanner",
"type": "ZAProxy_PluginId",
"url": "https://github.com/zaproxy/zaproxy/blob/w2019-01-14/docs/scanners.md",
"value": "20012"
},
{
"name": "CWE-352",
"type": "CWE",
"url": "https://cwe.mitre.org/data/definitions/352.html",
"value": "352"
},
{
"name": "WASC-9",
"type": "WASC",
"url": "https://projects.webappsec.org/Cross-Site-Request-Forgery",
"value": "9"
}
],
"links": [
{
"url": "http://projects.webappsec.org/Cross-Site-Request-Forgery"
},
{
"url": "http://cwe.mitre.org/data/definitions/352.html"
}
],
"location": {
"hostname": "http://goat:8080",
"method": "GET",
"param": "",
"path": "/WebGoat/login"
},
"message": "Anti CSRF Tokens Scanner",
"scanner": {
"id": "zaproxy",
"name": "ZAProxy"
},
"severity": "high",
"solution": "Phase: Architecture and Design Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid. For example, use anti-CSRF packages such as the OWASP CSRFGuard. Phase: Implementation Ensure that your application is free of cross-site scripting issues, because most CSRF defenses can be bypassed using attacker-controlled script. Phase: Architecture and Design Generate a unique nonce for each form, place the nonce into the form, and verify the nonce upon receipt of the form. Be sure that the nonce is not predictable (CWE-330). Note that this can be bypassed using XSS. Identify especially dangerous operations. When the user performs a dangerous operation, send a separate confirmation request to ensure that the user intended to perform that operation. Note that this can be bypassed using XSS. Use the ESAPI Session Management control. This control includes a component for CSRF. Do not use the GET method for any request that triggers a state change. Phase: Implementation Check the HTTP Referer header to see if the request originated from an expected page. This could break legitimate functionality, because users or proxies may have disabled sending the Referer for privacy reasons."
},
{
"category": "dast",
"confidence": "medium",
"cve": "20012",
"description": "A cross-site request forgery is an attack that involves forcing a victim to send an HTTP request to a target destination without their knowledge or intent in order to perform an action as the victim. The underlying cause is application functionality using predictable URL/form actions in a repeatable way. The nature of the attack is that CSRF exploits the trust that a web site has for a user. By contrast, cross-site scripting (XSS) exploits the trust that a user has for a web site. Like XSS, CSRF attacks are not necessarily cross-site, but they can be. Cross-site request forgery is also known as CSRF, XSRF, one-click attack, session riding, confused deputy, and sea surf. CSRF attacks are effective in a number of situations, including: * The victim has an active session on the target site. * The victim is authenticated via HTTP auth on the target site. * The victim is on the same local network as the target site. CSRF has primarily been used to perform an action against a target site using the victim's privileges, but recent techniques have been discovered to disclose information by gaining access to the response. The risk of information disclosure is dramatically increased when the target site is vulnerable to XSS, because XSS can be used as a platform for CSRF, allowing the attack to operate within the bounds of the same-origin policy.",
"identifiers": [
{
"name": "Anti CSRF Tokens Scanner",
"type": "ZAProxy_PluginId",
"url": "https://github.com/zaproxy/zaproxy/blob/w2019-01-14/docs/scanners.md",
"value": "20012"
},
{
"name": "CWE-352",
"type": "CWE",
"url": "https://cwe.mitre.org/data/definitions/352.html",
"value": "352"
},
{
"name": "WASC-9",
"type": "WASC",
"url": "https://projects.webappsec.org/Cross-Site-Request-Forgery",
"value": "9"
}
],
"links": [
{
"url": "http://projects.webappsec.org/Cross-Site-Request-Forgery"
},
{
"url": "http://cwe.mitre.org/data/definitions/352.html"
}
],
"location": {
"hostname": "http://goat:8080",
"method": "GET",
"param": "",
"path": "/WebGoat/login?error"
},
"message": "Anti CSRF Tokens Scanner",
"scanner": {
"id": "zaproxy",
"name": "ZAProxy"
},
"severity": "high",
"solution": "Phase: Architecture and Design Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid. For example, use anti-CSRF packages such as the OWASP CSRFGuard. Phase: Implementation Ensure that your application is free of cross-site scripting issues, because most CSRF defenses can be bypassed using attacker-controlled script. Phase: Architecture and Design Generate a unique nonce for each form, place the nonce into the form, and verify the nonce upon receipt of the form. Be sure that the nonce is not predictable (CWE-330). Note that this can be bypassed using XSS. Identify especially dangerous operations. When the user performs a dangerous operation, send a separate confirmation request to ensure that the user intended to perform that operation. Note that this can be bypassed using XSS. Use the ESAPI Session Management control. This control includes a component for CSRF. Do not use the GET method for any request that triggers a state change. Phase: Implementation Check the HTTP Referer header to see if the request originated from an expected page. This could break legitimate functionality, because users or proxies may have disabled sending the Referer for privacy reasons."
},
{
"category": "dast",
"confidence": "medium",
"cve": "20012",
"description": "A cross-site request forgery is an attack that involves forcing a victim to send an HTTP request to a target destination without their knowledge or intent in order to perform an action as the victim. The underlying cause is application functionality using predictable URL/form actions in a repeatable way. The nature of the attack is that CSRF exploits the trust that a web site has for a user. By contrast, cross-site scripting (XSS) exploits the trust that a user has for a web site. Like XSS, CSRF attacks are not necessarily cross-site, but they can be. Cross-site request forgery is also known as CSRF, XSRF, one-click attack, session riding, confused deputy, and sea surf. CSRF attacks are effective in a number of situations, including: * The victim has an active session on the target site. * The victim is authenticated via HTTP auth on the target site. * The victim is on the same local network as the target site. CSRF has primarily been used to perform an action against a target site using the victim's privileges, but recent techniques have been discovered to disclose information by gaining access to the response. The risk of information disclosure is dramatically increased when the target site is vulnerable to XSS, because XSS can be used as a platform for CSRF, allowing the attack to operate within the bounds of the same-origin policy.",
"identifiers": [
{
"name": "Anti CSRF Tokens Scanner",
"type": "ZAProxy_PluginId",
"url": "https://github.com/zaproxy/zaproxy/blob/w2019-01-14/docs/scanners.md",
"value": "20012"
},
{
"name": "CWE-352",
"type": "CWE",
"url": "https://cwe.mitre.org/data/definitions/352.html",
"value": "352"
},
{
"name": "WASC-9",
"type": "WASC",
"url": "https://projects.webappsec.org/Cross-Site-Request-Forgery",
"value": "9"
}
],
"links": [
{
"url": "http://projects.webappsec.org/Cross-Site-Request-Forgery"
},
{
"url": "http://cwe.mitre.org/data/definitions/352.html"
}
],
"location": {
"hostname": "http://goat:8080",
"method": "GET",
"param": "",
"path": "/WebGoat/registration"
},
"message": "Anti CSRF Tokens Scanner",
"scanner": {
"id": "zaproxy",
"name": "ZAProxy"
},
"severity": "high",
"solution": "Phase: Architecture and Design Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid. For example, use anti-CSRF packages such as the OWASP CSRFGuard. Phase: Implementation Ensure that your application is free of cross-site scripting issues, because most CSRF defenses can be bypassed using attacker-controlled script. Phase: Architecture and Design Generate a unique nonce for each form, place the nonce into the form, and verify the nonce upon receipt of the form. Be sure that the nonce is not predictable (CWE-330). Note that this can be bypassed using XSS. Identify especially dangerous operations. When the user performs a dangerous operation, send a separate confirmation request to ensure that the user intended to perform that operation. Note that this can be bypassed using XSS. Use the ESAPI Session Management control. This control includes a component for CSRF. Do not use the GET method for any request that triggers a state change. Phase: Implementation Check the HTTP Referer header to see if the request originated from an expected page. This could break legitimate functionality, because users or proxies may have disabled sending the Referer for privacy reasons."
},
{
"category": "dast",
"confidence": "medium",
"cve": "20012",
"description": "A cross-site request forgery is an attack that involves forcing a victim to send an HTTP request to a target destination without their knowledge or intent in order to perform an action as the victim. The underlying cause is application functionality using predictable URL/form actions in a repeatable way. The nature of the attack is that CSRF exploits the trust that a web site has for a user. By contrast, cross-site scripting (XSS) exploits the trust that a user has for a web site. Like XSS, CSRF attacks are not necessarily cross-site, but they can be. Cross-site request forgery is also known as CSRF, XSRF, one-click attack, session riding, confused deputy, and sea surf. CSRF attacks are effective in a number of situations, including: * The victim has an active session on the target site. * The victim is authenticated via HTTP auth on the target site. * The victim is on the same local network as the target site. CSRF has primarily been used to perform an action against a target site using the victim's privileges, but recent techniques have been discovered to disclose information by gaining access to the response. The risk of information disclosure is dramatically increased when the target site is vulnerable to XSS, because XSS can be used as a platform for CSRF, allowing the attack to operate within the bounds of the same-origin policy.",
"identifiers": [
{
"name": "Anti CSRF Tokens Scanner",
"type": "ZAProxy_PluginId",
"url": "https://github.com/zaproxy/zaproxy/blob/w2019-01-14/docs/scanners.md",
"value": "20012"
},
{
"name": "CWE-352",
"type": "CWE",
"url": "https://cwe.mitre.org/data/definitions/352.html",
"value": "352"
},
{
"name": "WASC-9",
"type": "WASC",
"url": "https://projects.webappsec.org/Cross-Site-Request-Forgery",
"value": "9"
}
],
"links": [
{
"url": "http://projects.webappsec.org/Cross-Site-Request-Forgery"
},
{
"url": "http://cwe.mitre.org/data/definitions/352.html"
}
],
"location": {
"hostname": "http://goat:8080",
"method": "POST",
"param": "",
"path": "/WebGoat/register.mvc"
},
"message": "Anti CSRF Tokens Scanner",
"scanner": {
"id": "zaproxy",
"name": "ZAProxy"
},
"severity": "high",
"solution": "Phase: Architecture and Design Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid. For example, use anti-CSRF packages such as the OWASP CSRFGuard. Phase: Implementation Ensure that your application is free of cross-site scripting issues, because most CSRF defenses can be bypassed using attacker-controlled script. Phase: Architecture and Design Generate a unique nonce for each form, place the nonce into the form, and verify the nonce upon receipt of the form. Be sure that the nonce is not predictable (CWE-330). Note that this can be bypassed using XSS. Identify especially dangerous operations. When the user performs a dangerous operation, send a separate confirmation request to ensure that the user intended to perform that operation. Note that this can be bypassed using XSS. Use the ESAPI Session Management control. This control includes a component for CSRF. Do not use the GET method for any request that triggers a state change. Phase: Implementation Check the HTTP Referer header to see if the request originated from an expected page. This could break legitimate functionality, because users or proxies may have disabled sending the Referer for privacy reasons."
},
{
"category": "dast",
"confidence": "medium",
"cve": "10202",
"description": "No Anti-CSRF tokens were found in a HTML submission form. A cross-site request forgery is an attack that involves forcing a victim to send an HTTP request to a target destination without their knowledge or intent in order to perform an action as the victim. The underlying cause is application functionality using predictable URL/form actions in a repeatable way. The nature of the attack is that CSRF exploits the trust that a web site has for a user. By contrast, cross-site scripting (XSS) exploits the trust that a user has for a web site. Like XSS, CSRF attacks are not necessarily cross-site, but they can be. Cross-site request forgery is also known as CSRF, XSRF, one-click attack, session riding, confused deputy, and sea surf. CSRF attacks are effective in a number of situations, including: * The victim has an active session on the target site. * The victim is authenticated via HTTP auth on the target site. * The victim is on the same local network as the target site. CSRF has primarily been used to perform an action against a target site using the victim's privileges, but recent techniques have been discovered to disclose information by gaining access to the response. The risk of information disclosure is dramatically increased when the target site is vulnerable to XSS, because XSS can be used as a platform for CSRF, allowing the attack to operate within the bounds of the same-origin policy.",
"identifiers": [
{
"name": "Absence of Anti-CSRF Tokens",
"type": "ZAProxy_PluginId",
"url": "https://github.com/zaproxy/zaproxy/blob/w2019-01-14/docs/scanners.md",
"value": "10202"
},
{
"name": "CWE-352",
"type": "CWE",
"url": "https://cwe.mitre.org/data/definitions/352.html",
"value": "352"
},
{
"name": "WASC-9",
"type": "WASC",
"url": "https://projects.webappsec.org/Cross-Site-Request-Forgery",
"value": "9"
}
],
"links": [
{
"url": "http://projects.webappsec.org/Cross-Site-Request-Forgery"
},
{
"url": "http://cwe.mitre.org/data/definitions/352.html"
}
],
"location": {
"hostname": "http://goat:8080",
"method": "GET",
"param": "",
"path": "/WebGoat/login"
},
"message": "Absence of Anti-CSRF Tokens",
"scanner": {
"id": "zaproxy",
"name": "ZAProxy"
},
"severity": "low",
"solution": "Phase: Architecture and Design Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid. For example, use anti-CSRF packages such as the OWASP CSRFGuard. Phase: Implementation Ensure that your application is free of cross-site scripting issues, because most CSRF defenses can be bypassed using attacker-controlled script. Phase: Architecture and Design Generate a unique nonce for each form, place the nonce into the form, and verify the nonce upon receipt of the form. Be sure that the nonce is not predictable (CWE-330). Note that this can be bypassed using XSS. Identify especially dangerous operations. When the user performs a dangerous operation, send a separate confirmation request to ensure that the user intended to perform that operation. Note that this can be bypassed using XSS. Use the ESAPI Session Management control. This control includes a component for CSRF. Do not use the GET method for any request that triggers a state change. Phase: Implementation Check the HTTP Referer header to see if the request originated from an expected page. This could break legitimate functionality, because users or proxies may have disabled sending the Referer for privacy reasons."
},
{
"category": "dast",
"confidence": "medium",
"cve": "10202",
"description": "No Anti-CSRF tokens were found in a HTML submission form. A cross-site request forgery is an attack that involves forcing a victim to send an HTTP request to a target destination without their knowledge or intent in order to perform an action as the victim. The underlying cause is application functionality using predictable URL/form actions in a repeatable way. The nature of the attack is that CSRF exploits the trust that a web site has for a user. By contrast, cross-site scripting (XSS) exploits the trust that a user has for a web site. Like XSS, CSRF attacks are not necessarily cross-site, but they can be. Cross-site request forgery is also known as CSRF, XSRF, one-click attack, session riding, confused deputy, and sea surf. CSRF attacks are effective in a number of situations, including: * The victim has an active session on the target site. * The victim is authenticated via HTTP auth on the target site. * The victim is on the same local network as the target site. CSRF has primarily been used to perform an action against a target site using the victim's privileges, but recent techniques have been discovered to disclose information by gaining access to the response. The risk of information disclosure is dramatically increased when the target site is vulnerable to XSS, because XSS can be used as a platform for CSRF, allowing the attack to operate within the bounds of the same-origin policy.",
"identifiers": [
{
"name": "Absence of Anti-CSRF Tokens",
"type": "ZAProxy_PluginId",
"url": "https://github.com/zaproxy/zaproxy/blob/w2019-01-14/docs/scanners.md",
"value": "10202"
},
{
"name": "CWE-352",
"type": "CWE",
"url": "https://cwe.mitre.org/data/definitions/352.html",
"value": "352"
},
{
"name": "WASC-9",
"type": "WASC",
"url": "https://projects.webappsec.org/Cross-Site-Request-Forgery",
"value": "9"
}
],
"links": [
{
"url": "http://projects.webappsec.org/Cross-Site-Request-Forgery"
},
{
"url": "http://cwe.mitre.org/data/definitions/352.html"
}
],
"location": {
"hostname": "http://goat:8080",
"method": "GET",
"param": "",
"path": "/WebGoat/login?error"
},
"message": "Absence of Anti-CSRF Tokens",
"scanner": {
"id": "zaproxy",
"name": "ZAProxy"
},
"severity": "low",
"solution": "Phase: Architecture and Design Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid. For example, use anti-CSRF packages such as the OWASP CSRFGuard. Phase: Implementation Ensure that your application is free of cross-site scripting issues, because most CSRF defenses can be bypassed using attacker-controlled script. Phase: Architecture and Design Generate a unique nonce for each form, place the nonce into the form, and verify the nonce upon receipt of the form. Be sure that the nonce is not predictable (CWE-330). Note that this can be bypassed using XSS. Identify especially dangerous operations. When the user performs a dangerous operation, send a separate confirmation request to ensure that the user intended to perform that operation. Note that this can be bypassed using XSS. Use the ESAPI Session Management control. This control includes a component for CSRF. Do not use the GET method for any request that triggers a state change. Phase: Implementation Check the HTTP Referer header to see if the request originated from an expected page. This could break legitimate functionality, because users or proxies may have disabled sending the Referer for privacy reasons."
},
{
"category": "dast",
"confidence": "medium",
"cve": "10202",
"description": "No Anti-CSRF tokens were found in a HTML submission form. A cross-site request forgery is an attack that involves forcing a victim to send an HTTP request to a target destination without their knowledge or intent in order to perform an action as the victim. The underlying cause is application functionality using predictable URL/form actions in a repeatable way. The nature of the attack is that CSRF exploits the trust that a web site has for a user. By contrast, cross-site scripting (XSS) exploits the trust that a user has for a web site. Like XSS, CSRF attacks are not necessarily cross-site, but they can be. Cross-site request forgery is also known as CSRF, XSRF, one-click attack, session riding, confused deputy, and sea surf. CSRF attacks are effective in a number of situations, including: * The victim has an active session on the target site. * The victim is authenticated via HTTP auth on the target site. * The victim is on the same local network as the target site. CSRF has primarily been used to perform an action against a target site using the victim's privileges, but recent techniques have been discovered to disclose information by gaining access to the response. The risk of information disclosure is dramatically increased when the target site is vulnerable to XSS, because XSS can be used as a platform for CSRF, allowing the attack to operate within the bounds of the same-origin policy.",
"identifiers": [
{
"name": "Absence of Anti-CSRF Tokens",
"type": "ZAProxy_PluginId",
"url": "https://github.com/zaproxy/zaproxy/blob/w2019-01-14/docs/scanners.md",
"value": "10202"
},
{
"name": "CWE-352",
"type": "CWE",
"url": "https://cwe.mitre.org/data/definitions/352.html",
"value": "352"
},
{
"name": "WASC-9",
"type": "WASC",
"url": "https://projects.webappsec.org/Cross-Site-Request-Forgery",
"value": "9"
}
],
"links": [
{
"url": "http://projects.webappsec.org/Cross-Site-Request-Forgery"
},
{
"url": "http://cwe.mitre.org/data/definitions/352.html"
}
],
"location": {
"hostname": "http://goat:8080",
"method": "GET",
"param": "",
"path": "/WebGoat/registration"
},
"message": "Absence of Anti-CSRF Tokens",
"scanner": {
"id": "zaproxy",
"name": "ZAProxy"
},
"severity": "low",
"solution": "Phase: Architecture and Design Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid. For example, use anti-CSRF packages such as the OWASP CSRFGuard. Phase: Implementation Ensure that your application is free of cross-site scripting issues, because most CSRF defenses can be bypassed using attacker-controlled script. Phase: Architecture and Design Generate a unique nonce for each form, place the nonce into the form, and verify the nonce upon receipt of the form. Be sure that the nonce is not predictable (CWE-330). Note that this can be bypassed using XSS. Identify especially dangerous operations. When the user performs a dangerous operation, send a separate confirmation request to ensure that the user intended to perform that operation. Note that this can be bypassed using XSS. Use the ESAPI Session Management control. This control includes a component for CSRF. Do not use the GET method for any request that triggers a state change. Phase: Implementation Check the HTTP Referer header to see if the request originated from an expected page. This could break legitimate functionality, because users or proxies may have disabled sending the Referer for privacy reasons."
},
{
"category": "dast",
"confidence": "medium",
"cve": "10202",
"description": "No Anti-CSRF tokens were found in a HTML submission form. A cross-site request forgery is an attack that involves forcing a victim to send an HTTP request to a target destination without their knowledge or intent in order to perform an action as the victim. The underlying cause is application functionality using predictable URL/form actions in a repeatable way. The nature of the attack is that CSRF exploits the trust that a web site has for a user. By contrast, cross-site scripting (XSS) exploits the trust that a user has for a web site. Like XSS, CSRF attacks are not necessarily cross-site, but they can be. Cross-site request forgery is also known as CSRF, XSRF, one-click attack, session riding, confused deputy, and sea surf. CSRF attacks are effective in a number of situations, including: * The victim has an active session on the target site. * The victim is authenticated via HTTP auth on the target site. * The victim is on the same local network as the target site. CSRF has primarily been used to perform an action against a target site using the victim's privileges, but recent techniques have been discovered to disclose information by gaining access to the response. The risk of information disclosure is dramatically increased when the target site is vulnerable to XSS, because XSS can be used as a platform for CSRF, allowing the attack to operate within the bounds of the same-origin policy.",
"identifiers": [
{
"name": "Absence of Anti-CSRF Tokens",
"type": "ZAProxy_PluginId",
"url": "https://github.com/zaproxy/zaproxy/blob/w2019-01-14/docs/scanners.md",
"value": "10202"
},
{
"name": "CWE-352",
"type": "CWE",
"url": "https://cwe.mitre.org/data/definitions/352.html",
"value": "352"
},
{
"name": "WASC-9",
"type": "WASC",
"url": "https://projects.webappsec.org/Cross-Site-Request-Forgery",
"value": "9"
}
],
"links": [
{
"url": "http://projects.webappsec.org/Cross-Site-Request-Forgery"
},
{
"url": "http://cwe.mitre.org/data/definitions/352.html"
}
],
"location": {
"hostname": "http://goat:8080",
"method": "POST",
"param": "",
"path": "/WebGoat/register.mvc"
},
"message": "Absence of Anti-CSRF Tokens",
"scanner": {
"id": "zaproxy",
"name": "ZAProxy"
},
"severity": "low",
"solution": "Phase: Architecture and Design Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid. For example, use anti-CSRF packages such as the OWASP CSRFGuard. Phase: Implementation Ensure that your application is free of cross-site scripting issues, because most CSRF defenses can be bypassed using attacker-controlled script. Phase: Architecture and Design Generate a unique nonce for each form, place the nonce into the form, and verify the nonce upon receipt of the form. Be sure that the nonce is not predictable (CWE-330). Note that this can be bypassed using XSS. Identify especially dangerous operations. When the user performs a dangerous operation, send a separate confirmation request to ensure that the user intended to perform that operation. Note that this can be bypassed using XSS. Use the ESAPI Session Management control. This control includes a component for CSRF. Do not use the GET method for any request that triggers a state change. Phase: Implementation Check the HTTP Referer header to see if the request originated from an expected page. This could break legitimate functionality, because users or proxies may have disabled sending the Referer for privacy reasons."
},
{
"category": "dast",
"confidence": "medium",
"cve": "10010",
"description": "A cookie has been set without the HttpOnly flag, which means that the cookie can be accessed by JavaScript. If a malicious script can be run on this page then the cookie will be accessible and can be transmitted to another site. If this is a session cookie then session hijacking may be possible.",
"identifiers": [
{
"name": "Cookie No HttpOnly Flag",
"type": "ZAProxy_PluginId",
"url": "https://github.com/zaproxy/zaproxy/blob/w2019-01-14/docs/scanners.md",
"value": "10010"
},
{
"name": "CWE-16",
"type": "CWE",
"url": "https://cwe.mitre.org/data/definitions/16.html",
"value": "16"
},
{
"name": "WASC-13",
"type": "WASC",
"url": "https://projects.webappsec.org/Information-Leakage",
"value": "13"
}
],
"links": [
{
"url": "http://www.owasp.org/index.php/HttpOnly"
}
],
"location": {
"hostname": "http://goat:8080",
"method": "GET",
"param": "JSESSIONID",
"path": "/WebGoat/login?logout"
},
"message": "Cookie No HttpOnly Flag",
"scanner": {
"id": "zaproxy",
"name": "ZAProxy"
},
"severity": "low",
"solution": "Ensure that the HttpOnly flag is set for all cookies."
},
{
"category": "dast",
"confidence": "medium",
"cve": "10010",
"description": "A cookie has been set without the HttpOnly flag, which means that the cookie can be accessed by JavaScript. If a malicious script can be run on this page then the cookie will be accessible and can be transmitted to another site. If this is a session cookie then session hijacking may be possible.",
"evidence": {
"request": {
"headers": [
{
"name": "Accept",
"value": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
},
{
"name": "Accept-Language",
"value": "en-US,en;q=0.5"
},
{
"name": "Connection",
"value": "keep-alive"
},
{
"name": "Cookie",
"value": "JSESSIONID=BB38BE6D77E83FA7522D1429AA5F2EAF"
},
{
"name": "Host",
"value": "goat:8080"
},
{
"name": "Referer",
"value": "http://goat:8080/WebGoat/logout"
},
{
"name": "Upgrade-Insecure-Requests",
"value": "1"
},
{
"name": "User-Agent",
"value": "Mozilla/5.0 (X11; Linux x86_64; rv:59.0) Gecko/20100101 Firefox/59.0"
}
],
"method": "GET",
"url": "http://goat:8080/WebGoat/logout"
},
"response": {
"headers": [
{
"name": "Connection",
"value": "keep-alive"
},
{
"name": "Content-Length",
"value": "0"
},
{
"name": "Date",
"value": "Thu, 07 May 2020 07:18:06 GMT"
},
{
"name": "Gitlab-DAST-Permission",
"value": "allow"
},
{
"name": "Location",
"value": "http://goat:8080/WebGoat/login"
},
{
"name": "Server",
"value": "nginx/1.17.6"
},
{
"name": "Set-Cookie",
"value": "JSESSIONID=1624E8274D30BB5A029F5A18BB7E4400; Path=/WebGoat"
},
{
"name": "X-Content-Type-Options",
"value": "nosniff"
},
{
"name": "X-Frame-Options",
"value": "DENY"
},
{
"name": "X-XSS-Protection",
"value": "1; mode=block"
}
],
"reason_phrase": "Found",
"status_code": 302
},
"summary": "Set-Cookie: JSESSIONID"
},
"identifiers": [
{
"name": "Cookie No HttpOnly Flag",
"type": "ZAProxy_PluginId",
"url": "https://github.com/zaproxy/zaproxy/blob/w2019-01-14/docs/scanners.md",
"value": "10010"
},
{
"name": "CWE-16",
"type": "CWE",
"url": "https://cwe.mitre.org/data/definitions/16.html",
"value": "16"
},
{
"name": "WASC-13",
"type": "WASC",
"url": "https://projects.webappsec.org/Information-Leakage",
"value": "13"
}
],
"links": [
{
"url": "http://www.owasp.org/index.php/HttpOnly"
}
],
"location": {
"hostname": "http://goat:8080",
"method": "GET",
"param": "JSESSIONID",
"path": "/WebGoat/logout"
},
"message": "Cookie No HttpOnly Flag",
"scanner": {
"id": "zaproxy",
"name": "ZAProxy"
},
"severity": "low",
"solution": "Ensure that the HttpOnly flag is set for all cookies."
},
{
"category": "dast",
"confidence": "medium",
"cve": "10054",
"description": "A cookie has been set without the SameSite attribute, which means that the cookie can be sent as a result of a 'cross-site' request. The SameSite attribute is an effective counter measure to cross-site request forgery, cross-site script inclusion, and timing attacks.",
"identifiers": [
{
"name": "Cookie Without SameSite Attribute",
"type": "ZAProxy_PluginId",
"url": "https://github.com/zaproxy/zaproxy/blob/w2019-01-14/docs/scanners.md",
"value": "10054"
},
{
"name": "CWE-16",
"type": "CWE",
"url": "https://cwe.mitre.org/data/definitions/16.html",
"value": "16"
},
{
"name": "WASC-13",
"type": "WASC",
"url": "https://projects.webappsec.org/Information-Leakage",
"value": "13"
}
],
"links": [
{
"url": "https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site"
}
],
"location": {
"hostname": "http://goat:8080",
"method": "GET",
"param": "JSESSIONID",
"path": "/WebGoat/login?logout"
},
"message": "Cookie Without SameSite Attribute",
"scanner": {
"id": "zaproxy",
"name": "ZAProxy"
},
"severity": "low",
"solution": "Ensure that the SameSite attribute is set to either 'lax' or ideally 'strict' for all cookies."
},
{
"category": "dast",
"confidence": "medium",
"cve": "10054",
"description": "A cookie has been set without the SameSite attribute, which means that the cookie can be sent as a result of a 'cross-site' request. The SameSite attribute is an effective counter measure to cross-site request forgery, cross-site script inclusion, and timing attacks.",
"identifiers": [
{
"name": "Cookie Without SameSite Attribute",
"type": "ZAProxy_PluginId",
"url": "https://github.com/zaproxy/zaproxy/blob/w2019-01-14/docs/scanners.md",
"value": "10054"
},
{
"name": "CWE-16",
"type": "CWE",
"url": "https://cwe.mitre.org/data/definitions/16.html",
"value": "16"
},
{
"name": "WASC-13",
"type": "WASC",
"url": "https://projects.webappsec.org/Information-Leakage",
"value": "13"
}
],
"links": [
{
"url": "https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site"
}
],
"location": {
"hostname": "http://goat:8080",
"method": "GET",
"param": "JSESSIONID",
"path": "/WebGoat/logout"
},
"message": "Cookie Without SameSite Attribute",
"scanner": {
"id": "zaproxy",
"name": "ZAProxy"
},
"severity": "low",
"solution": "Ensure that the SameSite attribute is set to either 'lax' or ideally 'strict' for all cookies."
},
{
"category": "dast",
"confidence": "low",
"cve": "90011",
"description": "This check identifies responses where the HTTP Content-Type header declares a charset different from the charset defined by the body of the HTML or XML. When there's a charset mismatch between the HTTP header and content body Web browsers can be forced into an undesirable content-sniffing mode to determine the content's correct character set. An attacker could manipulate content on the page to be interpreted in an encoding of their choice. For example, if an attacker can control content at the beginning of the page, they could inject script using UTF-7 encoded text and manipulate some browsers into interpreting that text.",
"identifiers": [
{
"name": "Charset Mismatch (Header Versus Meta Content-Type Charset)",
"type": "ZAProxy_PluginId",
"url": "https://github.com/zaproxy/zaproxy/blob/w2019-01-14/docs/scanners.md",
"value": "90011"
},
{
"name": "CWE-16",
"type": "CWE",
"url": "https://cwe.mitre.org/data/definitions/16.html",
"value": "16"
},
{
"name": "WASC-15",
"type": "WASC",
"url": "https://projects.webappsec.org/Application-Misconfiguration",
"value": "15"
}
],
"links": [
{
"url": "http://code.google.com/p/browsersec/wiki/Part2#Character_set_handling_and_detection"
}
],
"location": {
"hostname": "http://goat:8080",
"method": "GET",
"param": "",
"path": "/WebGoat/start.mvc"
},
"message": "Charset Mismatch (Header Versus Meta Content-Type Charset)",
"scanner": {
"id": "zaproxy",
"name": "ZAProxy"
},
"severity": "info",
"solution": "Force UTF-8 for all text content in both the HTTP header and meta tags in HTML or encoding declarations in XML."
},
{
"category": "dast",
"confidence": "medium",
"cve": "10027",
"description": "The response appears to contain suspicious comments which may help an attacker.",
"identifiers": [
{
"name": "Information Disclosure - Suspicious Comments",
"type": "ZAProxy_PluginId",
"url": "https://github.com/zaproxy/zaproxy/blob/w2019-01-14/docs/scanners.md",
"value": "10027"
},
{
"name": "CWE-200",
"type": "CWE",
"url": "https://cwe.mitre.org/data/definitions/200.html",
"value": "200"
},
{
"name": "WASC-13",
"type": "WASC",
"url": "https://projects.webappsec.org/Information-Leakage",
"value": "13"
}
],
"links": [],
"location": {
"hostname": "http://goat:8080",
"method": "GET",
"param": "",
"path": "/WebGoat/js/html5shiv.js"
},
"message": "Information Disclosure - Suspicious Comments",
"scanner": {
"id": "zaproxy",
"name": "ZAProxy"
},
"severity": "info",
"solution": "Remove all comments that return information that may help an attacker and fix any underlying problems they refer to."
},
{
"category": "dast",
"confidence": "medium",
"cve": "10027",
"description": "The response appears to contain suspicious comments which may help an attacker.",
"identifiers": [
{
"name": "Information Disclosure - Suspicious Comments",
"type": "ZAProxy_PluginId",
"url": "https://github.com/zaproxy/zaproxy/blob/w2019-01-14/docs/scanners.md",
"value": "10027"
},
{
"name": "CWE-200",
"type": "CWE",
"url": "https://cwe.mitre.org/data/definitions/200.html",
"value": "200"
},
{
"name": "WASC-13",
"type": "WASC",
"url": "https://projects.webappsec.org/Information-Leakage",
"value": "13"
}
],
"links": [],
"location": {
"hostname": "http://goat:8080",
"method": "GET",
"param": "",
"path": "/WebGoat/js/modernizr-2.6.2.min.js"
},
"message": "Information Disclosure - Suspicious Comments",
"scanner": {
"id": "zaproxy",
"name": "ZAProxy"
},
"severity": "info",
"solution": "Remove all comments that return information that may help an attacker and fix any underlying problems they refer to."
},
{
"category": "dast",
"confidence": "medium",
"cve": "10027",
"description": "The response appears to contain suspicious comments which may help an attacker.",
"identifiers": [
{
"name": "Information Disclosure - Suspicious Comments",
"type": "ZAProxy_PluginId",
"url": "https://github.com/zaproxy/zaproxy/blob/w2019-01-14/docs/scanners.md",
"value": "10027"
},
{
"name": "CWE-200",
"type": "CWE",
"url": "https://cwe.mitre.org/data/definitions/200.html",
"value": "200"
},
{
"name": "WASC-13",
"type": "WASC",
"url": "https://projects.webappsec.org/Information-Leakage",
"value": "13"
}
],
"links": [],
"location": {
"hostname": "http://goat:8080",
"method": "GET",
"param": "",
"path": "/WebGoat/js/respond.min.js"
},
"message": "Information Disclosure - Suspicious Comments",
"scanner": {
"id": "zaproxy",
"name": "ZAProxy"
},
"severity": "info",
"solution": "Remove all comments that return information that may help an attacker and fix any underlying problems they refer to."
},
{
"category": "dast",
"confidence": "medium",
"cve": "10027",
"description": "The response appears to contain suspicious comments which may help an attacker.",
"identifiers": [
{
"name": "Information Disclosure - Suspicious Comments",
"type": "ZAProxy_PluginId",
"url": "https://github.com/zaproxy/zaproxy/blob/w2019-01-14/docs/scanners.md",
"value": "10027"
},
{
"name": "CWE-200",
"type": "CWE",
"url": "https://cwe.mitre.org/data/definitions/200.html",
"value": "200"
},
{
"name": "WASC-13",
"type": "WASC",
"url": "https://projects.webappsec.org/Information-Leakage",
"value": "13"
}
],
"links": [],
"location": {
"hostname": "http://goat:8080",
"method": "GET",
"param": "",
"path": "/WebGoat/start.mvc"
},
"message": "Information Disclosure - Suspicious Comments",
"scanner": {
"id": "zaproxy",
"name": "ZAProxy"
},
"severity": "info",
"solution": "Remove all comments that return information that may help an attacker and fix any underlying problems they refer to."
},
{
"category": "dast",
"confidence": "low",
"cve": "90033",
"description": "Cookies can be scoped by domain or path. This check is only concerned with domain scope.The domain scope applied to a cookie determines which domains can access it. For example, a cookie can be scoped strictly to a subdomain e.g. www.nottrusted.com, or loosely scoped to a parent domain e.g. nottrusted.com. In the latter case, any subdomain of nottrusted.com can access the cookie. Loosely scoped cookies are common in mega-applications like google.com and live.com. Cookies set from a subdomain like app.foo.bar are transmitted only to that domain by the browser. However, cookies scoped to a parent-level domain may be transmitted to the parent, or any subdomain of the parent.",
"identifiers": [
{
"name": "Loosely Scoped Cookie",
"type": "ZAProxy_PluginId",
"url": "https://github.com/zaproxy/zaproxy/blob/w2019-01-14/docs/scanners.md",
"value": "90033"
},
{
"name": "CWE-565",
"type": "CWE",
"url": "https://cwe.mitre.org/data/definitions/565.html",
"value": "565"
},
{
"name": "WASC-15",
"type": "WASC",
"url": "https://projects.webappsec.org/Application-Misconfiguration",
"value": "15"
}
],
"links": [
{
"url": "https://tools.ietf.org/html/rfc6265#section-4.1"
},
{
"url": "https://www.owasp.org/index.php/Testing_for_cookies_attributes_(OTG-SESS-002)"
},
{
"url": "http://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_cookies"
}
],
"location": {
"hostname": "http://goat:8080",
"method": "GET",
"param": "",
"path": "/WebGoat/login?logout"
},
"message": "Loosely Scoped Cookie",
"scanner": {
"id": "zaproxy",
"name": "ZAProxy"
},
"severity": "info",
"solution": "Always scope cookies to a FQDN (Fully Qualified Domain Name)."
},
{
"category": "dast",
"confidence": "low",
"cve": "90033",
"description": "Cookies can be scoped by domain or path. This check is only concerned with domain scope.The domain scope applied to a cookie determines which domains can access it. For example, a cookie can be scoped strictly to a subdomain e.g. www.nottrusted.com, or loosely scoped to a parent domain e.g. nottrusted.com. In the latter case, any subdomain of nottrusted.com can access the cookie. Loosely scoped cookies are common in mega-applications like google.com and live.com. Cookies set from a subdomain like app.foo.bar are transmitted only to that domain by the browser. However, cookies scoped to a parent-level domain may be transmitted to the parent, or any subdomain of the parent.",
"identifiers": [
{
"name": "Loosely Scoped Cookie",
"type": "ZAProxy_PluginId",
"url": "https://github.com/zaproxy/zaproxy/blob/w2019-01-14/docs/scanners.md",
"value": "90033"
},
{
"name": "CWE-565",
"type": "CWE",
"url": "https://cwe.mitre.org/data/definitions/565.html",
"value": "565"
},
{
"name": "WASC-15",
"type": "WASC",
"url": "https://projects.webappsec.org/Application-Misconfiguration",
"value": "15"
}
],
"links": [
{
"url": "https://tools.ietf.org/html/rfc6265#section-4.1"
},
{
"url": "https://www.owasp.org/index.php/Testing_for_cookies_attributes_(OTG-SESS-002)"
},
{
"url": "http://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_cookies"
}
],
"location": {
"hostname": "http://goat:8080",
"method": "GET",
"param": "",
"path": "/WebGoat/logout"
},
"message": "Loosely Scoped Cookie",
"scanner": {
"id": "zaproxy",
"name": "ZAProxy"
},
"severity": "info",
"solution": "Always scope cookies to a FQDN (Fully Qualified Domain Name)."
},
{
"category": "dast",
"confidence": "low",
"cve": "10096",
"description": "A timestamp was disclosed by the application/web server - Unix",
"identifiers": [
{
"name": "Timestamp Disclosure - Unix",
"type": "ZAProxy_PluginId",
"url": "https://github.com/zaproxy/zaproxy/blob/w2019-01-14/docs/scanners.md",
"value": "10096"
},
{
"name": "CWE-200",
"type": "CWE",
"url": "https://cwe.mitre.org/data/definitions/200.html",
"value": "200"
},
{
"name": "WASC-13",
"type": "WASC",
"url": "https://projects.webappsec.org/Information-Leakage",
"value": "13"
}
],
"links": [
{
"url": "https://www.owasp.org/index.php/Top_10_2013-A6-Sensitive_Data_Exposure"
},
{
"url": "http://projects.webappsec.org/w/page/13246936/Information%20Leakage"
}
],
"location": {
"hostname": "http://goat:8080",
"method": "GET",
"param": "",
"path": "/WebGoat/plugins/bootstrap/css/bootstrap.min.css"
},
"message": "Timestamp Disclosure - Unix",
"scanner": {
"id": "zaproxy",
"name": "ZAProxy"
},
"severity": "info",
"solution": "Manually confirm that the timestamp data is not sensitive, and that the data cannot be aggregated to disclose exploitable patterns."
},
{
"category": "dast",
"confidence": "low",
"cve": "10096",
"description": "A timestamp was disclosed by the application/web server - Unix",
"identifiers": [
{
"name": "Timestamp Disclosure - Unix",
"type": "ZAProxy_PluginId",
"url": "https://github.com/zaproxy/zaproxy/blob/w2019-01-14/docs/scanners.md",
"value": "10096"
},
{
"name": "CWE-200",
"type": "CWE",
"url": "https://cwe.mitre.org/data/definitions/200.html",
"value": "200"
},
{
"name": "WASC-13",
"type": "WASC",
"url": "https://projects.webappsec.org/Information-Leakage",
"value": "13"
}
],
"links": [
{
"url": "https://www.owasp.org/index.php/Top_10_2013-A6-Sensitive_Data_Exposure"
},
{
"url": "http://projects.webappsec.org/w/page/13246936/Information%20Leakage"
}
],
"location": {
"hostname": "http://goat:8080",
"method": "GET",
"param": "",
"path": "/WebGoat/plugins/bootstrap/css/bootstrap.min.css"
},
"message": "Timestamp Disclosure - Unix",
"scanner": {
"id": "zaproxy",
"name": "ZAProxy"
},
"severity": "info",
"solution": "Manually confirm that the timestamp data is not sensitive, and that the data cannot be aggregated to disclose exploitable patterns."
},
{
"category": "dast",
"confidence": "low",
"cve": "10096",
"description": "A timestamp was disclosed by the application/web server - Unix",
"identifiers": [
{
"name": "Timestamp Disclosure - Unix",
"type": "ZAProxy_PluginId",
"url": "https://github.com/zaproxy/zaproxy/blob/w2019-01-14/docs/scanners.md",
"value": "10096"
},
{
"name": "CWE-200",
"type": "CWE",
"url": "https://cwe.mitre.org/data/definitions/200.html",
"value": "200"
},
{
"name": "WASC-13",
"type": "WASC",
"url": "https://projects.webappsec.org/Information-Leakage",
"value": "13"
}
],
"links": [
{
"url": "https://www.owasp.org/index.php/Top_10_2013-A6-Sensitive_Data_Exposure"
},
{
"url": "http://projects.webappsec.org/w/page/13246936/Information%20Leakage"
}
],
"location": {
"hostname": "http://goat:8080",
"method": "GET",
"param": "",
"path": "/WebGoat/plugins/bootstrap/css/bootstrap.min.css"
},
"message": "Timestamp Disclosure - Unix",
"scanner": {
"id": "zaproxy",
"name": "ZAProxy"
},
"severity": "info",
"solution": "Manually confirm that the timestamp data is not sensitive, and that the data cannot be aggregated to disclose exploitable patterns."
},
{
"category": "dast",
"confidence": "low",
"cve": "10096",
"description": "A timestamp was disclosed by the application/web server - Unix",
"identifiers": [
{
"name": "Timestamp Disclosure - Unix",
"type": "ZAProxy_PluginId",
"url": "https://github.com/zaproxy/zaproxy/blob/w2019-01-14/docs/scanners.md",
"value": "10096"
},
{
"name": "CWE-200",
"type": "CWE",
"url": "https://cwe.mitre.org/data/definitions/200.html",
"value": "200"
},
{
"name": "WASC-13",
"type": "WASC",
"url": "https://projects.webappsec.org/Information-Leakage",
"value": "13"
}
],
"links": [
{
"url": "https://www.owasp.org/index.php/Top_10_2013-A6-Sensitive_Data_Exposure"
},
{
"url": "http://projects.webappsec.org/w/page/13246936/Information%20Leakage"
}
],
"location": {
"hostname": "http://goat:8080",
"method": "GET",
"param": "",
"path": "/WebGoat/plugins/bootstrap/css/bootstrap.min.css"
},
"message": "Timestamp Disclosure - Unix",
"scanner": {
"id": "zaproxy",
"name": "ZAProxy"
},
"severity": "info",
"solution": "Manually confirm that the timestamp data is not sensitive, and that the data cannot be aggregated to disclose exploitable patterns."
},
{
"category": "dast",
"confidence": "low",
"cve": "10096",
"description": "A timestamp was disclosed by the application/web server - Unix",
"identifiers": [
{
"name": "Timestamp Disclosure - Unix",
"type": "ZAProxy_PluginId",
"url": "https://github.com/zaproxy/zaproxy/blob/w2019-01-14/docs/scanners.md",
"value": "10096"
},
{
"name": "CWE-200",
"type": "CWE",
"url": "https://cwe.mitre.org/data/definitions/200.html",
"value": "200"
},
{
"name": "WASC-13",
"type": "WASC",
"url": "https://projects.webappsec.org/Information-Leakage",
"value": "13"
}
],
"links": [
{
"url": "https://www.owasp.org/index.php/Top_10_2013-A6-Sensitive_Data_Exposure"
},
{
"url": "http://projects.webappsec.org/w/page/13246936/Information%20Leakage"
}
],
"location": {
"hostname": "http://goat:8080",
"method": "GET",
"param": "",
"path": "/WebGoat/plugins/bootstrap/css/bootstrap.min.css"
},
"message": "Timestamp Disclosure - Unix",
"scanner": {
"id": "zaproxy",
"name": "ZAProxy"
},
"severity": "info",
"solution": "Manually confirm that the timestamp data is not sensitive, and that the data cannot be aggregated to disclose exploitable patterns."
}
]
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe GitlabSchema.types['ScannedResource'] do
specify { expect(described_class.graphql_name).to eq('ScannedResource') }
it 'has specific fields' do
expected_fields = %w[url request_method]
expect(described_class).to include_graphql_fields(*expected_fields)
end
end
......@@ -6,7 +6,7 @@ RSpec.describe GitlabSchema.types['SecurityReportSummarySection'] do
specify { expect(described_class.graphql_name).to eq('SecurityReportSummarySection') }
it 'has specific fields' do
expected_fields = %w[vulnerabilities_count scanned_resources_count]
expected_fields = %w[vulnerabilities_count scanned_resources_count scanned_resources]
expect(described_class).to include_graphql_fields(*expected_fields)
end
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Query.project(fullPath).pipeline(iid).securityReportSummary' do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:pipeline) { create(:ci_pipeline, :success, project: project) }
let_it_be(:user) { create(:user) }
before_all do
create(:ci_build, :success, name: 'dast_job', pipeline: pipeline, project: project) do |job|
create(:ee_ci_job_artifact, :dast_large_scanned_resources_field, job: job, project: project)
create(:security_scan, scan_type: 'dast', scanned_resources_count: 26, build: job)
end
create(:ci_build, :success, name: 'sast_job', pipeline: pipeline, project: project) do |job|
create(:ee_ci_job_artifact, :sast, job: job, project: project)
end
end
let_it_be(:query) do
%(
query {
project(fullPath:"#{project.full_path}") {
pipeline(iid:"#{pipeline.iid}") {
securityReportSummary {
dast {
scannedResourcesCount
vulnerabilitiesCount
scannedResources {
nodes {
url
requestMethod
}
}
}
sast {
vulnerabilitiesCount
}
}
}
}
}
)
end
before do
stub_licensed_features(sast: true, dependency_scanning: true, container_scanning: true, dast: true)
project.add_developer(user)
end
subject { GitlabSchema.execute(query, context: { current_user: user }).as_json }
let(:security_report_summary) { subject.dig('data', 'project', 'pipeline', 'securityReportSummary') }
it 'shows the vulnerabilitiesCount and scannedResourcesCount' do
expect(security_report_summary.dig('dast', 'vulnerabilitiesCount')).to eq(20)
expect(security_report_summary.dig('dast', 'scannedResourcesCount')).to eq(26)
expect(security_report_summary.dig('sast', 'vulnerabilitiesCount')).to eq(33)
end
it 'shows the first 20 scanned resources' do
dast_scanned_resources = security_report_summary.dig('dast', 'scannedResources', 'nodes')
expect(dast_scanned_resources.length).to eq(20)
end
end
......@@ -8,7 +8,7 @@ RSpec.describe Security::ReportSummaryService, '#execute' do
before_all do
create(:ci_build, :success, name: 'dast_job', pipeline: pipeline, project: project) do |job|
create(:ee_ci_job_artifact, :dast, job: job, project: project)
create(:ee_ci_job_artifact, :dast_large_scanned_resources_field, job: job, project: project)
end
create(:ci_build, :success, name: 'sast_job', pipeline: pipeline, project: project) do |job|
create(:ee_ci_job_artifact, :sast, job: job, project: project)
......@@ -21,7 +21,7 @@ RSpec.describe Security::ReportSummaryService, '#execute' do
create(:ee_ci_job_artifact, :dependency_scanning, job: job, project: project)
end
create_security_scan(project, pipeline, 'dast', 34)
create_security_scan(project, pipeline, 'dast', 26)
create_security_scan(project, pipeline, 'sast', 12)
end
......@@ -46,7 +46,7 @@ RSpec.describe Security::ReportSummaryService, '#execute' do
it 'returns only the request fields' do
expect(result).to eq({
dast: { scanned_resources_count: 34, vulnerabilities_count: 20 },
dast: { scanned_resources_count: 26, vulnerabilities_count: 20 },
container_scanning: { vulnerabilities_count: 8 }
})
end
......@@ -73,7 +73,7 @@ RSpec.describe Security::ReportSummaryService, '#execute' do
context 'All fields are requested' do
let(:selection_information) do
{
dast: [:scanned_resources_count, :vulnerabilities_count],
dast: [:scanned_resources_count, :vulnerabilities_count, :scanned_resources],
sast: [:scanned_resources_count, :vulnerabilities_count],
container_scanning: [:scanned_resources_count, :vulnerabilities_count],
dependency_scanning: [:scanned_resources_count, :vulnerabilities_count]
......@@ -82,7 +82,7 @@ RSpec.describe Security::ReportSummaryService, '#execute' do
it 'returns the scanned_resources_count' do
expect(result).to match(a_hash_including(
dast: a_hash_including(scanned_resources_count: 34),
dast: a_hash_including(scanned_resources_count: 26),
sast: a_hash_including(scanned_resources_count: 12),
container_scanning: a_hash_including(scanned_resources_count: 0),
dependency_scanning: a_hash_including(scanned_resources_count: 0)
......@@ -98,6 +98,10 @@ RSpec.describe Security::ReportSummaryService, '#execute' do
))
end
it 'returns the scanned resources limited to 20' do
expect(result[:dast][:scanned_resources].length).to eq(20)
end
context 'When no security scans ran' do
let(:pipeline) { create(:ci_pipeline, :success) }
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Security::ScannedResourcesService, '#execute' do
before do
stub_licensed_features(sast: true, dependency_scanning: true, container_scanning: true, dast: true)
end
let_it_be(:project) { create(:project, :repository) }
let_it_be(:pipeline) { create(:ci_pipeline, :success, project: project) }
before_all do
create(:ci_build, :success, name: 'dast_job', pipeline: pipeline, project: project) do |job|
create(:ee_ci_job_artifact, :dast, job: job, project: project)
end
create(:ci_build, :success, name: 'sast_job', pipeline: pipeline, project: project) do |job|
create(:ee_ci_job_artifact, :sast, job: job, project: project)
end
end
context 'The pipeline has security builds' do
context 'Report types are requested' do
subject { described_class.new(pipeline, %w[sast dast]).execute }
it 'only returns the requested scans' do
expect(subject.keys).to contain_exactly('sast', 'dast')
end
it 'returns the scanned resources' do
expect(subject['sast']).to be_empty
expect(subject['dast'].length).to eq(6)
expect(subject['dast']).to include(
{
'url' => 'http://api-server/',
'request_method' => 'GET'
}
)
end
end
end
context 'A limited number of scanned resources are requested' do
subject { described_class.new(pipeline, %w[dast], 2).execute }
it 'returns the scanned resources' do
expect(subject['dast'].length).to eq(2)
end
end
context 'The Pipeline has no security builds' do
let_it_be(:pipeline) { create(:ci_pipeline, :success) }
subject { described_class.new(pipeline, %w[sast dast]).execute }
it {
is_expected.to match(
a_hash_including('sast' => [], 'dast' => [])
)
}
end
context 'Pipeline is nil' do
subject { described_class.new(nil, %w[sast dast]).execute }
it {
is_expected.to match(
a_hash_including('sast' => [], 'dast' => [])
)
}
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment