mirror of
https://github.com/sherlock-project/sherlock
synced 2024-11-22 11:53:03 +00:00
67258b58a4
When using tox, pass `-e offline` to exclude online tests. When using pytest, pass `-m "not online"` to do the same.
105 lines
4.5 KiB
Python
105 lines
4.5 KiB
Python
import pytest
|
|
import random
|
|
import string
|
|
import re
|
|
from sherlock.sherlock import sherlock
|
|
from sherlock.notify import QueryNotify
|
|
from sherlock.result import QueryStatus
|
|
#from sherlock_interactives import Interactives
|
|
|
|
|
|
def simple_query(sites_info: dict, site: str, username: str) -> QueryStatus:
|
|
query_notify = QueryNotify()
|
|
site_data: dict = {}
|
|
site_data[site] = sites_info[site]
|
|
return sherlock(
|
|
username=username,
|
|
site_data=site_data,
|
|
query_notify=query_notify,
|
|
)[site]['status'].status
|
|
|
|
|
|
@pytest.mark.online
|
|
class TestLiveTargets:
|
|
"""Actively test probes against live and trusted targets"""
|
|
# Known positives should only use sites trusted to be reliable and unchanging
|
|
@pytest.mark.parametrize('site,username',[
|
|
('GitLab', 'ppfeister'),
|
|
('AllMyLinks', 'blue'),
|
|
])
|
|
def test_known_positives_via_message(self, sites_info, site, username):
|
|
assert simple_query(sites_info=sites_info, site=site, username=username) is QueryStatus.CLAIMED
|
|
|
|
|
|
# Known positives should only use sites trusted to be reliable and unchanging
|
|
@pytest.mark.parametrize('site,username',[
|
|
('GitHub', 'ppfeister'),
|
|
('GitHub', 'sherlock-project'),
|
|
('Docker Hub', 'ppfeister'),
|
|
('Docker Hub', 'sherlock'),
|
|
])
|
|
def test_known_positives_via_status_code(self, sites_info, site, username):
|
|
assert simple_query(sites_info=sites_info, site=site, username=username) is QueryStatus.CLAIMED
|
|
|
|
|
|
# Known positives should only use sites trusted to be reliable and unchanging
|
|
@pytest.mark.parametrize('site,username',[
|
|
('BodyBuilding', 'blue'),
|
|
('labpentestit', 'CSV'),
|
|
])
|
|
def test_known_positives_via_response_url(self, sites_info, site, username):
|
|
assert simple_query(sites_info=sites_info, site=site, username=username) is QueryStatus.CLAIMED
|
|
|
|
|
|
# Randomly generate usernames of high length and test for positive availability
|
|
# Randomly generated usernames should be simple alnum for simplicity and high
|
|
# compatibility. Several attempts may be made ~just in case~ a real username is
|
|
# generated.
|
|
@pytest.mark.parametrize('site,random_len',[
|
|
('GitLab', 255),
|
|
('Codecademy', 30)
|
|
])
|
|
def test_likely_negatives_via_message(self, sites_info, site, random_len):
|
|
num_attempts: int = 3
|
|
attempted_usernames: list[str] = []
|
|
status: QueryStatus = QueryStatus.CLAIMED
|
|
for i in range(num_attempts):
|
|
acceptable_types = string.ascii_letters + string.digits
|
|
random_handle = ''.join(random.choice(acceptable_types) for _ in range (random_len))
|
|
attempted_usernames.append(random_handle)
|
|
status = simple_query(sites_info=sites_info, site=site, username=random_handle)
|
|
if status is QueryStatus.AVAILABLE:
|
|
break
|
|
assert status is QueryStatus.AVAILABLE, f"Could not validate available username after {num_attempts} attempts with randomly generated usernames {attempted_usernames}."
|
|
|
|
|
|
# Randomly generate usernames of high length and test for positive availability
|
|
# Randomly generated usernames should be simple alnum for simplicity and high
|
|
# compatibility. Several attempts may be made ~just in case~ a real username is
|
|
# generated.
|
|
@pytest.mark.parametrize('site,random_len',[
|
|
('GitHub', 39),
|
|
('Docker Hub', 30)
|
|
])
|
|
def test_likely_negatives_via_status_code(self, sites_info, site, random_len):
|
|
num_attempts: int = 3
|
|
attempted_usernames: list[str] = []
|
|
status: QueryStatus = QueryStatus.CLAIMED
|
|
for i in range(num_attempts):
|
|
acceptable_types = string.ascii_letters + string.digits
|
|
random_handle = ''.join(random.choice(acceptable_types) for _ in range (random_len))
|
|
attempted_usernames.append(random_handle)
|
|
status = simple_query(sites_info=sites_info, site=site, username=random_handle)
|
|
if status is QueryStatus.AVAILABLE:
|
|
break
|
|
assert status is QueryStatus.AVAILABLE, f"Could not validate available username after {num_attempts} attempts with randomly generated usernames {attempted_usernames}."
|
|
|
|
|
|
def test_username_illegal_regex(sites_info):
|
|
site: str = 'BitBucket'
|
|
invalid_handle: str = '*#$Y&*JRE'
|
|
pattern = re.compile(sites_info[site]['regexCheck'])
|
|
# Ensure that the username actually fails regex before testing sherlock
|
|
assert pattern.match(invalid_handle) is None
|
|
assert simple_query(sites_info=sites_info, site=site, username=invalid_handle) is QueryStatus.ILLEGAL
|
|
|