Skip to content

Commit c2067b9

Browse files
javixeneizekingthorin
authored andcommitted
Added corsair scan
Corsair scan added as a zap script Signed-off-by: javixeneize <javi.xeneize@gmail.com>
1 parent 3dd10f2 commit c2067b9

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
66
## [Unreleased]
77
### Added
88
- variant/CompoundCookies.js - An input vector script that handles splitting of compound cookies (Issue 6582).
9+
- active/corsair.py > An active scan script to check for CORS related issues.)
910

1011
## [13] - 2021-10-14
1112
### Fixed

active/corsair.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
"""
2+
This is an adaptation of Corsair Scan (https://github.com/Santandersecurityresearch/corsair_scan) as a ZAP active scan script.
3+
This script will resend requests to all the sites being scanned in ZAP, injecting different origins. Then, it will read the value of Access-Control-Allow-Origin and based on that, it
4+
will assess if CORS is properly configured.
5+
"""
6+
import urlparse
7+
alertTitle = 'Corsair - CORS Misconfigured'
8+
alertDescription = "Cross Origin Resource Sharing (CORS) is misconfigured. \n"
9+
alertRisk = 2
10+
alertConfidence = 3
11+
alertSolution = "Configure CORS in a more restrictive way, to give access only the sites allowed to access your domain."
12+
alertInfo = "Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any other origins (domain, scheme, or port) than its own from which a browser should permit loading of resources."
13+
cweID = 942
14+
wascID = 14
15+
16+
SM_ORIGIN = 'https://example.com'
17+
SM_ORIGIN_NO_PROTOCOL = 'example.com'
18+
SM_ORIGIN_DOMAIN = 'example'
19+
20+
"""
21+
In this method, we read the request performed and create a new request with a fake origin. Also, if the request already contains an origin header, we perform two extra requests:
22+
1 - Fake subdomain. It is, we set as origin a fake subdomain to validate if CORS is configured at domain level, or if it has granularity at subdomain level.
23+
2 - Fake postdomain. Here, we set a request using the existing origin as a subdomain for a fake domain. We do it to validate if CORS is misconfigured and it only checks if the expected value exists in the origin header.
24+
Then, we call cors_scan, which will send that request and validate the response.
25+
"""
26+
def scanNode(sas, msg):
27+
origMsg = msg
28+
msg = origMsg.cloneRequest()
29+
msg.getRequestHeader().setHeader("Origin", SM_ORIGIN)
30+
cors_scan(sas,msg, "fake origin")
31+
if origMsg.getRequestHeader().getHeader('Origin'):
32+
parsed_url = urlparse.urlparse(origMsg.getRequestHeader().getHeader('Origin'))
33+
subdomain= parsed_url.scheme + '://' + SM_ORIGIN_DOMAIN + '.' + parsed_url.netloc
34+
postdomain = origMsg.getRequestHeader().getHeader('Origin') + '.' + SM_ORIGIN_NO_PROTOCOL
35+
msg.getRequestHeader().setHeader("Origin", subdomain)
36+
cors_scan(sas,msg, "fake subdomain")
37+
msg.getRequestHeader().setHeader("Origin", postdomain)
38+
cors_scan(sas,msg, "fake postdomain")
39+
40+
"""
41+
cors_scan sends the request crafted by scanNode and reads the value of the Access-Control-Allow-Origin header.
42+
If it is the origin reflected, * or NULL, we consider that CORS is misconfigured and raise an alert.
43+
"""
44+
def cors_scan(sas,msg, test_type):
45+
sas.sendAndReceive(msg, True, False);
46+
header = str(msg.getResponseHeader().getHeader("Access-Control-Allow-Origin"))
47+
if (header in ['null', '*', msg.getRequestHeader().getHeader('Origin')]):
48+
alertParam = "Test performed: Injecting a "+test_type
49+
sas.raiseAlert(alertRisk, alertConfidence, alertTitle, alertDescription + alertParam, msg.getRequestHeader().getURI().toString(), "Origin",
50+
msg.getRequestHeader().getHeader('Origin'), alertInfo, alertSolution, msg.getRequestHeader().getHeader('Origin'), cweID, wascID, msg);
51+
52+
def scan(sas, msg, param, value):
53+
pass

0 commit comments

Comments
 (0)