-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #24 from juerkkil/basic_unittests
basic unittests
- Loading branch information
Showing
4 changed files
with
145 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
class MockHTTPResponse: | ||
def __init__(self, sock=None, debuglevel=0, method=None, url=None): | ||
pass | ||
|
||
def getheaders(self): | ||
return [ | ||
('x-xss-protection', '1;'), | ||
('server', 'nginx') | ||
] | ||
|
||
def getsomething(self): | ||
pass | ||
|
||
|
||
class MockHTTPSConnection: | ||
def __init__(self, h, context, timeout): | ||
pass | ||
|
||
def request(self, method, url, headers): | ||
pass | ||
|
||
def headers(self): | ||
return "content-type", "accept" | ||
|
||
def getresponse(self): | ||
a = MockHTTPResponse() | ||
return a | ||
|
||
def close(self): | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
from unittest import mock, TestCase | ||
from urllib.parse import ParseResult | ||
|
||
from secheaders.securityheaders import SecurityHeaders | ||
|
||
from .mock_classes import MockHTTPSConnection | ||
|
||
|
||
@mock.patch("http.client.HTTPSConnection", MockHTTPSConnection) | ||
class TestSecurityHeaders(TestCase): | ||
|
||
def test_init(self) -> None: | ||
secheaders = SecurityHeaders("https://www.example.com", 0) | ||
assert secheaders.target_url == ParseResult( | ||
scheme='https', netloc='www.example.com', path='', params='', query='', fragment='') | ||
|
||
def test_fetch_headers(self) -> None: | ||
secheaders = SecurityHeaders("https://www.example.com", 0) | ||
expected_value = { | ||
'server': 'nginx', | ||
'x-xss-protection': '1;', | ||
} | ||
secheaders.fetch_headers() | ||
assert secheaders.headers == expected_value | ||
|
||
def test_eval_headers(self) -> None: | ||
secheaders = SecurityHeaders("https://www.example.com", 0) | ||
expected_value = { | ||
'x-frame-options': {'defined': False, 'warn': True, 'contents': None, 'notes': []}, | ||
'strict-transport-security': {'defined': False, 'warn': True, 'contents': None, 'notes': []}, | ||
'content-security-policy': {'defined': False, 'warn': True, 'contents': None, 'notes': []}, | ||
'x-content-type-options': {'defined': False, 'warn': True, 'contents': None, 'notes': []}, | ||
'x-xss-protection': {'defined': True, 'warn': True, 'contents': '1;', 'notes': []}, | ||
'referrer-policy': {'defined': False, 'warn': True, 'contents': None, 'notes': []}, | ||
'permissions-policy': {'defined': False, 'warn': True, 'contents': None, 'notes': []}, | ||
'server': {'defined': True, 'warn': False, 'contents': 'nginx', 'notes': []}, | ||
} | ||
|
||
secheaders.fetch_headers() | ||
res = secheaders.check_headers() | ||
assert res == expected_value |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
from unittest import TestCase | ||
from secheaders import utils | ||
from secheaders.constants import EVAL_OK, EVAL_WARN | ||
|
||
|
||
class TestUtils(TestCase): | ||
|
||
def test_csp_parser(self) -> None: | ||
example_csp = ( | ||
"default-src 'none' *.example.com; script-src 'self' src.example.com 'unsafe-inline'; connect-src 'self';" | ||
"img-src *; style-src 'self'; base-uri 'self';form-action 'self'" | ||
) | ||
expected_value = { | ||
"default-src": ["'none'", "*.example.com"], | ||
"script-src": ["'self'", "src.example.com", "'unsafe-inline'"], | ||
"connect-src": ["'self'"], | ||
"img-src": ["*"], | ||
"style-src": ["'self'"], | ||
"base-uri": ["'self'"], | ||
"form-action": ["'self'"], | ||
} | ||
res = utils.csp_parser(example_csp) | ||
assert res == expected_value | ||
|
||
def test_eval_csp(self) -> None: | ||
unsafe_csp = ( | ||
"default-src 'none' *.example.com; script-src 'self' src.example.com 'unsafe-inline'; connect-src 'self';" | ||
"img-src *; style-src 'self'; base-uri 'self';form-action 'self'" | ||
) | ||
res = utils.eval_csp(unsafe_csp) | ||
expected_value = ( | ||
EVAL_WARN, | ||
["Unsafe source 'unsafe-inline' in directive script-src"] | ||
) | ||
assert res == expected_value | ||
|
||
safe_csp = "default-src 'self'; img-src 'self' cdn.example.com;" | ||
expected_value = (EVAL_OK, []) | ||
res = utils.eval_csp(safe_csp) | ||
assert res == expected_value | ||
|
||
def test_eval_version_info(self) -> None: | ||
nginx_banner_warn = 'nginx 1.17.10 (Ubuntu)' | ||
nginx_banner_ok = 'nginx' | ||
res = utils.eval_version_info(nginx_banner_warn) | ||
assert res == (EVAL_WARN, []) | ||
res = utils.eval_version_info(nginx_banner_ok) | ||
assert res == (EVAL_OK, []) | ||
|
||
def test_permissions_policy_parser(self) -> None: | ||
example_pp = ( | ||
'geolocation=(src "https://a.example.com" "https://b.example.com"), picture-in-picture=(), camera=*;' | ||
) | ||
expected_value = { | ||
'geolocation': ['src', '"https://a.example.com"', '"https://b.example.com"'], | ||
'picture-in-picture': [], | ||
'camera': ['*'], | ||
} | ||
res = utils.permissions_policy_parser(example_pp) | ||
assert expected_value == res | ||
|
||
def test_eval_permissions_policy(self) -> None: | ||
unsafe_pp = 'geolocation=(src "https://a.example.com"), picture-in-picture=(), camera=*;' | ||
expected_value = (EVAL_WARN, [ | ||
"Privacy-sensitive feature 'camera' allowed from unsafe origin '*'", | ||
"Privacy-sensitive feature 'microphone' not defined in permission-policy, always allowed.", | ||
"Privacy-sensitive feature 'payment' not defined in permission-policy, always allowed.", | ||
]) | ||
res = utils.eval_permissions_policy(unsafe_pp) | ||
assert res == expected_value | ||
safe_pp = "geolocation=(src), camera=(), microphone=(), payment=()" | ||
expected_value = EVAL_OK, [] | ||
res = utils.eval_permissions_policy(safe_pp) | ||
assert res == expected_value |