Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v0.12.4 #37

Merged
merged 6 commits into from
Jan 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/offat/report/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ def save_report(report_path: str | None, report_file_content: str | Table | None

@staticmethod
def generate_report(results: list[dict], report_format: str | None, report_path: str | None):
if report_path:
report_format = report_path.split('.')[-1]

formatted_results = ReportGenerator.handle_report_format(
results=results, report_format=report_format)
ReportGenerator.save_report(
Expand Down
96 changes: 93 additions & 3 deletions src/offat/tester/test_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,94 @@ def sqli_fuzz_params_test(

return tasks

def sqli_in_uri_path_fuzz_test(
self,
openapi_parser: OpenAPIParser,
success_codes: list[int] = [500],
*args,
**kwargs
):
'''Generate Tests for SQLi in endpoint path

Args:
openapi_parser (OpenAPIParser): An instance of the OpenAPIParser class containing the parsed OpenAPI specification.
success_codes (list[int], optional): A list of HTTP success codes to consider as successful BOLA responses. Defaults to [200, 201, 301].
*args: Variable-length positional arguments.
**kwargs: Arbitrary keyword arguments.

Returns:
list[dict]: list of dict containing test case for endpoint

Raises:
Any exceptions raised during the execution.
'''
base_url: str = openapi_parser.base_url
request_response_params: list[dict] = openapi_parser.request_response_params

# filter path containing params in path
endpoints_with_param_in_path = list(
filter(lambda path_obj: '/{' in path_obj.get('path'), request_response_params))

basic_sqli_payloads = [
"' OR 1=1 ;--",
"' UNION SELECT 1,2,3 -- -",
"' OR '1'='1--",
"' AND (SELECT * FROM (SELECT(SLEEP(5)))abc)",
"' AND SLEEP(5) --",
]

tasks = []
for sqli_payload in basic_sqli_payloads:
for path_obj in endpoints_with_param_in_path:
# handle path params from request_params
request_params = path_obj.get('request_params', [])
request_params = fill_params(request_params)

# get request body params
request_body_params = list(
filter(lambda x: x.get('in') == 'body', request_params))

# handle path params from path_params
# and replace path params by value in
# endpoint path
endpoint_path: str = path_obj.get('path')

path_params = path_obj.get('path_params', [])
path_params_in_body = list(
filter(lambda x: x.get('in') == 'path', request_params))
path_params += path_params_in_body
path_params = fill_params(path_params)

for path_param in path_params:
path_param_name = path_param.get('name')
# path_param_value = path_param.get('value')
endpoint_path = endpoint_path.replace(
'{' + str(path_param_name) + '}', str(sqli_payload))

request_query_params = list(
filter(lambda x: x.get('in') == 'query', request_params))

tasks.append({
'test_name': 'SQLi Test in URI Path with Fuzzed Params',
'url': f'{base_url}{openapi_parser.api_base_path}{endpoint_path}',
'endpoint': f'{openapi_parser.api_base_path}{endpoint_path}',
'method': path_obj.get('http_method').upper(),
'body_params': request_body_params,
'query_params': request_query_params,
'path_params': path_params,
'malicious_payload': sqli_payload,
'args': args,
'kwargs': kwargs,
'result_details': {
True: 'Endpoint is not vulnerable to SQLi', # passed
False: 'Endpoint might be vulnerable to SQli', # failed
},
'success_codes': success_codes,
'response_filter': PostTestFiltersEnum.STATUS_CODE_FILTER.name
})

return tasks

def bola_fuzz_path_test(
self,
openapi_parser: OpenAPIParser,
Expand Down Expand Up @@ -350,7 +438,8 @@ def bola_fuzz_path_test(

tasks.append({
'test_name': 'BOLA Path Test with Fuzzed Params',
'url': f'{base_url}{endpoint_path}',
# f'{base_url}{endpoint_path}',
'url': f'{base_url}{openapi_parser.api_base_path}{endpoint_path}',
'endpoint': f'{openapi_parser.api_base_path}{endpoint_path}',
'method': path_obj.get('http_method').upper(),
'body_params': request_body_params,
Expand Down Expand Up @@ -422,7 +511,7 @@ def bola_fuzz_trailing_slash_path_test(
'{' + str(path_param_name) + '}', str(path_param_value))

# generate URL for BOLA attack
url = f'{base_url}{endpoint_path}'
url = f'{base_url}{openapi_parser.api_base_path}{endpoint_path}'
if url.endswith('/'):
url = f'{url}{generate_random_int()}'
else:
Expand Down Expand Up @@ -537,7 +626,8 @@ def bopla_fuzz_test(

tasks.append({
'test_name': 'BOPLA Test',
'url': f'{base_url}{endpoint_path}',
# f'{base_url}{endpoint_path}',
'url': f'{base_url}{openapi_parser.api_base_path}{endpoint_path}',
'endpoint': f'{openapi_parser.api_base_path}{endpoint_path}',
'method': path_obj.get('http_method', '').upper(),
'body_params': request_body_params,
Expand Down
12 changes: 11 additions & 1 deletion src/offat/tester/tester_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,17 @@ def generate_and_run_tests(api_parser: OpenAPIParser, regex_pattern: Optional[st
test_runner=test_runner,
tests=sqli_fuzz_tests,
regex_pattern=regex_pattern,
description='(FUZZED) Checking for SQLi vulnerability:',
description=f'(FUZZED) {test_name}',
)

test_name = 'Checking for SQLi vulnerability in URI Path:'
logger.info(test_name)
sqli_fuzz_tests = test_generator.sqli_in_uri_path_fuzz_test(api_parser)
results += run_test(
test_runner=test_runner,
tests=sqli_fuzz_tests,
regex_pattern=regex_pattern,
description=f'(FUZZED) {test_name}',
)

# OS Command Injection Fuzz Test
Expand Down
Loading
Loading