test(privacy): Created a test to check external requests during page load
This test checks if the external request is within the apporved list. This test will prevent the adding of external urls within the page load. MR !2
This commit is contained in:
3
test/requirements.txt
Normal file
3
test/requirements.txt
Normal file
@ -0,0 +1,3 @@
|
||||
selenium==3.141.0
|
||||
|
||||
pytest==6.2.5
|
105
test/unit/conftest.py
Normal file
105
test/unit/conftest.py
Normal file
@ -0,0 +1,105 @@
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
|
||||
import pytest
|
||||
|
||||
from selenium import webdriver
|
||||
from selenium.webdriver.chrome.options import Options
|
||||
|
||||
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
|
||||
|
||||
class Data:
|
||||
|
||||
def process_browser_log_entry(self, entry):
|
||||
response = json.loads(entry['message'])['message']
|
||||
return response
|
||||
|
||||
def __init__(self):
|
||||
|
||||
caps = DesiredCapabilities.CHROME
|
||||
caps['goog:loggingPrefs'] = {'performance': 'ALL'}
|
||||
|
||||
|
||||
chrome_options = Options()
|
||||
chrome_options.add_argument("no-sandbox")
|
||||
chrome_options.add_argument("headless")
|
||||
chrome_options.add_argument("start-maximized")
|
||||
chrome_options.add_argument("window-size=1900,1080");
|
||||
|
||||
self.driver = webdriver.Chrome(desired_capabilities=caps, options=chrome_options)
|
||||
|
||||
self.urls = []
|
||||
self.suffux_path = os.path.realpath('./build')
|
||||
self.urls += [os.path.join(dp, f) for dp, dn, fn in os.walk(os.path.expanduser('./build')) for f in fn if f.endswith('.html')]
|
||||
|
||||
|
||||
data = {
|
||||
'page_load_resource_links': {},
|
||||
'source_files': [],
|
||||
'hyperlinks': {}
|
||||
}
|
||||
|
||||
|
||||
for check_file in self.urls:
|
||||
|
||||
check_url = 'file://' + self.suffux_path + check_file.replace('./build','')
|
||||
source_file = check_file.replace('./build','')[1:]
|
||||
|
||||
if source_file not in data['source_files']:
|
||||
data['source_files'].append(source_file)
|
||||
|
||||
self.driver.get(check_url)
|
||||
|
||||
events = [self.process_browser_log_entry(entry) for entry in self.driver.get_log('performance')]
|
||||
|
||||
for entry in events:
|
||||
|
||||
if entry['method'] == 'Network.requestWillBeSent':
|
||||
|
||||
http_status = str([response['params']['response']['status'] for response in events if response['method'] == 'Network.responseReceived' and response['params']['requestId'] == entry['params']['requestId']]).replace('[', '').replace(']', '')
|
||||
|
||||
url = str(entry['params']['request']['url'])
|
||||
|
||||
|
||||
url_id = hashlib.md5(bytes(url, 'utf-8')).hexdigest()
|
||||
|
||||
|
||||
if re.match("^http|file.*", url) is not None:
|
||||
|
||||
source_file_line_number = ''
|
||||
|
||||
if 'lineNumber' in entry['params']['initiator']:
|
||||
|
||||
source_file_line_number = str(entry['params']['initiator']['lineNumber'])
|
||||
|
||||
request_protocol = re.match("^[http|file]+s?", url).group(0)
|
||||
|
||||
if re.match("^http.*", url) is not None:
|
||||
|
||||
domain = re.match(r'^([a-z]+[\.|a-z|]+)',url.replace(request_protocol + '://', '')).group(0)
|
||||
|
||||
request_path = url.replace(request_protocol + '://','').replace(domain, '')[1:]
|
||||
|
||||
|
||||
elif re.match("^file.*", url) is not None:
|
||||
|
||||
domain = 'file'
|
||||
|
||||
request_path = url.replace(request_protocol + '://','')[1:]
|
||||
|
||||
if url_id in data['page_load_resource_links']:
|
||||
|
||||
data['page_load_resource_links'][url_id]['source_files'].append({'name': source_file, 'line_number': source_file_line_number, 'http_status': http_status})
|
||||
|
||||
else:
|
||||
|
||||
data['page_load_resource_links'][url_id] = {'url': url, 'request_protocol': request_protocol, 'domain': domain, 'request_path': request_path, 'source_files': [ {'name': source_file, 'line_number': source_file_line_number, 'http_status': http_status} ]}
|
||||
|
||||
self.test_data = data
|
||||
|
||||
|
||||
print("\n"+'Creating test data')
|
||||
print("\n\ntest data:\n" + json.dumps(Data().test_data, indent=2, default=str))
|
||||
|
38
test/unit/privacy_test.py
Normal file
38
test/unit/privacy_test.py
Normal file
@ -0,0 +1,38 @@
|
||||
import pytest
|
||||
|
||||
from conftest import Data
|
||||
|
||||
class Test:
|
||||
|
||||
data = Data()
|
||||
|
||||
def setup_method(self):
|
||||
|
||||
self.approved_external_requests = {
|
||||
'gitlab.com': [
|
||||
'api/v4/projects/nofusscomputing%2Finfrastructure%2Fwebsite',
|
||||
'uploads/-/system/user/avatar/4125177/avatar.png'
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
argnames='data',
|
||||
argvalues=[link for url_id, link in data.test_data['page_load_resource_links'].items() if link['request_protocol'][0:4] =='http'],
|
||||
ids=[url_id for url_id, link in data.test_data['page_load_resource_links'].items() if link['request_protocol'][0:4] =='http']
|
||||
)
|
||||
def test_page_external_requests(self, data):
|
||||
|
||||
check_url = data['url']
|
||||
|
||||
assert data['request_protocol'] == 'https', f"Insecure Request to domain [{data['request_path']}] in source files [{data['source_files']}]"
|
||||
|
||||
assert data['domain'] in self.approved_external_requests, f"A request is being made to a non-approved domain [{data['domain']}] path [{data['request_path']}] in source files [{data['source_files']}]"
|
||||
|
||||
assert data['request_path'] in self.approved_external_requests[data['domain']], f"A request is being made to a non-approved path [{data['request_path']}] on domain [{data['domain']}] in source files [{data['source_files']}]"
|
||||
|
||||
|
||||
|
||||
def teardown_method(self):
|
||||
pass
|
||||
|
Reference in New Issue
Block a user