Skip to content

Commit

Permalink
Merge pull request #37 from OWASP/dev
Browse files Browse the repository at this point in the history
Release v0.12.4
  • Loading branch information
dmdhrumilmistry authored Jan 2, 2024
2 parents a73fe9c + 50141b1 commit 2b1753d
Show file tree
Hide file tree
Showing 5 changed files with 992 additions and 741 deletions.
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

0 comments on commit 2b1753d

Please sign in to comment.