diff --git a/.github/ISSUE_TEMPLATE/support_request.md b/.github/ISSUE_TEMPLATE/support_request.md index 4dc3873471f..f575ea0762d 100644 --- a/.github/ISSUE_TEMPLATE/support_request.md +++ b/.github/ISSUE_TEMPLATE/support_request.md @@ -7,7 +7,7 @@ assignees: '' --- **Slack us first!** -The easiest and fastest way to help you is via Slack. There's a free and easy signup to join our #defectdojo channel in the OWASP Slack workspace: [Get Access.](https://owasp-slack.herokuapp.com/) +The easiest and fastest way to help you is via Slack. There's a free and easy signup to join our #defectdojo channel in the OWASP Slack workspace: [Get Access.](https://owasp.org/slack/invite) If you're confident you've found a bug, or are allergic to Slack, you can submit an issue anyway. **Be informative** diff --git a/Dockerfile.integration-tests-debian b/Dockerfile.integration-tests-debian index 3a01815f820..ae890a24c15 100644 --- a/Dockerfile.integration-tests-debian +++ b/Dockerfile.integration-tests-debian @@ -1,7 +1,7 @@ # code: language=Dockerfile -FROM openapitools/openapi-generator-cli:v7.8.0@sha256:c409bfa9b276faf27726d2884b859d18269bf980cb63546e80b72f3b2648c492 AS openapitools +FROM openapitools/openapi-generator-cli:v7.9.0@sha256:bb32f5f0c9f5bdbb7b00959e8009de0230aedc200662701f05fc244c36f967ba AS openapitools FROM python:3.11.9-slim-bookworm@sha256:8c1036ec919826052306dfb5286e4753ffd9d5f6c24fbc352a5399c3b405b57e AS build WORKDIR /app RUN \ diff --git a/README.md b/README.md index 6cb9098145b..17d7bedfb3e 100644 --- a/README.md +++ b/README.md @@ -132,15 +132,14 @@ Core Moderators can help you with pull requests or feedback on dev ideas: * Cody Maffucci ([@Maffooch](https://github.com/maffooch) | [LinkedIn](https://www.linkedin.com/in/cody-maffucci)) Moderators can help you with pull requests or feedback on dev ideas: -* Damien Carol ([@damiencarol](https://github.com/damiencarol) | [LinkedIn](https://www.linkedin.com/in/damien-carol/)) -* Jannik Jürgens ([@alles-klar](https://github.com/alles-klar)) -* Dubravko Sever ([@dsever](https://github.com/dsever)) * Charles Neill ([@cneill](https://github.com/cneill) | [@ccneill](https://twitter.com/ccneill)) * Jay Paz ([@jjpaz](https://twitter.com/jjpaz)) * Blake Owens ([@blakeaowens](https://github.com/blakeaowens)) ## Hall of Fame - +* Jannik Jürgens ([@alles-klar](https://github.com/alles-klar)) - Jannik was a long time contributor and moderator for + DefectDojo and made significant contributions to many areas of the platform. Jannik was instrumental in pioneering + and optimizing deployment methods. * Valentijn Scholten ([@valentijnscholten](https://github.com/valentijnscholten) | [Sponsor](https://github.com/sponsors/valentijnscholten) | [LinkedIn](https://www.linkedin.com/in/valentijn-scholten/)) - Valentijn served as a core moderator for 3 years. diff --git a/docker/entrypoint-initializer.sh b/docker/entrypoint-initializer.sh index c6f86970d89..08e77dc46ca 100755 --- a/docker/entrypoint-initializer.sh +++ b/docker/entrypoint-initializer.sh @@ -154,7 +154,7 @@ EOD echo "Importing fixtures all at once" python3 manage.py loaddata system_settings initial_banner_conf product_type test_type \ development_environment benchmark_type benchmark_category benchmark_requirement \ - language_type objects_review regulation initial_surveys role + language_type objects_review regulation initial_surveys role sla_configurations echo "UPDATE dojo_system_settings SET jira_webhook_secret='$DD_JIRA_WEBHOOK_SECRET'" | python manage.py dbshell diff --git a/docs/content/en/getting_started/architecture.md b/docs/content/en/getting_started/architecture.md index 676d8184024..fe53d0ef3f1 100644 --- a/docs/content/en/getting_started/architecture.md +++ b/docs/content/en/getting_started/architecture.md @@ -20,8 +20,8 @@ dynamic content. ## Message Broker -The application server sends tasks to a [Message Broker](https://docs.celeryproject.org/en/stable/getting-started/brokers/index.html) -for asynchronous execution. +The application server sends tasks to a [Message Broker](https://docs.celeryq.dev/en/stable/getting-started/backends-and-brokers/index.html) +for asynchronous execution. Currently, only [Redis](https://github.com/redis/redis) is supported as a broker. ## Celery Worker diff --git a/docs/content/en/getting_started/upgrading/2.40.md b/docs/content/en/getting_started/upgrading/2.40.md index 3420f9b8356..fd399b3f536 100644 --- a/docs/content/en/getting_started/upgrading/2.40.md +++ b/docs/content/en/getting_started/upgrading/2.40.md @@ -2,6 +2,8 @@ title: 'Upgrading to DefectDojo Version 2.40.x' toc_hide: true weight: -20241007 -description: No special instructions. +description: Breaking Change for Postgres 12. --- -There are no special instructions for upgrading to 2.40.x. Check the [Release Notes](https://github.com/DefectDojo/django-DefectDojo/releases/tag/2.40.0) for the contents of the release. +With the upgrade to Django 5.1.x, Posgres 12 will no longer be supported. Please make plans to upgrade to a later version of Postrges before upgrading to version 2.40.0 of DefectDojo. To determine which version of Postgres to target, please refer to the [end of life version schedule](https://endoflife.date/postgresql) + +Check the [Release Notes](https://github.com/DefectDojo/django-DefectDojo/releases/tag/2.40.0) for the contents of the release. diff --git a/docs/content/en/integrations/importing.md b/docs/content/en/integrations/importing.md index 20590ee1f71..127f6429324 100644 --- a/docs/content/en/integrations/importing.md +++ b/docs/content/en/integrations/importing.md @@ -69,7 +69,7 @@ An import can be performed by specifying the names of these entities in the API } ``` -When `auto_create_context` is `True`, the product and engagement will be created if needed. Make sure your user has sufficient [permissions](../usage/permissions) to do this. +When `auto_create_context` is `True`, the product, engagement, and environment will be created if needed. Make sure your user has sufficient [permissions](../usage/permissions) to do this. A classic way of importing a scan is by specifying the ID of the engagement instead: diff --git a/docs/content/en/integrations/parsers/file/ptart.md b/docs/content/en/integrations/parsers/file/ptart.md new file mode 100644 index 00000000000..5ce56967493 --- /dev/null +++ b/docs/content/en/integrations/parsers/file/ptart.md @@ -0,0 +1,14 @@ +--- +title: "PTART Reports" +toc_hide: true +--- + +### What is PTART? +PTART is a Pentest and Security Auditing Reporting Tool developed by the Michelin CERT (https://github.com/certmichelin/PTART) + +### Importing Reports +Reports can be exported to JSON format from the PTART web UI, and imported into DefectDojo by using the "PTART Report" importer. + +### Sample Scan Data +Sample scan data for testing purposes can be found [here](https://github.com/DefectDojo/django-DefectDojo/tree/master/unittests/scans/ptart). + diff --git a/dojo/api_v2/serializers.py b/dojo/api_v2/serializers.py index eed696a2c95..f83ba2c0e13 100644 --- a/dojo/api_v2/serializers.py +++ b/dojo/api_v2/serializers.py @@ -2046,7 +2046,7 @@ def get_findings_list(self, obj) -> list[int]: return obj.open_findings_list -class ImportScanSerializer(serializers.Serializer): +class CommonImportScanSerializer(serializers.Serializer): scan_date = serializers.DateField( required=False, help_text="Scan completion date will be used on all findings.", @@ -2063,7 +2063,7 @@ class ImportScanSerializer(serializers.Serializer): verified = serializers.BooleanField( help_text="Override the verified setting from the tool.", ) - scan_type = serializers.ChoiceField(choices=get_choices_sorted()) + # TODO: why do we allow only existing endpoints? endpoint_to_add = serializers.PrimaryKeyRelatedField( queryset=Endpoint.objects.all(), @@ -2084,35 +2084,15 @@ class ImportScanSerializer(serializers.Serializer): required=False, help_text="Resource link to source code", ) - engagement = serializers.PrimaryKeyRelatedField( - queryset=Engagement.objects.all(), required=False, - ) + test_title = serializers.CharField(required=False) auto_create_context = serializers.BooleanField(required=False) deduplication_on_engagement = serializers.BooleanField(required=False) lead = serializers.PrimaryKeyRelatedField( allow_null=True, default=None, queryset=User.objects.all(), ) - tags = TagListSerializerField( - required=False, allow_empty=True, help_text="Add tags that help describe this scan.", - ) - close_old_findings = serializers.BooleanField( - required=False, - default=False, - help_text="Select if old findings no longer present in the report get closed as mitigated when importing. " - "If service has been set, only the findings for this service will be closed.", - ) - close_old_findings_product_scope = serializers.BooleanField( - required=False, - default=False, - help_text="Select if close_old_findings applies to all findings of the same type in the product. " - "By default, it is false meaning that only old findings of the same type in the engagement are in scope.", - ) push_to_jira = serializers.BooleanField(default=False) environment = serializers.CharField(required=False) - version = serializers.CharField( - required=False, help_text="Version that was scanned.", - ) build_id = serializers.CharField( required=False, help_text="ID of the build that was scanned.", ) @@ -2146,9 +2126,6 @@ class ImportScanSerializer(serializers.Serializer): # extra fields populated in response # need to use the _id suffix as without the serializer framework gets # confused - test = serializers.IntegerField( - read_only=True, - ) # left for backwards compatibility test_id = serializers.IntegerField(read_only=True) engagement_id = serializers.IntegerField(read_only=True) product_id = serializers.IntegerField(read_only=True) @@ -2163,10 +2140,75 @@ class ImportScanSerializer(serializers.Serializer): required=False, ) - def set_context( + def get_importer( + self, + **kwargs: dict, + ) -> BaseImporter: + """ + Returns a new instance of an importer that extends + the BaseImporter class + """ + return DefaultImporter(**kwargs) + + def process_scan( self, data: dict, - ) -> dict: + context: dict, + ) -> None: + """ + Process the scan with all of the supplied data fully massaged + into the format we are expecting + + Raises exceptions in the event of an error + """ + try: + importer = self.get_importer(**context) + context["test"], _, _, _, _, _, _ = importer.process_scan( + context.pop("scan", None), + ) + # Update the response body with some new data + if test := context.get("test"): + data["test"] = test.id + data["test_id"] = test.id + data["engagement_id"] = test.engagement.id + data["product_id"] = test.engagement.product.id + data["product_type_id"] = test.engagement.product.prod_type.id + data["statistics"] = {"after": test.statistics} + # convert to exception otherwise django rest framework will swallow them as 400 error + # exceptions are already logged in the importer + except SyntaxError as se: + raise Exception(se) + except ValueError as ve: + raise Exception(ve) + + def validate(self, data: dict) -> dict: + scan_type = data.get("scan_type") + file = data.get("file") + if not file and requires_file(scan_type): + msg = f"Uploading a Report File is required for {scan_type}" + raise serializers.ValidationError(msg) + if file and is_scan_file_too_large(file): + msg = f"Report file is too large. Maximum supported size is {settings.SCAN_FILE_MAX_SIZE} MB" + raise serializers.ValidationError(msg) + tool_type = requires_tool_type(scan_type) + if tool_type: + api_scan_configuration = data.get("api_scan_configuration") + if ( + api_scan_configuration + and tool_type + != api_scan_configuration.tool_configuration.tool_type.name + ): + msg = f"API scan configuration must be of tool type {tool_type}" + raise serializers.ValidationError(msg) + return data + + def validate_scan_date(self, value: str) -> None: + if value and value > timezone.localdate(): + msg = "The scan_date cannot be in the future!" + raise serializers.ValidationError(msg) + return value + + def setup_common_context(self, data: dict) -> dict: """ Process all of the user supplied inputs to massage them into the correct format the importer is expecting to see @@ -2174,9 +2216,17 @@ def set_context( context = dict(data) # update some vars context["scan"] = data.pop("file", None) - context["environment"] = Development_Environment.objects.get( - name=data.get("environment", "Development"), - ) + + if context.get("auto_create_context"): + environment = Development_Environment.objects.get_or_create(name=data.get("environment", "Development"))[0] + else: + try: + environment = Development_Environment.objects.get(name=data.get("environment", "Development")) + except: + msg = "Environment named " + data.get("environment") + " does not exist." + raise ValidationError(msg) + + context["environment"] = environment # Set the active/verified status based upon the overrides if "active" in self.initial_data: context["active"] = data.get("active") @@ -2207,6 +2257,44 @@ def set_context( if context.get("scan_date") else None ) + return context + + +class ImportScanSerializer(CommonImportScanSerializer): + scan_type = serializers.ChoiceField(choices=get_choices_sorted()) + engagement = serializers.PrimaryKeyRelatedField( + queryset=Engagement.objects.all(), required=False, + ) + tags = TagListSerializerField( + required=False, allow_empty=True, help_text="Add tags that help describe this scan.", + ) + close_old_findings = serializers.BooleanField( + required=False, + default=False, + help_text="Select if old findings no longer present in the report get closed as mitigated when importing. " + "If service has been set, only the findings for this service will be closed.", + ) + close_old_findings_product_scope = serializers.BooleanField( + required=False, + default=False, + help_text="Select if close_old_findings applies to all findings of the same type in the product. " + "By default, it is false meaning that only old findings of the same type in the engagement are in scope.", + ) + version = serializers.CharField( + required=False, help_text="Version that was scanned.", + ) + # extra fields populated in response + # need to use the _id suffix as without the serializer framework gets + # confused + test = serializers.IntegerField( + read_only=True, + ) # left for backwards compatibility + + def set_context( + self, + data: dict, + ) -> dict: + context = self.setup_common_context(data) # Process the auto create context inputs self.process_auto_create_create_context(context) @@ -2233,47 +2321,6 @@ def process_auto_create_create_context( # Raise an explicit drf exception here raise ValidationError(str(e)) - def get_importer( - self, - **kwargs: dict, - ) -> BaseImporter: - """ - Returns a new instance of an importer that extends - the BaseImporter class - """ - return DefaultImporter(**kwargs) - - def process_scan( - self, - data: dict, - context: dict, - ) -> None: - """ - Process the scan with all of the supplied data fully massaged - into the format we are expecting - - Raises exceptions in the event of an error - """ - try: - importer = self.get_importer(**context) - context["test"], _, _, _, _, _, _ = importer.process_scan( - context.pop("scan", None), - ) - # Update the response body with some new data - if test := context.get("test"): - data["test"] = test.id - data["test_id"] = test.id - data["engagement_id"] = test.engagement.id - data["product_id"] = test.engagement.product.id - data["product_type_id"] = test.engagement.product.prod_type.id - data["statistics"] = {"after": test.statistics} - # convert to exception otherwise django rest framework will swallow them as 400 error - # exceptions are already logged in the importer - except SyntaxError as se: - raise Exception(se) - except ValueError as ve: - raise Exception(ve) - def save(self, push_to_jira=False): # Go through the validate method data = self.validated_data @@ -2284,50 +2331,9 @@ def save(self, push_to_jira=False): # Import the scan with all of the supplied data self.process_scan(data, context) - def validate(self, data: dict) -> dict: - scan_type = data.get("scan_type") - file = data.get("file") - if not file and requires_file(scan_type): - msg = f"Uploading a Report File is required for {scan_type}" - raise serializers.ValidationError(msg) - if file and is_scan_file_too_large(file): - msg = f"Report file is too large. Maximum supported size is {settings.SCAN_FILE_MAX_SIZE} MB" - raise serializers.ValidationError(msg) - tool_type = requires_tool_type(scan_type) - if tool_type: - api_scan_configuration = data.get("api_scan_configuration") - if ( - api_scan_configuration - and tool_type - != api_scan_configuration.tool_configuration.tool_type.name - ): - msg = f"API scan configuration must be of tool type {tool_type}" - raise serializers.ValidationError(msg) - return data - - def validate_scan_date(self, value: str) -> None: - if value and value > timezone.localdate(): - msg = "The scan_date cannot be in the future!" - raise serializers.ValidationError(msg) - return value +class ReImportScanSerializer(TaggitSerializer, CommonImportScanSerializer): -class ReImportScanSerializer(TaggitSerializer, serializers.Serializer): - scan_date = serializers.DateField( - required=False, - help_text="Scan completion date will be used on all findings.", - ) - minimum_severity = serializers.ChoiceField( - choices=SEVERITY_CHOICES, - default="Info", - help_text="Minimum severity level to be imported", - ) - active = serializers.BooleanField( - help_text="Override the active setting from the tool.", - ) - verified = serializers.BooleanField( - help_text="Override the verified setting from the tool.", - ) help_do_not_reactivate = "Select if the import should ignore active findings from the report, useful for triage-less scanners. Will keep existing findings closed, without reactivating them. For more information check the docs." do_not_reactivate = serializers.BooleanField( default=False, required=False, help_text=help_do_not_reactivate, @@ -2335,35 +2341,11 @@ class ReImportScanSerializer(TaggitSerializer, serializers.Serializer): scan_type = serializers.ChoiceField( choices=get_choices_sorted(), required=True, ) - endpoint_to_add = serializers.PrimaryKeyRelatedField( - queryset=Endpoint.objects.all(), - required=False, - default=None, - help_text="Enter the ID of an Endpoint that is associated with the target Product. New Findings will be added to that Endpoint.", - ) - file = serializers.FileField(allow_empty_file=True, required=False) - product_type_name = serializers.CharField(required=False) - product_name = serializers.CharField(required=False) - engagement_name = serializers.CharField(required=False) - engagement_end_date = serializers.DateField( - required=False, - help_text="End Date for Engagement. Default is current time + 365 days. Required format year-month-day", - ) - source_code_management_uri = serializers.URLField( - max_length=600, - required=False, - help_text="Resource link to source code", - ) test = serializers.PrimaryKeyRelatedField( required=False, queryset=Test.objects.all(), ) - test_title = serializers.CharField(required=False) - auto_create_context = serializers.BooleanField(required=False) - deduplication_on_engagement = serializers.BooleanField(required=False) - - push_to_jira = serializers.BooleanField(default=False) # Close the old findings if the parameter is not provided. This is to - # mentain the old API behavior after reintroducing the close_old_findings parameter + # maintain the old API behavior after reintroducing the close_old_findings parameter # also for ReImport. close_old_findings = serializers.BooleanField( required=False, @@ -2381,113 +2363,18 @@ class ReImportScanSerializer(TaggitSerializer, serializers.Serializer): required=False, help_text="Version that will be set on existing Test object. Leave empty to leave existing value in place.", ) - build_id = serializers.CharField( - required=False, help_text="ID of the build that was scanned.", - ) - branch_tag = serializers.CharField( - required=False, help_text="Branch or Tag that was scanned.", - ) - commit_hash = serializers.CharField( - required=False, help_text="Commit that was scanned.", - ) - api_scan_configuration = serializers.PrimaryKeyRelatedField( - allow_null=True, - default=None, - queryset=Product_API_Scan_Configuration.objects.all(), - ) - service = serializers.CharField( - required=False, - help_text="A service is a self-contained piece of functionality within a Product. " - "This is an optional field which is used in deduplication and closing of old findings when set. " - "This affects the whole engagement/product depending on your deduplication scope.", - ) - environment = serializers.CharField(required=False) - lead = serializers.PrimaryKeyRelatedField( - allow_null=True, default=None, queryset=User.objects.all(), - ) tags = TagListSerializerField( required=False, allow_empty=True, help_text="Modify existing tags that help describe this scan. (Existing test tags will be overwritten)", ) - group_by = serializers.ChoiceField( - required=False, - choices=Finding_Group.GROUP_BY_OPTIONS, - help_text="Choose an option to automatically group new findings by the chosen option.", - ) - create_finding_groups_for_all_findings = serializers.BooleanField( - help_text="If set to false, finding groups will only be created when there is more than one grouped finding", - required=False, - default=True, - ) - - # extra fields populated in response - # need to use the _id suffix as without the serializer framework gets - # confused - test_id = serializers.IntegerField(read_only=True) - engagement_id = serializers.IntegerField( - read_only=True, - ) # need to use the _id suffix as without the serializer framework gets confused - product_id = serializers.IntegerField(read_only=True) - product_type_id = serializers.IntegerField(read_only=True) - - statistics = ImportStatisticsSerializer(read_only=True, required=False) - apply_tags_to_findings = serializers.BooleanField( - help_text="If set to True, the tags will be applied to the findings", - required=False, - ) - apply_tags_to_endpoints = serializers.BooleanField( - help_text="If set to True, the tags will be applied to the endpoints", - required=False, - ) - def set_context( self, data: dict, ) -> dict: - """ - Process all of the user supplied inputs to massage them into the correct - format the importer is expecting to see - """ - context = dict(data) - # update some vars - context["scan"] = data.get("file", None) - context["environment"] = Development_Environment.objects.get( - name=data.get("environment", "Development"), - ) - # Set the active/verified status based upon the overrides - if "active" in self.initial_data: - context["active"] = data.get("active") - else: - context["active"] = None - if "verified" in self.initial_data: - context["verified"] = data.get("verified") - else: - context["verified"] = None - # Change the way that endpoints are sent to the importer - if endpoints_to_add := data.get("endpoint_to_add"): - context["endpoints_to_add"] = [endpoints_to_add] - else: - context["endpoint_to_add"] = None - # Convert the tags to a list if needed. At this point, the - # TaggitListSerializer has already removed commas supplied - # by the user, so this operation will consistently return - # a list to be used by the importer - if tags := context.get("tags"): - if isinstance(tags, str): - context["tags"] = tags.split(", ") - # have to make the scan_date_time timezone aware otherwise uploads via - # the API would fail (but unit tests for api upload would pass...) - context["scan_date"] = ( - timezone.make_aware( - datetime.combine(context.get("scan_date"), datetime.min.time()), - ) - if context.get("scan_date") - else None - ) - return context + return self.setup_common_context(data) def process_auto_create_create_context( self, @@ -2511,16 +2398,6 @@ def process_auto_create_create_context( # Raise an explicit drf exception here raise ValidationError(str(e)) - def get_importer( - self, - **kwargs: dict, - ) -> BaseImporter: - """ - Returns a new instance of an importer that extends - the BaseImporter class - """ - return DefaultImporter(**kwargs) - def get_reimporter( self, **kwargs: dict, @@ -2599,33 +2476,6 @@ def save(self, push_to_jira=False): # Import the scan with all of the supplied data self.process_scan(auto_create_manager, data, context) - def validate(self, data): - scan_type = data.get("scan_type") - file = data.get("file") - if not file and requires_file(scan_type): - msg = f"Uploading a Report File is required for {scan_type}" - raise serializers.ValidationError(msg) - if file and is_scan_file_too_large(file): - msg = f"Report file is too large. Maximum supported size is {settings.SCAN_FILE_MAX_SIZE} MB" - raise serializers.ValidationError(msg) - tool_type = requires_tool_type(scan_type) - if tool_type: - api_scan_configuration = data.get("api_scan_configuration") - if ( - api_scan_configuration - and tool_type - != api_scan_configuration.tool_configuration.tool_type.name - ): - msg = f"API scan configuration must be of tool type {tool_type}" - raise serializers.ValidationError(msg) - return data - - def validate_scan_date(self, value): - if value and value > timezone.localdate(): - msg = "The scan_date cannot be in the future!" - raise serializers.ValidationError(msg) - return value - class EndpointMetaImporterSerializer(serializers.Serializer): file = serializers.FileField(required=True) diff --git a/dojo/api_v2/views.py b/dojo/api_v2/views.py index 09e7cb734b5..52978f3b241 100644 --- a/dojo/api_v2/views.py +++ b/dojo/api_v2/views.py @@ -1517,6 +1517,7 @@ class JiraProjectViewSet( "jira_instance", "product", "engagement", + "enabled", "component", "project_key", "push_all_issues", diff --git a/dojo/db_migrations/0217_jira_project_enabled.py b/dojo/db_migrations/0217_jira_project_enabled.py new file mode 100644 index 00000000000..6bde35303ba --- /dev/null +++ b/dojo/db_migrations/0217_jira_project_enabled.py @@ -0,0 +1,18 @@ +# Generated by Django 5.0.8 on 2024-10-10 17:07 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dojo', '0216_alter_jira_project_push_all_issues'), + ] + + operations = [ + migrations.AddField( + model_name='jira_project', + name='enabled', + field=models.BooleanField(blank=True, default=True, help_text='When disabled, Findings will no longer be pushed to Jira, even if they have already been pushed previously.', verbose_name='Enable Connection With Jira Project'), + ), + ] diff --git a/dojo/engagement/views.py b/dojo/engagement/views.py index 54781eed409..9cfab608896 100644 --- a/dojo/engagement/views.py +++ b/dojo/engagement/views.py @@ -16,7 +16,7 @@ from django.db import DEFAULT_DB_ALIAS from django.db.models import Count, Q from django.db.models.query import Prefetch, QuerySet -from django.http import FileResponse, HttpRequest, HttpResponse, HttpResponseRedirect, QueryDict, StreamingHttpResponse +from django.http import HttpRequest, HttpResponse, HttpResponseRedirect, QueryDict, StreamingHttpResponse from django.shortcuts import get_object_or_404, render from django.urls import Resolver404, reverse from django.utils import timezone @@ -99,6 +99,7 @@ add_success_message_to_response, async_delete, calculate_grade, + generate_file_response_from_file_path, get_cal_event, get_page_items, get_return_url, @@ -1515,7 +1516,7 @@ def upload_threatmodel(request, eid): @user_is_authorized(Engagement, Permissions.Engagement_View, "eid") def view_threatmodel(request, eid): eng = get_object_or_404(Engagement, pk=eid) - return FileResponse(open(eng.tmodel_path, "rb")) + return generate_file_response_from_file_path(eng.tmodel_path) @user_is_authorized(Engagement, Permissions.Engagement_View, "eid") diff --git a/dojo/fixtures/defect_dojo_sample_data.json b/dojo/fixtures/defect_dojo_sample_data.json index cad4786caf5..8f57b8685d4 100644 --- a/dojo/fixtures/defect_dojo_sample_data.json +++ b/dojo/fixtures/defect_dojo_sample_data.json @@ -35220,6 +35220,7 @@ "engagement": null, "component": "", "push_all_issues": false, + "enabled": true, "enable_engagement_epic_mapping": true, "push_notes": false, "product_jira_sla_notification": false, @@ -35237,6 +35238,7 @@ "engagement": null, "component": "", "push_all_issues": true, + "enabled": true, "enable_engagement_epic_mapping": true, "push_notes": true, "product_jira_sla_notification": false, @@ -35254,6 +35256,7 @@ "engagement": null, "component": "", "push_all_issues": false, + "enabled": true, "enable_engagement_epic_mapping": false, "push_notes": false, "product_jira_sla_notification": false, diff --git a/dojo/fixtures/sla_configurations.json b/dojo/fixtures/sla_configurations.json new file mode 100644 index 00000000000..f90d022581d --- /dev/null +++ b/dojo/fixtures/sla_configurations.json @@ -0,0 +1,35 @@ +[ + { + "model": "dojo.sla_configuration", + "pk": 1, + "fields": { + "name": "Default", + "description": "The Default SLA Configuration. Products not using an explicit SLA Configuration will use this one.", + "critical": 7, + "enforce_critical": true, + "high": 30, + "enforce_high": true, + "medium": 90, + "enforce_medium": true, + "low": 120, + "enforce_low": true, + "async_updating": false + } + }, + { + "model": "dojo.sla_configuration", + "fields": { + "name": "No SLA Enforced", + "description": "No SLA is enforced for a product which uses this SLA configuration.", + "critical": 7, + "enforce_critical": false, + "high": 30, + "enforce_high": false, + "medium": 90, + "enforce_medium": false, + "low": 120, + "enforce_low": false, + "async_updating": false + } + } +] diff --git a/dojo/forms.py b/dojo/forms.py index fcd37a467d7..2d58e0cd423 100644 --- a/dojo/forms.py +++ b/dojo/forms.py @@ -752,6 +752,23 @@ class UploadThreatForm(forms.Form): attrs={"accept": ".jpg,.png,.pdf"}), label="Select Threat Model") + def clean(self): + if (file := self.cleaned_data.get("file", None)) is not None: + ext = os.path.splitext(file.name)[1] # [0] returns path+filename + valid_extensions = [".jpg", ".png", ".pdf"] + if ext.lower() not in valid_extensions: + if accepted_extensions := f"{', '.join(valid_extensions)}": + msg = ( + "Unsupported extension. Supported extensions are as " + f"follows: {accepted_extensions}" + ) + else: + msg = ( + "File uploads are prohibited due to the list of acceptable " + "file extensions being empty" + ) + raise ValidationError(msg) + class MergeFindings(forms.ModelForm): FINDING_ACTION = (("", "Select an Action"), ("inactive", "Inactive"), ("delete", "Delete")) @@ -2422,7 +2439,7 @@ def clean(self): return self.cleaned_data -class JIRAForm(BaseJiraForm): +class AdvancedJIRAForm(BaseJiraForm): issue_template_dir = forms.ChoiceField(required=False, choices=JIRA_TEMPLATE_CHOICES, help_text="Choose the folder containing the Django templates used to render the JIRA issue description. These are stored in dojo/templates/issue-trackers. Leave empty to use the default jira_full templates.") @@ -2442,8 +2459,11 @@ class Meta: exclude = [""] -class ExpressJIRAForm(BaseJiraForm): +class JIRAForm(BaseJiraForm): issue_key = forms.CharField(required=True, help_text="A valid issue ID is required to gather the necessary information.") + issue_template_dir = forms.ChoiceField(required=False, + choices=JIRA_TEMPLATE_CHOICES, + help_text="Choose the folder containing the Django templates used to render the JIRA issue description. These are stored in dojo/templates/issue-trackers. Leave empty to use the default jira_full templates.") class Meta: model = JIRA_Instance @@ -2853,7 +2873,7 @@ class JIRAProjectForm(forms.ModelForm): class Meta: model = JIRA_Project exclude = ["product", "engagement"] - fields = ["inherit_from_product", "jira_instance", "project_key", "issue_template_dir", "epic_issue_type_name", "component", "custom_fields", "jira_labels", "default_assignee", "add_vulnerability_id_to_jira_label", "push_all_issues", "enable_engagement_epic_mapping", "push_notes", "product_jira_sla_notification", "risk_acceptance_expiration_notification"] + fields = ["inherit_from_product", "jira_instance", "project_key", "issue_template_dir", "epic_issue_type_name", "component", "custom_fields", "jira_labels", "default_assignee", "enabled", "add_vulnerability_id_to_jira_label", "push_all_issues", "enable_engagement_epic_mapping", "push_notes", "product_jira_sla_notification", "risk_acceptance_expiration_notification"] def __init__(self, *args, **kwargs): from dojo.jira_link import helper as jira_helper @@ -2891,6 +2911,7 @@ def __init__(self, *args, **kwargs): self.fields["custom_fields"].disabled = False self.fields["default_assignee"].disabled = False self.fields["jira_labels"].disabled = False + self.fields["enabled"].disabled = False self.fields["add_vulnerability_id_to_jira_label"].disabled = False self.fields["push_all_issues"].disabled = False self.fields["enable_engagement_epic_mapping"].disabled = False @@ -2915,6 +2936,7 @@ def __init__(self, *args, **kwargs): self.initial["custom_fields"] = jira_project_product.custom_fields self.initial["default_assignee"] = jira_project_product.default_assignee self.initial["jira_labels"] = jira_project_product.jira_labels + self.initial["enabled"] = jira_project_product.enabled self.initial["add_vulnerability_id_to_jira_label"] = jira_project_product.add_vulnerability_id_to_jira_label self.initial["push_all_issues"] = jira_project_product.push_all_issues self.initial["enable_engagement_epic_mapping"] = jira_project_product.enable_engagement_epic_mapping @@ -2930,6 +2952,7 @@ def __init__(self, *args, **kwargs): self.fields["custom_fields"].disabled = True self.fields["default_assignee"].disabled = True self.fields["jira_labels"].disabled = True + self.fields["enabled"].disabled = True self.fields["add_vulnerability_id_to_jira_label"].disabled = True self.fields["push_all_issues"].disabled = True self.fields["enable_engagement_epic_mapping"].disabled = True diff --git a/dojo/home/views.py b/dojo/home/views.py index 67e90bec106..3f5c5870d0a 100644 --- a/dojo/home/views.py +++ b/dojo/home/views.py @@ -32,7 +32,7 @@ def dashboard(request: HttpRequest) -> HttpResponse: date_range = [today - timedelta(days=6), today] # 7 days (6 days plus today) finding_count = findings\ - .filter(created__date__range=date_range)\ + .filter(date__range=date_range)\ .count() mitigated_count = findings\ .filter(mitigated__date__range=date_range)\ diff --git a/dojo/jira_link/helper.py b/dojo/jira_link/helper.py index c05f8808260..860f4f01d1b 100644 --- a/dojo/jira_link/helper.py +++ b/dojo/jira_link/helper.py @@ -71,11 +71,12 @@ def is_jira_configured_and_enabled(obj): if not is_jira_enabled(): return False - if get_jira_project(obj) is None: + jira_project = get_jira_project(obj) + if jira_project is None: logger.debug('JIRA project not found for: "%s" not doing anything', obj) return False - return True + return jira_project.enabled def is_push_to_jira(instance, push_to_jira_parameter=None): @@ -88,6 +89,10 @@ def is_push_to_jira(instance, push_to_jira_parameter=None): if push_to_jira_parameter is not None: return push_to_jira_parameter + # Check to see if jira project is disabled to prevent pushing findings + if not jira_project.enabled: + return False + # push_to_jira was not specified, so look at push_all_issues in JIRA_Project return jira_project.push_all_issues @@ -96,8 +101,10 @@ def is_push_all_issues(instance): if not is_jira_configured_and_enabled(instance): return False - jira_project = get_jira_project(instance) - if jira_project: + if jira_project := get_jira_project(instance): + # Check to see if jira project is disabled to prevent pushing findings + if not jira_project.enabled: + return None return jira_project.push_all_issues return None @@ -108,9 +115,13 @@ def is_push_all_issues(instance): # returns True/False, error_message, error_code def can_be_pushed_to_jira(obj, form=None): # logger.debug('can be pushed to JIRA: %s', finding_or_form) - if not get_jira_project(obj): + jira_project = get_jira_project(obj) + if not jira_project: return False, f"{to_str_typed(obj)} cannot be pushed to jira as there is no jira project configuration for this product.", "error_no_jira_project" + if not jira_project.enabled: + return False, f"{to_str_typed(obj)} cannot be pushed to jira as the jira project is not enabled.", "error_no_jira_project" + if not hasattr(obj, "has_jira_issue"): return False, f"{to_str_typed(obj)} cannot be pushed to jira as there is no jira_issue attribute.", "error_no_jira_issue_attribute" @@ -148,7 +159,13 @@ def can_be_pushed_to_jira(obj, form=None): elif isinstance(obj, Finding_Group): if not obj.findings.all(): return False, f"{to_str_typed(obj)} cannot be pushed to jira as it is empty.", "error_empty" - if "Active" not in obj.status(): + # Accommodating a strange behavior where a finding group sometimes prefers `obj.status` rather than `obj.status()` + try: + not_active = "Active" not in obj.status() + except TypeError: # TypeError: 'str' object is not callable + not_active = "Active" not in obj.status + # Determine if the finding group is not active + if not_active: return False, f"{to_str_typed(obj)} cannot be pushed to jira as it is not active.", "error_inactive" else: @@ -1389,6 +1406,13 @@ def add_comment(obj, note, force_push=False, **kwargs): def add_simple_jira_comment(jira_instance, jira_issue, comment): try: + jira_project = get_jira_project(jira_issue) + + # Check to see if jira project is disabled to prevent pushing findings + if not jira_project.enabled: + log_jira_generic_alert("JIRA Project is disabled", "Push to JIRA for Epic skipped because JIRA Project is disabled") + return False + jira = get_jira_connection(jira_instance) jira.add_comment( @@ -1403,9 +1427,13 @@ def add_simple_jira_comment(jira_instance, jira_issue, comment): def finding_link_jira(request, finding, new_jira_issue_key): logger.debug("linking existing jira issue %s for finding %i", new_jira_issue_key, finding.id) - existing_jira_issue = jira_get_issue(get_jira_project(finding), new_jira_issue_key) - jira_project = get_jira_project(finding) + existing_jira_issue = jira_get_issue(jira_project, new_jira_issue_key) + + # Check to see if jira project is disabled to prevent pushing findings + if not jira_project.enabled: + add_error_message_to_response("Push to JIRA for finding skipped because JIRA Project is disabled") + return False if not existing_jira_issue: raise ValueError("JIRA issue not found or cannot be retrieved: " + new_jira_issue_key) @@ -1433,9 +1461,13 @@ def finding_link_jira(request, finding, new_jira_issue_key): def finding_group_link_jira(request, finding_group, new_jira_issue_key): logger.debug("linking existing jira issue %s for finding group %i", new_jira_issue_key, finding_group.id) - existing_jira_issue = jira_get_issue(get_jira_project(finding_group), new_jira_issue_key) - jira_project = get_jira_project(finding_group) + existing_jira_issue = jira_get_issue(jira_project, new_jira_issue_key) + + # Check to see if jira project is disabled to prevent pushing findings + if not jira_project.enabled: + add_error_message_to_response("Push to JIRA for group skipped because JIRA Project is disabled") + return False if not existing_jira_issue: raise ValueError("JIRA issue not found or cannot be retrieved: " + new_jira_issue_key) diff --git a/dojo/jira_link/urls.py b/dojo/jira_link/urls.py index 84abc6faef6..97295ddea49 100644 --- a/dojo/jira_link/urls.py +++ b/dojo/jira_link/urls.py @@ -8,7 +8,8 @@ re_path(r"^jira/webhook/(?P[\w-]+)$", views.webhook, name="jira_web_hook_secret"), re_path(r"^jira/webhook/", views.webhook, name="jira_web_hook"), re_path(r"^jira/add", views.NewJiraView.as_view(), name="add_jira"), + re_path(r"^jira/advanced", views.AdvancedJiraView.as_view(), name="add_jira_advanced"), re_path(r"^jira/(?P\d+)/edit$", views.EditJiraView.as_view(), name="edit_jira"), re_path(r"^jira/(?P\d+)/delete$", views.DeleteJiraView.as_view(), name="delete_jira"), re_path(r"^jira$", views.ListJiraView.as_view(), name="jira"), - re_path(r"^jira/express", views.ExpressJiraView.as_view(), name="express_jira")] +] diff --git a/dojo/jira_link/views.py b/dojo/jira_link/views.py index 7ab70a1f5a4..0461f600dee 100644 --- a/dojo/jira_link/views.py +++ b/dojo/jira_link/views.py @@ -22,7 +22,7 @@ from dojo.authorization.authorization import user_has_configuration_permission # Local application/library imports -from dojo.forms import DeleteJIRAInstanceForm, ExpressJIRAForm, JIRAForm +from dojo.forms import AdvancedJIRAForm, DeleteJIRAInstanceForm, JIRAForm from dojo.models import JIRA_Instance, JIRA_Issue, Notes, System_Settings, User from dojo.notifications.helper import create_notification from dojo.utils import add_breadcrumb, add_error_message_to_response, get_setting @@ -285,24 +285,24 @@ def get_custom_field(jira, label): return field -class ExpressJiraView(View): +class NewJiraView(View): def get_template(self): - return "dojo/express_new_jira.html" + return "dojo/new_jira.html" def get_fallback_template(self): - return "dojo/new_jira.html" + return "dojo/new_jira_advanced.html" def get_form_class(self): - return ExpressJIRAForm + return JIRAForm def get_fallback_form_class(self): - return JIRAForm + return AdvancedJIRAForm def get(self, request): if not user_has_configuration_permission(request.user, "dojo.add_jira_instance"): raise PermissionDenied jform = self.get_form_class()() - add_breadcrumb(title="New Jira Configuration (Express)", top_level=False, request=request) + add_breadcrumb(title="New Jira Configuration", top_level=False, request=request) return render(request, self.get_template(), {"jform": jform}) def post(self, request): @@ -391,18 +391,18 @@ def post(self, request): return render(request, self.get_template(), {"jform": jform}) -class NewJiraView(View): +class AdvancedJiraView(View): def get_template(self): - return "dojo/new_jira.html" + return "dojo/new_jira_advanced.html" def get_form_class(self): - return JIRAForm + return AdvancedJIRAForm def get(self, request): if not user_has_configuration_permission(request.user, "dojo.add_jira_instance"): raise PermissionDenied jform = self.get_form_class()() - add_breadcrumb(title="New Jira Configuration", top_level=False, request=request) + add_breadcrumb(title="New Jira Configuration (Advanced)", top_level=False, request=request) return render(request, self.get_template(), {"jform": jform}) def post(self, request): @@ -442,7 +442,7 @@ def get_template(self): return "dojo/edit_jira.html" def get_form_class(self): - return JIRAForm + return AdvancedJIRAForm def get(self, request, jid=None): if not user_has_configuration_permission(request.user, "dojo.change_jira_instance"): diff --git a/dojo/models.py b/dojo/models.py index aec1549d49d..b4a163f1a78 100644 --- a/dojo/models.py +++ b/dojo/models.py @@ -3918,9 +3918,17 @@ class JIRA_Project(models.Model): push_notes = models.BooleanField(default=False, blank=True) product_jira_sla_notification = models.BooleanField(default=False, blank=True, verbose_name=_("Send SLA notifications as comment?")) risk_acceptance_expiration_notification = models.BooleanField(default=False, blank=True, verbose_name=_("Send Risk Acceptance expiration notifications as comment?")) + enabled = models.BooleanField( + verbose_name=_("Enable Connection With Jira Project"), + help_text=_("When disabled, Findings will no longer be pushed to Jira, even if they have already been pushed previously."), + default=True, + blank=True) def __str__(self): - return ("%s: " + self.project_key + "(%s)") % (str(self.id), str(self.jira_instance.url) if self.jira_instance else "None") + value = f"{self.id}: {self.project_key} ({self.jira_instance.url if self.jira_instance else 'None'})" + if not self.enabled: + value += " - Not Connected" + return value def clean(self): if not self.jira_instance: diff --git a/dojo/reports/views.py b/dojo/reports/views.py index b9505ada877..667cb0bb6ac 100644 --- a/dojo/reports/views.py +++ b/dojo/reports/views.py @@ -948,6 +948,7 @@ def get(self, request): except Exception as exc: logger.error("Error in attribute: " + str(exc)) cell = worksheet.cell(row=row_num, column=col_num, value=key) + col_num += 1 continue cell = worksheet.cell(row=row_num, column=col_num, value="found_by") cell.font = font_bold @@ -999,6 +1000,7 @@ def get(self, request): except Exception as exc: logger.error("Error in attribute: " + str(exc)) worksheet.cell(row=row_num, column=col_num, value="Value not supported") + col_num += 1 continue worksheet.cell(row=row_num, column=col_num, value=finding.test.test_type.name) col_num += 1 diff --git a/dojo/settings/settings.dist.py b/dojo/settings/settings.dist.py index 354607a5d5c..ae0afaaabda 100644 --- a/dojo/settings/settings.dist.py +++ b/dojo/settings/settings.dist.py @@ -1516,6 +1516,7 @@ def saml2_attrib_map_format(dict): "ThreatComposer Scan": DEDUPE_ALGO_UNIQUE_ID_FROM_TOOL_OR_HASH_CODE, "Invicti Scan": DEDUPE_ALGO_HASH_CODE, "KrakenD Audit Scan": DEDUPE_ALGO_HASH_CODE, + "PTART Report": DEDUPE_ALGO_UNIQUE_ID_FROM_TOOL, } # Override the hardcoded settings here via the env var @@ -1735,6 +1736,10 @@ def saml2_attrib_map_format(dict): "RHEA": "https://access.redhat.com/errata/", "FEDORA": "https://bodhi.fedoraproject.org/updates/", "ALSA": "https://osv.dev/vulnerability/", # e.g. https://osv.dev/vulnerability/ALSA-2024:0827 + "USN": "https://ubuntu.com/security/notices/", # e.g. https://ubuntu.com/security/notices/USN-6642-1 + "DLA": "https://security-tracker.debian.org/tracker/", # e.g. https://security-tracker.debian.org/tracker/DLA-3917-1 + "ELSA": "https://linux.oracle.com/errata/&&.html", # e.g. https://linux.oracle.com/errata/ELSA-2024-12714.html + "RXSA": "https://errata.rockylinux.org/", # e.g. https://errata.rockylinux.org/RXSA-2024:4928 } # List of acceptable file types that can be uploaded to a given object via arbitrary file upload FILE_UPLOAD_TYPES = env("DD_FILE_UPLOAD_TYPES") diff --git a/dojo/templates/base.html b/dojo/templates/base.html index 9515d68d349..5470baf13bd 100644 --- a/dojo/templates/base.html +++ b/dojo/templates/base.html @@ -589,8 +589,8 @@ {% block support-tab %}
  • {% endblock %} diff --git a/dojo/templates/dojo/express_new_jira.html b/dojo/templates/dojo/express_new_jira.html deleted file mode 100644 index 4394c5d6bbc..00000000000 --- a/dojo/templates/dojo/express_new_jira.html +++ /dev/null @@ -1,16 +0,0 @@ -{% extends "base.html"%} -{% block content %} - {{ block.super }} -

    Add a JIRA Configuration Express

    -
    {% csrf_token %} - {% include "dojo/form_fields.html" with form=jform %} -
    -
    - -
    -

    - Finding severity mappings and other options can be edited after express configuration is complete. -
    -
    -
    -{% endblock %} diff --git a/dojo/templates/dojo/jira.html b/dojo/templates/dojo/jira.html index a3208648d64..1068cf7c4ca 100644 --- a/dojo/templates/dojo/jira.html +++ b/dojo/templates/dojo/jira.html @@ -19,13 +19,13 @@

    diff --git a/dojo/templates/dojo/new_jira.html b/dojo/templates/dojo/new_jira.html index 232117681cb..6f4cb6e055e 100644 --- a/dojo/templates/dojo/new_jira.html +++ b/dojo/templates/dojo/new_jira.html @@ -6,8 +6,11 @@

    Add a JIRA Configuration

    {% include "dojo/form_fields.html" with form=jform %}
    - + +
    +

    + Finding severity mappings and other options can be edited after configuration is complete.
    -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/dojo/templates/dojo/new_jira_advanced.html b/dojo/templates/dojo/new_jira_advanced.html new file mode 100644 index 00000000000..2af3a37c600 --- /dev/null +++ b/dojo/templates/dojo/new_jira_advanced.html @@ -0,0 +1,13 @@ +{% extends "base.html"%} +{% block content %} + {{ block.super }} +

    Add a JIRA Configuration (Advanced)

    +
    {% csrf_token %} + {% include "dojo/form_fields.html" with form=jform %} +
    +
    + +
    +
    +
    +{% endblock %} \ No newline at end of file diff --git a/dojo/templates/dojo/support.html b/dojo/templates/dojo/support.html index fd0a49a095b..45066a551f9 100644 --- a/dojo/templates/dojo/support.html +++ b/dojo/templates/dojo/support.html @@ -14,24 +14,68 @@

    Community Support

    What's included:

    Support from the community via OWASP Slack

    -

    Community based discussion

    +

    Community-based discussion

    Join #defectdojo
    -

    Get DefectDojo Pro

    +

    Go Pro!

    What's included:

    -

    Support directly from the creators

    -

    Additional features

    -

    Response time SLA

    -

    Bug fixes

    -

    Feature enhancements

    -

    Best practice advice

    +

    New UI + + +

    +

    Connectors + + +

    +

    Insights + + +

    +

    Data Enrichment + + +

    +

    Universal Importer + + +

    +

    Async Functions + + +

    +

    Support directly from the DefectDojo Team

    +

    Assistance with best practice and implementation

    - Meet The Creators + Go Pro Now
    diff --git a/dojo/templates/dojo/view_test.html b/dojo/templates/dojo/view_test.html index 55bcb4ff8de..a4e0390b91a 100644 --- a/dojo/templates/dojo/view_test.html +++ b/dojo/templates/dojo/view_test.html @@ -1080,8 +1080,7 @@

    {% endif %} {% if finding.test.engagement.product.enable_full_risk_acceptance %}
  • - + {% trans "Add Risk Acceptance..." %}
  • diff --git a/dojo/templatetags/display_tags.py b/dojo/templatetags/display_tags.py index e00603f9eec..7b634febf63 100644 --- a/dojo/templatetags/display_tags.py +++ b/dojo/templatetags/display_tags.py @@ -780,6 +780,8 @@ def vulnerability_url(vulnerability_id): for key in settings.VULNERABILITY_URLS: if vulnerability_id.upper().startswith(key): + if "&&" in settings.VULNERABILITY_URLS[key]: + return settings.VULNERABILITY_URLS[key].split("&&")[0] + str(vulnerability_id) + settings.VULNERABILITY_URLS[key].split("&&")[1] return settings.VULNERABILITY_URLS[key] + str(vulnerability_id) return "" diff --git a/dojo/tools/awssecurityhub/parser.py b/dojo/tools/awssecurityhub/parser.py index 3d07d2554c7..e59afa23ce3 100644 --- a/dojo/tools/awssecurityhub/parser.py +++ b/dojo/tools/awssecurityhub/parser.py @@ -28,7 +28,7 @@ def get_tests(self, scan_type, scan): aws_acc = [] for finding in findings: prod.append(finding.get("ProductName", "AWS Security Hub Ruleset")) - aws_acc.append(finding.get("AwsAccountId")) + aws_acc.append(finding.get("AwsAccountId", "No Account Found")) report_date = data.get("createdAt") test = ParserTest( name=self.ID, type=self.ID, version="", diff --git a/dojo/tools/netsparker/parser.py b/dojo/tools/netsparker/parser.py index 35a08920542..47b81a2a65b 100644 --- a/dojo/tools/netsparker/parser.py +++ b/dojo/tools/netsparker/parser.py @@ -3,6 +3,7 @@ import html2text from cvss import parser as cvss_parser +from dateutil import parser as date_parser from dojo.models import Endpoint, Finding @@ -24,14 +25,20 @@ def get_findings(self, filename, test): except Exception: data = json.loads(tree) dupes = {} - if "UTC" in data["Generated"]: - scan_date = datetime.datetime.strptime( - data["Generated"].split(" ")[0], "%d/%m/%Y", - ).date() - else: - scan_date = datetime.datetime.strptime( - data["Generated"], "%d/%m/%Y %H:%M %p", - ).date() + try: + if "UTC" in data["Generated"]: + scan_date = datetime.datetime.strptime( + data["Generated"].split(" ")[0], "%d/%m/%Y", + ).date() + else: + scan_date = datetime.datetime.strptime( + data["Generated"], "%d/%m/%Y %H:%M %p", + ).date() + except ValueError: + try: + scan_date = date_parser.parse(data["Generated"]) + except date_parser.ParserError: + scan_date = None for item in data["Vulnerabilities"]: title = item["Name"] diff --git a/dojo/tools/osv_scanner/parser.py b/dojo/tools/osv_scanner/parser.py index 42e9408825c..f91ec10f7d9 100644 --- a/dojo/tools/osv_scanner/parser.py +++ b/dojo/tools/osv_scanner/parser.py @@ -30,26 +30,34 @@ def get_findings(self, file, test): except json.decoder.JSONDecodeError: return [] findings = [] - for result in data["results"]: - source_path = result["source"]["path"] - source_type = result["source"]["type"] - for package in result["packages"]: - package_name = package["package"]["name"] - package_version = package["package"]["version"] - package_ecosystem = package["package"]["ecosystem"] - for vulnerability in package["vulnerabilities"]: + for result in data.get("results", []): + # Extract source locations if present + source_path = result.get("source", {}).get("path", "") + source_type = result.get("source", {}).get("type", "") + for package in result.get("packages", []): + package_name = package.get("package", {}).get("name") + package_version = package.get("package", {}).get("version") + package_ecosystem = package.get("package", {}).get("ecosystem", "") + for vulnerability in package.get("vulnerabilities", []): vulnerabilityid = vulnerability.get("id", "") vulnerabilitysummary = vulnerability.get("summary", "") - vulnerabilitydetails = vulnerability["details"] - vulnerabilitypackagepurl = vulnerability["affected"][0].get("package", "") - if vulnerabilitypackagepurl != "": - vulnerabilitypackagepurl = vulnerabilitypackagepurl["purl"] - cwe = vulnerability["affected"][0]["database_specific"].get("cwes", None) - if cwe is not None: - cwe = cwe[0]["cweId"] + vulnerabilitydetails = vulnerability.get("details", "") + vulnerabilitypackagepurl = "" + cwe = None + # Make sure we have an affected section to work with + if (affected := vulnerability.get("affected")) is not None: + if len(affected) > 0: + # Pull the package purl if present + if (vulnerabilitypackage := affected[0].get("package", "")) != "": + vulnerabilitypackagepurl = vulnerabilitypackage.get("purl", "") + # Extract the CWE + if (cwe := affected[0].get("database_specific", {}).get("cwes", None)) is not None: + cwe = cwe[0]["cweId"] + # Create some references reference = "" for ref in vulnerability.get("references"): reference += ref.get("url") + "\n" + # Define the description description = vulnerabilitysummary + "\n" description += "**source_type**: " + source_type + "\n" description += "**package_ecosystem**: " + package_ecosystem + "\n" diff --git a/dojo/tools/ptart/__init__.py b/dojo/tools/ptart/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/dojo/tools/ptart/assessment_parser.py b/dojo/tools/ptart/assessment_parser.py new file mode 100644 index 00000000000..02387a7d65d --- /dev/null +++ b/dojo/tools/ptart/assessment_parser.py @@ -0,0 +1,62 @@ +import dojo.tools.ptart.ptart_parser_tools as ptart_tools +from dojo.models import Finding + + +class PTARTAssessmentParser: + def __init__(self): + self.cvss_type = None + + def get_test_data(self, tree): + # Check that the report is valid, If we have no assessments, then + # return an empty list + if "assessments" not in tree: + return [] + + self.cvss_type = tree.get("cvss_type", None) + assessments = tree["assessments"] + return [finding for assessment in assessments + for finding in self.parse_assessment(assessment)] + + def parse_assessment(self, assessment): + hits = assessment.get("hits", []) + return [self.get_finding(assessment, hit) for hit in hits] + + def get_finding(self, assessment, hit): + effort = ptart_tools.parse_ptart_fix_effort(hit.get("fix_complexity")) + finding = Finding( + title=ptart_tools.parse_title_from_hit(hit), + severity=ptart_tools.parse_ptart_severity(hit.get("severity")), + effort_for_fixing=effort, + component_name=assessment.get("title", "Unknown Component"), + date=ptart_tools.parse_date_added_from_hit(hit), + ) + + # Don't add fields if they are blank + if hit["body"]: + finding.description = hit.get("body") + + if hit["remediation"]: + finding.mitigation = hit.get("remediation") + + if hit["id"]: + finding.unique_id_from_tool = hit.get("id") + finding.vuln_id_from_tool = hit.get("id") + finding.cve = hit.get("id") + + # Clean up and parse the CVSS vector + cvss_vector = ptart_tools.parse_cvss_vector(hit, self.cvss_type) + if cvss_vector: + finding.cvssv3 = cvss_vector + + if "labels" in hit: + finding.unsaved_tags = hit["labels"] + + finding.unsaved_endpoints = ptart_tools.parse_endpoints_from_hit(hit) + + # Add screenshots to files, and add other attachments as well. + finding.unsaved_files = ptart_tools.parse_screenshots_from_hit(hit) + finding.unsaved_files.extend(ptart_tools.parse_attachment_from_hit(hit)) + + finding.references = ptart_tools.parse_references_from_hit(hit) + + return finding diff --git a/dojo/tools/ptart/parser.py b/dojo/tools/ptart/parser.py new file mode 100644 index 00000000000..c52ebf4fb49 --- /dev/null +++ b/dojo/tools/ptart/parser.py @@ -0,0 +1,77 @@ +import json + +import dojo.tools.ptart.ptart_parser_tools as ptart_tools +from dojo.tools.parser_test import ParserTest +from dojo.tools.ptart.assessment_parser import PTARTAssessmentParser +from dojo.tools.ptart.retest_parser import PTARTRetestParser + + +class PTARTParser: + + """ + Imports JSON reports from the PTART reporting tool + (https://github.com/certmichelin/PTART) + """ + + def get_scan_types(self): + return ["PTART Report"] + + def get_label_for_scan_types(self, scan_type): + return "PTART Report" + + def get_description_for_scan_types(self, scan_type): + return "Import a PTART report file in JSON format." + + def get_tests(self, scan_type, scan): + data = json.load(scan) + + test = ParserTest( + name="Pen Test Report", + type="Pen Test", + version="", + ) + + # We set both to the same value for now, setting just the name doesn't + # seem to display when imported. This may cause issues with the UI in + # the future, but there's not much (read no) documentation on this. + if "name" in data: + test.name = data["name"] + " Report" + test.type = data["name"] + " Report" + + # Generate a description from the various fields in the report data + description = ptart_tools.generate_test_description_from_report(data) + + # Check that the fields are filled, otherwise don't set the description + if description: + test.description = description + + # Setting the dates doesn't seem to want to work in reality :( + # Perhaps in a future version of DefectDojo? + if "start_date" in data: + test.target_start = ptart_tools.parse_date( + data["start_date"], "%Y-%m-%d", + ) + + if "end_date" in data: + test.target_end = ptart_tools.parse_date( + data["end_date"], "%Y-%m-%d", + ) + + findings = self.get_items(data) + test.findings = findings + return [test] + + def get_findings(self, file, test): + data = json.load(file) + return self.get_items(data) + + def get_items(self, data): + # We have several main sections in the report json: Assessments and + # Retest Campaigns. I haven't been able to create multiple tests for + # each section, so we'll just merge them for now. + findings = PTARTAssessmentParser().get_test_data(data) + findings.extend(PTARTRetestParser().get_test_data(data)) + return findings + + def requires_file(self, scan_type): + return True diff --git a/dojo/tools/ptart/ptart_parser_tools.py b/dojo/tools/ptart/ptart_parser_tools.py new file mode 100644 index 00000000000..f538a81f3c5 --- /dev/null +++ b/dojo/tools/ptart/ptart_parser_tools.py @@ -0,0 +1,187 @@ +import pathlib +from datetime import datetime + +import cvss + +from dojo.models import Endpoint + +ATTACHMENT_ERROR = "Attachment data not found" +SCREENSHOT_ERROR = "Screenshot data not found" + + +def parse_ptart_severity(severity): + severity_mapping = { + 1: "Critical", + 2: "High", + 3: "Medium", + 4: "Low", + } + return severity_mapping.get(severity, "Info") # Default severity + + +def parse_ptart_fix_effort(effort): + effort_mapping = { + 1: "High", + 2: "Medium", + 3: "Low", + } + return effort_mapping.get(effort, None) + + +def parse_title_from_hit(hit): + hit_title = hit.get("title", None) + hit_id = hit.get("id", None) + + return f"{hit_id}: {hit_title}" \ + if hit_title and hit_id \ + else (hit_title or hit_id or "Unknown Hit") + + +def parse_date_added_from_hit(hit): + PTART_DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%f" + date_added = hit.get("added", None) + return parse_date(date_added, PTART_DATETIME_FORMAT) + + +def parse_date(date, format): + try: + return datetime.strptime(date, format) if date else datetime.now() + except ValueError: + return datetime.now() + + +def parse_cvss_vector(hit, cvss_type): + cvss_vector = hit.get("cvss_vector", None) + # Defect Dojo Only supports CVSS v3 for now. + if cvss_vector: + # Similar application once CVSS v4 is supported + if cvss_type == 3: + try: + c = cvss.CVSS3(cvss_vector) + return c.clean_vector() + except cvss.CVSS3Error: + return None + return None + + +def parse_retest_status(status): + fix_status_mapping = { + "F": "Fixed", + "NF": "Not Fixed", + "PF": "Partially Fixed", + "NA": "Not Applicable", + "NT": "Not Tested", + } + return fix_status_mapping.get(status, None) + + +def parse_screenshots_from_hit(hit): + if "screenshots" not in hit: + return [] + screenshots = [parse_screenshot_data(screenshot) + for screenshot in hit["screenshots"]] + return [ss for ss in screenshots if ss is not None] + + +def parse_screenshot_data(screenshot): + try: + title = get_screenshot_title(screenshot) + data = get_screenshot_data(screenshot) + return { + "title": title, + "data": data, + } + except ValueError: + return None + + +def get_screenshot_title(screenshot): + caption = screenshot.get("caption", "screenshot") + if not caption: + caption = "screenshot" + return f"{caption}{get_file_suffix_from_screenshot(screenshot)}" + + +def get_screenshot_data(screenshot): + if ("screenshot" not in screenshot + or "data" not in screenshot["screenshot"] + or not screenshot["screenshot"]["data"]): + raise ValueError(SCREENSHOT_ERROR) + return screenshot["screenshot"]["data"] + + +def get_file_suffix_from_screenshot(screenshot): + return pathlib.Path(screenshot["screenshot"]["filename"]).suffix \ + if ("screenshot" in screenshot + and "filename" in screenshot["screenshot"]) \ + else "" + + +def parse_attachment_from_hit(hit): + if "attachments" not in hit: + return [] + files = [parse_attachment_data(attachment) + for attachment in hit["attachments"]] + return [f for f in files if f is not None] + + +def parse_attachment_data(attachment): + try: + title = get_attachement_title(attachment) + data = get_attachment_data(attachment) + return { + "title": title, + "data": data, + } + except ValueError: + # No data in attachment, let's not import this file. + return None + + +def get_attachment_data(attachment): + if "data" not in attachment or not attachment["data"]: + raise ValueError(ATTACHMENT_ERROR) + return attachment["data"] + + +def get_attachement_title(attachment): + title = attachment.get("title", "attachment") + if not title: + title = "attachment" + return title + + +def parse_endpoints_from_hit(hit): + if "asset" not in hit or not hit["asset"]: + return [] + endpoint = Endpoint.from_uri(hit["asset"]) + return [endpoint] + + +def generate_test_description_from_report(data): + keys = ["executive_summary", "engagement_overview", "conclusion"] + clauses = [clause for clause in [data.get(key) for key in keys] if clause] + description = "\n\n".join(clauses) + return description or None + + +def parse_references_from_hit(hit): + if "references" not in hit: + return None + + references = hit.get("references", []) + all_refs = [get_transformed_reference(ref) for ref in references] + clean_refs = [tref for tref in all_refs if tref] + if not clean_refs: + return None + return "\n".join(clean_refs) + + +def get_transformed_reference(reference): + title = reference.get("name", "Reference") + url = reference.get("url", None) + if not url: + if not title: + return url + return None + return f"{title}: {url}" diff --git a/dojo/tools/ptart/retest_parser.py b/dojo/tools/ptart/retest_parser.py new file mode 100644 index 00000000000..812a458344a --- /dev/null +++ b/dojo/tools/ptart/retest_parser.py @@ -0,0 +1,102 @@ +import dojo.tools.ptart.ptart_parser_tools as ptart_tools +from dojo.models import Finding + + +def generate_retest_hit_title(hit, original_hit): + # Fake a title for the retest hit with the fix status if available + title = original_hit.get("title", "") + hit_id = hit.get("id", None) + if "status" in hit: + title = f"{title} ({ptart_tools.parse_retest_status(hit['status'])})" + fake_retest_hit = { + "title": title, + "id": hit_id, + } + return ptart_tools.parse_title_from_hit(fake_retest_hit) + + +class PTARTRetestParser: + def __init__(self): + self.cvss_type = None + + def get_test_data(self, tree): + if "retests" in tree: + self.cvss_type = tree.get("cvss_type", None) + retests = tree["retests"] + else: + return [] + + return [finding for retest in retests + for finding in self.parse_retest(retest)] + + def parse_retest(self, retest): + hits = retest.get("hits", []) + # Get all the potential findings, valid or not. + all_findings = [self.get_finding(retest, hit) for hit in hits] + # We want to make sure we include only valid findings for a retest. + return [finding for finding in all_findings if finding is not None] + + def get_finding(self, retest, hit): + + # The negatives are a bit confusing, but we want to skip hits that + # don't have an original hit. Hit is invalid in a retest if not linked + # to an original. + if "original_hit" not in hit or not hit["original_hit"]: + return None + + # Get the original hit from the retest + original_hit = hit["original_hit"] + + # Set the Finding title to the original hit title with the retest + # status if available. We don't really have any other places to set + # this field. + finding_title = generate_retest_hit_title(hit, original_hit) + + # As the retest hit doesn't have a date added, use the start of the + # retest campaign as something that's close enough. + finding = Finding( + title=finding_title, + severity=ptart_tools.parse_ptart_severity( + original_hit.get("severity"), + ), + effort_for_fixing=ptart_tools.parse_ptart_fix_effort( + original_hit.get("fix_complexity"), + ), + component_name=f"Retest: {retest.get('name', 'Retest')}", + date=ptart_tools.parse_date( + retest.get("start_date"), + "%Y-%m-%d", + ), + ) + + # Don't add the fields if they are blank. + if hit["body"]: + finding.description = hit.get("body") + + if original_hit["remediation"]: + finding.mitigation = original_hit.get("remediation") + + if hit["id"]: + finding.unique_id_from_tool = hit.get("id") + finding.vuln_id_from_tool = original_hit.get("id") + finding.cve = original_hit.get("id") + + cvss_vector = ptart_tools.parse_cvss_vector( + original_hit, + self.cvss_type, + ) + if cvss_vector: + finding.cvssv3 = cvss_vector + + if "labels" in original_hit: + finding.unsaved_tags = original_hit["labels"] + + finding.unsaved_endpoints = ptart_tools.parse_endpoints_from_hit( + original_hit, + ) + + # We only have screenshots in a retest. Refer to the original hit for + # the attachments. + finding.unsaved_files = ptart_tools.parse_screenshots_from_hit(hit) + + return finding diff --git a/dojo/tools/redhatsatellite/parser.py b/dojo/tools/redhatsatellite/parser.py index 102f47876ff..897273d8a18 100644 --- a/dojo/tools/redhatsatellite/parser.py +++ b/dojo/tools/redhatsatellite/parser.py @@ -62,7 +62,10 @@ def get_findings(self, filename, test): description += "**hosts_applicable_count:** " + str(hosts_applicable_count) + "\n" description += "**installable:** " + str(installable) + "\n" if bugs != []: - description += "**bugs:** " + str(bugs) + "\n" + description += "**bugs:** " + for bug in bugs[:-1]: + description += "[" + bug.get("bug_id") + "](" + bug.get("href") + ")" + ", " + description += "[" + bugs[-1].get("bug_id") + "](" + bugs[-1].get("href") + ")" + "\n" if module_streams != []: description += "**module_streams:** " + str(module_streams) + "\n" description += "**packages:** " + ", ".join(packages) diff --git a/dojo/tools/sonarqube/sonarqube_restapi_json.py b/dojo/tools/sonarqube/sonarqube_restapi_json.py index 9a8e3bab226..3caf725c4e5 100644 --- a/dojo/tools/sonarqube/sonarqube_restapi_json.py +++ b/dojo/tools/sonarqube/sonarqube_restapi_json.py @@ -115,6 +115,7 @@ def get_json_items(self, json_content, test, mode): component_version=component_version, cwe=cwe, cvssv3_score=cvss, + file_path=component, tags=["vulnerability"], ) vulnids = [] @@ -183,6 +184,7 @@ def get_json_items(self, json_content, test, mode): severity=self.severitytranslator(issue.get("severity")), static_finding=True, dynamic_finding=False, + file_path=component, tags=["code_smell"], ) items.append(item) @@ -225,6 +227,7 @@ def get_json_items(self, json_content, test, mode): severity=self.severitytranslator(hotspot.get("vulnerabilityProbability")), static_finding=True, dynamic_finding=False, + file_path=component, tags=["hotspot"], ) items.append(item) diff --git a/dojo/tools/tenable/csv_format.py b/dojo/tools/tenable/csv_format.py index c1ea9fc2c8d..2c2e0134462 100644 --- a/dojo/tools/tenable/csv_format.py +++ b/dojo/tools/tenable/csv_format.py @@ -100,7 +100,7 @@ def get_findings(self, filename: str, test: Test): severity = self._convert_severity(raw_severity) # Other text fields description = row.get("Synopsis", row.get("definition.synopsis", "N/A")) - mitigation = str(row.get("Solution", row.get("definition.solution", "N/A"))) + mitigation = str(row.get("Solution", row.get("definition.solution", row.get("Steps to Remediate", "N/A")))) impact = row.get("Description", row.get("definition.description", "N/A")) references = row.get("See Also", row.get("definition.see_also", "N/A")) # Determine if the current row has already been processed diff --git a/dojo/utils.py b/dojo/utils.py index 35ccac5aea2..65d6bdf728c 100644 --- a/dojo/utils.py +++ b/dojo/utils.py @@ -5,6 +5,7 @@ import logging import mimetypes import os +import pathlib import re from calendar import monthrange from collections.abc import Callable @@ -2616,14 +2617,32 @@ def generate_file_response(file_object: FileUpload) -> FileResponse: raise TypeError(msg) # Determine the path of the file on disk within the MEDIA_ROOT file_path = f"{settings.MEDIA_ROOT}/{file_object.file.url.lstrip(settings.MEDIA_URL)}" - _, file_extension = os.path.splitext(file_path) + + return generate_file_response_from_file_path( + file_path, file_name=file_object.title, file_size=file_object.file.size, + ) + + +def generate_file_response_from_file_path( + file_path: str, file_name: str | None = None, file_size: int | None = None, +) -> FileResponse: + """Serve an local file in a uniformed way.""" + # Determine the file path + file_path_without_extension, file_extension = os.path.splitext(file_path) + # Determine the file name if not supplied + if file_name is None: + file_name = file_path_without_extension.rsplit("/")[-1] + # Determine the file size if not supplied + if file_size is None: + file_size = pathlib.Path(file_path).stat().st_size # Generate the FileResponse + full_file_name = f"{file_name}{file_extension}" response = FileResponse( open(file_path, "rb"), - filename=f"{file_object.title}{file_extension}", + filename=full_file_name, content_type=f"{mimetypes.guess_type(file_path)}", ) # Add some important headers - response["Content-Disposition"] = f'attachment; filename="{file_object.title}{file_extension}"' - response["Content-Length"] = file_object.file.size + response["Content-Disposition"] = f'attachment; filename="{full_file_name}"' + response["Content-Length"] = file_size return response diff --git a/helm/defectdojo/Chart.yaml b/helm/defectdojo/Chart.yaml index 4f2c96ba0fa..ffac3d938b3 100644 --- a/helm/defectdojo/Chart.yaml +++ b/helm/defectdojo/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 appVersion: "2.40.0-dev" description: A Helm chart for Kubernetes to install DefectDojo name: defectdojo -version: 1.6.154-dev +version: 1.6.158-dev icon: https://www.defectdojo.org/img/favicon.ico maintainers: - name: madchap diff --git a/helm/defectdojo/values.yaml b/helm/defectdojo/values.yaml index 67c41eeab3d..b2d0422bc2c 100644 --- a/helm/defectdojo/values.yaml +++ b/helm/defectdojo/values.yaml @@ -454,7 +454,7 @@ cloudsql: image: # set repo and image tag of gce-proxy repository: gcr.io/cloudsql-docker/gce-proxy - tag: 1.37.0 + tag: 1.37.1 pullPolicy: IfNotPresent # set CloudSQL instance: 'project:zone:instancename' instance: "" diff --git a/requirements-lint.txt b/requirements-lint.txt index 0e4ee0a0eae..8bf2f348238 100644 --- a/requirements-lint.txt +++ b/requirements-lint.txt @@ -1 +1 @@ -ruff==0.6.9 \ No newline at end of file +ruff==0.7.1 \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index b1e8b0be6a5..3e560a89d61 100644 --- a/requirements.txt +++ b/requirements.txt @@ -30,25 +30,25 @@ PyGithub==1.58.2 lxml==5.3.0 Markdown==3.7 openpyxl==3.1.5 -Pillow==10.4.0 # required by django-imagekit +Pillow==11.0.0 # required by django-imagekit psycopg[c]==3.2.3 -cryptography==43.0.1 +cryptography==43.0.3 python-dateutil==2.9.0.post0 pytz==2024.2 -redis==5.1.1 +redis==5.2.0 requests==2.32.3 -sqlalchemy==2.0.35 # Required by Celery broker transport +sqlalchemy==2.0.36 # Required by Celery broker transport urllib3==1.26.18 -uWSGI==2.0.27 +uWSGI==2.0.28 vobject==0.9.8 whitenoise==5.2.0 titlecase==2.4.1 social-auth-app-django==5.4.2 social-auth-core==4.5.4 gitpython==3.1.43 -python-gitlab==4.13.0 +python-gitlab==5.0.0 cpe==1.3.1 -packageurl-python==0.15.6 +packageurl-python==0.16.0 django-crum==0.7.9 JSON-log-formatter==1.1 django-split-settings==1.3.2 @@ -69,8 +69,8 @@ django-ratelimit==4.1.0 argon2-cffi==23.1.0 blackduck==1.1.3 pycurl==7.45.3 # Required for Celery Broker AWS (SQS) support -boto3==1.35.38 # Required for Celery Broker AWS (SQS) support +boto3==1.35.49 # Required for Celery Broker AWS (SQS) support netaddr==1.3.0 -vulners==2.2.2 +vulners==2.2.3 fontawesomefree==6.6.0 PyYAML==6.0.2 diff --git a/ruff.toml b/ruff.toml index 9a34bf6e005..25e456a5488 100644 --- a/ruff.toml +++ b/ruff.toml @@ -75,7 +75,6 @@ select = [ "TRY003", "TRY004", "TRY2", - "TRY302", "FLY", "NPY", "FAST", diff --git a/unittests/dojo_test_case.py b/unittests/dojo_test_case.py index f72918cf938..39d65e113bc 100644 --- a/unittests/dojo_test_case.py +++ b/unittests/dojo_test_case.py @@ -173,6 +173,7 @@ def get_new_product_with_jira_project_data(self): "jira-project-form-jira_instance": 2, "jira-project-form-enable_engagement_epic_mapping": "on", "jira-project-form-epic_issue_type_name": "Epic", + "jira-project-form-enabled": "True", "jira-project-form-push_notes": "on", "jira-project-form-product_jira_sla_notification": "on", "jira-project-form-custom_fields": "null", @@ -188,6 +189,7 @@ def get_new_product_without_jira_project_data(self): "sla_configuration": 1, # A value is set by default by the model, so we need to add it here as well "jira-project-form-epic_issue_type_name": "Epic", + "jira-project-form-enabled": "True", # 'project_key': 'IFFF', # 'jira_instance': 2, # 'enable_engagement_epic_mapping': 'on', @@ -204,6 +206,7 @@ def get_product_with_jira_project_data(self, product): "jira-project-form-jira_instance": 2, "jira-project-form-enable_engagement_epic_mapping": "on", "jira-project-form-epic_issue_type_name": "Epic", + "jira-project-form-enabled": "True", "jira-project-form-push_notes": "on", "jira-project-form-product_jira_sla_notification": "on", "jira-project-form-custom_fields": "null", @@ -220,6 +223,7 @@ def get_product_with_jira_project_data2(self, product): "jira-project-form-jira_instance": 2, "jira-project-form-enable_engagement_epic_mapping": "on", "jira-project-form-epic_issue_type_name": "Epic", + "jira-project-form-enabled": "True", "jira-project-form-push_notes": "on", "jira-project-form-product_jira_sla_notification": "on", "jira-project-form-custom_fields": "null", @@ -235,6 +239,7 @@ def get_product_with_empty_jira_project_data(self, product): "sla_configuration": 1, # A value is set by default by the model, so we need to add it here as well "jira-project-form-epic_issue_type_name": "Epic", + "jira-project-form-enabled": "True", "jira-project-form-custom_fields": "null", # 'project_key': 'IFFF', # 'jira_instance': 2, diff --git a/unittests/scans/awssecurityhub/missing_account_id.json b/unittests/scans/awssecurityhub/missing_account_id.json new file mode 100644 index 00000000000..fe7ddfc2e94 --- /dev/null +++ b/unittests/scans/awssecurityhub/missing_account_id.json @@ -0,0 +1,112 @@ +{ + "findings": [ + { + "EpssScore": "0.00239", + "SchemaVersion": "2018-10-08", + "Id": "arn:aws:inspector2:us-east-1:1234567:finding/12344bc", + "ProductArn": "arn:aws:securityhub:us-east-1::product/aws/inspector", + "ProductName": "Inspector", + "CompanyName": "Amazon", + "Region": "us-east-1", + "GeneratorId": "AWSInspector", + "Types": [ + "Software and Configuration Checks/Vulnerabilities/CVE" + ], + "FirstObservedAt": "2024-07-30T12:17:32.646Z", + "LastObservedAt": "2024-09-18T05:16:44.106Z", + "CreatedAt": "2024-07-30T12:17:32.646Z", + "UpdatedAt": "2024-09-18T05:16:44.106Z", + "Severity": { + "Label": "MEDIUM", + "Normalized": 50 + }, + "Title": "CVE-2024-123 - fdd", + "Description": "A vulnerability was found in sdd.", + "Remediation": { + "Recommendation": { + "Text": "None Provided" + } + }, + "ProductFields": { + "aws/inspector/FindingStatus": "ACTIVE", + "aws/inspector/inspectorScore": "5.1", + "aws/inspector/resources/1/resourceDetails/awsEc2InstanceDetails/platform": "AMAZON_LINUX_2023", + "aws/inspector/ProductVersion": "1", + "aws/inspector/instanceId": "i-1234xxyy", + "aws/securityhub/FindingId": "arn:aws:inspector2:us-east-1:1234567:finding/addfss", + "aws/securityhub/ProductName": "Inspector", + "aws/securityhub/CompanyName": "Amazon" + }, + "Resources": [ + { + "Type": "AwsEc2Instance", + "Id": "i-1234xxyy", + "Partition": "aws", + "Region": "us-east-1", + "Tags": { + "Name": "Name:xx-123-yy" + }, + "Details": { + "AwsEc2Instance": { + "Type": "tt", + "ImageId": "ami-1234", + "IpV4Addresses": [ + "0.0.0.0" + ], + "IamInstanceProfileArn": "arn:aws:iam::1234567:instance-profile/something", + "VpcId": "vpc-1234", + "SubnetId": "subnet-xxxxxxx", + "LaunchedAt": "2024-09-18T05:16:44.106Z" + } + } + } + ], + "WorkflowState": "NEW", + "Workflow": { + "Status": "NEW" + }, + "RecordState": "ACTIVE", + "Vulnerabilities": [ + { + "Id": "CVE-2024-1234", + "VulnerablePackages": [ + { + "Name": "aa", + "Version": "1.2.0", + "Architecture": "X86_64]", + "PackageManager": "OS", + "FixedInVersion": "abc[2.0]" + } + ], + "Cvss": [ + { + "Version": "3.1", + "BaseScore": "7.5", + "BaseVector": "CVSS:9.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N", + "Source": "NVD" + } + ], + "Vendor": { + "Name": "AMAZON_CVE", + "Url": "https://alas.aws.amazon.com/cve/json/v1/CVE-2024-1234.json", + "VendorSeverity": "Medium", + "VendorCreatedAt": "2024-01-16T00:00:00Z", + "VendorUpdatedAt": "2024-09-18T05:16:44.106Z" + }, + "ReferenceUrls": [ + "https://alas.aws.amazon.com" + ], + "FixAvailable": "YES" + } + ], + "FindingProviderFields": { + "Severity": { + "Label": "MEDIUM" + }, + "Types": [ + "Software and Configuration Checks/Vulnerabilities/CVE" + ] + } + } + ] + } \ No newline at end of file diff --git a/unittests/scans/netsparker/issue_11020.json b/unittests/scans/netsparker/issue_11020.json new file mode 100644 index 00000000000..1c54c7a995e --- /dev/null +++ b/unittests/scans/netsparker/issue_11020.json @@ -0,0 +1,227 @@ +{ + "Generated": "2024-10-08 02:33 PM", + "Target": { + "Duration": "00:00:38.3663144", + "Initiated": "2024-10-08 12:33 PM", + "ScanId": "93d4edbae56145ef001ab203020d164c", + "Url": "http://php.testsparker.com/auth/login.php" + }, + "Vulnerabilities": [ + { + "Certainty": 90, + "Classification": { + "Iso27001": "A.18.1.3", + "Capec": "170", + "Cvss": null, + "Cvss31": null, + "Cvss40": null, + "Cwe": "205", + "Hipaa": "164.306(a), 164.308(a)", + "Owasp": "A5", + "OwaspProactiveControls": "", + "Pci32": "", + "Wasc": "13", + "Asvs40": "14.3.3", + "Nistsp80053": "AC-22", + "DisaStig": "V-16814", + "OwaspApiTop10": "API7", + "OwaspTopTen2021": "A05", + "OwaspTopTen2023": "API8", + "PciDss40": "" + }, + "Confirmed": false, + "Description": "

    Invicti Enterprise identified a version disclosure (PHP) in the target web server's HTTP response.

    \n

    This information can help an attacker gain a greater understanding of the systems in use and potentially develop further attacks targeted at the specific version of PHP.

    ", + "ExploitationSkills": "", + "ExternalReferences": "", + "ExtraInformation": [ + { + "Name": "Extracted Version", + "Value": "5.2.6" + } + ], + "FirstSeenDate": "2024-07-23 05:32 PM", + "HttpRequest": { + "Content": "GET /auth/login.php HTTP/1.1\r\nHost: php.testsparker.com\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\nAccept-Language: en-us,en;q=0.5\r\nCache-Control: no-cache\r\nCookie: PHPSESSID=e6ab62571859a3d766d49945296f081d\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.6167.140 Safari/537.36\r\n\r\n", + "Method": "GET", + "Parameters": [] + }, + "HttpResponse": { + "Content": "HTTP/1.1 200 OK\r\nServer: Apache/2.2.8 (Win32) PHP/5.2.6\r\nContent-Length: 3058\r\nX-Powered-By: PHP/5.2.6\r\nPragma: no-cache\r\nExpires: Thu, 19 Nov 1981 08:52:00 GMT\r\nKeep-Alive: timeout=5, max=150\r\nConnection: Keep-Alive\r\nContent-Type: text/html\r\nDate: Tue, 08 Oct 2024 09:37:09 GMT\r\nCache-Control: no-store, must-revalidate, no-cache, post-check=0, pre-check=0\r\n\r\n\n\n\n\n\n\n\nInvicti Test Web Site - PHP\n\n\n
    \n \n\t
    \n\t\t\n\t
    \n\t\n\t
    \n\n\t
    \n\t\t
    \n\t
    \n\t
    \n\t\t
    \n\t\t\t
    \n\t\t\t\t\t\t\t\t

    Login Area

    \n\t\t\t\t\t

    \n Enter your credentials (admin / admin123456)\n
    \n

    \n Username: \n
    \n Password:  \n\n\n
    \n\t \n
    \n \n
    \n

    \n\n\t\t\t\t
     
    \n\t\t\t\t
    \n\n\n\t\t\t\t
    \n\t\t\t
    \n\t\t
     
    \n\t\t
    \n\t\t\n\t \n\t
    \n\t\t\t
      \n\t\t\t\t
    • \n\t\t\t\t\t
      \n\t\t\t\t\t\t
      \n\t\t\t\t\t\t\t
      \n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t
      \n\t\t\t\t\t\t
      \n\t\t\t\t\n\t\t\t\t\t
      \n\t\t\t\t\t
       
      \n\t\t\t\t
    • \n\t\t\t\t
    • \n\t\t\t\t\t

      Tags

      \n\t\t\t\t\t

      netsparker xss web-application-security false-positive-free automated-exploitation sql-injection local/remote-file-inclusion

      \n\t\t\t\t
    • \n\t\t\t\t
    • \n\t\t\t\t\t

      Inner Pages

      \n\t\t\t\t\t\n\t\t\t\t
    • \n\t\t\t\t
    • \n\t\t\t\t\t

      Links

      \n\t\t\t\t\t\n\t\t\t\t
    • \n\t\t\t\t
    • \n\n\t\t\t
    \n\t\t
    \t\t\n\t\t
     
    \n\t
    \n\t
    \n\t
    \n\t\n
    \nv\n
    \n\t\t

    Copyright (c) 2010 testsparker.com. All rights reserved. Design by Free CSS Templates.

    \n\t
    \t\n\n\n", + "Duration": 458.7166, + "StatusCode": 200 + }, + "LookupId": "bfc0a79b-e3dc-45af-0195-b1a1030bc008", + "Impact": "
    An attacker might use the disclosed information to harvest specific security vulnerabilities for the version identified.
    ", + "KnownVulnerabilities": [], + "LastSeenDate": "2024-10-08 12:37 PM", + "Name": "Version Disclosure (PHP)", + "ProofOfConcept": "", + "RemedialActions": "", + "RemedialProcedure": "
    Configure your web server to prevent information leakage from the SERVER header of its HTTP response.
    ", + "RemedyReferences": "", + "Severity": "Low", + "State": "Present, Scanning", + "Type": "PhpVersionDisclosure", + "Url": "http://php.testsparker.com/auth/login.php", + "Tags": [] + }, + { + "Certainty": 90, + "Classification": { + "Iso27001": "A.14.1.2", + "Capec": "310", + "Cvss": null, + "Cvss31": null, + "Cvss40": null, + "Cwe": "1035, 937", + "Hipaa": "164.308(a)(1)(i)", + "Owasp": "A9", + "OwaspProactiveControls": "C1", + "Pci32": "6.2", + "Wasc": "", + "Asvs40": "1.14.3", + "Nistsp80053": "CM-6", + "DisaStig": "V-16836", + "OwaspApiTop10": "", + "OwaspTopTen2021": "A06", + "OwaspTopTen2023": "API8", + "PciDss40": "6.3.3" + }, + "Confirmed": false, + "Description": "

    Invicti Enterprise identified you are using an out-of-date version of Apache.

    ", + "ExploitationSkills": "", + "ExternalReferences": "", + "ExtraInformation": [ + { + "Name": "Identified Version", + "Value": "2.2.8" + }, + { + "Name": "Latest Version", + "Value": "2.2.34 (in this branch)" + }, + { + "Name": "Overall Latest Version", + "Value": "2.4.62" + }, + { + "Name": "Branch Status", + "Value": "This branch has stopped receiving updates since 7/11/2017." + }, + { + "Name": "Vulnerability Database", + "Value": "Result is based on 10/01/2024 18:00:00 vulnerability database content." + } + ], + "FirstSeenDate": "2024-07-23 05:32 PM", + "HttpRequest": { + "Content": "GET /auth/login.php HTTP/1.1\r\nHost: php.testsparker.com\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\nAccept-Language: en-us,en;q=0.5\r\nCache-Control: no-cache\r\nCookie: PHPSESSID=e6ab62571859a3d766d49945296f081d\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.6167.140 Safari/537.36\r\n\r\n", + "Method": "GET", + "Parameters": [] + }, + "HttpResponse": { + "Content": "HTTP/1.1 200 OK\r\nServer: Apache/2.2.8 (Win32) PHP/5.2.6\r\nContent-Length: 3058\r\nX-Powered-By: PHP/5.2.6\r\nPragma: no-cache\r\nExpires: Thu, 19 Nov 1981 08:52:00 GMT\r\nKeep-Alive: timeout=5, max=150\r\nConnection: Keep-Alive\r\nContent-Type: text/html\r\nDate: Tue, 08 Oct 2024 09:37:09 GMT\r\nCache-Control: no-store, must-revalidate, no-cache, post-check=0, pre-check=0\r\n\r\n\n\n\n\n\n\n\nInvicti Test Web Site - PHP\n\n\n
    \n \n\t
    \n\t\t\n\t
    \n\t\n\t
    \n\n\t
    \n\t\t
    \n\t
    \n\t
    \n\t\t
    \n\t\t\t
    \n\t\t\t\t\t\t\t\t

    Login Area

    \n\t\t\t\t\t

    \n Enter your credentials (admin / admin123456)\n
    \n

    \n Username: \n
    \n Password:  \n\n\n
    \n\t \n
    \n \n
    \n

    \n\n\t\t\t\t
     
    \n\t\t\t\t
    \n\n\n\t\t\t\t
    \n\t\t\t
    \n\t\t
     
    \n\t\t
    \n\t\t\n\t \n\t
    \n\t\t\t
      \n\t\t\t\t
    • \n\t\t\t\t\t
      \n\t\t\t\t\t\t
      \n\t\t\t\t\t\t\t
      \n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t
      \n\t\t\t\t\t\t
      \n\t\t\t\t\n\t\t\t\t\t
      \n\t\t\t\t\t
       
      \n\t\t\t\t
    • \n\t\t\t\t
    • \n\t\t\t\t\t

      Tags

      \n\t\t\t\t\t

      netsparker xss web-application-security false-positive-free automated-exploitation sql-injection local/remote-file-inclusion

      \n\t\t\t\t
    • \n\t\t\t\t
    • \n\t\t\t\t\t

      Inner Pages

      \n\t\t\t\t\t\n\t\t\t\t
    • \n\t\t\t\t
    • \n\t\t\t\t\t

      Links

      \n\t\t\t\t\t\n\t\t\t\t
    • \n\t\t\t\t
    • \n\n\t\t\t
    \n\t\t
    \t\t\n\t\t
     
    \n\t
    \n\t
    \n\t
    \n\t\n
    \nv\n
    \n\t\t

    Copyright (c) 2010 testsparker.com. All rights reserved. Design by Free CSS Templates.

    \n\t
    \t\n\n\n", + "Duration": 458.7166, + "StatusCode": 200 + }, + "LookupId": "e3f86681-1ae6-49e8-0186-b1a1030bbbb1", + "Impact": "
    Since this is an old version of the software, it may be vulnerable to attacks.
    ", + "KnownVulnerabilities": [ + { + "Severity": "Critical", + "Title": "Apache HTTP Server Out-of-bounds Read Vulnerability" + } + ], + "LastSeenDate": "2024-10-08 12:37 PM", + "Name": "Out-of-date Version (Apache)", + "ProofOfConcept": "", + "RemedialActions": "", + "RemedialProcedure": "
    \n

    Please upgrade your installation of Apache to the latest stable version.

    \n
    ", + "RemedyReferences": "
    ", + "Severity": "Critical", + "State": "Present, Scanning", + "Type": "ApacheOutOfDate", + "Url": "http://php.testsparker.com/auth/login.php", + "Tags": [] + }, + { + "Certainty": 90, + "Classification": { + "Iso27001": "A.14.1.2", + "Capec": "310", + "Cvss": null, + "Cvss31": null, + "Cvss40": null, + "Cwe": "1035, 937", + "Hipaa": "164.308(a)(1)(i)", + "Owasp": "A9", + "OwaspProactiveControls": "C1", + "Pci32": "6.2", + "Wasc": "", + "Asvs40": "1.14.3", + "Nistsp80053": "CM-6", + "DisaStig": "V-16836", + "OwaspApiTop10": "", + "OwaspTopTen2021": "A06", + "OwaspTopTen2023": "API8", + "PciDss40": "6.3.3" + }, + "Confirmed": false, + "Description": "

    Invicti Enterprise identified you are using an out-of-date version of PHP.

    ", + "ExploitationSkills": "", + "ExternalReferences": "", + "ExtraInformation": [ + { + "Name": "Identified Version", + "Value": "5.2.6" + }, + { + "Name": "Latest Version", + "Value": "5.2.17 (in this branch)" + }, + { + "Name": "Overall Latest Version", + "Value": "8.3.12" + }, + { + "Name": "Branch Status", + "Value": "This branch has stopped receiving updates since 1/6/2011." + }, + { + "Name": "Vulnerability Database", + "Value": "Result is based on 10/01/2024 18:00:00 vulnerability database content." + } + ], + "FirstSeenDate": "2024-07-23 05:32 PM", + "HttpRequest": { + "Content": "GET /auth/login.php HTTP/1.1\r\nHost: php.testsparker.com\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\nAccept-Language: en-us,en;q=0.5\r\nCache-Control: no-cache\r\nCookie: PHPSESSID=e6ab62571859a3d766d49945296f081d\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.6167.140 Safari/537.36\r\n\r\n", + "Method": "GET", + "Parameters": [] + }, + "HttpResponse": { + "Content": "HTTP/1.1 200 OK\r\nServer: Apache/2.2.8 (Win32) PHP/5.2.6\r\nContent-Length: 3058\r\nX-Powered-By: PHP/5.2.6\r\nPragma: no-cache\r\nExpires: Thu, 19 Nov 1981 08:52:00 GMT\r\nKeep-Alive: timeout=5, max=150\r\nConnection: Keep-Alive\r\nContent-Type: text/html\r\nDate: Tue, 08 Oct 2024 09:37:09 GMT\r\nCache-Control: no-store, must-revalidate, no-cache, post-check=0, pre-check=0\r\n\r\n\n\n\n\n\n\n\nInvicti Test Web Site - PHP\n\n\n
    \n \n\t
    \n\t\t\n\t
    \n\t\n\t
    \n\n\t
    \n\t\t
    \n\t
    \n\t
    \n\t\t
    \n\t\t\t
    \n\t\t\t\t\t\t\t\t

    Login Area

    \n\t\t\t\t\t

    \n Enter your credentials (admin / admin123456)\n
    \n

    \n Username: \n
    \n Password:  \n\n\n
    \n\t \n
    \n \n
    \n

    \n\n\t\t\t\t
     
    \n\t\t\t\t
    \n\n\n\t\t\t\t
    \n\t\t\t
    \n\t\t
     
    \n\t\t
    \n\t\t\n\t \n\t
    \n\t\t\t
      \n\t\t\t\t
    • \n\t\t\t\t\t
      \n\t\t\t\t\t\t
      \n\t\t\t\t\t\t\t
      \n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t
      \n\t\t\t\t\t\t
      \n\t\t\t\t\n\t\t\t\t\t
      \n\t\t\t\t\t
       
      \n\t\t\t\t
    • \n\t\t\t\t
    • \n\t\t\t\t\t

      Tags

      \n\t\t\t\t\t

      netsparker xss web-application-security false-positive-free automated-exploitation sql-injection local/remote-file-inclusion

      \n\t\t\t\t
    • \n\t\t\t\t
    • \n\t\t\t\t\t

      Inner Pages

      \n\t\t\t\t\t\n\t\t\t\t
    • \n\t\t\t\t
    • \n\t\t\t\t\t

      Links

      \n\t\t\t\t\t\n\t\t\t\t
    • \n\t\t\t\t
    • \n\n\t\t\t
    \n\t\t
    \t\t\n\t\t
     
    \n\t
    \n\t
    \n\t
    \n\t\n
    \nv\n
    \n\t\t

    Copyright (c) 2010 testsparker.com. All rights reserved. Design by Free CSS Templates.

    \n\t
    \t\n\n\n", + "Duration": 458.7166, + "StatusCode": 200 + }, + "LookupId": "c609abb8-f7c6-4646-0190-b1a1030bbeb1", + "Impact": "
    Since this is an old version of the software, it may be vulnerable to attacks.
    ", + "KnownVulnerabilities": [ + { + "Severity": "Critical", + "Title": "PHP Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection') Vulnerability" + } + ], + "LastSeenDate": "2024-10-08 12:37 PM", + "Name": "Out-of-date Version (PHP)", + "ProofOfConcept": "", + "RemedialActions": "", + "RemedialProcedure": "
    Please upgrade your installation of PHP to the latest stable version.
    ", + "RemedyReferences": "
    ", + "Severity": "Critical", + "State": "Present, Scanning", + "Type": "PhpOutOfDate", + "Url": "http://php.testsparker.com/auth/login.php", + "Tags": [] + } + ] +} \ No newline at end of file diff --git a/unittests/scans/ptart/empty_with_error.json b/unittests/scans/ptart/empty_with_error.json new file mode 100644 index 00000000000..9e26dfeeb6e --- /dev/null +++ b/unittests/scans/ptart/empty_with_error.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/unittests/scans/ptart/ptart_many_vul.json b/unittests/scans/ptart/ptart_many_vul.json new file mode 100644 index 00000000000..1e6afebcff5 --- /dev/null +++ b/unittests/scans/ptart/ptart_many_vul.json @@ -0,0 +1,84 @@ +{ + "name": "Test", + "executive_summary": "Mistakes were made", + "engagement_overview": "Things were done", + "conclusion": "Things should be put right", + "scope": "test.example.com", + "client": "Test Client", + "start_date": "2024-08-11", + "end_date": "2024-08-16", + "cvss_type": 3, + "tools": [ + "Burp Suite" + ], + "methodologies": [ + "OWASP Testing Guide V4.2" + ], + "pentesters": [ + { + "username": "hydragyrum", + "first_name": "", + "last_name": "" + } + ], + "assessments": [ + { + "title": "Test Assessment", + "hits": [ + { + "id": "PTART-2024-00002", + "title": "Broken Access Control", + "body": "Access control enforces policy such that users cannot act outside of their intended permissions. Failures typically lead to unauthorized information disclosure, modification or destruction of all data, or performing a business function outside of the limits of the user.", + "remediation": "Access control vulnerabilities can generally be prevented by taking a defense-in-depth approach and applying the following principles:\n\n* Never rely on obfuscation alone for access control.\n* Unless a resource is intended to be publicly accessible, deny access by default.\n* Wherever possible, use a single application-wide mechanism for enforcing access controls.\n* At the code level, make it mandatory for developers to declare the access that is allowed for each resource, and deny access by default.\n* Thoroughly audit and test access controls to ensure they are working as designed.", + "asset": "https://test.example.com", + "severity": 2, + "fix_complexity": 3, + "cvss_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H", + "cvss_score": "10.0", + "added": "2024-09-06T03:33:07.908", + "labels": [ + "A01:2021-Broken Access Control", + "A04:2021-Insecure Design" + ], + "screenshots": [ + { + "caption": "Borked", + "order": 0, + "screenshot": { + "filename": "screenshots/a78bebcc-6da7-4c25-86a3-441435ea68d0.png", + "data": "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AggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQCUUAAgbwtcOFErJyYv1jiFi+Tsxs35O2b5e58SiB/7ToS0byJFL21uQQXLeJTY2ewCCCAAAIIIIAAAggggAACCCCAAAIIIJA3BfwuqZQ3b427QgCB2MVL5fB3P8qFwwflYnKKXEpJAQUBrxHwCwwU/6BACY4uJdFPPCxFmjf1mrExEAQQQAABBBBAAAEEEEAAAQQQQAABBBC4PgWYcXZ9Pnfu+joQ0EGzQxMnSdLBGMlXoaJENGsiZR5/6Dq4c27RVwQOfP+TxC1ZJuf37DbeVT1ugme+8vQYJwIIIIAAAggggAACCCCAAAIIIIAAAnlTgMBZ3nyu3NV1LqCXZ9QzzXTQLKLJTVKswx0SXqnida7C7XubQFSH9lKgehU5Pn2GxC1bbryzBapWYdlGb3tQjAcBBBBAAAEEEEAAAQQQQAABBBBAAIHrSCBXAmcparm48+fPuzAHBQVJSEiIS3lWC1JTUyUxMdHldH9/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IYAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAII+KoAgTNffXKMGwEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAwKMCBM48yklnCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACvipA4MxXnxzjRgABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQ8KgAgTOPctIZAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICArwoQOPPVJ8e4EUAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEPCpA4MyjnHSGAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCDgqwIEznz1yTFuBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABjwoQOPMoJ50hgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgj4qgCBM199cowbAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEDAowIEzjzKSWcIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAK+KkDgzFefHONGAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBDwqACBM49y0hkCCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggICvChA489Unx7gRQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQ8KkDgzKOcdIYAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIOCrAgTOfPXJMW4EEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAGPChA48ygnnSGAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCPiqAIEzX31yjBsBBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQMCjAgTOPMpJZwgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAr4qQODMV58c40YAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEPCoAIEzj3LSGQIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgK8KEDjz1SfHuBFAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBDwqQODMo5zZ39nadeuleu0bjU/Heztl/wW5AgIIIIAAAggggAACCCCAAAIIIIAAAggggAAC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kGcF0l9TMM/eNjeGAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgKMAgTNHD44QQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQSuUwECZ9fpg+e2EUAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEHAXyxB5njrfkfUfVqlaVO26/3RhYwwY3et8AGRECCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggID4XVIJBwQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQSudwGWarze3wDuHwEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAwBAgcMaLgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggIASIHDGa4AAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICAEiBwxmuAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgBIgcMZrgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggIASIHDGa4AAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICAEiBwxmuAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgBIgcMZrgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggIASIHDGa4AAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICAEiBwxmuAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgBIgcMZrgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggIASIHDGa4AAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICAEiBwxmuAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgBIgcMZrgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggIASIHDGa4AAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICAEiBwxmuAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgBIgcMZrgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggIASIHDGa4AAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICAEiBwxmuAAAIIIIAAAggg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AAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2Hvgrw34OTJk7J23To5depU3m/ClQgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAo5A0Uhw2LZtu6xavVp27NwpRw4fkYRyCVK5UiU5r9m5UrRoRDQxEpj82pCSsk06duosBw4ekLKxsfLBogUSFxfnV4cdBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQACBnAuENZX6/IsvZdgjj8qW5OSgLS5apIh07nydjHxsuERHRwetc7oefGXOHCc00/ff98sv8uZbb0vvu/92unLw3ggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIDAHxYIW3D23Ky/y5MTJ2X5AifMVIRvzX1bvlrxlcx59WWpUrlylvVPp5OVAywqVaqY4fWnPT1Dkrdtc473ur2HNGxQP0MdDiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCKQLhCU4u/+BAfLu+wv9+iAhPk4a1K8v8Qnxsm7tBtm4aaNocKZFR6Rd0bqd/Gvum9KkcSO/607XnS43XC8rV62W5cuXS7s2baTDVe0zUMx5/XVJ3bPXOX7xhRcSnGUQ4gACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggg4BPI9+BsxVdf+4Vmuj7XszOny/nnNfO1ymwdSUuT4Y89LvPeme8c1xBt4OAhsnhB+r5f5dNwp0RMjIwf+/erY6MAAAArSURBVMRp+Oa8MgIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCDw5wj8P5sIjyCqFeV9AAAAAElFTkSuQmCC" + } + } + ], + "attachments": [ + { + "title": "License", + "filename": "attachments/019f49df-c3f9-4faf-81b1-decc13cc19da.ptart", + "data": "TUlUIExpY2Vuc2UKCkNvcHlyaWdodCAoYykgMjAxNyBQYXZhbiwgRmlzamthcnMsIE1pY2hlbGluIENFUlQKClBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cwp0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCmNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwpmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgoKVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsCmNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCgpUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgpJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCkFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUKU09GVFdBUkUuCg==" + } + ], + "references": [] + }, + { + "id": "PTART-2024-00003", + "title": "Unrated Hit", + "body": "Some hits are not rated.", + "remediation": "They can be informational or not related to a direct attack", + "asset": "https://test.example.com", + "severity": 5, + "fix_complexity": 3, + "cvss_vector": "", + "cvss_score": "", + "added": "2024-09-06T04:22:24.707", + "labels": [ + "A09:2021-Security Logging and Monitoring Failures" + ], + "screenshots": [], + "attachments": [], + "references": [] + } + ] + } + ], + "retests": [] +} \ No newline at end of file diff --git a/unittests/scans/ptart/ptart_one_vul.json b/unittests/scans/ptart/ptart_one_vul.json new file mode 100644 index 00000000000..67930bc3391 --- /dev/null +++ b/unittests/scans/ptart/ptart_one_vul.json @@ -0,0 +1,71 @@ +{ + "name": "Test", + "executive_summary": "Mistakes were made", + "engagement_overview": "Things were done", + "conclusion": "Things should be put right", + "scope": "test.example.com", + "client": "Test Client", + "start_date": "2024-08-11", + "end_date": "2024-08-16", + "cvss_type": 3, + "tools": [ + "Burp Suite" + ], + "methodologies": [ + "OWASP Testing Guide V4.2" + ], + "pentesters": [ + { + "username": "hydragyrum", + "first_name": "", + "last_name": "" + } + ], + "assessments": [ + { + "title": "Test Assessment", + "hits": [ + { + "id": "PTART-2024-00002", + "title": "Broken Access Control", + "body": "Access control enforces policy such that users cannot act outside of their intended permissions. Failures typically lead to unauthorized information disclosure, modification or destruction of all data, or performing a business function outside of the limits of the user.", + "remediation": "Access control vulnerabilities can generally be prevented by taking a defense-in-depth approach and applying the following principles:\n\n* Never rely on obfuscation alone for access control.\n* Unless a resource is intended to be publicly accessible, deny access by default.\n* Wherever possible, use a single application-wide mechanism for enforcing access controls.\n* At the code level, make it mandatory for developers to declare the access that is allowed for each resource, and deny access by default.\n* Thoroughly audit and test access controls to ensure they are working as designed.", + "asset": "https://test.example.com", + "severity": 2, + "fix_complexity": 3, + "cvss_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H", + "cvss_score": "10.0", + "added": "2024-09-06T03:33:07.908", + "labels": [ + "A01:2021-Broken Access Control", + "A04:2021-Insecure Design" + ], + "screenshots": [ + { + "caption": "Borked", + "order": 0, + "screenshot": { + "filename": "screenshots/a78bebcc-6da7-4c25-86a3-441435ea68d0.png", + "data": "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AggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQCUUAAgbwtcOFErJyYv1jiFi+Tsxs35O2b5e58SiB/7ToS0byJFL21uQQXLeJTY2ewCCCAAAIIIIAAAggggAACCCCAAAIIIJA3BfwuqZQ3b427QgCB2MVL5fB3P8qFwwflYnKKXEpJAQUBrxHwCwwU/6BACY4uJdFPPCxFmjf1mrExEAQQQAABBBBAAAEEEEAAAQQQQAABBBC4PgWYcXZ9Pnfu+joQ0EGzQxMnSdLBGMlXoaJENGsiZR5/6Dq4c27RVwQOfP+TxC1ZJuf37DbeVT1ugme+8vQYJwIIIIAAAggggAACCCCAAAIIIIAAAnlTgMBZ3nyu3NV1LqCXZ9QzzXTQLKLJTVKswx0SXqnida7C7XubQFSH9lKgehU5Pn2GxC1bbryzBapWYdlGb3tQjAcBBBBAAAEEEEAAAQQQQAABBBBAAIHrSCBXAmcparm48+fPuzAHBQVJSEiIS3lWC1JTUyUxMdHldH9/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IYAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAII+KoAgTNffXKMGwEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAwKMCBM48yklnCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACvipA4MxXnxzjRgABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQ8KgAgTOPctIZAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICArwoQOPPVJ8e4EUAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEPCpA4MyjnHSGAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCDgqwIEznz1yTFuBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABjwoQOPMoJ50hgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgj4qgCBM199cowbAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEDAowIEzjzKSWcIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAK+KkDgzFefHONGAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBDwqACBM49y0hkCCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggICvChA489Unx7gRQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQ8KkDgzKOcdIYAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIOCrAgTOfPXJMW4EEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAGPChA48ygnnSGAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCPiqAIEzX31yjBsBBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQMCjAgTOPMpJZwgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAr4qQODMV58c40YAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEPCoAIEzj3LSGQIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgK8KEDjz1SfHuBFAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBDwqQODMo5zZ39nadeuleu0bjU/Heztl/wW5AgIIIIAAAggggAACCCCAAAIIIIAAAggggAAC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kGcF0l9TMM/eNjeGAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgKMAgTNHD44QQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQSuUwECZ9fpg+e2EUAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEHAXyxB5njrfkfUfVqlaVO26/3RhYwwY3et8AGRECCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggID4XVIJBwQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQSudwGWarze3wDuHwEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAwBAgcMaLgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggIASIHDGa4AAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICAEiBwxmuAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgBIgcMZrgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggIASIHDGa4AAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICAEiBwxmuAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgBIgcMZrgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggIASIHDGa4AAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICAEiBwxmuAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgBIgcMZrgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggIASIHDGa4AAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICAEiBwxmuAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgBIgcMZrgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggIASIHDGa4AAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICAEiBwxmuAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgBIgcMZrgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggIASIHDGa4AAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICAEiBwxmuAAAIIIIAAAggg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AAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2Hvgrw34OTJk7J23To5depU3m/ClQgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAo5A0Uhw2LZtu6xavVp27NwpRw4fkYRyCVK5UiU5r9m5UrRoRDQxEpj82pCSsk06duosBw4ekLKxsfLBogUSFxfnV4cdBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQACBnAuENZX6/IsvZdgjj8qW5OSgLS5apIh07nydjHxsuERHRwetc7oefGXOHCc00/ff98sv8uZbb0vvu/92unLw3ggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIDAHxYIW3D23Ky/y5MTJ2X5AifMVIRvzX1bvlrxlcx59WWpUrlylvVPp5OVAywqVaqY4fWnPT1Dkrdtc473ur2HNGxQP0MdDiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCKQLhCU4u/+BAfLu+wv9+iAhPk4a1K8v8Qnxsm7tBtm4aaNocKZFR6Rd0bqd/Gvum9KkcSO/607XnS43XC8rV62W5cuXS7s2baTDVe0zUMx5/XVJ3bPXOX7xhRcSnGUQ4gACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggg4BPI9+BsxVdf+4Vmuj7XszOny/nnNfO1ymwdSUuT4Y89LvPeme8c1xBt4OAhsnhB+r5f5dNwp0RMjIwf+/erY6MAAAArSURBVMRp+Oa8MgIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCDw5wj8P5sIjyCqFeV9AAAAAElFTkSuQmCC" + } + } + ], + "attachments": [ + { + "title": "License", + "filename": "attachments/019f49df-c3f9-4faf-81b1-decc13cc19da.ptart", + "data": "TUlUIExpY2Vuc2UKCkNvcHlyaWdodCAoYykgMjAxNyBQYXZhbiwgRmlzamthcnMsIE1pY2hlbGluIENFUlQKClBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cwp0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCmNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwpmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgoKVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsCmNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCgpUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgpJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCkFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUKU09GVFdBUkUuCg==" + } + ], + "references": [ + { + "name": "Reference", + "url": "https://ref.example.com" + } + ] + } + ] + } + ], + "retests": [] +} \ No newline at end of file diff --git a/unittests/scans/ptart/ptart_vuln_plus_retest.json b/unittests/scans/ptart/ptart_vuln_plus_retest.json new file mode 100644 index 00000000000..ad0f0dca0a3 --- /dev/null +++ b/unittests/scans/ptart/ptart_vuln_plus_retest.json @@ -0,0 +1,125 @@ +{ + "name": "Test", + "executive_summary": "Mistakes were made", + "engagement_overview": "Things were done", + "conclusion": "Things should be put right", + "scope": "test.example.com", + "client": "Test Client", + "start_date": "2024-08-11", + "end_date": "2024-08-16", + "cvss_type": 3, + "tools": [ + "Burp Suite" + ], + "methodologies": [ + "OWASP Testing Guide V4.2" + ], + "pentesters": [ + { + "username": "hydragyrum", + "first_name": "", + "last_name": "" + } + ], + "assessments": [ + { + "title": "Test Assessment", + "hits": [ + { + "id": "PTART-2024-00002", + "title": "Broken Access Control", + "body": "Access control enforces policy such that users cannot act outside of their intended permissions. Failures typically lead to unauthorized information disclosure, modification or destruction of all data, or performing a business function outside of the limits of the user.", + "remediation": "Access control vulnerabilities can generally be prevented by taking a defense-in-depth approach and applying the following principles:\n\n* Never rely on obfuscation alone for access control.\n* Unless a resource is intended to be publicly accessible, deny access by default.\n* Wherever possible, use a single application-wide mechanism for enforcing access controls.\n* At the code level, make it mandatory for developers to declare the access that is allowed for each resource, and deny access by default.\n* Thoroughly audit and test access controls to ensure they are working as designed.", + "asset": "https://test.example.com", + "severity": 2, + "fix_complexity": 3, + "cvss_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H", + "cvss_score": "10.0", + "added": "2024-09-06T03:33:07.908", + "labels": [ + "A01:2021-Broken Access Control", + "A04:2021-Insecure Design" + ], + "screenshots": [ + { + "caption": "Borked", + "order": 0, + "screenshot": { + "filename": "screenshots/a78bebcc-6da7-4c25-86a3-441435ea68d0.png", + "data": "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AggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQCUUAAgbwtcOFErJyYv1jiFi+Tsxs35O2b5e58SiB/7ToS0byJFL21uQQXLeJTY2ewCCCAAAIIIIAAAggggAACCCCAAAIIIJA3BfwuqZQ3b427QgCB2MVL5fB3P8qFwwflYnKKXEpJAQUBrxHwCwwU/6BACY4uJdFPPCxFmjf1mrExEAQQQAABBBBAAAEEEEAAAQQQQAABBBC4PgWYcXZ9Pnfu+joQ0EGzQxMnSdLBGMlXoaJENGsiZR5/6Dq4c27RVwQOfP+TxC1ZJuf37DbeVT1ugme+8vQYJwIIIIAAAggggAACCCCAAAIIIIAAAnlTgMBZ3nyu3NV1LqCXZ9QzzXTQLKLJTVKswx0SXqnida7C7XubQFSH9lKgehU5Pn2GxC1bbryzBapWYdlGb3tQjAcBBBBAAAEEEEAAAQQQQAABBBBAAIHrSCBXAmcparm48+fPuzAHBQVJSEiIS3lWC1JTUyUxMdHldH9/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IYAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAII+KoAgTNffXKMGwEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAwKMCBM48yklnCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACvipA4MxXnxzjRgABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQ8KgAgTOPctIZAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICArwoQOPPVJ8e4EUAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEPCpA4MyjnHSGAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCDgqwIEznz1yTFuBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABjwoQOPMoJ50hgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgj4qgCBM199cowbAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEDAowIEzjzKSWcIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAK+KkDgzFefHONGAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBDwqACBM49y0hkCCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggICvChA489Unx7gRQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQ8KkDgzKOcdIYAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIOCrAgTOfPXJMW4EEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAGPChA48ygnnSGAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCPiqAIEzX31yjBsBBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQMCjAgTOPMpJZwgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAr4qQODMV58c40YAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEPCoAIEzj3LSGQIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgK8KEDjz1SfHuBFAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBDwqQODMo5zZ39nadeuleu0bjU/Heztl/wW5AgIIIIAAAggggAACCCCAAAIIIIAAAggggAAC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kGcF0l9TMM/eNjeGAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgKMAgTNHD44QQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQSuUwECZ9fpg+e2EUAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEHAXyxB5njrfkfUfVqlaVO26/3RhYwwY3et8AGRECCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggID4XVIJBwQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQSudwGWarze3wDuHwEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAwBAgcMaLgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggIASIHDGa4AAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICAEiBwxmuAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgBIgcMZrgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggIASIHDGa4AAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICAEiBwxmuAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgBIgcMZrgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggIASIHDGa4AAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICAEiBwxmuAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgBIgcMZrgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggIASIHDGa4AAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICAEiBwxmuAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgBIgcMZrgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggIASIHDGa4AAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICAEiBwxmuAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgBIgcMZrgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggIASIHDGa4AAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICAEiBwxmuAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgBIgcMZrgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggIASIHDGa4AAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICAEgjMLYVzCefl5Ok4OXsuUZIuJOfWMLguAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIBALgmEBAdJ/vBQKVwoQsLD8uXSKNIu63dJpbTDnMkdOHRUYk/F58zFuAoCCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggIDXCxSJLChlSpbI1XHmeOBs174YOXM20bjp4kULSWREQckXEix+fn65CsHFEUAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEck5Az+06n3RBTsXFy7ETp40LF8gfKpXKlc65QThdKUcDZ7aZZnraXfky0RKaL8RpOBwigAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAghcbwKJ55Nk74HDxvZeuTnzzD+n4PWeZrblGQma5ZQ610EAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEvF9AT7bS8SOddDxJx5VyI+VY4Ozk6Tjj/vTyjMw0y41HzTURQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAe8V0PEjHUfSyRZXyunR5ljg7Oy5y/ua6T3NSAgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgg4C9jiSLa4knN9dh/nWOAs6UKycS/5QoKz+57oHwEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAwAcFbHEkW1wpp28hxwJnthvz8/OzZflGAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAwBTI7ThSjgfOzDsngwACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggIAXCRA486KHwVAQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQRyT4DAWe7Zc2UEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEvEiBw5kUPg6EggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgjkngCBs9yz58oIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAJeJEDgzIseBkNBAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBDIPQECZ7lnz5URQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQS8SIDAmRc9DIaCAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCQewIEznLPnisjgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgh4kQCBMy96GAwFAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg9wQInOWePVdGAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBDwIgECZ170MBgKAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIBA7gkQOMs9e66MAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCDgRQIEzrzoYTAUBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQACB3BMgcJZ79lwZAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEDAiwQInHnRw2AoCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACuSdA4Cz37LkyAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICAFwkEetFYGIqFQO/+r8nePfuMml4vPiNtWrW0aEURAr4hcCL2pOzZu1diDh6W2NgTUiiysESXKCb16taR8LAw37gJHxvlvZ27yKVLl8TPz0+++WqsFIoo6GN3wHARQAABBBBAAAEEEEAAAQQQQAABBBBAAIGcE8izgbMFi5bIsOFjJPViiqEZ4G99q4UKRUiFCmWlerWq0vKWm6VE8WI5p5+JK8XFxZn3cO5cYibOyLtNvv52kvw2bYbp8dOkiRIeHp53bzgP3dnS5Svkux9+kgMHYtzeVYUK5aVf755SvlxZt22ouHqBlNRk86TkCxfMPBkEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABVwHraJJrO58rSUxMNAMsevC2AJrzjcSejBX9WbV6rUz+76/ynzcHSv16dZybcewFAjP++tvhOf4+Y5Y83LmTF4yMIbgTSE1NlTeGDJWNGze7a2KW79mzV156eYD069NTBbFbmOXenvlz5mxZvnKVMcybGjWUO9u38/YhMz4EEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABNwLXzR5nfuL6f84mOrg2WP3I/9ecuc5VHOeywJat2yQhIcFhFDNn/e1wzIF3CVxITpbnX+rnEjQLCgqW8uXLSp3aNaVQoUIOg74kl+ST4aNl7PivHMq9+WDJsuWyes0646PzJAQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAHfFcizM87sH4n+oX7Kz9/bFxl5PSvt31175OvvJ8uOHTvN+nETJkrrVrdIYECAWUYmdwX+77dpLgM4ceKEHDh4SMqUKulSR0HuC4z5/Es5fPiwOZDAgCDp9lQX6XDHbeLvnxaz17PSfvjxF/n51ylm2z9n/iX584fLE489bJaRQQABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAguwXSfr3O7it5Yf+hoaFSu1YN+fTDd6Vpk0bmCJOTL8jGTVvMYzK5K5CiAiurVq03B6EDMLY05bffbVm+vUhg1+698vc/88wR6eD1qBEfSse72jsEzXSDABWg1gGyD959SwWr057tL7/+JnHx8WYfZBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQyG6B62LGWWYQX+rxnCxdttJseujQYbmxbm3zWAdvNlzZpylfSLDUqF7NqIs/c0aWLV8lm7Zsk9B8IfLM010tZ6rpc3fs2i2HDx1RgQJ/iY6OkmpVKkv1alXMa1xLZt/+A2qvtlNmF/Xq1HIJUOjK3WofqU2bt8qBmING29JqtlatmjWkUsXyxrHVP6fj4o3zdF2RwpFSrmwZo9k5tXTiylVrZIMKMkZGRkjlShWlZo3qUiB/fqtuslw2f8FCc2+zfPlCpedz3WTYZ2OM/uYtWCK9ej53VX0bz+LfXWo21FHJH66Cp2rJQD3u0Hz5Mt2P9tb9HDp8RPSMqRrVq6qlB2tJ4UjHpQfT6zA29qSsWrNWPYsYOXfuvERFFZcblGGDG+umd5pDnX42Gzdvls2btxnvVTX1PlWvWlWKFins0M7dgR6/4bHzXymizqlWtYr6VJbwsDB3p2SqfMLEbx3aDXlzkJQpXcqhzPmgVs3q8niXh+Xrby/PDtXLNv41Z5480Kmjc1Pz2PYcDqv7SDyfJCWiikl59X42btjA8v23nahnKh4/fsI4LF+urPncjqmyZStWya7de4zxVrmhkvFsAwMd/1OZeP68bN22wzj/xIlYW7ei82vWbTCP9d94WFiocWx1zUuXLskOZb9k6XI5HX9GmqkAvt4nzTmlpKTI0hUrZf+BGDl27IT6GwuTktEl5Ua1H2N0VAnn5hwjgAACCCCAAAIIIIAAAggggAACCCCAAAIIZFHA8dfgLHaSF04rWKCAsQua/rFep4IRBRxua9++/cb+Z7pQ75Y25dcfpFffAbJ/f4xDu65dHpHAKz+U64o/Zvwl3076r8v+XLaTChYsKM+qYFvLW262FV3199LlK2ToB8PM84oULiITxg6XkJAQs2y7WorykxFjHJbOMytVJjo6Wvq//KJUrXKDfbGR//3PGfLTz/8z8mXLlpZhH7wrvfq9atmXtnmyaxe5/94OLv1ktWDq9Bnmqc2a3iQtWjSXEaPGG8G0CxfOG8GnhvVvNNu4y8ya/bdM/O4HOXf2nEOT/7sya03vt/X24FelYoXyDvX2B9rx05Fj5aAKvNgnvbSgTsHB+aTn809Jm1YtjWOrf3Sw66NhI8xArHObMBW0evrJLnJ7uzbOVeaxDhi9NvhtiVN92aepv/9pHOp34N2333C7jOX8RYtl+IhxkpKabH+6ma+ngsavD+wnelbm1aaLFy/Ktq2Xg0r63GrVdFCxZqa6ua/jnfLfn36V8+cTjfZLl62wDJzp4O9nY8ZbvoP6RD3DrcOdtynHxy2vq/dR27Vrl1F3b8e7pNWtLWTg60PM69qfpJ/HqwP6OgTS163f4PA3Z2sfo94LvU+iLfXv86L6225hHDpfUwdJh382zgwK60Z6Hz/7wJkOyo5R+739/fd8h3a2/vW3/pt8pU8vqVC+nH0xeQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAIEsCFzXSzXae+3Zu0+FzC4HzXR5wxvr2Ve75N/7cJhL0My50YfDPpNxE75yGzTT7ePVUnSfDB8lXzjN0HHuy92xnh1jHzQrXry4fD56mEPQbMGiJdJ/4Jtugwy6b70XVf+Bb8jipcvcXcoov5h6Ufq88prbvrShnjH05dffpdtPZiv1Un271bJ/tnRPhzuMGX116tSwFclv0/4w8+4yw0eNk1FjJ7gEzezbnz59Wnr3HSTz1Aw3q/T33HmGo3PQzL6tDuQNHzlO9P5eVknPOur+Qm+3QTN9jg6e6LFO+PIbqy5k7rwF8mLvV1yCZvaNY0/GSo8X+6p7WWRfbORHjf1CPh420m3QTDdat36jPN7tBTmoZl5ebVqhZiGmXkwxT+t8391mPqOM3vvs4/eHyIB+vY3PU0886nLKjFlzZNAbb7l9B/UJernVKVOnS+/+r8mFZOvgoK3jE7GnpP+gwZZBM91GP48333rXo8u36gDbMBW8s3eyjcf2fe7cOXn+pX7ylwr4ptdOB+979Rkoi5ctt53KNwIIIIAAAggggAACCCCAAAIIIIAAAgggkC0CHe57SPTn9z9mZrp/3dZ2XqZPysWGzDhT+ImJifLmkPfMx1ClcuV0Z9ro4NCKlauN9npmS7lyZYzlCxMSzqkZR5f3aPp1yjRZqAJW9knP6mrUoJ76UT9FzZJap5aKO25W65lCldWycFcz82zF6jUy9P1PzD50/6OHf+gQNNNL8ekgiX1QUAfXGtavJ3pmkF5W7tixY0Yfus0HH42Qbyd+bi5dZ3Z+JaN/8NdJzyyrqGbM3FivtprdEyjr1m1SS9dtu9JKZOq0P+W+jh2M5f/Mwixk7P/4CqhZgbYlJTvcebusvbIk3vr1m+TChQvKPtjyCtrWfr8t3ahEiRLSpHEDiYgoaCxduWbt5T3UtIGeGVSmdGl1rQpmf3vVjEMdELNPejz11bKKeubQnr37Zf78RWaAY8as2VJILV/52EMPmKfo2UMDXlUBmsQEs0z3UbdObSlRrIisUcGqvXvSArjT/pghNWtWk+ZNm5jt9fKOn3421nye+jnco2Zp6eU2T6qlOlesWi1r1240xqHvZayarWT/Ts2dv0BmzZ5j9qdnUz1w/31qtlIZ2amWEl29er1s277dqNezvnRA9603BpntM5PZvGWr2UyPr2GD+uZxZjJ65pS72VN677Qxn3/h0I1+hjfWq6eWp4w0Zh/u23vA9NGzyoaPHCsDVSDOXVq0+PLfqf5brlnj8uy4M2fOyqIlyx3+Rj8ePlK+++pzo5sqN9wgDz3YycjP+usf0UFXnfSsxdtva23k9T81qlc38/aZVavXmoeF1fKnVdWSjvr69dXfky29rf62dUDblgL8A6VSpQpSr24tFdA8JOs2bDIDwcbf7ofD5asJo6V4saK2U/hGAAEEEEAAAQQQQAABBBBAAAEEEEAAAQSyRUBP/CiltoKqr7aTSS/pGIS7SSLpnZebdddF4EzPPtH7ONmncyrIdeToCdmydassU3ub6R+eddKBhHffet2+qdt861YtpW+vF1zq9Sypb7+bbJbr4MHY0Z+6LJu3ddt2eUUFUmzps9Hj5ebmTS33SLO1sX3rvbHe+f/27gTO6nn/4/inbaZpM81MTfu+FyKESGhTRERCKeYSFSolJbSotGhRIdcScS9ycyMtpOzhuvyv9g010zqV1qmU/t/Pb3x/53fOnFkdc87o9X08xvkt39/v9/09v2e6j8e87/f7HT3ebXd1s07T5AljJKpYenBn640aO8Gto8ceGvSAXHrxRfa086kjeGwYoQ4aEIwd6WuXX2Wzo+8zZtSjcmYT36gvDYgWLVkq05+Z5VTX+7y3aLHcfmu3wMtztb/kw4/c+pdf5pvOUtew0qBB+1af9cHS5dLxqrZuXbtx8NAhefHl1+yu0/Ypk8b6hWI3meBI15kaMNjX76++/oZfYDTKE1Dqze7sdbsJBju499WN3kk9pUfSvW4wpuGhNzh76ZU5ctCsiWfLlVe0kv79fN+fXuaEBnT3D3jYDeAmT3vWrHvVXAoVKuRctujDpc772nvMemaq3xpXHdq3Ee/UnTpaSkcitTD30PLugvQpJXVbpwl9+fkZbuCo0112u/EGmWZGu+koJy3ffvu9WX/tsJQsWdLZz8l/dASXLXFxcTn6Ptv62X2OHucLirXufX16S9vWl7uX9ex+i9Pe2//W1+0HDbA7m+kY69Wt49YL3NDf+1kzp0qsCeFsucNMOaq/PzYk12Byw8bNJuCu5QTC3bt1daquW7dBvv89OKthQnR73N4ns0+d1nPyhNHumoHeetqHq1atdg9pIPeiCcUCf79fe+Mt+cc/5zr19PdgzPinZIr5d4CCAAIIIIAAAggggAACCCCAAAIIIIAAAgj8GQKdzKxw883ySvr3yNFjJ8mkJ0dKZgMhdKY/raN1tei1BaGcNlM16npQ3h+d3vCFl2aLrqFkO61t6ytk1owpJjyLybbvLrrw/KChmV6oa2nZe+r+gwP7ZQjN9HhDs/bTnb166KZTNASyo1/ssWCf35rRUSNGPek+o44ZqTZ10rgMf1TftTtVtm5Ndm9x6y03ZQjN9ORV7Vqb0KmdW2/lD6uznN6uX5+7/UIze2H7tldKuXLl7K6ZynKru52XDQ2RNKyw5ZqOvl8qDZKaX3CePWUCoYXutndj8QcfuSGUHu9779/8QjNbV0MV7y+tBkZHjqQ5p3W6wp07d9qq5rnNMoRmelK/N0MH93fraWilU2nasuiD5XbTWffLG5rZEzVMADps6EC760wf+J0ZiWbLtm077KboSKWKFRLdfbtxUfML5OGHBkj3W292fqpVrWpPSeqeVHe76dlnuaGZe9Bs9O2dJHcl9XKuve3Wriag9A9jvXWDbe/d5+uz0mVyHrgFu5f32NbkFL8RYK0ua+kXmtm6GvKNHTncCUntsX/9O+vpPKdPmeAXmul1+h3rf9+9fvfRf+hDVZ4zU6pWr+brG+99//WOr7060mziuFEZfr+1vgazZ57pWz9u48ZNomExBQEEEEAAAQQQQAABBBBAAAEEEEAAAQQQ+DMEksygkgubn+/cWpcuGj7iCdm3L31GLu/z9Jie0zpa9Bq9tiCU0yY4y0lnfPbFCnnFjDT65Zf92Va/ql3G0U32omVmyj5bqlatIpdd0sLuZvjUkTA61ZwtH370sd0M+qnDGh8fOdYNzRo3aihPPTk66KiehUs+cO+hf3zX0USZlR4mILFFQ78VX31jdzN8tmqZ+ftoe2zZtt0XNtljufl8+5133eoJCQkZQqJOHX1hn04hqdMYBpaly3yeOpVluzZXBlZx95NMiKkjmPrec5cTsEVFRznnFi72jdLS0XYPD/YFW+7Fv2/osNThQwel38Pcp3bNGs4ZHanknaLx7jt7OseD/ecCM7WhTuFoi/c7UbNmDXvYCRW9wZx7wmzoCLOuXTo7P1XNcFlb1MAWHUm1fUfGPtJ1xjp1bO9en9kUmPY+gZ+HPMFNyZKlAk/neX/REt8Uk9oPwUZ72pvrqLAWZvSmLd6pEe0x+xkfF5/p9IalS5UyAWWcrSo/b9nibv+RDe2HcplMqahTqK41o1FtuebqtlIhsbzdzfA5fMggv2MfLfvEb58dBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAgVAKFCxeSQQPuc5af0XtqnvKICciOHj3mPkK39ZjNWnSpGr1Gry0IpWhBaGQo2tj0bN/aQfZ+qal7zAicfc6oHj2mI4R0ijoNjZ43U+CVNNO3ZVbO9ozyCKyzO9UX4NSuVSvwdIb9ambUyQ8/rHKOp3hGFAVW/MFM3fb8C7Pd0EzfadRjw9xp/ALrb9r0o9+h1WvW+u1ntaOje4IVDXSyClIqVvT9gf/YsePBbpGjY6dOnTKj71a4ddtc2crdthuNGjaQ4jEl3EBq3vz3TGLtG8Gn9Xbv3mOrO2vIuTtBNjQw8k77Z6v89LNv5FzZuNigIaWtq5/Nz/eNhLPHdSpIbzl27KiZJjRn/bHDE241P+9ceXn2HPdWo81UglVMMNam9ZVmLbQLsgxY9KJm55zlTgGoa5jddc/90qRJQ2l75eVynrm3BkV/tJTyTOuov1OhKj97RjBqmKX9lVWpX6+OO4JT31UDqWDX1KuX9e9ofHyc7Nmb/j1K8/zjn9Wzszt3VhPfKLHAunvN/xPDO2K1fv16gVX89nWko077aP+fG5tDOCrO70HsIIAAAggggAACCCCAAAIIIIAAAggggAACRiA6KkoeHfaQDHzoEdmxY4f8bGaPGz1ugox8NH05JN3WY1oqVKjg1NVrCko5LYIzXQtr9OOPZNonJ06ckIlTZrh/ZD9g1ih74MGh8vzMKUGv0dEuRYoUCXpODx5LS5/iT7fr1a2tH1mWOrVqusHZwUOHM62r00p6y/lmZJJd+8p73G7v8UxzePK3EzJ46GP2VLafqZ7wz1u5bNkzvLsZtotHx2Q4lpcDX5nRUDp1pS2VKiaKjrYLLAkmyEpOSQ9nlpqRNoHB2bGj6cNA9boG9esGXp6jfa9jNTOCMC9l165dfpcNeWSE335WO/t+Xz9L61StUllu7HKdvDX3HfcSHW330uxXnR8NUJqe3Vi6dO4kGiwGlhuu62SC4W/Nmm4bnFMa0PywcrXzowc0GL3UjNS6/rprsg3hAu9t98uWLWs3zZpuoZs2cJ9nJGjVqr5RdO7DAjYamODMWzSQSjAhWGBJLO8LewPP6X50dO6mqgx2j8BjMTHRgYfc/d27d7vbutGwfn2//WA7Gljb/yHas8cXFgeryzEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQOCPCpxRprQJyh52wrODBw/K92bJoedfNAN/zKAY3daif2/WOlq3IJXTIjjLrkOKFi0qQx68X16rUkn+8cZcp/r27dudqf90tElui3e0SGL5hGwvr5DoW6fqxPFfs61vK+iXUIM5XSstWLFrdAU7l92xNE/glF3dP+P8vPkL/G47yQSb2RX95Vy3foM7RFTre/uifCZT42V3X+/IuXIJ5bKrHvT8gYOZB6JBL/AcPH7cN8RVD99+azepYMKef741z2/NLz2no450Ckb90SlAnxo/RhLL+9qsge/EcSPl7y++IkvMtKDe6SP1ejV8f9ES56dhgwYydtRw0d+P3JSE+Fi3+h4zqjOzkV5upRxueL/P5T1r6WV2eaLn90rraCAeLDjL7PpwHd9/4KDfo+PNWnbZFa1jg7MjR3xhcXbXcR4BBBBAAAEEEEAAAQQQQAABBBBAAAEEEMirQKWKFeQxM/Ls4eEjnYEw7y5Y6N5KBzTpOa1T0Eru/iJe0N4ul+29ukM7NzjTS7/59jtp3zbzNbEyu72uJ6YjvLToNH/Bpu7zXvvT70MW9VhUNqNbateuLZs3bXYDoaGPjpaXZk2X2NiMI8FKlSrpBivaph7du3kfm2E7Le2IxJipD7U0aRQ8jMtw0Z9wQEO71avW5OnOui7a0MED3Gu9fbFp849y4QUZp1F0K2eyoam4HTHmnS4wk+pBD58R61vHTiv0ur170Hr24K8njptxjYVMaFVMypePt4fdT12rTX90Ss3FZnrR70yCn7x1m/u904r79x+Qe/o9KM9On+S3hpdOV3hXUk/nR0fxLf/kc1lppgG172gfsmbtWun7wCB55umnshzZaOvbz/SpBd93djW41LY1O+dsezrPn6VL+77PWzKZStR78x8Dpiz0rlXmrRdp2/GeNdW0bTqiUEcaZlW27/CNaCxT5o9Pt5nVsziHAAIIIIAAAggggAACCCCAAAIIIIAAAghYAZ3pbdCAvjL2yclubqF/29ZjeZ0Fzt47XJ8EZx75M8qU8VsraP3GTXkKzqKLR5n10tKDs42bNnmeEHxz0+af3BMa0mRWypj2TZ04RhYsXCLPzHrBqabTGQ4cMlxmzZicYfpIHYXy448/OfXi4svKDdddndmtI+r4oiUfub9g2jBdyy0mpnimbfxyxTfuua+//q+cPHnStSheIloOH0rvi8B1xtyLstmIN9NB2m5MTgm+9ls2t5DyCf4jD6+9un2uR3IFe4YGKnZ6Sh0C++1338uLZg20LVuSneo6Ak1HkPXsfkuwy+Xcpmc5P3ry2LFjsuzjz5zr7dpkGtqs37DJjOKrE/T6YAcvan6BE/rZ0X7vmLXnchOc6UjK/5npI7U0MItG9umd5GzHmSkgN8tPznaKaVd2Ze369X5VYs0IvIJQygWMjFy3bkO2wdnuXanuqyXEZwxa3ZNsIIAAAggggAACCCCAAAIIIIAAAggggAACIRa4+MLmknRHD2eqRr21buuxgloIzjw9pyOdNGiwJSdTpNm63s9q1arK2rXrnEPr1m/0nsqwrSHPlq3pIYeerFsn8zXRbr7xeuf6jle1lZWr18inn33h7O/cuVPGTZwiwx4a6Ozb/9Q3Se9/zKg5Lam7U0M2ZZ69/5/1qUGPLfXq1pWs1qfTervMu91xVx/nkhMnf5VPP/9CWrW81NmvVbOGu37cWjONY1bTBh4/flxmz/mHCd5+M6FWESds0mkKz2zS2Jn6UG+ogZI+L6tpH+eaUW92isJrr+ngDEVt1NB/BN+atevNfRs5bQzVf3S9u/POPceEVE2l6213OG3Ve3/73f9lGpx5nx0dHe0ExRpUJvXu55768utvchWcFTXTQdY1Qdt6463lOzOqbcPGzea7Xcu9Z2YbOvry3++mj1bTOt415XRKUvt91iklDx46JKVLZT666n8/pIdveh+dtjI/ysnffvvDj9GAT4cx2zX+/mtG7LW+slWm9922fYfo996WxmEcLWrbwCcCCCCAAAIIIIAAAggggAACCCCAAAIInF4C+rdw/fkrlMJ/hZcI1TuMHf+U363q1K7pt5/TnfZtrnCr7t27T/7+0mx3P3BjwuTpcvRomnu4Q7vW7nZWG4P695OKFSu6Vb5c8bXMm+8LHPREu9a+aSZ19M/IMePd+oEbhw8flj5mWr477u7n/Kz5PfgLrPdn7+/ctVt0fTlbOrTP3kNDrPJmzS9b5r+32G7KVW191x8+dFjUO7MyxvS/hjbvvb9I3lvgC+/aBoQWg4c+ZoKKk0Fv8/6iD+RlM+JL53JdsHCxWTPskFOvRvVqUtJMnWnLuImTJS3N1+/2uP0cNXaC2xdz5823h81csSOk34CH5L6BD8mnX3zpHvduaIBWu1YN99CvJhDUsn3HTudavX7A4EdEA5dgpUJieWfkpT13/Ogxu5njz6Set/nVHfbYKEnds9fvWOCOBpfjJkz2O+ztP52a0luGPDLCWWjSe8xuL122XFaZ6SdtueySFnYz5J/qbcs+8/seinJes6bubT759DPRKTWDlRMnTsiQRx53T+kQ6EtbXOzus4EAAggggAACCCCAAAIIIIAAAggggAACCCCQO4HTPjg7/uuvzh+l+/YfJP81I3NsKW7W+spubTJbN/Cz5aUtpHjxGPfwOybQWvLhMme0kz2owcsbc+fJZ2Z0lC2xsbFy1pmN7W6Wn7pO1YSxI/0CjhdMQLd6zVr3uriysdLAjNKxRUfrTJs5S/SdvSVl23YTqAyRn81oH13nak/qXqlRo7q3Sr5tvzN/gfssDQFatbzE3c9qo22by93T6zdsEA0CtbS4qLlfYPXpZ5/Lm2/P8wu+dNTfPPNcO5pJr2vX9gp3KsWSJUtKs3N9QUZqaqqMfOJJZ8ST1rVFw8ZnnkufQlOPabDpneKw87W+qTJ1/bH+g4bKATNyyluOHEmTUWPHy1df/8fpC+2Pep5RiAdMEKfTb27e/JOMnzDVrKG3xXu5s60hy8qVvjXiatas6RwvlxAvW35Odq5XowfNFJ8aVgWW19+c6zfysn6DuoFVst1v1LCBXHThBW49HanXu+8A+fzLFe4x74aug3ZLz7ud9bzs8Qb160uTxg3truhIrMaNfPv6fZ04ZbroSFFv0XtNmfase0i/R15790SINiokJrp30qkt//fDKnc/rxs333iD36UjR493Ru15D+p3/PHR40TDeVsuueQi93trj/GJAAIIIIAAAggggAACCCCAAAIIIIAAAgggkHOBojmvWnBr6pRn13e9PcMLnDSjNU7+lr7+lfdkkcJFzbSHA7yHcrUdVayYDBl0vzw+apx73bQZz8rTM56TKlUryykznVtKyna/dby04ojhQ9z6OdnQIOGJEcNk0MPD3erDHntCXnjuadHQTMvQwQOkV1If9z2XfLBU9CfR/LG/rKmzb98volM9ekuXLp0kpnjma4p564Z6e+myj91bnn12kxyHAB3atZE5r73hXjvfjBrrZsKHImbawOFDBvmNynllzj/l1TlvSI2a1UVH7CRvTfHrCw1abrm5i3sv3Rg88H65zQQ77vR5JmTt1v1OZ6RbbOwZsnnTT37T5ek1PXt00w+33NzlemO/zAnE9KCGLLf0SBJdu65SpYpO2LctZYfbV1qndu3afmHqLV1vkLHj00dl6SjCvmaUoI6202kf9Xu33kyJuMkuyGau13fp2T29HTrtZMuWF8uy5Z/oreXAgQNyY7deUq16FTnTBFL7TYi3avVa0WDQFm1byzyOYOrf715ZZ6ZrtMGOjqzUtus9axn72NiysjU5RTS4PZp2xD7S+Ywz6/MNDfI7qMduv+Ne1/rjTz4T/dHvc4kSMbJ1S4p7zt6w+21dJXDdMHsuFJ86verCxR+4txr66EjR4L18uTh5oO89Uq9uHfdcTjd0xGDHq9o5oxb1Gp2Ksf+gh52gvKr5N2T//v1+/aR1NKzv3+8e3aQggAACCCCAAAIIIIAAAggggAACCCCAAAII5FHgtBlxpmuXBf4EC810LaRZz0yRc8w6T3+k6FpT/e69ywku7H006Ni6NdkJTHTbFg03hg0ZaKbXSx8ZZI/n5LNhg3pyV1Ivt6oGOzqSSEdRadEAbcK4Ec6aSW4ls6Fhma7DFhiadWjfVrp36+qtmm/bK1etcdfl0ode3aFdjp9dpnRpqW6mQ7Rl8ZKP7KYzamnQwPsy9IWO3NL+8PaFBh5TnxonZ5hwx1tKligh08xxPe8tOiJM1/LyrjGl/fmACTBaBFn8cMrEMU7I472HBljaF9oW73eyatUqMmncSG9VM4LuQtE+8hZtw9KPljvhjTc007ZOfHK0JJYv51bvndRT6tXzjSDT56nDfDO1pAZQ3tCsWrUqMnPaJPFORejeKAcbGmQ9P3OqGb3o6xe9TN/3ezMqbPnHnzghX2BodokJ6l6cNcMNf72P0n6ZYEyiovyDXf0e63t4+0Gvu65TR7nphs7eW4R8u/UVl2VYQ03facuWZDMd5vY8P6/333pJq8ta+l2v/4ZpH3v7SSvoNKD6/YyKivKrzw4CCCCAAAIIIIAAAggggAACCCCAAAIIIIBA7gT+ssGZjjTKSSlWLEqqVK4kl5kpAe+56055yfzB3hs02Ht471e4cM7urWsyTZk0zm/EkL2ffmrAcl6zc+TZGZPloua+ae28dXRKRlu8bbDH9LNTx/bS4uLm7iENUma9MNvd1xEvOgpN31FH0wUrGjrp1I/33n1nhtPe5xYpEvx6e1Gxoj4b73X2fFafS5Yuc08XLVIs11Nl6qgzWzRY+MVMh2iLrnE1feoEOafpWX4Bmj2vIZOem/38dDMaqoY97PdZtUpl8/14Wtq1aS3avsCi3yV11OCt9RWtAk87+xrwzTL93fWm680IKf8Qzl6gI7Lu69NbnjGhlY4SCyzaR+PHjHBGmul3KLDou1xwfjN59YWZflNFaj2ddvIpE6bdbcLW0qYtwYo+v8v118rMqZOc6RGD1cnpsejoaJk26Unnd0tHkWVVtN0D7+8jQx683/j6vkeB19StU8sEa0/LFZe3CtoPWr9mzRoy4tGhktSrh+5mKEWK+H6vghl7L/B+j4O1S39HZ0yZ6Cx8qe/gX3z9k5tn6j00sHzwgT7y0KAHpLL5NypY0e+cjkx72fy7ValihWBV/I4VCfJ98qvADgIIIIAAAggggAACCCCAAAIIIIAAAgggcJoLFDplSn4YfL9qg/OYpo19o13y47mR8gxdS0qn5tttAh0lr1ihglQ20/Nl90f7ULdfR6Jt27HTTBW5TQqb8CCxXDknOPSGA6F+ZqTdT9d4SzZTBGpfaPDQsH5diYmJyVUzfzPTbe7YuUu2JiebPiwmNc2acHZ6zNzcaPfuVNlq+uLYsaMSHxcn1atVFQ2bclNsO6Kjop2gLDfX63voOmm7du82z483ox5riDeszU07clJ3g5lKcvOPPxq3FDO6ME2Km3eNT0iQc5ue6Rjm5B7eOtr+7eb7nJxipts0/5JpH1SpXNmZttFbLz+395rpT7Vd+rut06mGqhw8dMh8b7fJ/gP7nXtXrlRJKiSWz/OIwFC1i/sggAACCCCAAAIIIIAAAggggAACCCCAAAKhFghnpkRwFure5H4IIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAJ5FghncOabryzPzedCBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBAq+AMFZwe9D3gABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQCAEAgRnIUDkFggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgVfgOCs4Pchb4AAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIBACAYKzECByCwQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAgYIvQHBW8PuQN0AAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEAiBAMFZCBC5BQIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAQMEXIDgr+H3IGyCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCIRAgOAsBIjcAgEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAoOALEJwV/D7kDRBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBEIgQHAWAkRugQACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggUPAFCM4Kfh/yBggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAiEQIDgLASK3QAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQKPgCBGcFvw95AwQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAgRAIEJyFAJFbIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIFHwBgrOC34e8AQIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAQAgE8j04O3XqVAiazS0QQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQT+agLhzpHyLTiLjirm9N3RY8f/an3I+yCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCIRAwOZINlcKwS1zdYt8C85KlYxxGrZv/4FcNZDKCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACp4eAzZFsrpTfb51vwVlc7BnOu+1K/UXSjh7L7/fkeQgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAhEsoPmR5khabK6U383Nt+CsZIniEl+2jPN+P23dTniW3z3N8xBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQACBCBXQ0EzzIy2aJ2muFI5SyCyydio/H7zp52Q5eCjNeWT5hFgpe0YZKR4dJYUKFcrPZvAsBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQACBMApoRKVrmun0jHakWelSMVK7epWwtSrfgzN9063bdsqefax1FrZe58EIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAQIQJ6EizqpUSw9qqsARn+saHjxyVvb/sl0OH0+TY8V/DisDDEUAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEE8l8gOqqYlCoZ46xpFq7pGb1vHbbgzNsIthFAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBAIt0DhcDeA5yOAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2Hvgrw34OTJk7J23To5depU3m/ClQgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAo5A0Uhw2LZtu6xavVp27NwpRw4fkYRyCVK5UiU5r9m5UrRoRDQxEpj82pCSsk06duosBw4ekLKxsfLBogUSFxfnV4cdBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQACBnAuENZX6/IsvZdgjj8qW5OSgLS5apIh07nydjHxsuERHRwetc7oefGXOHCc00/ff98sv8uZbb0vvu/92unLw3ggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIDAHxYIW3D23Ky/y5MTJ2X5AifMVIRvzX1bvlrxlcx59WWpUrlylvVPp5OVAywqVaqY4fWnPT1Dkrdtc473ur2HNGxQP0MdDiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCKQLhCU4u/+BAfLu+wv9+iAhPk4a1K8v8Qnxsm7tBtm4aaNocKZFR6Rd0bqd/Gvum9KkcSO/607XnS43XC8rV62W5cuXS7s2baTDVe0zUMx5/XVJ3bPXOX7xhRcSnGUQ4gACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggg4BPI9+BsxVdf+4Vmuj7XszOny/nnNfO1ymwdSUuT4Y89LvPeme8c1xBt4OAhsnhB+r5f5dNwp0RMjIwf+/erY6MAAAArSURBVMRp+Oa8MgIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCDw5wj8P5sIjyCqFeV9AAAAAElFTkSuQmCC" + } + } + ], + "attachments": [ + { + "title": "License", + "filename": "attachments/019f49df-c3f9-4faf-81b1-decc13cc19da.ptart", + "data": "TUlUIExpY2Vuc2UKCkNvcHlyaWdodCAoYykgMjAxNyBQYXZhbiwgRmlzamthcnMsIE1pY2hlbGluIENFUlQKClBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cwp0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCmNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwpmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgoKVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsCmNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCgpUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgpJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCkFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUKU09GVFdBUkUuCg==" + } + ], + "references": [] + }, + { + "id": "PTART-2024-00003", + "title": "Unrated Hit", + "body": "Some hits are not rated.", + "remediation": "They can be informational or not related to a direct attack", + "asset": "https://test.example.com", + "severity": 5, + "fix_complexity": 3, + "cvss_vector": "", + "cvss_score": "", + "added": "2024-09-06T04:22:24.707", + "labels": [ + "A09:2021-Security Logging and Monitoring Failures" + ], + "screenshots": [], + "attachments": [], + "references": [] + } + ] + } + ], + "retests": [ + { + "name": "Test Retest", + "introduction": "REEEEEEEEEEEEE-TEST!", + "conclusion": "Still broke, mate", + "start_date": "2024-09-08", + "end_date": "2024-09-13", + "hits": [ + { + "id": "PTART-2024-00002-RT", + "status": "NF", + "body": "Still borked", + "original_hit": { + "id": "PTART-2024-00002", + "title": "Broken Access Control", + "body": "Access control enforces policy such that users cannot act outside of their intended permissions. Failures typically lead to unauthorized information disclosure, modification or destruction of all data, or performing a business function outside of the limits of the user.", + "remediation": "Access control vulnerabilities can generally be prevented by taking a defense-in-depth approach and applying the following principles:\n\n* Never rely on obfuscation alone for access control.\n* Unless a resource is intended to be publicly accessible, deny access by default.\n* Wherever possible, use a single application-wide mechanism for enforcing access controls.\n* At the code level, make it mandatory for developers to declare the access that is allowed for each resource, and deny access by default.\n* Thoroughly audit and test access controls to ensure they are working as designed.", + "asset": "https://test.example.com", + "severity": 2, + "fix_complexity": 3, + "cvss_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H", + "cvss_score": "10.0", + "added": "2024-09-06T03:33:07.908", + "labels": [ + "A01:2021-Broken Access Control", + "A04:2021-Insecure Design" + ] + }, + "screenshots": [ + { + "caption": "Yet another Screenshot", + "order": 0, + "screenshot": { + "filename": "screenshots_retest/ea1c661f-7366-4619-a08b-133ec1a6cfd1.png", + "data": "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" + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/unittests/scans/ptart/ptart_vulns_with_mult_assessments.json b/unittests/scans/ptart/ptart_vulns_with_mult_assessments.json new file mode 100644 index 00000000000..1ad9d01d1f9 --- /dev/null +++ b/unittests/scans/ptart/ptart_vulns_with_mult_assessments.json @@ -0,0 +1,107 @@ +{ + "name": "Test", + "executive_summary": "Mistakes were made", + "engagement_overview": "Things were done", + "conclusion": "Things should be put right", + "scope": "test.example.com", + "client": "Test Client", + "start_date": "2024-08-11", + "end_date": "2024-08-16", + "cvss_type": 3, + "tools": [ + "Burp Suite" + ], + "methodologies": [ + "OWASP Testing Guide V4.2" + ], + "pentesters": [ + { + "username": "hydragyrum", + "first_name": "", + "last_name": "" + } + ], + "assessments": [ + { + "title": "New API", + "hits": [ + { + "id": "PTART-2024-00004", + "title": "HTML Injection", + "body": "HTML injection is a type of injection issue that occurs when a user is able to control an input point and is able to inject arbitrary HTML code into a vulnerable web page. This vulnerability can have many consequences, like disclosure of a user's session cookies that could be used to impersonate the victim, or, more generally, it can allow the attacker to modify the page content seen by the victims.", + "remediation": "Preventing HTML injection is trivial in some cases but can be much harder depending on the complexity of the application and the ways it handles user-controllable data.\n\nIn general, effectively preventing HTML injection vulnerabilities is likely to involve a combination of the following measures:\n\n* **Filter input on arrival**. At the point where user input is received, filter as strictly as possible based on what is expected or valid input.\n* **Encode data on output**. At the point where user-controllable data is output in HTTP responses, encode the output to prevent it from being interpreted as active content. Depending on the output context, this might require applying combinations of HTML, URL, JavaScript, and CSS encoding.", + "asset": "", + "severity": 4, + "fix_complexity": 2, + "cvss_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N", + "cvss_score": "8.2", + "added": "2024-09-06T09:47:16.944", + "labels": [ + "A03:2021-Injection" + ], + "screenshots": [], + "attachments": [], + "references": [] + } + ] + }, + { + "title": "Test Assessment", + "hits": [ + { + "id": "PTART-2024-00002", + "title": "Broken Access Control", + "body": "Access control enforces policy such that users cannot act outside of their intended permissions. Failures typically lead to unauthorized information disclosure, modification or destruction of all data, or performing a business function outside of the limits of the user.", + "remediation": "Access control vulnerabilities can generally be prevented by taking a defense-in-depth approach and applying the following principles:\n\n* Never rely on obfuscation alone for access control.\n* Unless a resource is intended to be publicly accessible, deny access by default.\n* Wherever possible, use a single application-wide mechanism for enforcing access controls.\n* At the code level, make it mandatory for developers to declare the access that is allowed for each resource, and deny access by default.\n* Thoroughly audit and test access controls to ensure they are working as designed.", + "asset": "https://test.example.com", + "severity": 2, + "fix_complexity": 3, + "cvss_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H", + "cvss_score": "10.0", + "added": "2024-09-06T03:33:07.908", + "labels": [ + "A01:2021-Broken Access Control", + "A04:2021-Insecure Design" + ], + "screenshots": [ + { + "caption": "Borked", + "order": 0, + "screenshot": { + "filename": "screenshots/a78bebcc-6da7-4c25-86a3-441435ea68d0.png", + "data": "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AggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQInPEaIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIKAECJzxGiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCgBAic8RoggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggoAQCUUAAgbwtcOFErJyYv1jiFi+Tsxs35O2b5e58SiB/7ToS0byJFL21uQQXLeJTY2ewCCCAAAIIIIAAAggggAACCCCAAAIIIJA3BfwuqZQ3b427QgCB2MVL5fB3P8qFwwflYnKKXEpJAQUBrxHwCwwU/6BACY4uJdFPPCxFmjf1mrExEAQQQAABBBBAAAEEEEAAAQQQQAABBBC4PgWYcXZ9Pnfu+joQ0EGzQxMnSdLBGMlXoaJENGsiZR5/6Dq4c27RVwQOfP+TxC1ZJuf37DbeVT1ugme+8vQYJwIIIIAAAggggAACCCCAAAIIIIAAAnlTgMBZ3nyu3NV1LqCXZ9QzzXTQLKLJTVKswx0SXqnida7C7XubQFSH9lKgehU5Pn2GxC1bbryzBapWYdlGb3tQjAcBBBBAAAEEEEAAAQQQQAABBBBAAIHrSCBXAmcparm48+fPuzAHBQVJSEiIS3lWC1JTUyUxMdHldH9/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IYAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAII+KoAgTNffXKMGwEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAwKMCBM48yklnCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACvipA4MxXnxzjRgABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQ8KgAgTOPctIZAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICArwoQOPPVJ8e4EUAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEPCpA4MyjnHSGAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCDgqwIEznz1yTFuBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABjwoQOPMoJ50hgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgj4qgCBM199cowbAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEDAowIEzjzKSWcIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAK+KkDgzFefHONGAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBDwqACBM49y0hkCCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggICvChA489Unx7gRQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQ8KkDgzKOcdIYAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIOCrAgTOfPXJMW4EEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAGPChA48ygnnSGAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCPiqAIEzX31yjBsBBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQMCjAgTOPMpJZwgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAr4qQODMV58c40YAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEPCoAIEzj3LSGQIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgK8KEDjz1SfHuBFAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBDwqQODMo5zZ39nadeuleu0bjU/Heztl/wW5AgIIIIAAAggggAACCCCAAAIIIIAAAggggAAC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kGcF0l9TMM/eNjeGAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgKMAgTNHD44QQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQSuUwECZ9fpg+e2EUAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEHAXyxB5njrfkfUfVqlaVO26/3RhYwwY3et8AGRECCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggID4XVIJBwQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQSudwGWarze3wDuHwEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAwBAgcMaLgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggIASIHDGa4AAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICAEiBwxmuAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgBIgcMZrgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggIASIHDGa4AAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICAEiBwxmuAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgBIgcMZrgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggIASIHDGa4AAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICAEiBwxmuAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgBIgcMZrgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggIASIHDGa4AAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICAEiBwxmuAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgBIgcMZrgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggIASIHDGa4AAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICAEiBwxmuAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAgBIgcMZrgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggIASIHDGa4AAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIICAEiBwxmuAAAIIIIAAAggg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AAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2HvAhqAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQCQIEZ5HQC7QBAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAg7AIEZ2Hvgrw34OTJk7J23To5depU3m/ClQgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAo5A0Uhw2LZtu6xavVp27NwpRw4fkYRyCVK5UiU5r9m5UrRoRDQxEpj82pCSsk06duosBw4ekLKxsfLBogUSFxfnV4cdBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQACBnAuENZX6/IsvZdgjj8qW5OSgLS5apIh07nydjHxsuERHRwetc7oefGXOHCc00/ff98sv8uZbb0vvu/92unLw3ggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIDAHxYIW3D23Ky/y5MTJ2X5AifMVIRvzX1bvlrxlcx59WWpUrlylvVPp5OVAywqVaqY4fWnPT1Dkrdtc473ur2HNGxQP0MdDiCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCKQLhCU4u/+BAfLu+wv9+iAhPk4a1K8v8Qnxsm7tBtm4aaNocKZFR6Rd0bqd/Gvum9KkcSO/607XnS43XC8rV62W5cuXS7s2baTDVe0zUMx5/XVJ3bPXOX7xhRcSnGUQ4gACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggg4BPI9+BsxVdf+4Vmuj7XszOny/nnNfO1ymwdSUuT4Y89LvPeme8c1xBt4OAhsnhB+r5f5dNwp0RMjIwf+/erY6MAAAArSURBVMRp+Oa8MgIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCDw5wj8P5sIjyCqFeV9AAAAAElFTkSuQmCC" + } + } + ], + "attachments": [ + { + "title": "License", + "filename": "attachments/019f49df-c3f9-4faf-81b1-decc13cc19da.ptart", + "data": "TUlUIExpY2Vuc2UKCkNvcHlyaWdodCAoYykgMjAxNyBQYXZhbiwgRmlzamthcnMsIE1pY2hlbGluIENFUlQKClBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cwp0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCmNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwpmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgoKVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsCmNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCgpUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgpJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCkFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUKU09GVFdBUkUuCg==" + } + ], + "references": [] + }, + { + "id": "PTART-2024-00003", + "title": "Unrated Hit", + "body": "Some hits are not rated.", + "remediation": "They can be informational or not related to a direct attack", + "asset": "https://test.example.com", + "severity": 5, + "fix_complexity": 3, + "cvss_vector": "", + "cvss_score": "", + "added": "2024-09-06T04:22:24.707", + "labels": [ + "A09:2021-Security Logging and Monitoring Failures" + ], + "screenshots": [], + "attachments": [], + "references": [] + } + ] + } + ], + "retests": [] +} \ No newline at end of file diff --git a/unittests/scans/ptart/ptart_zero_vul.json b/unittests/scans/ptart/ptart_zero_vul.json new file mode 100644 index 00000000000..bfdf77d03a8 --- /dev/null +++ b/unittests/scans/ptart/ptart_zero_vul.json @@ -0,0 +1,26 @@ +{ + "name": "Test", + "executive_summary": "Mistakes were made", + "engagement_overview": "Things were done", + "conclusion": "Things should be put right", + "scope": "test.example.com", + "client": "Test Client", + "start_date": "2024-08-11", + "end_date": "2024-08-16", + "cvss_type": 3, + "tools": [ + "Burp Suite" + ], + "methodologies": [ + "OWASP Testing Guide V4.2" + ], + "pentesters": [ + { + "username": "hydragyrum", + "first_name": "", + "last_name": "" + } + ], + "assessments": [], + "retests": [] +} \ No newline at end of file diff --git a/unittests/scans/tenable/issue_11102.csv b/unittests/scans/tenable/issue_11102.csv new file mode 100644 index 00000000000..4c901ff8645 --- /dev/null +++ b/unittests/scans/tenable/issue_11102.csv @@ -0,0 +1,61 @@ +"Plugin","Plugin Name","Family","Severity","IP Address","Protocol","Port","Exploit?","Repository","MAC Address","DNS Name","NetBIOS Name","Plugin Output","Synopsis","Description","Steps to Remediate","See Also","Risk Factor","STIG Severity","Vulnerability Priority Rating","CVSS V2 Base Score","CVSS V3 Base Score","CVSS V2 Temporal Score","CVSS V3 Temporal Score","CVSS V2 Vector","CVSS V3 Vector","CPE","CVE","BID","Cross References","First Discovered","Last Observed","Vuln Publication Date","Patch Publication Date","Plugin Publication Date","Plugin Modification Date","Exploit Ease","Exploit Frameworks","Check Type","Version","Recast Risk Comment","Accept Risk Comment","Agent ID","Host ID" +"42873","SSL Medium Strength Cipher Suites Supported (SWEET32)","General","High","1.2.3.4","TCP","443","No","Individual Scan","fa:16:3e:e6:0b:98","","","Plugin Output: + Medium Strength Ciphers (> 64-bit and < 112-bit key, or 3DES) + + Name Code KEX Auth Encryption MAC + ---------------------- ---------- --- ---- --------------------- --- + ECDHE-RSA-DES-CBC3-SHA 0xC0, 0x12 ECDH RSA 3DES-CBC(168) SHA1 + DES-CBC3-SHA 0x00, 0x0A RSA RSA 3DES-CBC(168) SHA1 + +The fields above are : + + {Tenable ciphername} + {Cipher ID code} + Kex={key exchange} + Auth={authentication} + Encrypt={symmetric encryption method} + MAC={message authentication code} + {export flag}","The remote service supports the use of medium strength SSL ciphers.","The remote host supports the use of SSL ciphers that offer medium strength encryption. Nessus regards medium strength as any encryption that uses key lengths at least 64 bits and less than 112 bits, or else that uses the 3DES encryption suite. + +Note that it is considerably easier to circumvent medium strength encryption if the attacker is on the same physical network.","Reconfigure the affected application if possible to avoid use of medium strength ciphers.","https://www.openssl.org/blog/blog/2016/08/24/sweet32/ +https://sweet32.info","Medium","","5.1","5.0","7.5","","","AV:N/AC:L/Au:N/C:P/I:N/A:N","AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N","","CVE-2016-2183","","","Feb 9, 2024 10:48:42 UTC","Oct 17, 2024 17:24:54 UTC","Aug 24, 2016 12:00:00 UTC","N/A","Nov 23, 2009 12:00:00 UTC","Feb 3, 2021 12:00:00 UTC","","","remote","1.21","","","","" +"42873","SSL Medium Strength Cipher Suites Supported (SWEET32)","General","High","2.3.4.5","TCP","443","No","Individual Scan","fa:16:3e:e6:0b:98","","","Plugin Output: + Medium Strength Ciphers (> 64-bit and < 112-bit key, or 3DES) + + Name Code KEX Auth Encryption MAC + ---------------------- ---------- --- ---- --------------------- --- + ECDHE-RSA-DES-CBC3-SHA 0xC0, 0x12 ECDH RSA 3DES-CBC(168) SHA1 + DES-CBC3-SHA 0x00, 0x0A RSA RSA 3DES-CBC(168) SHA1 + +The fields above are : + + {Tenable ciphername} + {Cipher ID code} + Kex={key exchange} + Auth={authentication} + Encrypt={symmetric encryption method} + MAC={message authentication code} + {export flag}","The remote service supports the use of medium strength SSL ciphers.","The remote host supports the use of SSL ciphers that offer medium strength encryption. Nessus regards medium strength as any encryption that uses key lengths at least 64 bits and less than 112 bits, or else that uses the 3DES encryption suite. + +Note that it is considerably easier to circumvent medium strength encryption if the attacker is on the same physical network.","Reconfigure the affected application if possible to avoid use of medium strength ciphers.","https://www.openssl.org/blog/blog/2016/08/24/sweet32/ +https://sweet32.info","Medium","","5.1","5.0","7.5","","","AV:N/AC:L/Au:N/C:P/I:N/A:N","AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N","","CVE-2016-2183","","","Feb 9, 2024 10:48:42 UTC","Oct 17, 2024 17:24:54 UTC","Aug 24, 2016 12:00:00 UTC","N/A","Nov 23, 2009 12:00:00 UTC","Feb 3, 2021 12:00:00 UTC","","","remote","1.21","","","","" +"42873","SSL Medium Strength Cipher Suites Supported (SWEET32)","General","High","1.2.3.4","TCP","8443","No","Individual Scan","fa:16:3e:e6:0b:98","","","Plugin Output: + Medium Strength Ciphers (> 64-bit and < 112-bit key, or 3DES) + + Name Code KEX Auth Encryption MAC + ---------------------- ---------- --- ---- --------------------- --- + ECDHE-RSA-DES-CBC3-SHA 0xC0, 0x12 ECDH RSA 3DES-CBC(168) SHA1 + DES-CBC3-SHA 0x00, 0x0A RSA RSA 3DES-CBC(168) SHA1 + +The fields above are : + + {Tenable ciphername} + {Cipher ID code} + Kex={key exchange} + Auth={authentication} + Encrypt={symmetric encryption method} + MAC={message authentication code} + {export flag}","The remote service supports the use of medium strength SSL ciphers.","The remote host supports the use of SSL ciphers that offer medium strength encryption. Nessus regards medium strength as any encryption that uses key lengths at least 64 bits and less than 112 bits, or else that uses the 3DES encryption suite. + +Note that it is considerably easier to circumvent medium strength encryption if the attacker is on the same physical network.","Reconfigure the affected application if possible to avoid use of medium strength ciphers.","https://www.openssl.org/blog/blog/2016/08/24/sweet32/ +https://sweet32.info","Medium","","5.1","5.0","7.5","","","AV:N/AC:L/Au:N/C:P/I:N/A:N","AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N","","CVE-2016-2183","","","Feb 9, 2024 10:48:42 UTC","Oct 17, 2024 17:24:54 UTC","Aug 24, 2016 12:00:00 UTC","N/A","Nov 23, 2009 12:00:00 UTC","Feb 3, 2021 12:00:00 UTC","","","remote","1.21","","","","" \ No newline at end of file diff --git a/unittests/test_jira_config_engagement.py b/unittests/test_jira_config_engagement.py index 6db30e089a3..59adb4f319b 100644 --- a/unittests/test_jira_config_engagement.py +++ b/unittests/test_jira_config_engagement.py @@ -30,6 +30,7 @@ def get_new_engagement_with_jira_project_data(self): "jira-project-form-jira_instance": 2, "jira-project-form-project_key": "IUNSEC", "jira-project-form-epic_issue_type_name": "Epic", + "jira-project-form-enabled": "True", "jira-project-form-product_jira_sla_notification": "on", "jira-project-form-custom_fields": "null", } @@ -47,6 +48,7 @@ def get_new_engagement_with_jira_project_data_and_epic_mapping(self): "jira-project-form-jira_instance": 2, "jira-project-form-project_key": "IUNSEC", "jira-project-form-epic_issue_type_name": "Epic", + "jira-project-form-enabled": "True", "jira-project-form-product_jira_sla_notification": "on", "jira-project-form-enable_engagement_epic_mapping": "on", "jira-epic-form-push_to_jira": "on", @@ -65,6 +67,7 @@ def get_new_engagement_without_jira_project_data(self): "jira-project-form-inherit_from_product": "on", # A value is set by default by the model, so we need to add it here as well "jira-project-form-epic_issue_type_name": "Epic", + "jira-project-form-enabled": "True", # 'project_key': 'IFFF', # 'jira_instance': 2, # 'enable_engagement_epic_mapping': 'on', @@ -85,6 +88,7 @@ def get_engagement_with_jira_project_data(self, engagement): "jira-project-form-jira_instance": 2, "jira-project-form-project_key": "ISEC", "jira-project-form-epic_issue_type_name": "Epic", + "jira-project-form-enabled": "True", "jira-project-form-product_jira_sla_notification": "on", "jira-project-form-custom_fields": "null", } @@ -102,6 +106,7 @@ def get_engagement_with_jira_project_data2(self, engagement): "jira-project-form-jira_instance": 2, "jira-project-form-project_key": "ISEC2", "jira-project-form-epic_issue_type_name": "Epic", + "jira-project-form-enabled": "True", "jira-project-form-product_jira_sla_notification": "on", "jira-project-form-custom_fields": "null", } @@ -118,6 +123,7 @@ def get_engagement_with_empty_jira_project_data(self, engagement): "jira-project-form-inherit_from_product": "on", # A value is set by default by the model, so we need to add it here as well "jira-project-form-epic_issue_type_name": "Epic", + "jira-project-form-enabled": "True", # 'project_key': 'IFFF', # 'jira_instance': 2, # 'enable_engagement_epic_mapping': 'on', diff --git a/unittests/test_jira_config_engagement_epic.py b/unittests/test_jira_config_engagement_epic.py index 75c241fab67..7b6b753416e 100644 --- a/unittests/test_jira_config_engagement_epic.py +++ b/unittests/test_jira_config_engagement_epic.py @@ -58,6 +58,7 @@ def get_new_engagement_with_jira_project_data_and_epic_mapping(self): "jira-project-form-jira_instance": 2, "jira-project-form-project_key": "NTEST", "jira-project-form-epic_issue_type_name": "Epic", + "jira-project-form-enabled": "True", "jira-project-form-product_jira_sla_notification": "on", "jira-project-form-enable_engagement_epic_mapping": "on", "jira-epic-form-push_to_jira": "on", diff --git a/unittests/test_jira_config_product.py b/unittests/test_jira_config_product.py index ff72f34993a..7213a2f5f00 100644 --- a/unittests/test_jira_config_product.py +++ b/unittests/test_jira_config_product.py @@ -49,7 +49,7 @@ def setUp(self): @patch("dojo.jira_link.views.jira_helper.get_jira_connection_raw") def add_jira_instance(self, data, jira_mock): - response = self.client.post(reverse("add_jira"), urlencode(data), content_type="application/x-www-form-urlencoded") + response = self.client.post(reverse("add_jira_advanced"), urlencode(data), content_type="application/x-www-form-urlencoded") # check that storing a new config triggers a login call to JIRA call_1 = call(data["url"], data["username"], data["password"]) call_2 = call(data["url"], data["username"], data["password"]) diff --git a/unittests/test_parsers.py b/unittests/test_parsers.py index 63edff395c6..9e2ac077f14 100644 --- a/unittests/test_parsers.py +++ b/unittests/test_parsers.py @@ -1,11 +1,14 @@ import os from pathlib import Path +from django.test import tag as test_tag + from .dojo_test_case import DojoTestCase, get_unit_tests_path basedir = os.path.join(get_unit_tests_path(), "..") +@test_tag("parser-supplement-tests") class TestParsers(DojoTestCase): def test_file_existence(self): for parser_dir in os.scandir(os.path.join(basedir, "dojo", "tools")): diff --git a/unittests/tools/test_appcheck_web_application_scanner_parser.py b/unittests/tools/test_appcheck_web_application_scanner_parser.py index 5c3e7dc96b9..9360eb9209f 100644 --- a/unittests/tools/test_appcheck_web_application_scanner_parser.py +++ b/unittests/tools/test_appcheck_web_application_scanner_parser.py @@ -1,3 +1,5 @@ +import string + from django.test import TestCase from dojo.models import Finding, Test @@ -548,7 +550,7 @@ def test_appcheck_web_application_scanner_parser_non_printable_escape(self): for test_string, expected in [ ("", ""), ( - "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c", + string.printable, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\\x0b\\x0c", ), ("'!Test String?'\"\"", "'!Test String?'\"\""), diff --git a/unittests/tools/test_awssecurityhub_parser.py b/unittests/tools/test_awssecurityhub_parser.py index 9d05083eaff..5885852b348 100644 --- a/unittests/tools/test_awssecurityhub_parser.py +++ b/unittests/tools/test_awssecurityhub_parser.py @@ -134,3 +134,9 @@ def test_issue_10956(self): self.assertEqual(1, len(findings)) finding = findings[0] self.assertEqual("0.00239", finding.epss_score) + + def test_missing_account_id(self): + with open(get_unit_tests_path() + sample_path("missing_account_id.json"), encoding="utf-8") as test_file: + parser = AwsSecurityHubParser() + findings = parser.get_findings(test_file, Test()) + self.assertEqual(1, len(findings)) diff --git a/unittests/tools/test_netsparker_parser.py b/unittests/tools/test_netsparker_parser.py index 55e396205ab..8537686b97b 100644 --- a/unittests/tools/test_netsparker_parser.py +++ b/unittests/tools/test_netsparker_parser.py @@ -96,3 +96,17 @@ def test_parse_file_issue_10311(self): self.assertEqual("High", finding.severity) self.assertEqual(614, finding.cwe) self.assertEqual("03/02/2019", finding.date.strftime("%d/%m/%Y")) + + def test_parse_file_issue_11020(self): + with open("unittests/scans/netsparker/issue_11020.json", encoding="utf-8") as testfile: + parser = NetsparkerParser() + findings = parser.get_findings(testfile, Test()) + self.assertEqual(3, len(findings)) + for finding in findings: + for endpoint in finding.unsaved_endpoints: + endpoint.clean() + with self.subTest(i=0): + finding = findings[0] + self.assertEqual("Low", finding.severity) + self.assertEqual(205, finding.cwe) + self.assertEqual("08/10/2024", finding.date.strftime("%d/%m/%Y")) diff --git a/unittests/tools/test_ptart_parser.py b/unittests/tools/test_ptart_parser.py new file mode 100644 index 00000000000..83be6417b3d --- /dev/null +++ b/unittests/tools/test_ptart_parser.py @@ -0,0 +1,694 @@ +from django.test import TestCase + +from dojo.models import Engagement, Product, Test +from dojo.tools.ptart.parser import PTARTParser + + +class TestPTARTParser(TestCase): + + def setUp(self): + self.product = Product(name="sample product", + description="what a description") + self.engagement = Engagement(name="sample engagement", + product=self.product) + self.test = Test(engagement=self.engagement) + + def test_ptart_parser_tools_parse_ptart_severity(self): + from dojo.tools.ptart.ptart_parser_tools import parse_ptart_severity + with self.subTest("Critical"): + self.assertEqual("Critical", parse_ptart_severity(1)) + with self.subTest("High"): + self.assertEqual("High", parse_ptart_severity(2)) + with self.subTest("Medium"): + self.assertEqual("Medium", parse_ptart_severity(3)) + with self.subTest("Low"): + self.assertEqual("Low", parse_ptart_severity(4)) + with self.subTest("Info"): + self.assertEqual("Info", parse_ptart_severity(5)) + with self.subTest("Unknown"): + self.assertEqual("Info", parse_ptart_severity(6)) + + def test_ptart_parser_tools_parse_ptart_fix_effort(self): + from dojo.tools.ptart.ptart_parser_tools import parse_ptart_fix_effort + with self.subTest("High"): + self.assertEqual("High", parse_ptart_fix_effort(1)) + with self.subTest("Medium"): + self.assertEqual("Medium", parse_ptart_fix_effort(2)) + with self.subTest("Low"): + self.assertEqual("Low", parse_ptart_fix_effort(3)) + with self.subTest("Unknown"): + self.assertEqual(None, parse_ptart_fix_effort(4)) + + def test_ptart_parser_tools_parse_title_from_hit(self): + from dojo.tools.ptart.ptart_parser_tools import parse_title_from_hit + with self.subTest("Title and ID"): + self.assertEqual("1234: Test Title", parse_title_from_hit({"title": "Test Title", "id": "1234"})) + with self.subTest("Title Only"): + self.assertEqual("Test Title", parse_title_from_hit({"title": "Test Title"})) + with self.subTest("ID Only"): + self.assertEqual("1234", parse_title_from_hit({"id": "1234"})) + with self.subTest("No Title or ID"): + self.assertEqual("Unknown Hit", parse_title_from_hit({})) + with self.subTest("Empty Title"): + self.assertEqual("Unknown Hit", parse_title_from_hit({"title": ""})) + with self.subTest("Empty ID"): + self.assertEqual("Unknown Hit", parse_title_from_hit({"id": ""})) + with self.subTest("Blank Title and Blank ID"): + self.assertEqual("Unknown Hit", parse_title_from_hit({"title": "", "id": ""})) + with self.subTest("Blank Title and Non-blank id"): + self.assertEqual("1234", parse_title_from_hit({"title": "", "id": "1234"})) + with self.subTest("Non-blank Title and Blank id"): + self.assertEqual("Test Title", parse_title_from_hit({"title": "Test Title", "id": ""})) + + def test_ptart_parser_tools_cvss_vector_acquisition(self): + from dojo.tools.ptart.ptart_parser_tools import parse_cvss_vector + with self.subTest("Test CVSSv3 Vector"): + hit = { + "cvss_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H", + } + self.assertEqual("CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H", parse_cvss_vector(hit, 3)) + with self.subTest("Test CVSSv4 Vector"): + hit = { + "cvss_vector": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:N/SI:N/SA:N", + } + self.assertEqual(None, parse_cvss_vector(hit, 4)) + with self.subTest("Test CVSSv3 Vector with CVSSv4 Request"): + hit = { + "cvss_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H", + } + self.assertEqual(None, parse_cvss_vector(hit, 4)) + with self.subTest("Test CVSSv4 Vector with CVSSv3 Request"): + hit = { + "cvss_vector": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:N/SI:N/SA:N", + } + self.assertEqual(None, parse_cvss_vector(hit, 3)) + with self.subTest("Test No CVSS Vector"): + hit = {} + self.assertEqual(None, parse_cvss_vector(hit, 3)) + with self.subTest("Test CVSSv2 Vector"): + hit = { + "cvss_vector": "CVSS:2.0/AV:N/AC:L/Au:N/C:C/I:C/A:C", + } + self.assertEqual(None, parse_cvss_vector(hit, 2)) + with self.subTest("Test Blank CVSS Vector"): + hit = { + "cvss_vector": "", + } + self.assertEqual(None, parse_cvss_vector(hit, 3)) + + def test_ptart_parser_tools_retest_fix_status_parse(self): + from dojo.tools.ptart.ptart_parser_tools import parse_retest_status + with self.subTest("Fixed"): + self.assertEqual("Fixed", parse_retest_status("F")) + with self.subTest("Not Fixed"): + self.assertEqual("Not Fixed", parse_retest_status("NF")) + with self.subTest("Partially Fixed"): + self.assertEqual("Partially Fixed", parse_retest_status("PF")) + with self.subTest("Not Applicable"): + self.assertEqual("Not Applicable", parse_retest_status("NA")) + with self.subTest("Not Tested"): + self.assertEqual("Not Tested", parse_retest_status("NT")) + with self.subTest("Unknown"): + self.assertEqual(None, parse_retest_status("U")) + with self.subTest("Empty"): + self.assertEqual(None, parse_retest_status("")) + + def test_ptart_parser_tools_parse_screenshots_from_hit(self): + from dojo.tools.ptart.ptart_parser_tools import parse_screenshots_from_hit + with self.subTest("No Screenshots"): + hit = {} + screenshots = parse_screenshots_from_hit(hit) + self.assertEqual([], screenshots) + with self.subTest("One Screenshot"): + hit = { + "screenshots": [{ + "caption": "One", + "order": 0, + "screenshot": { + "filename": "screenshots/a78bebcc-6da7-4c25-86a3-441435ea68d0.png", + "data": "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABzElEQVR42mNk", + }, + }], + } + screenshots = parse_screenshots_from_hit(hit) + self.assertEqual(1, len(screenshots)) + screenshot = screenshots[0] + self.assertEqual("One.png", screenshot["title"]) + self.assertTrue(screenshot["data"] == "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABzElEQVR42mNk", + "Invalid Screenshot Data") + with self.subTest("Two Screenshots"): + hit = { + "screenshots": [{ + "caption": "One", + "order": 0, + "screenshot": { + "filename": "screenshots/a78bebcc-6da7-4c25-86a3-441435ea68d0.png", + "data": "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABzElEQVR42mNk", + }, + }, { + "caption": "Two", + "order": 1, + "screenshot": { + "filename": "screenshots/123e4567-e89b-12d3-a456-426614174000.png", + "data": "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABzElEQVR42mNk", + }, + }], + } + screenshots = parse_screenshots_from_hit(hit) + self.assertEqual(2, len(screenshots)) + first_screenshot = screenshots[0] + self.assertEqual("One.png", first_screenshot["title"]) + self.assertTrue(first_screenshot["data"] == "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABzElEQVR42mNk", + "Invalid Screenshot Data") + second_screenshot = screenshots[1] + self.assertEqual("Two.png", second_screenshot["title"]) + self.assertTrue(second_screenshot["data"] == "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABzElEQVR42mNk", + "Invalid Screenshot Data") + with self.subTest("Empty Screenshot"): + hit = { + "screenshots": [{ + "caption": "Borked", + "order": 0, + "screenshot": { + "filename": "screenshots/a78bebcc-6da7-4c25-86a3-441435ea68d0.png", + "data": "", + }, + }], + } + screenshots = parse_screenshots_from_hit(hit) + self.assertEqual(0, len(screenshots)) + with self.subTest("Screenshot with No Caption"): + hit = { + "screenshots": [{ + "order": 0, + "screenshot": { + "filename": "screenshots/a78bebcc-6da7-4c25-86a3-441435ea68d0.png", + "data": "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABzElEQVR42mNk", + }, + }], + } + screenshots = parse_screenshots_from_hit(hit) + self.assertEqual(1, len(screenshots)) + screenshot = screenshots[0] + self.assertEqual("screenshot.png", screenshot["title"]) + self.assertTrue(screenshot["data"] == "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABzElEQVR42mNk", + "Invalid Screenshot Data") + with self.subTest("Screenshot with Blank Caption"): + hit = { + "screenshots": [{ + "caption": "", + "order": 0, + "screenshot": { + "filename": "screenshots/a78bebcc-6da7-4c25-86a3-441435ea68d0.png", + "data": "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABzElEQVR42mNk", + }, + }], + } + screenshots = parse_screenshots_from_hit(hit) + self.assertEqual(1, len(screenshots)) + screenshot = screenshots[0] + self.assertEqual("screenshot.png", screenshot["title"]) + self.assertTrue(screenshot["data"] == "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABzElEQVR42mNk", + "Invalid Screenshot Data") + + def test_ptart_parser_tools_parse_attachment_from_hit(self): + from dojo.tools.ptart.ptart_parser_tools import parse_attachment_from_hit + with self.subTest("No Attachments"): + hit = {} + attachments = parse_attachment_from_hit(hit) + self.assertEqual([], attachments) + with self.subTest("One Attachment"): + hit = { + "attachments": [{ + "title": "License", + "data": "TUlUIExpY2Vuc2UKCkNvcHl", + }], + } + attachments = parse_attachment_from_hit(hit) + self.assertEqual(1, len(attachments)) + attachment = attachments[0] + self.assertEqual("License", attachment["title"]) + self.assertTrue(attachment["data"] == "TUlUIExpY2Vuc2UKCkNvcHl", "Invalid Attachment Data") + with self.subTest("Two Attachments"): + hit = { + "attachments": [{ + "title": "License", + "data": "TUlUIExpY2Vuc2UKCkNvcHl", + }, { + "title": "Readme", + "data": "UkVBRERtZQoK", + }], + } + attachments = parse_attachment_from_hit(hit) + self.assertEqual(2, len(attachments)) + first_attachment = attachments[0] + self.assertEqual("License", first_attachment["title"]) + self.assertTrue(first_attachment["data"] == "TUlUIExpY2Vuc2UKCkNvcHl", "Invalid Attachment Data") + second_attachment = attachments[1] + self.assertEqual("Readme", second_attachment["title"]) + self.assertTrue(second_attachment["data"] == "UkVBRERtZQoK", "Invalid Attachment Data") + with self.subTest("Empty Attachment"): + hit = { + "attachments": [{ + "title": "License", + "data": "", + }], + } + attachments = parse_attachment_from_hit(hit) + self.assertEqual(0, len(attachments)) + with self.subTest("No Data Attachment"): + hit = { + "attachments": [{ + "title": "License", + }], + } + attachments = parse_attachment_from_hit(hit) + self.assertEqual(0, len(attachments)) + with self.subTest("Attachement with no Title"): + hit = { + "attachments": [{ + "data": "TUlUIExpY2Vuc2UKCkNvcHl", + }], + } + attachments = parse_attachment_from_hit(hit) + self.assertEqual(1, len(attachments)) + attachment = attachments[0] + self.assertEqual("attachment", attachment["title"]) + self.assertTrue(attachment["data"] == "TUlUIExpY2Vuc2UKCkNvcHl", "Invalid Attachment Data") + with self.subTest("Attachment with Blank Title"): + hit = { + "attachments": [{ + "title": "", + "data": "TUlUIExpY2Vuc2UKCkNvcHl", + }], + } + attachments = parse_attachment_from_hit(hit) + self.assertEqual(1, len(attachments)) + attachment = attachments[0] + self.assertEqual("attachment", attachment["title"]) + + self.assertTrue(attachment["data"] == "TUlUIExpY2Vuc2UKCkNvcHl", "Invalid Attachment Data") + + def test_ptart_parser_tools_get_description_from_report_base(self): + from dojo.tools.ptart.ptart_parser_tools import generate_test_description_from_report + with self.subTest("No Description"): + data = {} + self.assertEqual(None, generate_test_description_from_report(data)) + with self.subTest("Description from Executive Summary Only"): + data = { + "executive_summary": "This is a summary", + } + self.assertEqual("This is a summary", generate_test_description_from_report(data)) + with self.subTest("Description from Engagement Overview Only"): + data = { + "engagement_overview": "This is an overview", + } + self.assertEqual("This is an overview", generate_test_description_from_report(data)) + with self.subTest("Description from Conclusion Only"): + data = { + "conclusion": "This is a conclusion", + } + self.assertEqual("This is a conclusion", generate_test_description_from_report(data)) + with self.subTest("Description from All Sections"): + data = { + "executive_summary": "This is a summary", + "engagement_overview": "This is an overview", + "conclusion": "This is a conclusion", + } + self.assertEqual("This is a summary\n\nThis is an overview\n\nThis is a conclusion", + generate_test_description_from_report(data)) + with self.subTest("Description from Executive Summary and Conclusion"): + data = { + "executive_summary": "This is a summary", + "conclusion": "This is a conclusion", + } + self.assertEqual("This is a summary\n\nThis is a conclusion", + generate_test_description_from_report(data)) + with self.subTest("Description from Executive Summary and Engagement Overview"): + data = { + "executive_summary": "This is a summary", + "engagement_overview": "This is an overview", + } + self.assertEqual("This is a summary\n\nThis is an overview", + generate_test_description_from_report(data)) + with self.subTest("Description from Engagement Overview and Conclusion"): + data = { + "engagement_overview": "This is an overview", + "conclusion": "This is a conclusion", + } + self.assertEqual("This is an overview\n\nThis is a conclusion", + generate_test_description_from_report(data)) + with self.subTest("Description from All Sections with Empty Strings"): + data = { + "executive_summary": "", + "engagement_overview": "", + "conclusion": "", + } + self.assertEqual(None, generate_test_description_from_report(data)) + with self.subTest("Description with Some Blank Strings"): + data = { + "executive_summary": "", + "engagement_overview": "This is an overview", + "conclusion": "", + } + self.assertEqual("This is an overview", generate_test_description_from_report(data)) + + def test_ptart_parser_tools_parse_references_from_hit(self): + from dojo.tools.ptart.ptart_parser_tools import parse_references_from_hit + with self.subTest("No References"): + hit = {} + self.assertEqual(None, parse_references_from_hit(hit)) + with self.subTest("One Reference"): + hit = { + "references": [{ + "name": "Reference", + "url": "https://ref.example.com", + }], + } + self.assertEqual("Reference: https://ref.example.com", parse_references_from_hit(hit)) + with self.subTest("Two References"): + hit = { + "references": [{ + "name": "Reference1", + "url": "https://ref.example.com", + }, { + "name": "Reference2", + "url": "https://ref2.example.com", + }], + } + self.assertEqual("Reference1: https://ref.example.com\nReference2: https://ref2.example.com", + parse_references_from_hit(hit)) + with self.subTest("No Data Reference"): + hit = { + "references": [], + } + self.assertEqual(None, parse_references_from_hit(hit)) + with self.subTest("Reference with No Name"): + hit = { + "references": [{ + "url": "https://ref.example.com", + }], + } + self.assertEqual("Reference: https://ref.example.com", parse_references_from_hit(hit)) + with self.subTest("Reference with No URL"): + hit = { + "references": [{ + "name": "Reference", + }], + } + self.assertEqual(None, parse_references_from_hit(hit)) + with self.subTest("Mixed bag of valid and invalid references"): + hit = { + "references": [{ + "name": "Reference1", + "url": "https://ref.example.com", + }, { + "name": "Reference2", + }, { + "url": "https://ref3.example.com", + }], + } + self.assertEqual("Reference1: https://ref.example.com\nReference: https://ref3.example.com", parse_references_from_hit(hit)) + + def test_ptart_parser_with_empty_json_throws_error(self): + with open("unittests/scans/ptart/empty_with_error.json", encoding="utf-8") as testfile: + parser = PTARTParser() + findings = parser.get_findings(testfile, self.test) + self.assertEqual(0, len(findings)) + + def test_ptart_parser_with_no_assessments_has_no_findings(self): + with open("unittests/scans/ptart/ptart_zero_vul.json", encoding="utf-8") as testfile: + parser = PTARTParser() + findings = parser.get_findings(testfile, self.test) + self.assertEqual(0, len(findings)) + + def test_ptart_parser_with_one_assessment_has_one_finding(self): + with open("unittests/scans/ptart/ptart_one_vul.json", encoding="utf-8") as testfile: + parser = PTARTParser() + findings = parser.get_findings(testfile, self.test) + self.assertEqual(1, len(findings)) + with self.subTest("Test Assessment: Broken Access Control"): + finding = findings[0] + self.assertEqual("PTART-2024-00002: Broken Access Control", finding.title) + self.assertEqual("High", finding.severity) + self.assertEqual( + "Access control enforces policy such that users cannot act outside of their intended permissions. Failures typically lead to unauthorized information disclosure, modification or destruction of all data, or performing a business function outside of the limits of the user.", + finding.description) + self.assertEqual( + "Access control vulnerabilities can generally be prevented by taking a defense-in-depth approach and applying the following principles:\n\n* Never rely on obfuscation alone for access control.\n* Unless a resource is intended to be publicly accessible, deny access by default.\n* Wherever possible, use a single application-wide mechanism for enforcing access controls.\n* At the code level, make it mandatory for developers to declare the access that is allowed for each resource, and deny access by default.\n* Thoroughly audit and test access controls to ensure they are working as designed.", + finding.mitigation) + self.assertEqual("CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H", finding.cvssv3) + self.assertEqual("PTART-2024-00002", finding.unique_id_from_tool) + self.assertEqual("PTART-2024-00002", finding.vuln_id_from_tool) + self.assertEqual("PTART-2024-00002", finding.cve) + self.assertEqual("Low", finding.effort_for_fixing) + self.assertEqual("Test Assessment", finding.component_name) + self.assertEqual("2024-09-06", finding.date.strftime("%Y-%m-%d")) + self.assertEqual(2, len(finding.unsaved_tags)) + self.assertEqual([ + "A01:2021-Broken Access Control", + "A04:2021-Insecure Design", + ], finding.unsaved_tags) + self.assertEqual(1, len(finding.unsaved_endpoints)) + endpoint = finding.unsaved_endpoints[0] + self.assertEqual(str(endpoint), "https://test.example.com") + self.assertEqual(2, len(finding.unsaved_files)) + screenshot = finding.unsaved_files[0] + self.assertEqual("Borked.png", screenshot["title"]) + self.assertTrue(screenshot["data"].startswith("iVBORw0KGgoAAAAN"), "Invalid Screenshot Data") + attachment = finding.unsaved_files[1] + self.assertEqual("License", attachment["title"]) + self.assertTrue(attachment["data"].startswith("TUlUIExpY2Vuc2UKCkNvcHl"), "Invalid Attachment Data") + self.assertEqual("Reference: https://ref.example.com", finding.references) + + def test_ptart_parser_with_one_assessment_has_many_findings(self): + with open("unittests/scans/ptart/ptart_many_vul.json", encoding="utf-8") as testfile: + parser = PTARTParser() + findings = parser.get_findings(testfile, self.test) + self.assertEqual(2, len(findings)) + with self.subTest("Test Assessment: Broken Access Control"): + finding = findings[0] + self.assertEqual("PTART-2024-00002: Broken Access Control", finding.title) + self.assertEqual("High", finding.severity) + self.assertEqual( + "Access control enforces policy such that users cannot act outside of their intended permissions. Failures typically lead to unauthorized information disclosure, modification or destruction of all data, or performing a business function outside of the limits of the user.", + finding.description) + self.assertEqual( + "Access control vulnerabilities can generally be prevented by taking a defense-in-depth approach and applying the following principles:\n\n* Never rely on obfuscation alone for access control.\n* Unless a resource is intended to be publicly accessible, deny access by default.\n* Wherever possible, use a single application-wide mechanism for enforcing access controls.\n* At the code level, make it mandatory for developers to declare the access that is allowed for each resource, and deny access by default.\n* Thoroughly audit and test access controls to ensure they are working as designed.", + finding.mitigation) + self.assertEqual("CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H", finding.cvssv3) + self.assertEqual("PTART-2024-00002", finding.unique_id_from_tool) + self.assertEqual("PTART-2024-00002", finding.vuln_id_from_tool) + self.assertEqual("PTART-2024-00002", finding.cve) + self.assertEqual("Low", finding.effort_for_fixing) + self.assertEqual("Test Assessment", finding.component_name) + self.assertEqual("2024-09-06", finding.date.strftime("%Y-%m-%d")) + self.assertEqual(1, len(finding.unsaved_endpoints)) + endpoint = finding.unsaved_endpoints[0] + self.assertEqual(str(endpoint), "https://test.example.com") + self.assertEqual(2, len(finding.unsaved_files)) + screenshot = finding.unsaved_files[0] + self.assertEqual("Borked.png", screenshot["title"]) + self.assertTrue(screenshot["data"].startswith("iVBORw0KGgoAAAAN"), "Invalid Screenshot Data") + attachment = finding.unsaved_files[1] + self.assertEqual("License", attachment["title"]) + self.assertTrue(attachment["data"].startswith("TUlUIExpY2Vuc2UKCkNvcHl"), "Invalid Attachment Data") + self.assertEqual(None, finding.references) + with self.subTest("Test Assessment: Unrated Hit"): + finding = findings[1] + self.assertEqual("PTART-2024-00003: Unrated Hit", finding.title) + self.assertEqual("Info", finding.severity) + self.assertEqual("Some hits are not rated.", finding.description) + self.assertEqual("They can be informational or not related to a direct attack", finding.mitigation) + self.assertEqual(None, finding.cvssv3) + self.assertEqual("PTART-2024-00003", finding.unique_id_from_tool) + self.assertEqual("PTART-2024-00003", finding.vuln_id_from_tool) + self.assertEqual("PTART-2024-00003", finding.cve) + self.assertEqual("Low", finding.effort_for_fixing) + self.assertEqual("Test Assessment", finding.component_name) + self.assertEqual("2024-09-06", finding.date.strftime("%Y-%m-%d")) + self.assertEqual(None, finding.references) + + def test_ptart_parser_with_multiple_assessments_has_many_findings_correctly_grouped(self): + with open("unittests/scans/ptart/ptart_vulns_with_mult_assessments.json", encoding="utf-8") as testfile: + parser = PTARTParser() + findings = parser.get_findings(testfile, self.test) + self.assertEqual(3, len(findings)) + with self.subTest("Test Assessment: Broken Access Control"): + finding = next((f for f in findings if f.unique_id_from_tool == "PTART-2024-00002"), None) + self.assertEqual("PTART-2024-00002: Broken Access Control", finding.title) + self.assertEqual("High", finding.severity) + self.assertEqual( + "Access control enforces policy such that users cannot act outside of their intended permissions. Failures typically lead to unauthorized information disclosure, modification or destruction of all data, or performing a business function outside of the limits of the user.", + finding.description) + self.assertEqual( + "Access control vulnerabilities can generally be prevented by taking a defense-in-depth approach and applying the following principles:\n\n* Never rely on obfuscation alone for access control.\n* Unless a resource is intended to be publicly accessible, deny access by default.\n* Wherever possible, use a single application-wide mechanism for enforcing access controls.\n* At the code level, make it mandatory for developers to declare the access that is allowed for each resource, and deny access by default.\n* Thoroughly audit and test access controls to ensure they are working as designed.", + finding.mitigation) + self.assertEqual("CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H", finding.cvssv3) + self.assertEqual("PTART-2024-00002", finding.unique_id_from_tool) + self.assertEqual("PTART-2024-00002", finding.vuln_id_from_tool) + self.assertEqual("PTART-2024-00002", finding.cve) + self.assertEqual("Low", finding.effort_for_fixing) + self.assertEqual("Test Assessment", finding.component_name) + self.assertEqual("2024-09-06", finding.date.strftime("%Y-%m-%d")) + self.assertEqual(1, len(finding.unsaved_endpoints)) + endpoint = finding.unsaved_endpoints[0] + self.assertEqual(str(endpoint), "https://test.example.com") + self.assertEqual(2, len(finding.unsaved_files)) + screenshot = finding.unsaved_files[0] + self.assertEqual("Borked.png", screenshot["title"]) + self.assertTrue(screenshot["data"].startswith("iVBORw0KGgoAAAAN"), "Invalid Screenshot Data") + attachment = finding.unsaved_files[1] + self.assertEqual("License", attachment["title"]) + self.assertTrue(attachment["data"].startswith("TUlUIExpY2Vuc2UKCkNvcHl"), "Invalid Attachment Data") + self.assertEqual(None, finding.references) + with self.subTest("Test Assessment: Unrated Hit"): + finding = next((f for f in findings if f.unique_id_from_tool == "PTART-2024-00003"), None) + self.assertEqual("PTART-2024-00003: Unrated Hit", finding.title) + self.assertEqual("Info", finding.severity) + self.assertEqual("Some hits are not rated.", finding.description) + self.assertEqual("They can be informational or not related to a direct attack", finding.mitigation) + self.assertEqual(None, finding.cvssv3) + self.assertEqual("PTART-2024-00003", finding.unique_id_from_tool) + self.assertEqual("PTART-2024-00003", finding.vuln_id_from_tool) + self.assertEqual("PTART-2024-00003", finding.cve) + self.assertEqual("Low", finding.effort_for_fixing) + self.assertEqual("Test Assessment", finding.component_name) + self.assertEqual("2024-09-06", finding.date.strftime("%Y-%m-%d")) + self.assertEqual(None, finding.references) + with self.subTest("New Api: HTML Injection"): + finding = next((f for f in findings if f.unique_id_from_tool == "PTART-2024-00004"), None) + self.assertEqual("PTART-2024-00004: HTML Injection", finding.title) + self.assertEqual("Low", finding.severity) + self.assertEqual( + "HTML injection is a type of injection issue that occurs when a user is able to control an input point and is able to inject arbitrary HTML code into a vulnerable web page. This vulnerability can have many consequences, like disclosure of a user's session cookies that could be used to impersonate the victim, or, more generally, it can allow the attacker to modify the page content seen by the victims.", + finding.description) + self.assertEqual( + "Preventing HTML injection is trivial in some cases but can be much harder depending on the complexity of the application and the ways it handles user-controllable data.\n\nIn general, effectively preventing HTML injection vulnerabilities is likely to involve a combination of the following measures:\n\n* **Filter input on arrival**. At the point where user input is received, filter as strictly as possible based on what is expected or valid input.\n* **Encode data on output**. At the point where user-controllable data is output in HTTP responses, encode the output to prevent it from being interpreted as active content. Depending on the output context, this might require applying combinations of HTML, URL, JavaScript, and CSS encoding.", + finding.mitigation) + self.assertEqual("CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N", finding.cvssv3) + self.assertEqual("PTART-2024-00004", finding.unique_id_from_tool) + self.assertEqual("PTART-2024-00004", finding.vuln_id_from_tool) + self.assertEqual("PTART-2024-00004", finding.cve) + self.assertEqual("Medium", finding.effort_for_fixing) + self.assertEqual("New API", finding.component_name) + self.assertEqual("2024-09-06", finding.date.strftime("%Y-%m-%d")) + self.assertEqual(0, len(finding.unsaved_endpoints)) + self.assertEqual(0, len(finding.unsaved_files)) + self.assertEqual(None, finding.references) + + def test_ptart_parser_with_single_vuln_on_import_test(self): + with open("unittests/scans/ptart/ptart_one_vul.json", encoding="utf-8") as testfile: + parser = PTARTParser() + tests = parser.get_tests("PTART Report", testfile) + self.assertEqual(1, len(tests)) + test = tests[0] + self.assertEqual("Test Report", test.name) + self.assertEqual("Test Report", test.type) + self.assertEqual("", test.version) + self.assertEqual("Mistakes were made\n\nThings were done\n\nThings should be put right", test.description) + self.assertEqual("2024-08-11", test.target_start.strftime("%Y-%m-%d")) + self.assertEqual("2024-08-16", test.target_end.strftime("%Y-%m-%d")) + self.assertEqual(1, len(test.findings)) + finding = test.findings[0] + self.assertEqual("PTART-2024-00002: Broken Access Control", finding.title) + self.assertEqual("High", finding.severity) + self.assertEqual( + "Access control enforces policy such that users cannot act outside of their intended permissions. Failures typically lead to unauthorized information disclosure, modification or destruction of all data, or performing a business function outside of the limits of the user.", + finding.description) + self.assertEqual( + "Access control vulnerabilities can generally be prevented by taking a defense-in-depth approach and applying the following principles:\n\n* Never rely on obfuscation alone for access control.\n* Unless a resource is intended to be publicly accessible, deny access by default.\n* Wherever possible, use a single application-wide mechanism for enforcing access controls.\n* At the code level, make it mandatory for developers to declare the access that is allowed for each resource, and deny access by default.\n* Thoroughly audit and test access controls to ensure they are working as designed.", + finding.mitigation) + self.assertEqual("CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H", finding.cvssv3) + self.assertEqual("PTART-2024-00002", finding.unique_id_from_tool) + self.assertEqual("PTART-2024-00002", finding.vuln_id_from_tool) + self.assertEqual("PTART-2024-00002", finding.cve) + self.assertEqual("Low", finding.effort_for_fixing) + self.assertEqual("Test Assessment", finding.component_name) + self.assertEqual("2024-09-06", finding.date.strftime("%Y-%m-%d")) + self.assertEqual(2, len(finding.unsaved_tags)) + self.assertEqual([ + "A01:2021-Broken Access Control", + "A04:2021-Insecure Design", + ], finding.unsaved_tags) + self.assertEqual(1, len(finding.unsaved_endpoints)) + endpoint = finding.unsaved_endpoints[0] + self.assertEqual(str(endpoint), "https://test.example.com") + self.assertEqual(2, len(finding.unsaved_files)) + screenshot = finding.unsaved_files[0] + self.assertEqual("Borked.png", screenshot["title"]) + self.assertTrue(screenshot["data"].startswith("iVBORw0KGgoAAAAN"), "Invalid Screenshot Data") + attachment = finding.unsaved_files[1] + self.assertEqual("License", attachment["title"]) + self.assertTrue(attachment["data"].startswith("TUlUIExpY2Vuc2UKCkNvcHl"), "Invalid Attachment Data") + self.assertEqual("Reference: https://ref.example.com", finding.references) + + def test_ptart_parser_with_retest_campaign(self): + with open("unittests/scans/ptart/ptart_vuln_plus_retest.json", encoding="utf-8") as testfile: + parser = PTARTParser() + findings = parser.get_findings(testfile, self.test) + self.assertEqual(3, len(findings)) + with self.subTest("Test Assessment: Broken Access Control"): + finding = next((f for f in findings if f.unique_id_from_tool == "PTART-2024-00002"), None) + self.assertEqual("PTART-2024-00002: Broken Access Control", finding.title) + self.assertEqual("High", finding.severity) + self.assertEqual( + "Access control enforces policy such that users cannot act outside of their intended permissions. Failures typically lead to unauthorized information disclosure, modification or destruction of all data, or performing a business function outside of the limits of the user.", + finding.description) + self.assertEqual( + "Access control vulnerabilities can generally be prevented by taking a defense-in-depth approach and applying the following principles:\n\n* Never rely on obfuscation alone for access control.\n* Unless a resource is intended to be publicly accessible, deny access by default.\n* Wherever possible, use a single application-wide mechanism for enforcing access controls.\n* At the code level, make it mandatory for developers to declare the access that is allowed for each resource, and deny access by default.\n* Thoroughly audit and test access controls to ensure they are working as designed.", + finding.mitigation) + self.assertEqual("CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H", finding.cvssv3) + self.assertEqual("PTART-2024-00002", finding.unique_id_from_tool) + self.assertEqual("PTART-2024-00002", finding.vuln_id_from_tool) + self.assertEqual("PTART-2024-00002", finding.cve) + self.assertEqual("Low", finding.effort_for_fixing) + self.assertEqual("Test Assessment", finding.component_name) + self.assertEqual("2024-09-06", finding.date.strftime("%Y-%m-%d")) + self.assertEqual(1, len(finding.unsaved_endpoints)) + endpoint = finding.unsaved_endpoints[0] + self.assertEqual(str(endpoint), "https://test.example.com") + self.assertEqual(2, len(finding.unsaved_files)) + screenshot = finding.unsaved_files[0] + self.assertEqual("Borked.png", screenshot["title"]) + self.assertTrue(screenshot["data"].startswith("iVBORw0KGgoAAAAN"), "Invalid Screenshot Data") + attachment = finding.unsaved_files[1] + self.assertEqual("License", attachment["title"]) + self.assertTrue(attachment["data"].startswith("TUlUIExpY2Vuc2UKCkNvcHl"), "Invalid Attachment Data") + self.assertEqual(None, finding.references) + with self.subTest("Test Assessment: Unrated Hit"): + finding = next((f for f in findings if f.unique_id_from_tool == "PTART-2024-00003"), None) + self.assertEqual("PTART-2024-00003: Unrated Hit", finding.title) + self.assertEqual("Info", finding.severity) + self.assertEqual("Some hits are not rated.", finding.description) + self.assertEqual("They can be informational or not related to a direct attack", finding.mitigation) + self.assertEqual(None, finding.cvssv3) + self.assertEqual("PTART-2024-00003", finding.unique_id_from_tool) + self.assertEqual("PTART-2024-00003", finding.vuln_id_from_tool) + self.assertEqual("PTART-2024-00003", finding.cve) + self.assertEqual("Low", finding.effort_for_fixing) + self.assertEqual("Test Assessment", finding.component_name) + self.assertEqual("2024-09-06", finding.date.strftime("%Y-%m-%d")) + self.assertEqual(None, finding.references) + with self.subTest("Retest: Broken Access Control"): + finding = next((f for f in findings if f.unique_id_from_tool == "PTART-2024-00002-RT"), None) + self.assertEqual("PTART-2024-00002-RT: Broken Access Control (Not Fixed)", finding.title) + self.assertEqual("High", finding.severity) + self.assertEqual("Still borked", finding.description) + self.assertEqual( + "Access control vulnerabilities can generally be prevented by taking a defense-in-depth approach and applying the following principles:\n\n* Never rely on obfuscation alone for access control.\n* Unless a resource is intended to be publicly accessible, deny access by default.\n* Wherever possible, use a single application-wide mechanism for enforcing access controls.\n* At the code level, make it mandatory for developers to declare the access that is allowed for each resource, and deny access by default.\n* Thoroughly audit and test access controls to ensure they are working as designed.", + finding.mitigation) + self.assertEqual("CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H", finding.cvssv3) + self.assertEqual("PTART-2024-00002-RT", finding.unique_id_from_tool) + self.assertEqual("PTART-2024-00002", finding.vuln_id_from_tool) + self.assertEqual("PTART-2024-00002", finding.cve) + self.assertEqual("Low", finding.effort_for_fixing) + self.assertEqual("Retest: Test Retest", finding.component_name) + self.assertEqual("2024-09-08", finding.date.strftime("%Y-%m-%d")) + self.assertEqual(1, len(finding.unsaved_endpoints)) + endpoint = finding.unsaved_endpoints[0] + self.assertEqual(str(endpoint), "https://test.example.com") + self.assertEqual(1, len(finding.unsaved_files)) + screenshot = finding.unsaved_files[0] + self.assertEqual("Yet another Screenshot.png", screenshot["title"]) + self.assertTrue(screenshot["data"].startswith("iVBORw0KGgoAAAAN"), "Invalid Screenshot Data") diff --git a/unittests/tools/test_sonarqube_parser.py b/unittests/tools/test_sonarqube_parser.py index ffb05fb14df..16b80aa9eb1 100644 --- a/unittests/tools/test_sonarqube_parser.py +++ b/unittests/tools/test_sonarqube_parser.py @@ -642,6 +642,7 @@ def test_parse_json_file_from_api_with_multiple_findings_zip(self): item = findings[0] self.assertEqual(str, type(item.description)) self.assertEqual("OWASP:UsingComponentWithKnownVulnerability_fjioefjwoefijo", item.title) + self.assertEqual("testapplication", item.file_path) self.assertEqual("Medium", item.severity) item = findings[3] self.assertEqual("OWASP:UsingComponentWithKnownVulnerability_fjioefjwo1123efijo", item.title) diff --git a/unittests/tools/test_tenable_parser.py b/unittests/tools/test_tenable_parser.py index e80c3e4462c..7be782c49e3 100644 --- a/unittests/tools/test_tenable_parser.py +++ b/unittests/tools/test_tenable_parser.py @@ -299,3 +299,13 @@ def test_parse_issue_9612(self): endpoint.clean() self.assertEqual(2, len(findings)) self.assertEqual("Critical", findings[0].severity) + + def test_parse_issue_11102(self): + with open("unittests/scans/tenable/issue_11102.csv", encoding="utf-8") as testfile: + parser = TenableParser() + findings = parser.get_findings(testfile, self.create_test()) + for finding in findings: + for endpoint in finding.unsaved_endpoints: + endpoint.clean() + self.assertEqual(2, len(findings)) + self.assertEqual("Reconfigure the affected application if possible to avoid use of medium strength ciphers.", findings[0].mitigation)