
웹 애플리케이션 및 API에서 Origin 헤더 주입, 와일드카드 반사, 자격 증명 유출을 테스트하는 자동화된 CORS 오구성 스캐너.
CORS는 HTTP 헤더 기반 메커니즘으로, 서버가 자신의 출처(도메인, 스키마 또는 포트) 이외의 다른 출처에서 브라우저가 리소스를 로드하도록 허용해야 하는지 나타낼 수 있습니다. 이는 서버가 웹 브라우저에서 해당 정보를 읽을 수 있는 출처를 설명하는 새로운 HTTP 헤더를 추가하여 작동합니다.
CORS는 또한 브라우저가 교차 출처 리소스를 호스팅하는 서버에 "사전 요청(preflight)"을 보내 실제 요청을 서버가 허용할 것인지 확인하는 메커니즘에 의존합니다. 이 사전 요청에서 브라우저는 실제 요청에 사용될 HTTP 메서드와 헤더를 나타내는 헤더를 보냅니다.
CORS를 구현할 때 가장 흔하고 문제가 되는 보안 문제는 요청자를 검증/허용 목록에 추가하지 못하는 것입니다. 너무 자주 Access-Control-Allow-Origin의 값이 '*'로 설정된 것을 볼 수 있습니다.
불행히도 이것이 기본값이며, 따라서 웹 상의 모든 도메인이 해당 사이트의 리소스에 액세스할 수 있도록 허용합니다.
OWASP 애플리케이션 보안 검증 표준(ASVS) 요구 사항 14.5.3에 따르면:
교차 출처 리소스 공유(CORS) Access-Control-Allow-Origin 헤더는 신뢰할 수 있는 도메인 및 하위 도메인의 엄격한 허용 목록을 사용하여 일치시키고 "null" 출처를 지원하지 않는지 확인합니다.
Corsair_scan은 매개변수로 받은 요청(또는 요청 목록)을 다시 보내고 Origin 헤더에 값을 주입하여 작동합니다. 이 요청에 대한 응답의 Access-Control-Allow-Origin 헤더 내용에 따라 CORS 구성이 올바른지 여부를 확인할 수 있습니다. CORS가 잘못 구성되었음을 나타내는 세 가지 시나리오가 있습니다:
CORS가 잘못 구성된 것으로 확인되면 응답에 Access-Control-Allow-Credentials 헤더가 포함되어 있는지 확인합니다. 이는 서버가 교차 출처 요청에 자격 증명을 포함하도록 허용한다는 의미입니다.
종종 CORS 구성은 와일드카드를 사용합니다. 예를 들어 * example.com * 아래의 모든 것을 허용합니다. 이는 origin domain.com.evil.com이 주어진 정규식과 일치하여 허용됨을 의미합니다. 이에 대응하기 위해 corsair_scan은 네 가지 시나리오를 테스트합니다:
이 프로젝트는 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 파일이 필요합니다. 예제 파일은 테스트의 일부로 제공됩니다:
[{
"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은 Santander UK 보안 엔지니어링 팀이 개발했습니다. 팀 구성원은 다음과 같습니다: