
Corsair_scan 是一款用于测试跨域资源共享(CORS)错误配置的安全工具。CORS 是一种机制,允许网页上的受限资源被从最初提供该资源的域以外的其他域请求。如果配置不当,未授权的域也能访问这些资源。
CORS 是一种基于 HTTP 标头的机制,允许服务器指示除自身以外的其他源(域、方案或端口),浏览器应允许从这些源加载资源。它通过添加新的 HTTP 标头来工作,让服务器描述哪些源被允许从 Web 浏览器读取该信息。
CORS 还依赖于一种机制,浏览器会向托管跨源资源的服务器发送“预检”请求,以检查服务器是否允许实际请求。在预检中,浏览器会发送指示实际请求中将使用的 HTTP 方法和标头的标头。
实现 CORS 时最常见且最麻烦的安全问题是未能验证/白名单请求方。我们经常看到 Access-Control-Allow-Origin 的值被设置为 *。
不幸的是,这是默认值,因此允许 Web 上的任何域访问该站点的资源。
根据 OWASP 应用程序安全验证标准(ASVS)的要求 14.5.3 指出:
验证跨域资源共享(CORS)Access-Control-Allow-Origin 标头是否使用严格的受信任域和子域白名单进行匹配,并且不支持 "null" 源。
corsair_scan 通过重新发送请求(或请求列表,作为参数接收)并在 Origin 标头中注入一个值来工作。根据该请求的响应中 Access-Control-Allow-Origin 标头的内容,我们可以判断 CORS 配置是否正确。有三种情况表明 CORS 配置错误:
Access-Control-Allow-Origin 中被回显Access-Control-Allow-Origin 的值为 *Access-Control-Allow-Origin 的值为 null如果发现 CORS 配置错误,我们会检查响应中是否包含 Access-Control-Allow-Credentials 标头,这意味着服务器允许在跨源请求中包含凭据。
通常,CORS 配置会使用通配符,例如接受 *.example.com 下的任何内容。这意味着源 domain.com.evil.com 会被接受,因为它与给定的正则表达式匹配。为了应对这种情况,corsair_scan 测试了四种场景:
https://scarymonster.com,即使原始请求没有 Origin 标头https://example.com):
https://scarymonsterexample.comhttps://example.com.scarymonster.comhttps://scarymonster.example.com本项目使用 Python 3.9 开发,但应该适用于任何 Python 3.x 版本。最佳安装方式是使用 pip。
pip3 install corsair_scan --user
Corsair 既可以作为 Python 模块使用,也可以作为 CLI 使用。
执行 CORS 扫描的方法是 corsair_scan。以下是其定义:
接收一个请求列表和一个启用/禁用请求中证书检查的参数。
输入:
data [List]:请求列表。每个请求是一个包含请求相关数据的字典:
verify [Boolean] [默认:True]:将此值传递给每个请求的 corsair_scan_single_url
输出:
import corsair_scan.corsair_scan as corsair
url_data = {}
data = []
verb = 'GET'
url = 'https://example.com/'
params = 'user=user1&password=1234'
headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'en-GB,en;q=0.5', 'Connection': 'keep-alive', 'Upgrade-Insecure-Requests': '1',
'Origin': 'https://example.com',
'Host': 'example.com'}
url_data['verb'] = verb
url_data['url'] = url
url_data['params'] = params
url_data['headers'] = headers
data.append(url_data)
print (corsair.corsair_scan(data, verify=True))
响应:
{'report': [{'fake_origin': {'Access-Control-Allow-Origin': 'https://scarymonster.com',
'Origin': 'https://scarymonster.com',
'credentials': True,
'error': False,
'misconfigured': True,
'status_code': 200},
'post-domain': {'Access-Control-Allow-Origin': 'https://example.com.scarymonster.com',
'Origin': 'https://example.com.scarymonster.com',
'credentials': True,
'error': False,
'misconfigured': True,
'status_code': 200},
'pre-domain': {'Access-Control-Allow-Origin': 'https://scarymonsterexample.com',
'Origin': ' https://scarymonsterexample.com',
'credentials': True,
'error': False,
'misconfigured': True,
'status_code': 200},
'sub-domain': {'Access-Control-Allow-Origin': 'https://scarymonster.example.com',
'Origin': 'https://scarymonster.example.com',
'credentials': True,
'error': False,
'misconfigured': True,
'status_code': 200},
'url': 'https://example.com/',
'verb': 'GET'}],
'summary': {'error': [], 'misconfigured': [{'credentials': True,
'misconfigured_test': ['fake_origin',
'sub-domain',
'pre-domain',
'post-domain'],
'status_code': 200,
'url': 'https://domain.com',
'verb': 'GET'}]}}
作为 pip 包安装的一部分,会安装一个 CLI。执行语法如下:
corsair FILE [-nv/--noverify][-r/--report]
CLI 需要一个包含请求列表的 json 文件来执行扫描。测试文件中提供了一个示例文件 test/testfiles/json_test.json:
[{
"verb": "GET",
"url": "https://example.com/",
"params": "user=user1&password=1234",
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Language": "en-GB,en;q=0.5",
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
"Origin": "https://example.com",
"Host": "example.com"
}
}]
还有两个可选参数:
Corsair_scan 由桑坦德英国安全工程团队开发,团队成员包括: