diff --git a/components/package.json b/components/package.json index 8f52cc1e8d8..9c78c4b845c 100644 --- a/components/package.json +++ b/components/package.json @@ -1,6 +1,6 @@ { "name": "defectdojo", - "version": "2.47.3", + "version": "2.47.4", "license" : "BSD-3-Clause", "private": true, "dependencies": { diff --git a/docs/assets/images/pro_endpoint_metadata.png b/docs/assets/images/pro_endpoint_metadata.png new file mode 100644 index 00000000000..8da87ab41a9 Binary files /dev/null and b/docs/assets/images/pro_endpoint_metadata.png differ diff --git a/docs/assets/images/pro_finding_icons.png b/docs/assets/images/pro_finding_icons.png new file mode 100644 index 00000000000..ebff005ac4b Binary files /dev/null and b/docs/assets/images/pro_finding_icons.png differ diff --git a/docs/assets/images/pro_login.png b/docs/assets/images/pro_login.png new file mode 100644 index 00000000000..d44eafcf881 Binary files /dev/null and b/docs/assets/images/pro_login.png differ diff --git a/docs/assets/images/pro_vulnerable_endpoints.png b/docs/assets/images/pro_vulnerable_endpoints.png new file mode 100644 index 00000000000..70f0282a65c Binary files /dev/null and b/docs/assets/images/pro_vulnerable_endpoints.png differ diff --git a/docs/content/en/changelog/changelog.md b/docs/content/en/changelog/changelog.md index 7bade9a537f..2471612711b 100644 --- a/docs/content/en/changelog/changelog.md +++ b/docs/content/en/changelog/changelog.md @@ -11,6 +11,32 @@ For Open Source release notes, please see the [Releases page on GitHub](https:// ## June 2025: v2.47 +### June 16, 2025: v2.47.2 + +- **(Pro UI)** Endpoint Metadata can now be uploaded to Products. You can now import a .csv list of all endpoints associated with a Product, from **View Product > Endpoints > Import Endpoint Metadata** + +![image](images/pro_endpoint_metadata.png) + +- **(Pro UI)** Pie Charts for Metrics now dynamically update based on selected categories. +- **(Pro UI)** Finding metadata (specifically notes, endpoints, and file path/line number) are now visible from the Findings table if present. +- **(Pro UI)** Findings table now uses icons to identify linked Endpoints, Notes or Files. Clicking the Endpoints or Notes icon opens a window which lists all Endpoints or Notes. + +![image](images/pro_finding_icons.png) + +- **(Pro UI)** Login page has been redesigned. + +![image](images/pro_login.png) + + +### June 9, 2025: v2.47.1 + +- **(Pro UI)** Vulnerable Endpoints table has now been added to Finding pages. + +![image](images/pro_vulnerable_endpoints.png) + +- **(Pro UI)** "Original Finding" link has been added to Finding Metadata table for Duplicate Findings. +- **(Pro UI)** CI/CD Metadata has been added to Engagement view. + ### June 2, 2025: v2.47.0 - **(Pro UI)** Finding review can now be set through the Pro UI. You can now Request Review or clear a Finding review from Finding tables, or from the Finding View. diff --git a/docs/content/en/connecting_your_tools/parsers/api/cobalt.md b/docs/content/en/connecting_your_tools/parsers/api/cobalt.md index 59615c5d1ea..b7a66788794 100644 --- a/docs/content/en/connecting_your_tools/parsers/api/cobalt.md +++ b/docs/content/en/connecting_your_tools/parsers/api/cobalt.md @@ -7,6 +7,7 @@ All parsers which using API have common basic configuration step but with differ In `Tool Configuration`, select `Tool Type` to "Cobalt.io" and `Authentication Type` "API Key". Paste your Cobalt.io API token in the `API Key` field and the desired org token in the `Extras` field. +Currently Defect Dojo only supports [V1 API Keys](https://github.com/DefectDojo/django-DefectDojo/issues/12572). In `Add API Scan Configuration` provide the ID of the asset from which to import findings in the field `Service key 1`. diff --git a/docs/content/en/connecting_your_tools/parsers/file/trivy.md b/docs/content/en/connecting_your_tools/parsers/file/trivy.md index 01823598b70..99ad24e4477 100644 --- a/docs/content/en/connecting_your_tools/parsers/file/trivy.md +++ b/docs/content/en/connecting_your_tools/parsers/file/trivy.md @@ -4,5 +4,22 @@ toc_hide: true --- JSON report of [trivy scanner](https://github.com/aquasecurity/trivy). +The [status](https://trivy.dev/latest/docs/configuration/filtering/) field in Trivy is mapped to the Defect Dojo status flags in the following way: + +| Trivy Status | Active | Verified | Mitigated | Remarks | +|----------------------|--------|----------|-----------|-----------------------------------------------------------------------------------------------------------------| +| unknown | True | False | False | use default value for active which is usually True | +| not_affected | False | True | True | false positive is the most appropriate status for not affected as out of scope might be interpreted as something else | +| affected | True | True | False | standard case | +| fixed | True | True | False | fixed in this context means that there is a fix available by patching/updating/upgrading the package but it's still active and verified | +| under_investigation | True | False | False | no status flag in Defect Dojo to capture this, but verified is False | +| will_not_fix | True | True | False | no different from affected as Defect Dojo doesn't have a flag to capture will_not_fix by OS/Package Vendor; we can't set active to False as the user needs to risk accept this finding | +| fix_deferred | True | True | False | no different from affected as Defect Dojo doesn't have a flag to capture will_not_fix by OS/Package Vendor; we can't set active to False as the user needs to (temporarily) risk accept this finding | +| end_of_life | True | True | False | no different from affected as Defect Dojo doesn't have a flag to capture will_not_fix by OS/Package Vendor; we can't set active to False as the user needs to (temporarily) risk accept + +The status field contains the status as assigned by the OS/Package vendor such as Red Hat, Debian, etc. +It is recommended to assess the appropriate action in your Product's context. +If you want to exclude certain status from being imported into Defect Dojo, please [filter them in the export from Trivy](https://trivy.dev/latest/docs/configuration/filtering/) + ### Sample Scan Data -Sample Trivy scans can be found [here](https://github.com/DefectDojo/django-DefectDojo/tree/master/unittests/scans/trivy). \ No newline at end of file +Sample Trivy scans can be found [here](https://github.com/DefectDojo/django-DefectDojo/tree/master/unittests/scans/trivy) \ No newline at end of file diff --git a/docs/content/en/customize_dojo/notifications/about_notifications.md b/docs/content/en/customize_dojo/notifications/about_notifications.md index 1abfd045252..1426d42ac5d 100644 --- a/docs/content/en/customize_dojo/notifications/about_notifications.md +++ b/docs/content/en/customize_dojo/notifications/about_notifications.md @@ -59,3 +59,19 @@ To remove one or more Alerts from the Alerts Page, check the empty box next to i * Using the **Clear All Alerts \>** function in the Alerts Menu will also completely clear the **Alerts Page**, so use this feature with care. * Removing an Alert only affects your own Alerts List \- it will not affect any other user’s Alerts. * Removing an Alert does not remove any import history or activity logs from DefectDojo. + +## Open-Source Considerations + +### Specific overrides + +System notification settings (scope: system) describe the sending of notifications to superadmins. User notification settings (scope: personal) describe sending notifications to the specific user. + +However, there is a specific use-case when the user decides to disable notifications (to decrease noise) but the system setting is used to override this behavior. These overrides apply only to `user_mentioned` and `review_requested` by default. + +The scope of this setting is customizable (see environment variable `DD_NOTIFICATIONS_SYSTEM_LEVEL_TRUMP`). + +For more information about this behavior see the [related pull request #9699](https://github.com/DefectDojo/django-DefectDojo/pull/9699/) + +### Webhooks (experimental) + +DefectDojo also supports webhooks that follow the same events as other notifications (you can be notified in the same situations). Details about setup are described in [related page](/en/open_source/notification_webhooks/how_to). diff --git a/docs/content/en/open_source/archived_docs/jira.md b/docs/content/en/open_source/archived_docs/jira.md deleted file mode 100644 index ba3c9a16244..00000000000 --- a/docs/content/en/open_source/archived_docs/jira.md +++ /dev/null @@ -1,191 +0,0 @@ ---- -title: "JIRA integration" -description: "Bidirectional integration of DefectDojo findings with Jira issues." -draft: false -weight: 4 -exclude_search: true ---- - -DefectDojo\'s JIRA integration is bidirectional. You may push findings -to JIRA and share comments. If an issue is closed in JIRA it will -automatically be closed in Dojo. - -**NOTE:** These steps will configure the necessary webhook in JIRA and add JIRA integration into DefectDojo. This isn\'t sufficient by itself, you will need to configure products and findings to push to JIRA. On a product\'s settings page you will need to define a: - -- Project Key (and this project must exist in JIRA) -- JIRA Configuration (select the JIRA configuration that you - create in the steps below) -- Component (can be left blank) - -Then elect (via tickbox) whether you want to \'Push all issues\', -\'Enable engagement epic mapping\' and/or \'Push notes\'. Then click on -\'Submit\'. - -If creating a Finding, ensure to tick \'Push to jira\' if desired. - -Enabling the Webhook --------------------- - -1. Visit \<**YOUR JIRA URL**\>/plugins/servlet/webhooks -2. Click \'Create a Webhook\' -3. For the field labeled \'URL\' enter: \<**YOUR DOJO - DOMAIN**\>/jira/webhook/<**YOUR GENERATED WEBHOOK SECRET**> - This value can be found under Defect Dojo System settings -4. Under \'Comments\' enable \'Created\'. Under Issue enable - \'Updated\'. - -Configurations in Dojo ----------------------- - -1. Navigate to the System Settings from the menu on the left side - or by directly visiting \/system\_settings. -2. Enable \'Enable JIRA integration\' and click submit. -3. For the webhook created in Enabling the Webhook, enable - \'Enable JIRA web hook\' and click submit. - -Adding JIRA to Dojo -------------------- - -1. Click \'JIRA\' from the left hand menu. -2. Select \'Add Configuration\' from the drop-down. -3. For JIRA Server: - - Enter the _Username_ & _Password_. A _Username_ and JIRA _Personal Access Token_ will not necessarily work. - - For JIRA Cloud: - - Enter _Email Address_ & [API token for Jira](https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account/) -4. To obtain the \'open status key\' and \'closed status key\' - visit \<**YOUR JIRA - URL**\>/rest/api/latest/issue/\<**ANY VALID ISSUE - KEY**\>/transitions?expand=transitions.fields -5. The \'id\' for \'Todo\' should be filled in as the \'open status - key\' -6. The \'id\' for \'Done\' should be filled in as the \'closed - status key\' - -To obtain \'epic name id\': If you have admin access to JIRA: - -1. visit: \<**YOUR JIRA - URL**\>/secure/admin/ViewCustomFields.jspa -2. Click on the cog next to \'Epic Name\' and select view. -3. The numeric value for \'epic name id\' will be displayed in the - URL -4. **Note**: dojojira uses the same celery functionality as - reports. Make sure the celery runner is setup correctly as - described: - - -Or - -1. login to JIRA -2. visit and use control+F - or grep to search for \'Epic Name\' it should look something - like this: - -{ - "id":"customfield_122", - "key":"customfield_122", - "name":"Epic Name", - "custom":true, - "orderable":true, - "navigable":true, - "searchable":true, - "clauseNames":"cf[122]", - "Epic Name"\], - "schema":{"type":"string","custom":"com.pyxis.greenhopper.jira:gh-epic-label","customId":122} -} - -**In the above example 122 is the number needed** - -## Customize JIRA issue description - -By default Defect Dojo uses the `dojo/templates/issue-trackers/jira_full/jira-description.tpl` template to render the description of the 'to be' created JIRA issue. -This file can be modified to your needs, rebuild all containers afterwards. There's also a more limited template available, which can be chosen when -configuring a JIRA Instance or JIRA Project for a Product or Engagement: - -![image](images/jira_issue_templates.png) - -Any folder added to `dojo/templates/issue-trackers/` will be added to the dropdown (after rebuilding/restarting the containers). - -## Engagement Epic Mapping - -If creating an Engagement, ensure to tick 'Enable engagement epic mapping' if desired. This can also be done after engagement creation on the edit engagement page. -This will create an 'Epic' type issue within Jira. All findings in the engagement pushed to Jira will have a link to this Epic issue. -If Epic Mapping was enabled after associated findings have already been pushed to Jira, simply pushing them again will link the Jira issue to the Epic issue. - -## Pushing findings - -Findings can be pushed to Jira in a number of ways: - -1. When importing scanner reports, select 'Push to JIRA' to push every single finding in the report to Jira -2. When creating a new finding, select 'Push to JIRA' and submit. This will create the finding in DefectDojo and Jira simultaneously -3. If a finding already exist, visit the edit finding page and find the 'Push to JIRA' tick box at the bottom -4. When viewing a list of findings, select each relevant tick boxes to the left of the finding, and click the 'Bulk Edit' button at the top. find 'Push to JIRA' at the bottom of the menu - -## Status Sync - -DefectDojo will try to keep the status in sync with the status in JIRA -using the Close and Reopen transition IDs configured for each JIRA instance. This -will only work if your workflow in JIRA allows the Close transition to be -performed from every status a JIRA issue can be in. - -## Known Issues - -The Risk Acceptance feature -in DefectDojo will (for that reason) not (yet) try to sync statuses. A -comment will be pushed to JIRA if a finding is risk accepted or -unaccepted. Contributions are welcome to enhance the integration. - -## Status reconciliation - -Sometimes JIRA is down, or Defect Dojo is down, or there was bug in a webhook. In this case -JIRA can become out of sync with Defect Dojo. If this is the case for lots of issues, manual reconciliation -might not be feasible. For this scenario there is the management command 'jira_status_reconciliation'. - -{{< highlight bash >}} -usage: manage.py jira_status_reconciliation [-h] [--mode MODE] [--product PRODUCT] [--engagement ENGAGEMENT] [--dryrun] [--version] [-v {0,1,2,3}] - -Reconcile finding status with JIRA issue status, stdout will contain semicolon seperated CSV results. -Risk Accepted findings are skipped. Findings created before 1.14.0 are skipped. - -optional arguments: - -h, --help show this help message and exit - --mode MODE - reconcile: (default)reconcile any differences in status between Defect Dojo and JIRA, will look at the latest status change - timestamp in both systems to determine which one is the correct status - - push_status_to_jira: update JIRA status for all JIRA issues - connected to a Defect Dojo finding (will not push summary/description, only status) - - import_status_from_jira: update Defect Dojo - finding status from JIRA - --product PRODUCT Only process findings in this product (name) - --engagement ENGAGEMENT - Only process findings in this product (name) - --dryrun Only print actions to be performed, but make no modifications. - -v {0,1,2,3}, --verbosity {0,1,2,3} - Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output -{{< /highlight >}} - -This can be executed from the uwsgi docker container using: - -{{< highlight bash >}} -$ docker compose exec uwsgi /bin/bash -c 'python manage.py jira_status_reconciliation' -{{< /highlight >}} - -DEBUG output can be obtains via `-v 3`, but only after increasing the logging to DEBUG level in your settings.dist.py or local_settings.py file - -{{< highlight bash >}} -$ docker compose exec uwsgi /bin/bash -c 'python manage.py jira_status_reconciliation -v 3' -{{< /highlight >}} - -At the end of the command a semicolon seperated CSV summary will be printed. This can be captured by redirecting stdout to a file: - -{{< highlight bash >}} -$ docker compose exec uwsgi /bin/bash -c 'python manage.py jira_status_reconciliation > jira_reconciliation.csv' -{{< /highlight >}} - - -## Troubleshooting JIRA integration - -JIRA actions are typically performed in the celery background process. -Errors are logged as alerts/notifications to be seen on the top right of -the DefectDojo UI and in stdout of the celery workers. diff --git a/docs/content/en/open_source/archived_docs/notifications.md b/docs/content/en/open_source/archived_docs/notifications.md deleted file mode 100644 index 0740115ce9c..00000000000 --- a/docs/content/en/open_source/archived_docs/notifications.md +++ /dev/null @@ -1,133 +0,0 @@ ---- -title: "Notifications" -description: "DefectDojo can inform you about changes on different channels." -draft: false -weight: 6 -exclude_search: true ---- - -## Notifications - -![Notification settings](images/notifications_1.png) - -DefectDojo can inform you of different events in a variety of ways. You -can be notified about things like an upcoming engagement, when someone -mentions you in a comment, a scheduled report has finished generating, -and more. - -The following notification methods currently exist: - - Email - - Slack - - Microsoft Teams - - Webhooks - - Alerts within DefectDojo (default) - -You can set these notifications on a global scope (if you have -administrator rights) or on a personal scope. For instance, an -administrator might want notifications of all upcoming engagements sent -to a certain Slack channel, whereas an individual user wants email -notifications to be sent to the user\'s specified email address when a -report has finished generating. - -Users can define notifications on a product level as well, and these settings will be applied only for selected products. - -In order to identify and notify you about things like upcoming -engagements, DefectDojo runs scheduled tasks for this purpose. These -tasks are scheduled and run using Celery beat, so this needs to run for -those notifications to work. - -DefectDojo allows `template` to be used, administrator can use this feature to define which notification should be received by newly created users. - -### Slack - -#### Basic Integration -This method will allow DefectDojo to send Global notifications to a Slack channel. It can also send Personal notifications to an individual user's Slackbot. - -To configure Slack messaging, you will first need to create a new Slack app at https://api.slack.com/apps. - -This app can be created from scratch, or from a JSON manifest which includes all necessary scopes and bot functionality. This manifest can be copied and pasted into the Slack App wizard when you select 'Build From Manifest'. - -
- JSON Manifest - -~~~ -{ - "_metadata": { - "major_version": 1, - "minor_version": 1 - }, - "display_information": { - "name": "DefectDojo", - "description": "Notifications from DefectDojo", - "background_color": "#0000AA" - }, - "features": { - "bot_user": { - "display_name": "DefectDojo Notifications" - } - }, - "oauth_config": { - "scopes": { - "bot": [ - "chat:write", - "chat:write.customize", - "chat:write.public", - "incoming-webhook", - "users:read", - "users:read.email" - ] - }, - "redirect_urls": [ - "https://slack.com/oauth/v2/authorize" - ] - } -} -~~~ - -
- -Choose the channel where you want to post Global notifications during the 'Create From Manifest' process. Personal notifications will appear in a user's Slackbot if they have their Slack Email Address specified on their user profile. - -#### Scopes - -The following scopes have to be granted to your Slack App. If the App was created from the JSON Manifest above, these permission scopes will already be set correctly. - -![Slack OAuth scopes](images/slack_scopes.png) - -#### Token - -The Slack Bot Token needs to be pasted in the DefectDojo System Settings, nested underneath the 'Enable slack notifications' checkbox. This token can be found in the Features / OAuth & Permissions section on the Slack App settings. - -![Slack token](images/slack_tokens.png) - -#### Examples of Slack notifications - -![Add Product](images/slack_add_product.png) - -![Import Scan](images/slack_import_scan.png) - - -### Microsoft Teams - -Microsoft Teams does not provide an easy way to send messages to a personal -channel. Therefore, DefectDojo can only send system scope notifications -to Microsoft Teams. - -To activate notifications to Microsoft Teams, you have to: -- Configure an Incoming Webhook in a Teams channel and copy the URL of the webhook to the clipboard -- Activate `Enable Microsoft Teams notifications` in the System Settings -- Paste the URL of the Incoming Webhook into the field `Msteams url` - -## Specific overrides - -System notification settings (scope: system) describe the sending of notifications to superadmins. User notification settings (scope: personal) describe sending notifications to the specific user. - -However, there is a specific use-case when the user decides to disable notifications (to decrease noise) but the system setting is used to override this behavior. These overrides apply only to `user_mentioned` and `review_requested` by default. - -The scope of this setting is customizable (see environmental variable `DD_NOTIFICATIONS_SYSTEM_LEVEL_TRUMP`). - -For more information about this behavior see the [related pull request #9699](https://github.com/DefectDojo/django-DefectDojo/pull/9699/) - -## Webhooks (experimental) - -DefectDojo also supports webhooks that follow the same events as other notifications (you can be notified in the same situations). Details about setup are described in [related page](../../notification_webhooks/how_to). diff --git a/docs/content/en/share_your_findings/troubleshooting_jira.md b/docs/content/en/share_your_findings/troubleshooting_jira.md index cec412edc2d..5bdee959791 100644 --- a/docs/content/en/share_your_findings/troubleshooting_jira.md +++ b/docs/content/en/share_your_findings/troubleshooting_jira.md @@ -97,4 +97,50 @@ To correct this issue, you can add the 'Epic Name' field to your Project's issue 4. Type in 'Epic Name' 5. Add Epic Name as a field to this particular screen by following Jira's instructions. -![image](images/epic_name_error.png) \ No newline at end of file +![image](images/epic_name_error.png) + +## Jira and DefectDojo are out of sync + +Sometimes Jira is down, or DefectDojo is down, or there was bug in a webhook. In this case, Jira can become out of sync with DefectDojo. If this is the case for lots of issues, manual reconciliation might not be feasible. For this scenario there is the management command 'jira_status_reconciliation'. + +As this command requires access to the backend, it is not available to Cloud users of DefectDojo Pro; instead, please contact our Support team for assistance with this issue. + +{{< highlight bash >}} +usage: manage.py jira_status_reconciliation [-h] [--mode MODE] [--product PRODUCT] [--engagement ENGAGEMENT] [--dryrun] [--version] [-v {0,1,2,3}] + +Reconcile finding status with JIRA issue status, stdout will contain semicolon seperated CSV results. +Risk Accepted findings are skipped. Findings created before 1.14.0 are skipped. + +optional arguments: + -h, --help show this help message and exit + --mode MODE - reconcile: (default)reconcile any differences in status between Defect Dojo and JIRA, will look at the latest status change + timestamp in both systems to determine which one is the correct status + - push_status_to_jira: update JIRA status for all JIRA issues + connected to a Defect Dojo finding (will not push summary/description, only status) + - import_status_from_jira: update Defect Dojo + finding status from JIRA + --product PRODUCT Only process findings in this product (name) + --engagement ENGAGEMENT + Only process findings in this product (name) + --dryrun Only print actions to be performed, but make no modifications. + -v {0,1,2,3}, --verbosity {0,1,2,3} + Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output +{{< /highlight >}} + +This can be executed from the uwsgi docker container using: + +{{< highlight bash >}} +$ docker compose exec uwsgi /bin/bash -c 'python manage.py jira_status_reconciliation' +{{< /highlight >}} + +DEBUG output can be obtains via `-v 3`, but only after increasing the logging to DEBUG level in your settings.dist.py or local_settings.py file + +{{< highlight bash >}} +$ docker compose exec uwsgi /bin/bash -c 'python manage.py jira_status_reconciliation -v 3' +{{< /highlight >}} + +At the end of the command a semicolon seperated CSV summary will be printed. This can be captured by redirecting stdout to a file: + +{{< highlight bash >}} +$ docker compose exec uwsgi /bin/bash -c 'python manage.py jira_status_reconciliation > jira_reconciliation.csv' +{{< /highlight >}} diff --git a/dojo/__init__.py b/dojo/__init__.py index 3a53fb4802b..17de6567d7a 100644 --- a/dojo/__init__.py +++ b/dojo/__init__.py @@ -4,6 +4,6 @@ # Django starts so that shared_task will use this app. from .celery import app as celery_app # noqa: F401 -__version__ = "2.47.3" +__version__ = "2.47.4" __url__ = "https://github.com/DefectDojo/django-DefectDojo" __docs__ = "https://documentation.defectdojo.com" diff --git a/dojo/db_migrations/0230_add_finding_kev_fields.py b/dojo/db_migrations/0230_add_finding_kev_fields.py new file mode 100644 index 00000000000..f1f92900c69 --- /dev/null +++ b/dojo/db_migrations/0230_add_finding_kev_fields.py @@ -0,0 +1,42 @@ +# Generated by Django 5.1.8 on 2025-06-23 19:34 + +import django.core.validators +import dojo.models +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dojo', '0229_alter_finding_unique_id_from_tool'), + ] + + operations = [ + migrations.AddField( + model_name='finding', + name='kev_date', + field=models.DateField(blank=True, help_text='The date the vulnerability was added to the KEV catalog.', null=True, validators=[django.core.validators.MaxValueValidator(dojo.models.tomorrow)], verbose_name='KEV Date Added'), + ), + migrations.AddField( + model_name='finding', + name='known_exploited', + field=models.BooleanField(default=False, help_text='Whether this vulnerability is known to have been exploited in the wild.', verbose_name='Known Exploited'), + ), + migrations.AddField( + model_name='finding', + name='ransomware_used', + field=models.BooleanField(default=False, help_text='Whether this vulnerability is known to have been leveraged as part of a ransomware campaign.', verbose_name='Used in Ransomware'), + ), + migrations.AddIndex( + model_name='finding', + index=models.Index(fields=['known_exploited'], name='dojo_findin_known_e_8c584e_idx'), + ), + migrations.AddIndex( + model_name='finding', + index=models.Index(fields=['ransomware_used'], name='dojo_findin_ransomw_c185c6_idx'), + ), + migrations.AddIndex( + model_name='finding', + index=models.Index(fields=['kev_date'], name='dojo_findin_kev_dat_b54260_idx'), + ), + ] diff --git a/dojo/endpoint/signals.py b/dojo/endpoint/signals.py index f96510df786..6259ab45ab4 100644 --- a/dojo/endpoint/signals.py +++ b/dojo/endpoint/signals.py @@ -13,16 +13,15 @@ @receiver(post_delete, sender=Endpoint) def endpoint_post_delete(sender, instance, using, origin, **kwargs): if instance == origin: + description = _('The endpoint "%(name)s" was deleted') % {"name": str(instance)} if settings.ENABLE_AUDITLOG: - le = LogEntry.objects.get( + if le := LogEntry.objects.filter( action=LogEntry.Action.DELETE, content_type=ContentType.objects.get(app_label="dojo", model="endpoint"), object_id=instance.id, - ) - description = _('The endpoint "%(name)s" was deleted by %(user)s') % { + ).order_by("-id").first(): + description = _('The endpoint "%(name)s" was deleted by %(user)s') % { "name": str(instance), "user": le.actor} - else: - description = _('The endpoint "%(name)s" was deleted') % {"name": str(instance)} create_notification(event="endpoint_deleted", # template does not exists, it will default to "other" but this event name needs to stay because of unit testing title=_("Deletion of %(name)s") % {"name": str(instance)}, description=description, diff --git a/dojo/engagement/signals.py b/dojo/engagement/signals.py index 538ff001123..01b8f1139f2 100644 --- a/dojo/engagement/signals.py +++ b/dojo/engagement/signals.py @@ -39,16 +39,15 @@ def engagement_pre_save(sender, instance, **kwargs): @receiver(post_delete, sender=Engagement) def engagement_post_delete(sender, instance, using, origin, **kwargs): if instance == origin: + description = _('The engagement "%(name)s" was deleted') % {"name": instance.name} if settings.ENABLE_AUDITLOG: - le = LogEntry.objects.get( + if le := LogEntry.objects.filter( action=LogEntry.Action.DELETE, content_type=ContentType.objects.get(app_label="dojo", model="engagement"), object_id=instance.id, - ) - description = _('The engagement "%(name)s" was deleted by %(user)s') % { + ).order_by("-id").first(): + description = _('The engagement "%(name)s" was deleted by %(user)s') % { "name": instance.name, "user": le.actor} - else: - description = _('The engagement "%(name)s" was deleted') % {"name": instance.name} create_notification(event="engagement_deleted", # template does not exists, it will default to "other" but this event name needs to stay because of unit testing title=_("Deletion of %(name)s") % {"name": instance.name}, description=description, diff --git a/dojo/finding_group/signals.py b/dojo/finding_group/signals.py index 17ed6b1b9a9..1e2d771b557 100644 --- a/dojo/finding_group/signals.py +++ b/dojo/finding_group/signals.py @@ -13,16 +13,15 @@ @receiver(post_delete, sender=Finding_Group) def finding_group_post_delete(sender, instance, using, origin, **kwargs): if instance == origin: + description = _('The finding group "%(name)s" was deleted') % {"name": instance.name} if settings.ENABLE_AUDITLOG: - le = LogEntry.objects.get( + if le := LogEntry.objects.filter( action=LogEntry.Action.DELETE, content_type=ContentType.objects.get(app_label="dojo", model="finding_group"), object_id=instance.id, - ) - description = _('The finding group "%(name)s" was deleted by %(user)s') % { + ).order_by("-id").first(): + description = _('The finding group "%(name)s" was deleted by %(user)s') % { "name": instance.name, "user": le.actor} - else: - description = _('The finding group "%(name)s" was deleted') % {"name": instance.name} create_notification(event="finding_group_deleted", # template does not exists, it will default to "other" but this event name needs to stay because of unit testing title=_("Deletion of %(name)s") % {"name": instance.name}, description=description, diff --git a/dojo/metrics/utils.py b/dojo/metrics/utils.py index 9647f84c7f9..cf3e2813e13 100644 --- a/dojo/metrics/utils.py +++ b/dojo/metrics/utils.py @@ -1,4 +1,5 @@ +import logging import operator from collections.abc import Callable from datetime import date, datetime, timedelta @@ -32,6 +33,8 @@ queryset_check, ) +logger = logging.getLogger(__name__) + def get_metrics_finding_filter_class() -> type[MetricsFindingFilter | MetricsFindingFilterWithoutObjectLookups]: if get_system_setting("filter_string_matching", False): @@ -62,14 +65,12 @@ def finding_queries( findings_filter = finding_filter_class(request.GET, queryset=all_authorized_findings) form = findings_filter.form filtered_findings: QuerySet[Finding] = queryset_check(findings_filter) - # Quick check to determine if the filters were too tight and filtered everything away. If so, fall back to using all - # authorized Findings instead. - if not filtered_findings.exists() and all_authorized_findings.exists(): - filtered_findings = all_authorized_findings + + if not filtered_findings.exists(): messages.add_message( request, - messages.ERROR, - _("All objects have been filtered away. Displaying all objects"), + messages.WARNING, + _("No findings match the current filters."), extra_tags="alert-danger") start_date, end_date = get_date_range(filtered_findings) @@ -161,14 +162,13 @@ def endpoint_queries( endpoints_qs = queryset_check(endpoints) if not endpoints_qs.exists(): - endpoints = endpoints_query - endpoints_qs = endpoints if isinstance(endpoints, QuerySet) else endpoints.qs messages.add_message( request, - messages.ERROR, - _("All objects have been filtered away. Displaying all objects"), + messages.WARNING, + _("No endpoints match the current filters."), extra_tags="alert-danger") + endpoints = endpoints_qs start_date, end_date = get_date_range(endpoints_qs) if len(prod_type) > 0: diff --git a/dojo/models.py b/dojo/models.py index 177d820867d..1e7b490b155 100644 --- a/dojo/models.py +++ b/dojo/models.py @@ -5,7 +5,7 @@ import re import warnings from contextlib import suppress -from datetime import datetime +from datetime import datetime, timedelta from decimal import Decimal from pathlib import Path from uuid import uuid4 @@ -137,6 +137,11 @@ def _copy_model_util(model_in_database, exclude_fields: list[str] | None = None) return new_model_instance +def tomorrow(): + """Returns a date representing the day after today.""" + return timezone.now().date() + timedelta(days=1) + + @deconstructible class UniqueUploadNameProvider: @@ -2331,6 +2336,16 @@ class Finding(models.Model): verbose_name=_("EPSS percentile"), help_text=_("EPSS percentile for the CVE. Describes how many CVEs are scored at or below this one."), validators=[MinValueValidator(0.0), MaxValueValidator(1.0)]) + known_exploited = models.BooleanField(default=False, + verbose_name=_("Known Exploited"), + help_text=_("Whether this vulnerability is known to have been exploited in the wild.")) + ransomware_used = models.BooleanField(default=False, + verbose_name=_("Used in Ransomware"), + help_text=_("Whether this vulnerability is known to have been leveraged as part of a ransomware campaign.")) + kev_date = models.DateField(null=True, blank=True, + verbose_name=_("KEV Date Added"), + help_text=_("The date the vulnerability was added to the KEV catalog."), + validators=[MaxValueValidator(tomorrow)]) cvssv3_regex = RegexValidator(regex=r"^AV:[NALP]|AC:[LH]|PR:[UNLH]|UI:[NR]|S:[UC]|[CIA]:[NLH]", message="CVSS must be entered in format: 'AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H'") cvssv3 = models.TextField(validators=[cvssv3_regex], max_length=117, @@ -2660,6 +2675,9 @@ class Meta: models.Index(fields=["duplicate"]), models.Index(fields=["is_mitigated"]), models.Index(fields=["duplicate_finding", "id"]), + models.Index(fields=["known_exploited"]), + models.Index(fields=["ransomware_used"]), + models.Index(fields=["kev_date"]), ] def __init__(self, *args, **kwargs): diff --git a/dojo/product/signals.py b/dojo/product/signals.py index 72e9771e82c..7aa0704ae4e 100644 --- a/dojo/product/signals.py +++ b/dojo/product/signals.py @@ -23,16 +23,15 @@ def product_post_save(sender, instance, created, **kwargs): @receiver(post_delete, sender=Product) def product_post_delete(sender, instance, **kwargs): + description = _('The product "%(name)s" was deleted') % {"name": instance.name} if settings.ENABLE_AUDITLOG: - le = LogEntry.objects.get( + if le := LogEntry.objects.filter( action=LogEntry.Action.DELETE, content_type=ContentType.objects.get(app_label="dojo", model="product"), object_id=instance.id, - ) - description = _('The product "%(name)s" was deleted by %(user)s') % { + ).order_by("-id").first(): + description = _('The product "%(name)s" was deleted by %(user)s') % { "name": instance.name, "user": le.actor} - else: - description = _('The product "%(name)s" was deleted') % {"name": instance.name} create_notification(event="product_deleted", # template does not exists, it will default to "other" but this event name needs to stay because of unit testing title=_("Deletion of %(name)s") % {"name": instance.name}, description=description, diff --git a/dojo/product/views.py b/dojo/product/views.py index 736b7b5ec7e..2552d79dc48 100644 --- a/dojo/product/views.py +++ b/dojo/product/views.py @@ -364,7 +364,7 @@ def identify_view(request): return "Finding" -def finding_querys(request, prod): +def finding_queries(request, prod): filters = {} findings_query = Finding.objects.filter(test__engagement__product=prod) # prefetch only what's needed to avoid lots of repeated queries @@ -433,7 +433,7 @@ def finding_querys(request, prod): return filters -def endpoint_querys(request, prod): +def endpoint_queries(request, prod): filters = {} endpoints_query = Endpoint_Status.objects.filter(finding__test__engagement__product=prod, finding__severity__in=( @@ -449,13 +449,11 @@ def endpoint_querys(request, prod): filters["form"] = endpoints.form if not endpoints_qs and not endpoints_query: - endpoints = endpoints_query - endpoints_qs = queryset_check(endpoints) - messages.add_message(request, - messages.ERROR, - _("All objects have been filtered away. Displaying all objects"), - extra_tags="alert-danger") - + messages.add_message( + request, + messages.WARNING, + _("No Endpoints match the current filters."), + extra_tags="alert-danger") try: start_date = endpoints_qs.earliest("date").date start_date = datetime(start_date.year, @@ -538,9 +536,9 @@ def view_product_metrics(request, pid): filters = {} if view == "Finding": - filters = finding_querys(request, prod) + filters = finding_queries(request, prod) elif view == "Endpoint": - filters = endpoint_querys(request, prod) + filters = endpoint_queries(request, prod) start_date = timezone.make_aware(datetime.combine(filters["start_date"], datetime.min.time())) end_date = filters["end_date"] diff --git a/dojo/product_type/signals.py b/dojo/product_type/signals.py index 743995768eb..2fd1a70d0ec 100644 --- a/dojo/product_type/signals.py +++ b/dojo/product_type/signals.py @@ -23,16 +23,15 @@ def product_type_post_save(sender, instance, created, **kwargs): @receiver(post_delete, sender=Product_Type) def product_type_post_delete(sender, instance, **kwargs): + description = _('The product type "%(name)s" was deleted') % {"name": instance.name} if settings.ENABLE_AUDITLOG: - le = LogEntry.objects.get( + if le := LogEntry.objects.filter( action=LogEntry.Action.DELETE, content_type=ContentType.objects.get(app_label="dojo", model="product_type"), object_id=instance.id, - ) - description = _('The product type "%(name)s" was deleted by %(user)s') % { + ).order_by("-id").first(): + description = _('The product type "%(name)s" was deleted by %(user)s') % { "name": instance.name, "user": le.actor} - else: - description = _('The product type "%(name)s" was deleted') % {"name": instance.name} create_notification(event="product_type_deleted", # template does not exists, it will default to "other" but this event name needs to stay because of unit testing title=_("Deletion of %(name)s") % {"name": instance.name}, description=description, diff --git a/dojo/settings/settings.dist.py b/dojo/settings/settings.dist.py index 8b7ae27b18e..76cf43063d7 100644 --- a/dojo/settings/settings.dist.py +++ b/dojo/settings/settings.dist.py @@ -1838,6 +1838,7 @@ def saml2_attrib_map_format(din): "JSDSERVER-": "https://jira.atlassian.com/browse/", # e.g. https://jira.atlassian.com/browse/JSDSERVER-14872 "KB": "https://support.hcl-software.com/csm?id=kb_article&sysparm_article=", # e.g. https://support.hcl-software.com/csm?id=kb_article&sysparm_article=KB0108401 "KHV": "https://avd.aquasec.com/misconfig/kubernetes/", # e.g. https://avd.aquasec.com/misconfig/kubernetes/khv045 + "LEN-": "https://support.lenovo.com/cl/de/product_security/", # e.g. https://support.lenovo.com/cl/de/product_security/LEN-94953 "MGAA-": "https://advisories.mageia.org/&&.html", # e.g. https://advisories.mageia.org/MGAA-2013-0054.html "MGASA-": "https://advisories.mageia.org/&&.html", # e.g. https://advisories.mageia.org/MGASA-2025-0023.html "NTAP-": "https://security.netapp.com/advisory/", # e.g. https://security.netapp.com/advisory/ntap-20250328-0007 @@ -1861,6 +1862,7 @@ def saml2_attrib_map_format(din): "SUSE-SU-": "https://www.suse.com/support/update/announcement/", # e.g. https://www.suse.com/support/update/announcement/2024/suse-su-20244196-1 "SVD-": "https://advisory.splunk.com/advisories/", # e.g. https://advisory.splunk.com/advisories/SVD-2025-0103 "TEMP-": "https://security-tracker.debian.org/tracker/", # e.g. https://security-tracker.debian.org/tracker/TEMP-0841856-B18BAF + "TS-": """https://tailscale.com/security-bulletins#""", # e.g. https://tailscale.com/security-bulletins or https://tailscale.com/security-bulletins#ts-2022-001-1243 "TYPO3-": "https://typo3.org/security/advisory/", # e.g. https://typo3.org/security/advisory/typo3-core-sa-2025-010 "USN-": "https://ubuntu.com/security/notices/", # e.g. https://ubuntu.com/security/notices/USN-6642-1 "VNS": "https://vulners.com/", diff --git a/dojo/test/signals.py b/dojo/test/signals.py index f161f505baa..eec135fe710 100644 --- a/dojo/test/signals.py +++ b/dojo/test/signals.py @@ -16,16 +16,15 @@ @receiver(post_delete, sender=Test) def test_post_delete(sender, instance, using, origin, **kwargs): if instance == origin: + description = _('The test "%(name)s" was deleted') % {"name": str(instance)} if settings.ENABLE_AUDITLOG: - le = LogEntry.objects.get( + if le := LogEntry.objects.filter( action=LogEntry.Action.DELETE, content_type=ContentType.objects.get(app_label="dojo", model="test"), object_id=instance.id, - ) - description = _('The test "%(name)s" was deleted by %(user)s') % { + ).order_by("-id").first(): + description = _('The test "%(name)s" was deleted by %(user)s') % { "name": str(instance), "user": le.actor} - else: - description = _('The test "%(name)s" was deleted') % {"name": str(instance)} create_notification(event="test_deleted", # template does not exists, it will default to "other" but this event name needs to stay because of unit testing title=_("Deletion of %(name)s") % {"name": str(instance)}, description=description, diff --git a/dojo/tools/trivy/parser.py b/dojo/tools/trivy/parser.py index fbe87bd64cd..8b8deb130c1 100644 --- a/dojo/tools/trivy/parser.py +++ b/dojo/tools/trivy/parser.py @@ -66,6 +66,85 @@ def convert_cvss_score(self, raw_value): return "High" return "Critical" + def convert_trivy_status(self, trivy_status: str) -> dict: + """ + Determine status fields based on Trivy status + + From: https://trivy.dev/v0.54/docs/configuration/filtering/ + + Trivy has a Status field based on VEX vulnerability statuses. Please not these are statuses based on the vulnerability advisories by OS vendors such as Debian, RHEL, etc. + + - `unknown` + - `not_affected`: this package is not affected by this vulnerability on this platform + - `affected`: this package is affected by this vulnerability on this platform, but there is no patch released yet + - `fixed`: this vulnerability is fixed on this platform + - `under_investigation`: it is currently unknown whether or not this vulnerability affects this package on this platform, and it is under investigation + - `will_not_fix`: this package is affected by this vulnerability on this platform, but there is currently no intention to fix it (this would primarily be for flaws that are of Low or Moderate impact that pose no significant risk to customers) + - `fix_deferred`: this package is affected by this vulnerability on this platform, and may be fixed in the future + - `end_of_life`: this package has been identified to contain the impacted component, but analysis to determine whether it is affected or not by this vulnerability was not performed + + + Note that vulnerabilities with the `unknown`, `not_affected` or `under_investigation` status are not detected. + These are only defined for comprehensiveness, and you will not have the opportunity to specify these statuses. + + Some statuses are supported in limited distributions. + + | OS | Fixed | Affected | Under Investigation | Will Not Fix | Fix Deferred | End of Life | + |:----------:|:-----:|:--------:|:-------------------:|:------------:|:------------:|:-----------:| + | Debian | ✓ | ✓ | | | ✓ | ✓ | + | RHEL | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | + | Other OSes | ✓ | ✓ | | | | | + """ + status_mapping = { + "unknown": { + # use default value for active which is usually True + "verified": False, + }, + "not_affected": { + # false positive is the most appropriate status for not affected as out of scope might be interpreted as something else + "active": False, + "verified": True, + "is_mitigated": True, + }, + "affected": { + # standard case + "active": True, + "verified": True, + }, + "fixed": { + # fixed in this context means that there is a fix available by patching/updating/upgrading the package + # but it's still active and verified + "active": True, + "verified": True, + }, + "under_investigation": { + # no status flag in Defect Dojo to capture this, but verified is False + "active": True, + "verified": False, + }, + "will_not_fix": { + # no different from affected as Defect Dojo doesn't have a flag to capture will_not_fix by OS/Package Vendor + # we can't set active to False as the user needs to risk accept this finding + "active": True, + "verified": True, + }, + "fix_deferred": { + # no different from affected as Defect Dojo doesn't have a flag to capture will_not_fix by OS/Package Vendor + # we can't set active to False as the user needs to (temporarily) risk accept this finding + "active": True, + "verified": True, + }, + "end_of_life": { + # no different from affected as Defect Dojo doesn't have a flag to capture will_not_fix by OS/Package Vendor + # we can't set active to False as the user needs to (temporarily) risk accept this finding + "active": True, + "verified": True, + }, + } + + # default is to fallback to default Defect Dojo behaviour which takes scan parameters into account + return status_mapping.get(trivy_status, {}) + def get_findings(self, scan_file, test): scan_data = scan_file.read() @@ -194,6 +273,8 @@ def get_result_items(self, test, results, service_name=None, artifact_name=""): package_version = vuln.get("InstalledVersion", "") references = "\n".join(vuln.get("References", [])) mitigation = vuln.get("FixedVersion", "") + impact = vuln.get("Status", "") + status_fields = self.convert_trivy_status(vuln.get("Status", "")) cwe = int(vuln["CweIDs"][0].split("-")[1]) if len(vuln.get("CweIDs", [])) > 0 else 0 vul_type = target_data.get("Type", "") title = f"{vuln_id} {package_name} {package_version}" @@ -212,6 +293,7 @@ def get_result_items(self, test, results, service_name=None, artifact_name=""): file_path=file_path, references=references, description=description, + impact=impact, mitigation=mitigation, component_name=package_name, component_version=package_version, @@ -220,6 +302,7 @@ def get_result_items(self, test, results, service_name=None, artifact_name=""): dynamic_finding=False, tags=[vul_type, target_class], service=service_name, + **status_fields, ) if vuln_id: diff --git a/dojo/tools/twistlock/parser.py b/dojo/tools/twistlock/parser.py index a0b99575911..334a12f3e16 100644 --- a/dojo/tools/twistlock/parser.py +++ b/dojo/tools/twistlock/parser.py @@ -149,23 +149,23 @@ def get_item(vulnerability, test): # create the finding object finding = Finding( - title=vulnerability["id"] + title=vulnerability.get("id", "Unknown Vulnerability") + ": " - + vulnerability["packageName"] + + vulnerability.get("packageName", "Unknown Package") + " - " - + vulnerability["packageVersion"], + + str(vulnerability.get("packageVersion", "")), test=test, severity=severity, - description=vulnerability["description"] + description=vulnerability.get("description", "") + "

Vulnerable Package: " - + vulnerability["packageName"] + + vulnerability.get("packageName", "") + "

Current Version: " - + str(vulnerability["packageVersion"]) + + str(vulnerability.get("packageVersion", "")) + "

", - mitigation=status.title(), + mitigation=status.title() if isinstance(status, str) else "", references=vulnerability.get("link"), - component_name=vulnerability["packageName"], - component_version=vulnerability["packageVersion"], + component_name=vulnerability.get("packageName", ""), + component_version=vulnerability.get("packageVersion", ""), false_p=False, duplicate=False, out_of_scope=False, @@ -173,7 +173,7 @@ def get_item(vulnerability, test): severity_justification=f"{vector} (CVSS v3 base score: {cvss})\n\n{riskFactors}", impact=severity, ) - finding.unsaved_vulnerability_ids = [vulnerability["id"]] + finding.unsaved_vulnerability_ids = [vulnerability["id"]] if "id" in vulnerability else None finding.description = finding.description.strip() return finding diff --git a/dojo/user/views.py b/dojo/user/views.py index 97705de6981..998dd25a909 100644 --- a/dojo/user/views.py +++ b/dojo/user/views.py @@ -149,7 +149,7 @@ def login_view(request): return HttpResponseRedirect("/saml2/login") try: return HttpResponseRedirect("{}?{}".format(reverse("social:begin", args=[social_auth]), - urlencode({"next": request.GET.get("next")}))) + urlencode({"next": request.GET.get("next", "/dashboard")}))) except: return HttpResponseRedirect(reverse("social:begin", args=[social_auth])) else: diff --git a/dojo/utils.py b/dojo/utils.py index 81f282c2c09..d8344039a0b 100644 --- a/dojo/utils.py +++ b/dojo/utils.py @@ -18,6 +18,7 @@ import hyperlink import vobject from asteval import Interpreter +from auditlog.models import LogEntry from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from dateutil.parser import parse @@ -25,6 +26,7 @@ from django.conf import settings from django.contrib import messages from django.contrib.auth.signals import user_logged_in, user_logged_out, user_login_failed +from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError from django.core.paginator import Paginator from django.db.models import Case, Count, IntegerField, Q, Sum, Value, When @@ -2333,6 +2335,15 @@ def delete_chunk(self, objects, **kwargs): logger.debug("ASYNC_DELETE: object has already been deleted elsewhere. Skipping") # The id must be None # The object has already been deleted elsewhere + except LogEntry.MultipleObjectsReturned: + # Delete the log entrys first, then delete + LogEntry.objects.filter( + content_type=ContentType.objects.get_for_model(obj.__class__), + object_pk=str(obj.pk), + action=LogEntry.Action.DELETE, + ).delete() + # Now delete the object again + obj.delete() @dojo_async_task @app.task diff --git a/helm/defectdojo/Chart.yaml b/helm/defectdojo/Chart.yaml index ee07e3b07fa..09e6c7e9359 100644 --- a/helm/defectdojo/Chart.yaml +++ b/helm/defectdojo/Chart.yaml @@ -1,8 +1,8 @@ apiVersion: v2 -appVersion: "2.47.3" +appVersion: "2.47.4" description: A Helm chart for Kubernetes to install DefectDojo name: defectdojo -version: 1.6.193 +version: 1.6.194 icon: https://www.defectdojo.org/img/favicon.ico maintainers: - name: madchap diff --git a/tests/local-integration-tests.bat b/tests/local-integration-tests.bat deleted file mode 100644 index 17ce68eaafa..00000000000 --- a/tests/local-integration-tests.bat +++ /dev/null @@ -1,76 +0,0 @@ -set DD_ADMIN_USER=admin -set DD_ADMIN_PASSWORD=admin -set DD_BASE_URL=http://localhost:8080/ - -echo "Running Product type integration tests" -python tests/product_type_test.py -if %ERRORLEVEL% NEQ 0 GOTO END - -echo "Running Product integration tests" -python tests/product_test.py -if %ERRORLEVEL% NEQ 0 GOTO END - -echo "Running Endpoint integration tests" -python tests/endpoint_test.py -if %ERRORLEVEL% NEQ 0 GOTO END - -echo "Running Engagement integration tests" -python tests/engagement_test.py -if %ERRORLEVEL% NEQ 0 GOTO END - -echo "Running Environment integration tests" -python tests/environment_test.py -if %ERRORLEVEL% NEQ 0 GOTO END - -echo "Running Finding integration tests" -python tests/finding_test.py -if %ERRORLEVEL% NEQ 0 GOTO END - -echo "Running Test integration tests" -python tests/test_test.py -if %ERRORLEVEL% NEQ 0 GOTO END - -echo "Running User integration tests" -python tests/user_test.py -if %ERRORLEVEL% NEQ 0 GOTO END - -echo "Running Ibm Appscan integration test" -python tests/ibm_appscan_test.py -if %ERRORLEVEL% NEQ 0 GOTO END - -echo "Running Search integration test" -python tests/search_test.py -if %ERRORLEVEL% NEQ 0 GOTO END - -echo "Running Dedupe integration tests" -python tests/dedupe_test.py -if %ERRORLEVEL% NEQ 0 GOTO END - -echo "Running Report Builder integration tests" -python tests/report_builder_test.py -if %ERRORLEVEL% NEQ 0 GOTO END - -echo "Running Check Various Pages integration test" -python tests/check_various_pages.py -if %ERRORLEVEL% NEQ 0 GOTO END - -REM REM The below tests are commented out because they are still an unstable work in progress -REM REM Once Ready they can be uncommented. - -REM REM echo "Running Import Scanner integration test" -rem rem python tests/import_scanner_test.py -REM REM echo "Success: Import Scanner integration tests passed" -REM REM else -REM REM echo "Error: Import Scanner integration test failed"; exit 1 -REM REM fi - -REM REM echo "Running Zap integration test" -REM REM python tests/zap.py -REM REM echo "Success: zap integration tests passed" -REM REM else -REM REM echo "Error: Zap integration test failed"; exit 1 -REM REM fi - -REM echo "Done Running all configured integration tests." - -:END diff --git a/tests/local-integration-tests.sh b/tests/local-integration-tests.sh deleted file mode 100755 index db814125321..00000000000 --- a/tests/local-integration-tests.sh +++ /dev/null @@ -1,148 +0,0 @@ -#!/bin/bash - -export DD_BASE_URL='http://localhost:8080/' - - -# All available Unittest Scripts are activated below -# If successful, A success message is printed and the script continues -# If any script is unsuccessful a failure message is printed and the test script -# Exits with status code of 1 - -echo "Running Product type integration tests" -if python3 tests/regulations_test.py ; then - echo "Success: Regulation integration tests passed" -else - docker compose logs uwsgi --tail=120 - echo "Error: Regulation integration test failed."; exit 1 -fi - -echo "Running Product type integration tests" -if python3 tests/product_type_test.py ; then - echo "Success: Product type integration tests passed" -else - docker compose logs uwsgi --tail=120 - echo "Error: Product type integration test failed."; exit 1 -fi - -echo "Running Product integration tests" -if python3 tests/product_test.py ; then - echo "Success: Product integration tests passed" -else - docker compose logs uwsgi --tail=120 - echo "Error: Product integration test failed"; exit 1 -fi - -echo "Running Dedupe integration tests" -if python3 tests/dedupe_test.py ; then - echo "Success: Dedupe integration tests passed" -else - docker compose logs uwsgi --tail=120 - echo "Error: Dedupe integration test failed"; exit 1 -fi - -echo "Running Endpoint integration tests" -if python3 tests/endpoint_test.py ; then - echo "Success: Endpoint integration tests passed" -else - docker compose logs uwsgi --tail=120 - echo "Error: Endpoint integration test failed"; exit 1 -fi - -echo "Running Engagement integration tests" -if python3 tests/engagement_test.py ; then - echo "Success: Engagement integration tests passed" -else - docker compose logs uwsgi --tail=120 - echo "Error: Engagement integration test failed"; exit 1 -fi - -echo "Running Environment integration tests" -if python3 tests/environment_test.py ; then - echo "Success: Environment integration tests passed" -else - docker compose logs uwsgi --tail=120 - echo "Error: Environment integration test failed"; exit 1 -fi - -echo "Running Finding integration tests" -if python3 tests/finding_test.py ; then - echo "Success: Finding integration tests passed" -else - docker compose logs uwsgi --tail=120 - echo "Error: Finding integration test failed"; exit 1 -fi - -echo "Running Test integration tests" -if python3 tests/test_test.py ; then - echo "Success: Test integration tests passed" -else - docker compose logs uwsgi --tail=120 - echo "Error: Test integration test failed"; exit 1 -fi - -echo "Running User integration tests" -if python3 tests/user_test.py ; then - echo "Success: User integration tests passed" -else - docker compose logs uwsgi --tail=120 - echo "Error: User integration test failed"; exit 1 -fi - -echo "Running Ibm Appscan integration test" -if python3 tests/ibm_appscan_test.py ; then - echo "Success: Ibm AppScan integration tests passed" -else - docker compose logs uwsgi --tail=120 - echo "Error: Ibm AppScan integration test failed"; exit 1 -fi - -echo "Running Report Builder integration tests" -if python3 tests/report_builder_test.py ; then - echo "Success: Report Builder integration tests passed" -else - docker compose logs uwsgi --tail=120 - echo "Error: Report Builder integration test failed."; exit 1 -fi - -echo "Running Search integration test" -if python3 tests/search_test.py ; then - echo "Success: Search integration tests passed" -else - docker compose logs uwsgi --tail=120 - echo "Error: Search integration test failed"; exit 1 -fi - -test="Check Various Pages integration test" -echo "Running: $test" -if python3 tests/check_various_pages.py ; then - success "$test" -else - fail "$test" -fi - -test="Test notifications" -echo "Running: $test" -if python3 tests/notifications_test.py ; then - success "$test" -else - fail "$test" -fi - -# The below tests are commented out because they are still an unstable work in progress -## Once Ready they can be uncommented. - -# echo "Running Import Scanner integration test" -# if python3 tests/import_scanner_test.py ; then -# echo "Success: Import Scanner integration tests passed" -# else -# echo "Error: Import Scanner integration test failed"; exit 1 -# fi - -# echo "Running Zap integration test" -# if python3 tests/zap.py ; then -# echo "Success: zap integration tests passed" -# else -# echo "Error: Zap integration test failed"; exit 1 -# fi - -exec echo "Done Running all configured integration tests." diff --git a/unittests/scans/trivy/all_statuses.json b/unittests/scans/trivy/all_statuses.json new file mode 100644 index 00000000000..84fe54c5e19 --- /dev/null +++ b/unittests/scans/trivy/all_statuses.json @@ -0,0 +1,603 @@ +{ + "SchemaVersion": 2, + "CreatedAt": "2024-01-15T08:58:29.82753744Z", + "ArtifactName": "", + "ArtifactType": "container_image", + "Metadata": { + "OS": { + "Family": "debian", + "Name": "10.13" + }, + "ImageID": "sha256:22ae3921bdaac434bb4cb92dbbc209e46b1f3f70e9fa0b5fbbb43ce7d452c72d", + "DiffIDs": [ + "sha256:b2dba74777543b60e1a5be6da44e67659f51b8df1e96922205a5dde6b92dda3c", + "sha256:f1186e5061f20658954f6bfdfaead0abc5ed2371d70f707da05206e868a226ab", + "sha256:fe0fb3ab4a0f7be72784fcab5ef9c8fda65ea9b1067e8f7cdf293c12bcd25c13", + "sha256:c45660adde371317a1eafb102ee1d33b059328ec73a01b5c2461c4d04a40ecec", + "sha256:e01a454893a9a11115c598e5dec158ded8bd41326046c993c81b76b6a963590b", + "sha256:cb81227abde588a006a8b7ceac6034a303813efadc2c711fabf7b224649d183f", + "sha256:f8a91dd5fc84e4e5a1f261cf306ba1de28894524326d86eec0d74e9c0d22baec", + "sha256:3c777d951de2c488f73618f92b2adee8bd5de6f77e36bab51d57583bc487b99b", + "sha256:0d5f5a015e5d65973cce1dbab5aa60ce0836dbf2b3c9eabcb6efc89db1db3221", + "sha256:baa0956fea600c916f370870566aca1edf9a5ffc7facf51cfb1286e774f6e0e2", + "sha256:2f08eba9a3eddbb1e9dc2b70a25a1a3860807dac0d42c1e40fd890bbafbfba29", + "sha256:bf7d7d997f27e713b44ac0e763a38c46f9698e71e2243b0ffa80405d62d8c5e0" + ], + "RepoTags": [ + "" + ], + "RepoDigests": [ + "" + ], + "ImageConfig": { + "architecture": "amd64", + "created": "2024-01-15T08:56:27.807609822Z", + "history": [ + { + "created": "2023-04-12T00:20:15Z", + "created_by": "/bin/sh -c #(nop) ADD file:40953ed6e6f96703b2e0c13288437c2aaf8b3df33dbc423686290cbe0e595a5e in / " + }, + { + "created": "2023-04-12T00:20:15Z", + "created_by": "/bin/sh -c #(nop) CMD [\"bash\"]", + "empty_layer": true + }, + { + "created": "2023-04-12T07:52:41Z", + "created_by": "/bin/sh -c set -eux; \tapt-get update; \tapt-get install -y --no-install-recommends \t\tca-certificates \t\tcurl \t\tnetbase \t\twget \t; \trm -rf /var/lib/apt/lists/*" + }, + { + "created": "2023-04-12T07:52:47Z", + "created_by": "/bin/sh -c set -ex; \tif ! command -v gpg \u003e /dev/null; then \t\tapt-get update; \t\tapt-get install -y --no-install-recommends \t\t\tgnupg \t\t\tdirmngr \t\t; \t\trm -rf /var/lib/apt/lists/*; \tfi" + }, + { + "created": "2023-04-12T07:53:05Z", + "created_by": "/bin/sh -c apt-get update \u0026\u0026 apt-get install -y --no-install-recommends \t\tgit \t\tmercurial \t\topenssh-client \t\tsubversion \t\t\t\tprocps \t\u0026\u0026 rm -rf /var/lib/apt/lists/*" + }, + { + "created": "2023-04-12T07:54:04Z", + "created_by": "/bin/sh -c set -ex; \tapt-get update; \tapt-get install -y --no-install-recommends \t\tautoconf \t\tautomake \t\tbzip2 \t\tdpkg-dev \t\tfile \t\tg++ \t\tgcc \t\timagemagick \t\tlibbz2-dev \t\tlibc6-dev \t\tlibcurl4-openssl-dev \t\tlibdb-dev \t\tlibevent-dev \t\tlibffi-dev \t\tlibgdbm-dev \t\tlibglib2.0-dev \t\tlibgmp-dev \t\tlibjpeg-dev \t\tlibkrb5-dev \t\tliblzma-dev \t\tlibmagickcore-dev \t\tlibmagickwand-dev \t\tlibmaxminddb-dev \t\tlibncurses5-dev \t\tlibncursesw5-dev \t\tlibpng-dev \t\tlibpq-dev \t\tlibreadline-dev \t\tlibsqlite3-dev \t\tlibssl-dev \t\tlibtool \t\tlibwebp-dev \t\tlibxml2-dev \t\tlibxslt-dev \t\tlibyaml-dev \t\tmake \t\tpatch \t\tunzip \t\txz-utils \t\tzlib1g-dev \t\t\t\t$( \t\t\tif apt-cache show 'default-libmysqlclient-dev' 2\u003e/dev/null | grep -q '^Version:'; then \t\t\t\techo 'default-libmysqlclient-dev'; \t\t\telse \t\t\t\techo 'libmysqlclient-dev'; \t\t\tfi \t\t) \t; \trm -rf /var/lib/apt/lists/*" + }, + { + "created": "2023-04-12T09:05:40Z", + "created_by": "/bin/sh -c groupadd --gid 1000 node \u0026\u0026 useradd --uid 1000 --gid node --shell /bin/bash --create-home node" + }, + { + "created": "2023-04-12T09:11:56Z", + "created_by": "/bin/sh -c #(nop) ENV NODE_VERSION=14.21.3", + "empty_layer": true + }, + { + "created": "2023-04-12T09:12:09Z", + "created_by": "/bin/sh -c ARCH= \u0026\u0026 dpkgArch=\"$(dpkg --print-architecture)\" \u0026\u0026 case \"${dpkgArch##*-}\" in amd64) ARCH='x64';; ppc64el) ARCH='ppc64le';; s390x) ARCH='s390x';; arm64) ARCH='arm64';; armhf) ARCH='armv7l';; i386) ARCH='x86';; *) echo \"unsupported architecture\"; exit 1 ;; esac \u0026\u0026 set -ex \u0026\u0026 for key in 4ED778F539E3634C779C87C6D7062848A1AB005C 141F07595B7B3FFE74309A937405533BE57C7D57 74F12602B6F1C4E913FAA37AD3A89613643B6201 61FC681DFB92A079F1685E77973F295594EC4689 8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600 C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 890C08DB8579162FEE0DF9DB8BEAB4DFCF555EF4 C82FA3AE1CBEDC6BE46B9360C43CEC45C17AB93C 108F52B48DB57BB0CC439B2997B01419BD92F80A ; do gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys \"$key\" || gpg --batch --keyserver keyserver.ubuntu.com --recv-keys \"$key\" ; done \u0026\u0026 curl -fsSLO --compressed \"https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-$ARCH.tar.xz\" \u0026\u0026 curl -fsSLO --compressed \"https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc\" \u0026\u0026 gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \u0026\u0026 grep \" node-v$NODE_VERSION-linux-$ARCH.tar.xz\\$\" SHASUMS256.txt | sha256sum -c - \u0026\u0026 tar -xJf \"node-v$NODE_VERSION-linux-$ARCH.tar.xz\" -C /usr/local --strip-components=1 --no-same-owner \u0026\u0026 rm \"node-v$NODE_VERSION-linux-$ARCH.tar.xz\" SHASUMS256.txt.asc SHASUMS256.txt \u0026\u0026 ln -s /usr/local/bin/node /usr/local/bin/nodejs \u0026\u0026 node --version \u0026\u0026 npm --version" + }, + { + "created": "2023-04-12T09:12:09Z", + "created_by": "/bin/sh -c #(nop) ENV YARN_VERSION=1.22.19", + "empty_layer": true + }, + { + "created": "2023-04-12T09:12:12Z", + "created_by": "/bin/sh -c set -ex \u0026\u0026 for key in 6A010C5166006599AA17F08146C2130DFD2497F5 ; do gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys \"$key\" || gpg --batch --keyserver keyserver.ubuntu.com --recv-keys \"$key\" ; done \u0026\u0026 curl -fsSLO --compressed \"https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz\" \u0026\u0026 curl -fsSLO --compressed \"https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz.asc\" \u0026\u0026 gpg --batch --verify yarn-v$YARN_VERSION.tar.gz.asc yarn-v$YARN_VERSION.tar.gz \u0026\u0026 mkdir -p /opt \u0026\u0026 tar -xzf yarn-v$YARN_VERSION.tar.gz -C /opt/ \u0026\u0026 ln -s /opt/yarn-v$YARN_VERSION/bin/yarn /usr/local/bin/yarn \u0026\u0026 ln -s /opt/yarn-v$YARN_VERSION/bin/yarnpkg /usr/local/bin/yarnpkg \u0026\u0026 rm yarn-v$YARN_VERSION.tar.gz.asc yarn-v$YARN_VERSION.tar.gz \u0026\u0026 yarn --version" + }, + { + "created": "2023-04-12T09:12:12Z", + "created_by": "/bin/sh -c #(nop) COPY file:4d192565a7220e135cab6c77fbc1c73211b69f3d9fb37e62857b2c6eb9363d51 in /usr/local/bin/ " + }, + { + "created": "2023-04-12T09:12:12Z", + "created_by": "/bin/sh -c #(nop) ENTRYPOINT [\"docker-entrypoint.sh\"]", + "empty_layer": true + }, + { + "created": "2023-04-12T09:12:12Z", + "created_by": "/bin/sh -c #(nop) CMD [\"node\"]", + "empty_layer": true + }, + { + "created": "2024-01-15T08:56:23Z", + "created_by": "WORKDIR /usr/src/app/", + "comment": "buildkit.dockerfile.v0" + }, + { + "created": "2024-01-15T08:56:23Z", + "created_by": "COPY src/ /usr/src/app/ # buildkit", + "comment": "buildkit.dockerfile.v0" + }, + { + "created": "2024-01-15T08:56:27Z", + "created_by": "RUN /bin/sh -c npm install # buildkit", + "comment": "buildkit.dockerfile.v0" + }, + { + "created": "2024-01-15T08:56:27Z", + "created_by": "EXPOSE map[3000/tcp:{}]", + "comment": "buildkit.dockerfile.v0", + "empty_layer": true + }, + { + "created": "2024-01-15T08:56:27Z", + "created_by": "CMD [\"node\" \"index.js\"]", + "comment": "buildkit.dockerfile.v0", + "empty_layer": true + } + ], + "os": "linux", + "rootfs": { + "type": "layers", + "diff_ids": [ + "sha256:b2dba74777543b60e1a5be6da44e67659f51b8df1e96922205a5dde6b92dda3c", + "sha256:f1186e5061f20658954f6bfdfaead0abc5ed2371d70f707da05206e868a226ab", + "sha256:fe0fb3ab4a0f7be72784fcab5ef9c8fda65ea9b1067e8f7cdf293c12bcd25c13", + "sha256:c45660adde371317a1eafb102ee1d33b059328ec73a01b5c2461c4d04a40ecec", + "sha256:e01a454893a9a11115c598e5dec158ded8bd41326046c993c81b76b6a963590b", + "sha256:cb81227abde588a006a8b7ceac6034a303813efadc2c711fabf7b224649d183f", + "sha256:f8a91dd5fc84e4e5a1f261cf306ba1de28894524326d86eec0d74e9c0d22baec", + "sha256:3c777d951de2c488f73618f92b2adee8bd5de6f77e36bab51d57583bc487b99b", + "sha256:0d5f5a015e5d65973cce1dbab5aa60ce0836dbf2b3c9eabcb6efc89db1db3221", + "sha256:baa0956fea600c916f370870566aca1edf9a5ffc7facf51cfb1286e774f6e0e2", + "sha256:2f08eba9a3eddbb1e9dc2b70a25a1a3860807dac0d42c1e40fd890bbafbfba29", + "sha256:bf7d7d997f27e713b44ac0e763a38c46f9698e71e2243b0ffa80405d62d8c5e0" + ] + }, + "config": { + "Cmd": [ + "node", + "index.js" + ], + "Entrypoint": [ + "docker-entrypoint.sh" + ], + "Env": [ + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", + "NODE_VERSION=14.21.3", + "YARN_VERSION=1.22.19" + ], + "WorkingDir": "/usr/src/app/", + "ArgsEscaped": true + } + } + }, + "Results": [ + { + "Target": "noppaknopsta/example-app:main-159 (debian 10.13)", + "Class": "os-pkgs", + "Type": "debian", + "Vulnerabilities": [ + { + "VulnerabilityID": "CVE-2011-3374", + "PkgID": "apt@1.8.2.3", + "PkgName": "apt", + "InstalledVersion": "1.8.2.3", + "Status": "unknown", + "Layer": { + "DiffID": "sha256:b2dba74777543b60e1a5be6da44e67659f51b8df1e96922205a5dde6b92dda3c" + }, + "SeveritySource": "debian", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2011-3374", + "DataSource": { + "ID": "debian", + "Name": "Debian Security Tracker", + "URL": "https://salsa.debian.org/security-tracker-team/security-tracker" + }, + "Title": "It was found that apt-key in apt, all versions, do not correctly valid ...", + "Description": "It was found that apt-key in apt, all versions, do not correctly validate gpg keys with the master keyring, leading to a potential man-in-the-middle attack.", + "Severity": "LOW", + "CweIDs": [ + "CWE-347" + ], + "VendorSeverity": { + "debian": 1, + "nvd": 1 + }, + "CVSS": { + "nvd": { + "V2Vector": "AV:N/AC:M/Au:N/C:N/I:P/A:N", + "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N", + "V2Score": 4.3, + "V3Score": 3.7 + } + }, + "References": [ + "https://access.redhat.com/security/cve/cve-2011-3374", + "https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=642480", + "https://people.canonical.com/~ubuntu-security/cve/2011/CVE-2011-3374.html", + "https://seclists.org/fulldisclosure/2011/Sep/221", + "https://security-tracker.debian.org/tracker/CVE-2011-3374", + "https://snyk.io/vuln/SNYK-LINUX-APT-116518", + "https://ubuntu.com/security/CVE-2011-3374" + ], + "PublishedDate": "2019-11-26T00:15:11.03Z", + "LastModifiedDate": "2021-02-09T16:08:18.683Z" + }, + { + "VulnerabilityID": "CVE-2019-18276", + "PkgID": "bash@5.0-4", + "PkgName": "bash", + "InstalledVersion": "5.0-4", + "Status": "not_affected", + "Layer": { + "DiffID": "sha256:b2dba74777543b60e1a5be6da44e67659f51b8df1e96922205a5dde6b92dda3c" + }, + "SeveritySource": "debian", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2019-18276", + "DataSource": { + "ID": "debian", + "Name": "Debian Security Tracker", + "URL": "https://salsa.debian.org/security-tracker-team/security-tracker" + }, + "Title": "bash: when effective UID is not equal to its real UID the saved UID is not dropped", + "Description": "An issue was discovered in disable_priv_mode in shell.c in GNU Bash through 5.0 patch 11. By default, if Bash is run with its effective UID not equal to its real UID, it will drop privileges by setting its effective UID to its real UID. However, it does so incorrectly. On Linux and other systems that support \"saved UID\" functionality, the saved UID is not dropped. An attacker with command execution in the shell can use \"enable -f\" for runtime loading of a new builtin, which can be a shared object that calls setuid() and therefore regains privileges. However, binaries running with an effective UID of 0 are unaffected.", + "Severity": "LOW", + "CweIDs": [ + "CWE-273" + ], + "VendorSeverity": { + "cbl-mariner": 3, + "debian": 1, + "nvd": 3, + "oracle-oval": 1, + "photon": 3, + "redhat": 1, + "ubuntu": 1 + }, + "CVSS": { + "nvd": { + "V2Vector": "AV:L/AC:L/Au:N/C:C/I:C/A:C", + "V3Vector": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H", + "V2Score": 7.2, + "V3Score": 7.8 + }, + "redhat": { + "V3Vector": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H", + "V3Score": 7.8 + } + }, + "References": [ + "http://packetstormsecurity.com/files/155498/Bash-5.0-Patch-11-Privilege-Escalation.html", + "https://access.redhat.com/security/cve/CVE-2019-18276", + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-18276", + "https://github.com/bminor/bash/commit/951bdaad7a18cc0dc1036bba86b18b90874d39ff", + "https://linux.oracle.com/cve/CVE-2019-18276.html", + "https://linux.oracle.com/errata/ELSA-2021-1679.html", + "https://lists.apache.org/thread.html/rf9fa47ab66495c78bb4120b0754dd9531ca2ff0430f6685ac9b07772%40%3Cdev.mina.apache.org%3E", + "https://nvd.nist.gov/vuln/detail/CVE-2019-18276", + "https://security.gentoo.org/glsa/202105-34", + "https://security.netapp.com/advisory/ntap-20200430-0003/", + "https://ubuntu.com/security/notices/USN-5380-1", + "https://www.cve.org/CVERecord?id=CVE-2019-18276", + "https://www.oracle.com/security-alerts/cpuapr2022.html", + "https://www.youtube.com/watch?v=-wGtxJ8opa8" + ], + "PublishedDate": "2019-11-28T01:15:10.603Z", + "LastModifiedDate": "2023-11-07T03:06:25.3Z" + }, + { + "VulnerabilityID": "TEMP-0841856-B18BAF", + "PkgID": "bash@5.0-4", + "PkgName": "bash", + "InstalledVersion": "5.0-4", + "Status": "affected", + "Layer": { + "DiffID": "sha256:b2dba74777543b60e1a5be6da44e67659f51b8df1e96922205a5dde6b92dda3c" + }, + "SeveritySource": "debian", + "PrimaryURL": "https://security-tracker.debian.org/tracker/TEMP-0841856-B18BAF", + "DataSource": { + "ID": "debian", + "Name": "Debian Security Tracker", + "URL": "https://salsa.debian.org/security-tracker-team/security-tracker" + }, + "Title": "[Privilege escalation possible to other user than root]", + "Severity": "LOW", + "VendorSeverity": { + "debian": 1 + } + }, + { + "VulnerabilityID": "CVE-2018-1000876", + "PkgID": "binutils@2.31.1-16", + "PkgName": "binutils", + "InstalledVersion": "2.31.1-16", + "Status": "fixed", + "Layer": { + "DiffID": "sha256:e01a454893a9a11115c598e5dec158ded8bd41326046c993c81b76b6a963590b" + }, + "SeveritySource": "debian", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2018-1000876", + "DataSource": { + "ID": "debian", + "Name": "Debian Security Tracker", + "URL": "https://salsa.debian.org/security-tracker-team/security-tracker" + }, + "Title": "integer overflow leads to heap-based buffer overflow in objdump", + "Description": "binutils version 2.32 and earlier contains a Integer Overflow vulnerability in objdump, bfd_get_dynamic_reloc_upper_bound,bfd_canonicalize_dynamic_reloc that can result in Integer overflow trigger heap overflow. Successful exploitation allows execution of arbitrary code.. This attack appear to be exploitable via Local. This vulnerability appears to have been fixed in after commit 3a551c7a1b80fca579461774860574eabfd7f18f.", + "Severity": "LOW", + "CweIDs": [ + "CWE-190", + "CWE-787" + ], + "VendorSeverity": { + "amazon": 2, + "debian": 1, + "nvd": 3, + "oracle-oval": 2, + "photon": 3, + "redhat": 2, + "ubuntu": 1 + }, + "CVSS": { + "nvd": { + "V2Vector": "AV:L/AC:L/Au:N/C:P/I:P/A:P", + "V3Vector": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H", + "V2Score": 4.6, + "V3Score": 7.8 + }, + "redhat": { + "V3Vector": "CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H", + "V3Score": 7.8 + } + }, + "References": [ + "http://lists.opensuse.org/opensuse-security-announce/2019-10/msg00072.html", + "http://lists.opensuse.org/opensuse-security-announce/2019-11/msg00008.html", + "http://www.securityfocus.com/bid/106304", + "https://access.redhat.com/errata/RHSA-2019:2075", + "https://access.redhat.com/security/cve/CVE-2018-1000876", + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-1000876", + "https://linux.oracle.com/cve/CVE-2018-1000876.html", + "https://linux.oracle.com/errata/ELSA-2019-2075.html", + "https://nvd.nist.gov/vuln/detail/CVE-2018-1000876", + "https://sourceware.org/bugzilla/show_bug.cgi?id=23994", + "https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git%3Bh=3a551c7a1b80fca579461774860574eabfd7f18f", + "https://ubuntu.com/security/notices/USN-4336-1", + "https://ubuntu.com/security/notices/USN-4336-2", + "https://usn.ubuntu.com/4336-1/", + "https://www.cve.org/CVERecord?id=CVE-2018-1000876" + ], + "PublishedDate": "2018-12-20T17:29:01.033Z", + "LastModifiedDate": "2023-11-07T02:51:14.47Z" + }, + { + "VulnerabilityID": "CVE-2018-12697", + "PkgID": "binutils@2.31.1-16", + "PkgName": "binutils", + "InstalledVersion": "2.31.1-16", + "Status": "under_investigation", + "Layer": { + "DiffID": "sha256:e01a454893a9a11115c598e5dec158ded8bd41326046c993c81b76b6a963590b" + }, + "SeveritySource": "debian", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2018-12697", + "DataSource": { + "ID": "debian", + "Name": "Debian Security Tracker", + "URL": "https://salsa.debian.org/security-tracker-team/security-tracker" + }, + "Title": "binutils: NULL pointer dereference in work_stuff_copy_to_from in cplus-dem.c.", + "Description": "A NULL pointer dereference (aka SEGV on unknown address 0x000000000000) was discovered in work_stuff_copy_to_from in cplus-dem.c in GNU libiberty, as distributed in GNU Binutils 2.30. This can occur during execution of objdump.", + "Severity": "LOW", + "CweIDs": [ + "CWE-476" + ], + "VendorSeverity": { + "amazon": 2, + "debian": 1, + "nvd": 3, + "oracle-oval": 2, + "photon": 3, + "redhat": 1, + "ubuntu": 1 + }, + "CVSS": { + "nvd": { + "V2Vector": "AV:N/AC:L/Au:N/C:N/I:N/A:P", + "V3Vector": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V2Score": 5, + "V3Score": 7.5 + }, + "redhat": { + "V3Vector": "CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L", + "V3Score": 3.3 + } + }, + "References": [ + "http://www.securityfocus.com/bid/104538", + "https://access.redhat.com/errata/RHSA-2019:2075", + "https://access.redhat.com/security/cve/CVE-2018-12697", + "https://bugs.launchpad.net/ubuntu/+source/binutils/+bug/1763102", + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-12697", + "https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85454", + "https://linux.oracle.com/cve/CVE-2018-12697.html", + "https://linux.oracle.com/errata/ELSA-2019-2075.html", + "https://nvd.nist.gov/vuln/detail/CVE-2018-12697", + "https://security.gentoo.org/glsa/201908-01", + "https://sourceware.org/bugzilla/show_bug.cgi?id=23057", + "https://ubuntu.com/security/notices/USN-4326-1", + "https://ubuntu.com/security/notices/USN-4336-1", + "https://ubuntu.com/security/notices/USN-4336-2", + "https://usn.ubuntu.com/4326-1/", + "https://usn.ubuntu.com/4336-1/", + "https://www.cve.org/CVERecord?id=CVE-2018-12697" + ], + "PublishedDate": "2018-06-23T23:29:00.22Z", + "LastModifiedDate": "2019-08-03T13:15:17.257Z" + }, + { + "VulnerabilityID": "CVE-2018-12698", + "PkgID": "binutils@2.31.1-16", + "PkgName": "binutils", + "InstalledVersion": "2.31.1-16", + "Status": "will_not_fix", + "Layer": { + "DiffID": "sha256:e01a454893a9a11115c598e5dec158ded8bd41326046c993c81b76b6a963590b" + }, + "SeveritySource": "debian", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2018-12698", + "DataSource": { + "ID": "debian", + "Name": "Debian Security Tracker", + "URL": "https://salsa.debian.org/security-tracker-team/security-tracker" + }, + "Title": "binutils: excessive memory consumption in demangle_template in cplus-dem.c", + "Description": "demangle_template in cplus-dem.c in GNU libiberty, as distributed in GNU Binutils 2.30, allows attackers to trigger excessive memory consumption (aka OOM) during the \"Create an array for saving the template argument values\" XNEWVEC call. This can occur during execution of objdump.", + "Severity": "LOW", + "VendorSeverity": { + "debian": 1, + "nvd": 3, + "photon": 3, + "redhat": 1, + "ubuntu": 1 + }, + "CVSS": { + "nvd": { + "V2Vector": "AV:N/AC:L/Au:N/C:N/I:N/A:P", + "V3Vector": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V2Score": 5, + "V3Score": 7.5 + }, + "redhat": { + "V3Vector": "CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L", + "V3Score": 3.3 + } + }, + "References": [ + "http://www.securityfocus.com/bid/104539", + "https://access.redhat.com/security/cve/CVE-2018-12698", + "https://bugs.launchpad.net/ubuntu/+source/binutils/+bug/1763102", + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-12698", + "https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85454", + "https://nvd.nist.gov/vuln/detail/CVE-2018-12698", + "https://security.gentoo.org/glsa/201908-01", + "https://sourceware.org/bugzilla/show_bug.cgi?id=23057", + "https://ubuntu.com/security/notices/USN-4326-1", + "https://ubuntu.com/security/notices/USN-4336-1", + "https://ubuntu.com/security/notices/USN-4336-2", + "https://usn.ubuntu.com/4326-1/", + "https://usn.ubuntu.com/4336-1/", + "https://www.cve.org/CVERecord?id=CVE-2018-12698" + ], + "PublishedDate": "2018-06-23T23:29:00.283Z", + "LastModifiedDate": "2019-10-03T00:03:26.223Z" + }, + { + "VulnerabilityID": "CVE-2018-12699", + "PkgID": "binutils@2.31.1-16", + "PkgName": "binutils", + "InstalledVersion": "2.31.1-16", + "Status": "fix_deferred", + "Layer": { + "DiffID": "sha256:e01a454893a9a11115c598e5dec158ded8bd41326046c993c81b76b6a963590b" + }, + "SeveritySource": "debian", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2018-12699", + "DataSource": { + "ID": "debian", + "Name": "Debian Security Tracker", + "URL": "https://salsa.debian.org/security-tracker-team/security-tracker" + }, + "Title": "binutils: heap-based buffer overflow in finish_stab in stabs.c", + "Description": "finish_stab in stabs.c in GNU Binutils 2.30 allows attackers to cause a denial of service (heap-based buffer overflow) or possibly have unspecified other impact, as demonstrated by an out-of-bounds write of 8 bytes. This can occur during execution of objdump.", + "Severity": "LOW", + "CweIDs": [ + "CWE-787" + ], + "VendorSeverity": { + "debian": 1, + "nvd": 4, + "photon": 4, + "redhat": 1, + "ubuntu": 1 + }, + "CVSS": { + "nvd": { + "V2Vector": "AV:N/AC:L/Au:N/C:P/I:P/A:P", + "V3Vector": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", + "V2Score": 7.5, + "V3Score": 9.8 + }, + "redhat": { + "V3Vector": "CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L", + "V3Score": 3.3 + } + }, + "References": [ + "http://www.securityfocus.com/bid/104540", + "https://access.redhat.com/security/cve/CVE-2018-12699", + "https://bugs.launchpad.net/ubuntu/+source/binutils/+bug/1763102", + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-12699", + "https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85454", + "https://nvd.nist.gov/vuln/detail/CVE-2018-12699", + "https://security.gentoo.org/glsa/201908-01", + "https://sourceware.org/bugzilla/show_bug.cgi?id=23057", + "https://ubuntu.com/security/notices/USN-4336-1", + "https://ubuntu.com/security/notices/USN-4336-2", + "https://usn.ubuntu.com/4336-1/", + "https://www.cve.org/CVERecord?id=CVE-2018-12699" + ], + "PublishedDate": "2018-06-23T23:29:00.33Z", + "LastModifiedDate": "2019-08-03T13:15:17.587Z" + }, + { + "VulnerabilityID": "CVE-2018-12934", + "PkgID": "binutils@2.31.1-16", + "PkgName": "binutils", + "InstalledVersion": "2.31.1-16", + "Status": "end_of_life", + "Layer": { + "DiffID": "sha256:e01a454893a9a11115c598e5dec158ded8bd41326046c993c81b76b6a963590b" + }, + "SeveritySource": "debian", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2018-12934", + "DataSource": { + "ID": "debian", + "Name": "Debian Security Tracker", + "URL": "https://salsa.debian.org/security-tracker-team/security-tracker" + }, + "Title": "binutils: Uncontrolled Resource Consumption in remember_Ktype in cplus-dem.c", + "Description": "remember_Ktype in cplus-dem.c in GNU libiberty, as distributed in GNU Binutils 2.30, allows attackers to trigger excessive memory consumption (aka OOM). This can occur during execution of cxxfilt.", + "Severity": "LOW", + "CweIDs": [ + "CWE-770" + ], + "VendorSeverity": { + "debian": 1, + "nvd": 3, + "photon": 3, + "redhat": 1, + "ubuntu": 1 + }, + "CVSS": { + "nvd": { + "V2Vector": "AV:N/AC:L/Au:N/C:N/I:N/A:P", + "V3Vector": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", + "V2Score": 5, + "V3Score": 7.5 + }, + "redhat": { + "V3Vector": "CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H", + "V3Score": 5.5 + } + }, + "References": [ + "https://access.redhat.com/security/cve/CVE-2018-12934", + "https://bugs.launchpad.net/ubuntu/+source/binutils/+bug/1763101", + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-12934", + "https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85453", + "https://nvd.nist.gov/vuln/detail/CVE-2018-12934", + "https://sourceware.org/bugzilla/show_bug.cgi?id=23059", + "https://ubuntu.com/security/notices/USN-4326-1", + "https://ubuntu.com/security/notices/USN-4336-1", + "https://ubuntu.com/security/notices/USN-4336-2", + "https://usn.ubuntu.com/4326-1/", + "https://usn.ubuntu.com/4336-1/", + "https://www.cve.org/CVERecord?id=CVE-2018-12934" + ], + "PublishedDate": "2018-06-28T14:29:00.683Z", + "LastModifiedDate": "2020-04-21T22:15:13.15Z" + } + ] + } + ] + } + \ No newline at end of file diff --git a/unittests/scans/twistlock/one_vuln_no_link.json b/unittests/scans/twistlock/one_vuln_no_link_no_description.json similarity index 79% rename from unittests/scans/twistlock/one_vuln_no_link.json rename to unittests/scans/twistlock/one_vuln_no_link_no_description.json index e57799eb7e3..872448aee97 100644 --- a/unittests/scans/twistlock/one_vuln_no_link.json +++ b/unittests/scans/twistlock/one_vuln_no_link_no_description.json @@ -21,7 +21,6 @@ { "id": "PRISMA-2021-0013", "status": "fixed in 1.1.1", - "description": "marked package prior to 1.1.1 are vulnerable to Regular Expression Denial of Service (ReDoS). The regex within src/rules.js file have multiple unused capture groups which could lead to a denial of service attack if user input is reachable. Origin: https://github.com/markedjs/marked/commit/bd4f8c464befad2b304d51e33e89e567326e62e0", "severity": "medium", "packageName": "marked", "packageVersion": "0.3.9", diff --git a/unittests/test_metrics_queries.py b/unittests/test_metrics_queries.py index 68dd1f43fee..773a1f7d4cf 100644 --- a/unittests/test_metrics_queries.py +++ b/unittests/test_metrics_queries.py @@ -8,7 +8,7 @@ from django.urls import reverse from dojo.metrics import utils -from dojo.models import User +from dojo.models import Product_Type, User from .dojo_test_case import DojoTestCase @@ -21,23 +21,23 @@ def add(*args, **kwargs): #### # Test Findings data #### -FINDING_1 = {"id": 4, "title": "High Impact Test Finding", "date": date(2018, 1, 1), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "High", "description": "test finding", "mitigation": "test mitigation", "impact": "High", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 3, "active": False, "verified": False, "false_p": False, "duplicate": True, "duplicate_finding_id": 2, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "5d368a051fdec959e08315a32ef633ba5711bed6e8e75319ddee2cab4d4608c7", "line": None, "file_path": "", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": None, "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False} -FINDING_2 = {"id": 5, "title": "High Impact Test Finding", "date": date(2018, 1, 1), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "High", "description": "test finding", "mitigation": "test mitigation", "impact": "High", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 3, "active": False, "verified": False, "false_p": False, "duplicate": True, "duplicate_finding_id": 2, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "5d368a051fdec959e08315a32ef633ba5711bed6e8e75319ddee2cab4d4608c7", "line": None, "file_path": "", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": None, "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False} -FINDING_3 = {"id": 6, "title": "High Impact Test Finding", "date": date(2018, 1, 1), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "High", "description": "test finding", "mitigation": "test mitigation", "impact": "High", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 3, "active": False, "verified": False, "false_p": False, "duplicate": True, "duplicate_finding_id": 2, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "5d368a051fdec959e08315a32ef633ba5711bed6e8e75319ddee2cab4d4608c7", "line": None, "file_path": "", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": None, "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False} -FINDING_4 = {"id": 7, "title": "DUMMY FINDING", "date": date(2017, 12, 31), "sla_start_date": None, "sla_expiration_date": None, "cwe": 1, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": "http://www.example.com", "severity": "High", "description": "TEST finding", "mitigation": "MITIGATION", "impact": "High", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 3, "active": False, "verified": False, "false_p": False, "duplicate": False, "duplicate_finding_id": None, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 2, "under_defect_review": False, "defect_review_requested_by_id": 2, "is_mitigated": False, "thread_id": 1, "mitigated": None, "mitigated_by_id": None, "reporter_id": 2, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "c89d25e445b088ba339908f68e15e3177b78d22f3039d1bfea51c4be251bf4e0", "line": 100, "file_path": "", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": None, "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False} -FINDING_5 = {"id": 24, "title": "Low Impact Test Finding", "date": date(2018, 1, 1), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "Low", "description": "test finding", "mitigation": "test mitigation", "impact": "Low", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 33, "active": False, "verified": False, "false_p": False, "duplicate": True, "duplicate_finding_id": 22, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "9aca00affd340c4da02c934e7e3106a45c6ad0911da479daae421b3b28a2c1aa", "line": 123, "file_path": "/dev/urandom", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": None, "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False} -FINDING_6 = {"id": 125, "title": "Low Impact Test Finding", "date": date(2018, 1, 1), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "Low", "description": "test finding", "mitigation": "test mitigation", "impact": "Low", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 55, "active": False, "verified": False, "false_p": False, "duplicate": True, "duplicate_finding_id": None, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "9aca00affd340c4da02c934e7e3106a45c6ad0911da479daae421b3b28a2c1aa", "line": 123, "file_path": "/dev/urandom", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": "12345", "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False} -FINDING_7 = {"id": 225, "title": "UID Impact Test Finding", "date": date(2018, 1, 1), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "Low", "description": "test finding", "mitigation": "test mitigation", "impact": "Low", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 77, "active": False, "verified": False, "false_p": False, "duplicate": True, "duplicate_finding_id": 224, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "6f8d0bf970c14175e597843f4679769a4775742549d90f902ff803de9244c7e1", "line": 123, "file_path": "/dev/urandom", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": "6789", "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False} -FINDING_8 = {"id": 240, "title": "High Impact Test Finding", "date": date(2018, 1, 1), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "High", "description": "test finding", "mitigation": "test mitigation", "impact": "High", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 3, "active": True, "verified": False, "false_p": False, "duplicate": True, "duplicate_finding_id": 2, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "5d368a051fdec959e08315a32ef633ba5711bed6e8e75319ddee2cab4d4608c7", "line": None, "file_path": "", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": None, "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False} -FINDING_9 = {"id": 241, "title": "High Impact Test Finding", "date": date(2018, 1, 1), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "High", "description": "test finding", "mitigation": "test mitigation", "impact": "High", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 3, "active": False, "verified": False, "false_p": False, "duplicate": True, "duplicate_finding_id": 2, "out_of_scope": False, "risk_accepted": True, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "5d368a051fdec959e08315a32ef633ba5711bed6e8e75319ddee2cab4d4608c7", "line": None, "file_path": "", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": None, "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False} -FINDING_10 = {"id": 242, "title": "High Impact Test Finding", "date": date(2018, 1, 1), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "High", "description": "test finding", "mitigation": "test mitigation", "impact": "High", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 3, "active": False, "verified": False, "false_p": False, "duplicate": True, "duplicate_finding_id": 2, "out_of_scope": False, "risk_accepted": True, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "5d368a051fdec959e08315a32ef633ba5711bed6e8e75319ddee2cab4d4608c7", "line": None, "file_path": "", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": None, "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False} -FINDING_11 = {"id": 243, "title": "DUMMY FINDING", "date": date(2017, 12, 31), "sla_start_date": None, "sla_expiration_date": None, "cwe": 1, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": "http://www.example.com", "severity": "High", "description": "TEST finding", "mitigation": "MITIGATION", "impact": "High", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 3, "active": False, "verified": False, "false_p": False, "duplicate": False, "duplicate_finding_id": None, "out_of_scope": False, "risk_accepted": True, "under_review": False, "last_status_update": None, "review_requested_by_id": 2, "under_defect_review": False, "defect_review_requested_by_id": 2, "is_mitigated": True, "thread_id": 1, "mitigated": None, "mitigated_by_id": None, "reporter_id": 2, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "c89d25e445b088ba339908f68e15e3177b78d22f3039d1bfea51c4be251bf4e0", "line": 100, "file_path": "", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": None, "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False} -FINDING_12 = {"id": 244, "title": "Low Impact Test Finding", "date": date(2017, 12, 29), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "Low", "description": "test finding", "mitigation": "test mitigation", "impact": "Low", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 33, "active": True, "verified": True, "false_p": False, "duplicate": False, "duplicate_finding_id": None, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "9aca00affd340c4da02c934e7e3106a45c6ad0911da479daae421b3b28a2c1aa", "line": 123, "file_path": "/dev/urandom", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": None, "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False} -FINDING_13 = {"id": 245, "title": "Low Impact Test Finding", "date": date(2017, 12, 27), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "Low", "description": "test finding", "mitigation": "test mitigation", "impact": "Low", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 33, "active": False, "verified": False, "false_p": False, "duplicate": True, "duplicate_finding_id": 22, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "9aca00affd340c4da02c934e7e3106a45c6ad0911da479daae421b3b28a2c1aa", "line": 123, "file_path": "/dev/urandom", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": None, "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False} -FINDING_14 = {"id": 246, "title": "Low Impact Test Finding", "date": date(2018, 1, 2), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "Low", "description": "test finding", "mitigation": "test mitigation", "impact": "Low", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 33, "active": False, "verified": False, "false_p": False, "duplicate": True, "duplicate_finding_id": 22, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "9aca00affd340c4da02c934e7e3106a45c6ad0911da479daae421b3b28a2c1aa", "line": 123, "file_path": "/dev/urandom", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": None, "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False} -FINDING_15 = {"id": 247, "title": "Low Impact Test Finding", "date": date(2018, 1, 3), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "Low", "description": "test finding", "mitigation": "test mitigation", "impact": "Low", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 55, "active": False, "verified": False, "false_p": False, "duplicate": True, "duplicate_finding_id": None, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "9aca00affd340c4da02c934e7e3106a45c6ad0911da479daae421b3b28a2c1aa", "line": 123, "file_path": "/dev/urandom", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": "12345", "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False} -FINDING_16 = {"id": 248, "title": "UID Impact Test Finding", "date": date(2017, 12, 27), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "Low", "description": "test finding", "mitigation": "test mitigation", "impact": "Low", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 77, "active": True, "verified": True, "false_p": False, "duplicate": False, "duplicate_finding_id": None, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": True, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "6f8d0bf970c14175e597843f4679769a4775742549d90f902ff803de9244c7e1", "line": 123, "file_path": "/dev/urandom", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": "6789", "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False} -FINDING_17 = {"id": 249, "title": "UID Impact Test Finding", "date": date(2018, 1, 4), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "Low", "description": "test finding", "mitigation": "test mitigation", "impact": "Low", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 77, "active": False, "verified": False, "false_p": False, "duplicate": True, "duplicate_finding_id": 224, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "6f8d0bf970c14175e597843f4679769a4775742549d90f902ff803de9244c7e1", "line": 123, "file_path": "/dev/urandom", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": "6789", "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False} +FINDING_1 = {"id": 4, "title": "High Impact Test Finding", "date": date(2018, 1, 1), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "High", "description": "test finding", "mitigation": "test mitigation", "impact": "High", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 3, "active": False, "verified": False, "false_p": False, "duplicate": True, "duplicate_finding_id": 2, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "5d368a051fdec959e08315a32ef633ba5711bed6e8e75319ddee2cab4d4608c7", "line": None, "file_path": "", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": None, "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False, "known_exploited": False, "ransomware_used": False, "kev_date": None} +FINDING_2 = {"id": 5, "title": "High Impact Test Finding", "date": date(2018, 1, 1), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "High", "description": "test finding", "mitigation": "test mitigation", "impact": "High", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 3, "active": False, "verified": False, "false_p": False, "duplicate": True, "duplicate_finding_id": 2, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "5d368a051fdec959e08315a32ef633ba5711bed6e8e75319ddee2cab4d4608c7", "line": None, "file_path": "", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": None, "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False, "known_exploited": False, "ransomware_used": False, "kev_date": None} +FINDING_3 = {"id": 6, "title": "High Impact Test Finding", "date": date(2018, 1, 1), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "High", "description": "test finding", "mitigation": "test mitigation", "impact": "High", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 3, "active": False, "verified": False, "false_p": False, "duplicate": True, "duplicate_finding_id": 2, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "5d368a051fdec959e08315a32ef633ba5711bed6e8e75319ddee2cab4d4608c7", "line": None, "file_path": "", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": None, "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False, "known_exploited": False, "ransomware_used": False, "kev_date": None} +FINDING_4 = {"id": 7, "title": "DUMMY FINDING", "date": date(2017, 12, 31), "sla_start_date": None, "sla_expiration_date": None, "cwe": 1, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": "http://www.example.com", "severity": "High", "description": "TEST finding", "mitigation": "MITIGATION", "impact": "High", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 3, "active": False, "verified": False, "false_p": False, "duplicate": False, "duplicate_finding_id": None, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 2, "under_defect_review": False, "defect_review_requested_by_id": 2, "is_mitigated": False, "thread_id": 1, "mitigated": None, "mitigated_by_id": None, "reporter_id": 2, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "c89d25e445b088ba339908f68e15e3177b78d22f3039d1bfea51c4be251bf4e0", "line": 100, "file_path": "", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": None, "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False, "known_exploited": False, "ransomware_used": False, "kev_date": None} +FINDING_5 = {"id": 24, "title": "Low Impact Test Finding", "date": date(2018, 1, 1), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "Low", "description": "test finding", "mitigation": "test mitigation", "impact": "Low", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 33, "active": False, "verified": False, "false_p": False, "duplicate": True, "duplicate_finding_id": 22, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "9aca00affd340c4da02c934e7e3106a45c6ad0911da479daae421b3b28a2c1aa", "line": 123, "file_path": "/dev/urandom", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": None, "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False, "known_exploited": False, "ransomware_used": False, "kev_date": None} +FINDING_6 = {"id": 125, "title": "Low Impact Test Finding", "date": date(2018, 1, 1), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "Low", "description": "test finding", "mitigation": "test mitigation", "impact": "Low", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 55, "active": False, "verified": False, "false_p": False, "duplicate": True, "duplicate_finding_id": None, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "9aca00affd340c4da02c934e7e3106a45c6ad0911da479daae421b3b28a2c1aa", "line": 123, "file_path": "/dev/urandom", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": "12345", "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False, "known_exploited": False, "ransomware_used": False, "kev_date": None} +FINDING_7 = {"id": 225, "title": "UID Impact Test Finding", "date": date(2018, 1, 1), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "Low", "description": "test finding", "mitigation": "test mitigation", "impact": "Low", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 77, "active": False, "verified": False, "false_p": False, "duplicate": True, "duplicate_finding_id": 224, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "6f8d0bf970c14175e597843f4679769a4775742549d90f902ff803de9244c7e1", "line": 123, "file_path": "/dev/urandom", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": "6789", "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False, "known_exploited": False, "ransomware_used": False, "kev_date": None} +FINDING_8 = {"id": 240, "title": "High Impact Test Finding", "date": date(2018, 1, 1), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "High", "description": "test finding", "mitigation": "test mitigation", "impact": "High", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 3, "active": True, "verified": False, "false_p": False, "duplicate": True, "duplicate_finding_id": 2, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "5d368a051fdec959e08315a32ef633ba5711bed6e8e75319ddee2cab4d4608c7", "line": None, "file_path": "", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": None, "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False, "known_exploited": False, "ransomware_used": False, "kev_date": None} +FINDING_9 = {"id": 241, "title": "High Impact Test Finding", "date": date(2018, 1, 1), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "High", "description": "test finding", "mitigation": "test mitigation", "impact": "High", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 3, "active": False, "verified": False, "false_p": False, "duplicate": True, "duplicate_finding_id": 2, "out_of_scope": False, "risk_accepted": True, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "5d368a051fdec959e08315a32ef633ba5711bed6e8e75319ddee2cab4d4608c7", "line": None, "file_path": "", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": None, "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False, "known_exploited": False, "ransomware_used": False, "kev_date": None} +FINDING_10 = {"id": 242, "title": "High Impact Test Finding", "date": date(2018, 1, 1), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "High", "description": "test finding", "mitigation": "test mitigation", "impact": "High", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 3, "active": False, "verified": False, "false_p": False, "duplicate": True, "duplicate_finding_id": 2, "out_of_scope": False, "risk_accepted": True, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "5d368a051fdec959e08315a32ef633ba5711bed6e8e75319ddee2cab4d4608c7", "line": None, "file_path": "", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": None, "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False, "known_exploited": False, "ransomware_used": False, "kev_date": None} +FINDING_11 = {"id": 243, "title": "DUMMY FINDING", "date": date(2017, 12, 31), "sla_start_date": None, "sla_expiration_date": None, "cwe": 1, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": "http://www.example.com", "severity": "High", "description": "TEST finding", "mitigation": "MITIGATION", "impact": "High", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 3, "active": False, "verified": False, "false_p": False, "duplicate": False, "duplicate_finding_id": None, "out_of_scope": False, "risk_accepted": True, "under_review": False, "last_status_update": None, "review_requested_by_id": 2, "under_defect_review": False, "defect_review_requested_by_id": 2, "is_mitigated": True, "thread_id": 1, "mitigated": None, "mitigated_by_id": None, "reporter_id": 2, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "c89d25e445b088ba339908f68e15e3177b78d22f3039d1bfea51c4be251bf4e0", "line": 100, "file_path": "", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": None, "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False, "known_exploited": False, "ransomware_used": False, "kev_date": None} +FINDING_12 = {"id": 244, "title": "Low Impact Test Finding", "date": date(2017, 12, 29), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "Low", "description": "test finding", "mitigation": "test mitigation", "impact": "Low", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 33, "active": True, "verified": True, "false_p": False, "duplicate": False, "duplicate_finding_id": None, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "9aca00affd340c4da02c934e7e3106a45c6ad0911da479daae421b3b28a2c1aa", "line": 123, "file_path": "/dev/urandom", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": None, "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False, "known_exploited": False, "ransomware_used": False, "kev_date": None} +FINDING_13 = {"id": 245, "title": "Low Impact Test Finding", "date": date(2017, 12, 27), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "Low", "description": "test finding", "mitigation": "test mitigation", "impact": "Low", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 33, "active": False, "verified": False, "false_p": False, "duplicate": True, "duplicate_finding_id": 22, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "9aca00affd340c4da02c934e7e3106a45c6ad0911da479daae421b3b28a2c1aa", "line": 123, "file_path": "/dev/urandom", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": None, "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False, "known_exploited": False, "ransomware_used": False, "kev_date": None} +FINDING_14 = {"id": 246, "title": "Low Impact Test Finding", "date": date(2018, 1, 2), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "Low", "description": "test finding", "mitigation": "test mitigation", "impact": "Low", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 33, "active": False, "verified": False, "false_p": False, "duplicate": True, "duplicate_finding_id": 22, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "9aca00affd340c4da02c934e7e3106a45c6ad0911da479daae421b3b28a2c1aa", "line": 123, "file_path": "/dev/urandom", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": None, "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False, "known_exploited": False, "ransomware_used": False, "kev_date": None} +FINDING_15 = {"id": 247, "title": "Low Impact Test Finding", "date": date(2018, 1, 3), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "Low", "description": "test finding", "mitigation": "test mitigation", "impact": "Low", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 55, "active": False, "verified": False, "false_p": False, "duplicate": True, "duplicate_finding_id": None, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "9aca00affd340c4da02c934e7e3106a45c6ad0911da479daae421b3b28a2c1aa", "line": 123, "file_path": "/dev/urandom", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": "12345", "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False, "known_exploited": False, "ransomware_used": False, "kev_date": None} +FINDING_16 = {"id": 248, "title": "UID Impact Test Finding", "date": date(2017, 12, 27), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "Low", "description": "test finding", "mitigation": "test mitigation", "impact": "Low", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 77, "active": True, "verified": True, "false_p": False, "duplicate": False, "duplicate_finding_id": None, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": True, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "6f8d0bf970c14175e597843f4679769a4775742549d90f902ff803de9244c7e1", "line": 123, "file_path": "/dev/urandom", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": "6789", "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False, "known_exploited": False, "ransomware_used": False, "kev_date": None} +FINDING_17 = {"id": 249, "title": "UID Impact Test Finding", "date": date(2018, 1, 4), "sla_start_date": None, "sla_expiration_date": None, "cwe": None, "cve": None, "epss_score": None, "epss_percentile": None, "cvssv3": None, "cvssv3_score": None, "url": None, "severity": "Low", "description": "test finding", "mitigation": "test mitigation", "impact": "Low", "steps_to_reproduce": None, "severity_justification": None, "references": "", "test_id": 77, "active": False, "verified": False, "false_p": False, "duplicate": True, "duplicate_finding_id": 224, "out_of_scope": False, "risk_accepted": False, "under_review": False, "last_status_update": None, "review_requested_by_id": 1, "under_defect_review": False, "defect_review_requested_by_id": 1, "is_mitigated": False, "thread_id": 11, "mitigated": None, "mitigated_by_id": None, "reporter_id": 1, "numerical_severity": "S0", "last_reviewed": None, "last_reviewed_by_id": None, "param": None, "payload": None, "hash_code": "6f8d0bf970c14175e597843f4679769a4775742549d90f902ff803de9244c7e1", "line": 123, "file_path": "/dev/urandom", "component_name": None, "component_version": None, "static_finding": False, "dynamic_finding": False, "created": datetime(2017, 12, 1, 0, 0, tzinfo=UTC), "scanner_confidence": None, "sonarqube_issue_id": None, "unique_id_from_tool": "6789", "vuln_id_from_tool": None, "sast_source_object": None, "sast_sink_object": None, "sast_source_line": None, "sast_source_file_path": None, "nb_occurences": None, "publish_date": None, "service": None, "planned_remediation_date": None, "planned_remediation_version": None, "effort_for_fixing": None, "test__engagement__product__prod_type__member": False, "test__engagement__product__member": True, "test__engagement__product__prod_type__authorized_group": False, "test__engagement__product__authorized_group": False, "known_exploited": False, "ransomware_used": False, "kev_date": None} ALL_FINDINGS = [FINDING_1, FINDING_2, FINDING_3, FINDING_4, FINDING_5, FINDING_6, FINDING_7, FINDING_8, FINDING_9, @@ -184,10 +184,14 @@ def test_endpoint_queries_no_data(self): [], ) - def test_endpoint_queries(self): + @patch("dojo.filters.now") + def test_endpoint_queries(self, mock_now): + fake_now = pytz.UTC.localize(datetime(2020, 7, 1)) + mock_now.return_value = fake_now + # Queries over Finding and Endpoint_Status - with self.assertNumQueries(43): - product_types = [] + with self.assertNumQueries(44): + product_types = Product_Type.objects.all() endpoint_queries = utils.endpoint_queries( product_types, self.request, diff --git a/unittests/tools/test_checkmarx_cxflow_sast_parser.py b/unittests/tools/test_checkmarx_cxflow_sast_parser.py index 85867a86a56..a82d1cbdd08 100644 --- a/unittests/tools/test_checkmarx_cxflow_sast_parser.py +++ b/unittests/tools/test_checkmarx_cxflow_sast_parser.py @@ -22,6 +22,7 @@ def test_file_name_aggregated_parse_file_with_no_vulnerabilities_has_no_findings ) parser = CheckmarxCXFlowSastParser() findings = parser.get_findings(my_file_handle, test) + my_file_handle.close() self.assertEqual(0, len(findings)) def test_file_name_aggregated_parse_file_with_no_vulnerabilities_has_1_finding(self): @@ -52,6 +53,7 @@ def test_file_name_aggregated_parse_file_with_no_vulnerabilities_has_1_finding(s "Scripting (XSS)", finding.description) self.assertEqual(True, finding.active) self.assertEqual(False, finding.verified) + my_file_handle.close() def test_file_name_aggregated_parse_file_with_no_vulnerabilities_has_4_findings(self): my_file_handle, _, _, test = self.init( @@ -72,3 +74,4 @@ def test_file_name_aggregated_parse_file_with_no_vulnerabilities_has_4_findings( self.assertIsNotNone(finding.line) self.assertIsNotNone(finding.false_p) self.assertIsNotNone(finding.description) + my_file_handle.close() diff --git a/unittests/tools/test_trivy_parser.py b/unittests/tools/test_trivy_parser.py index 2a1b60f2fb4..ef4cf8099f9 100644 --- a/unittests/tools/test_trivy_parser.py +++ b/unittests/tools/test_trivy_parser.py @@ -230,3 +230,73 @@ def test_issue_10991(self): parser = TrivyParser() findings = parser.get_findings(test_file, Test()) self.assertEqual(len(findings), 37) + + def test_all_statuses(self): + with sample_path("all_statuses.json").open(encoding="utf-8") as test_file: + parser = TrivyParser() + findings = parser.get_findings(test_file, Test()) + self.assertEqual(len(findings), 8) + + with self.subTest("unknown"): + finding = findings[0] + self.assertEqual(True, finding.active) + self.assertEqual(False, finding.verified) + self.assertEqual(False, finding.false_p) + self.assertEqual(False, finding.out_of_scope) + self.assertEqual(False, finding.is_mitigated) + + with self.subTest("not_affected"): + finding = findings[1] + self.assertEqual(False, finding.active) + self.assertEqual(True, finding.verified) + self.assertEqual(False, finding.false_p) + self.assertEqual(False, finding.out_of_scope) + self.assertEqual(True, finding.is_mitigated) + + with self.subTest("affected"): + finding = findings[2] + self.assertEqual(True, finding.active) + self.assertEqual(True, finding.verified) + self.assertEqual(False, finding.false_p) + self.assertEqual(False, finding.out_of_scope) + self.assertEqual(False, finding.is_mitigated) + + with self.subTest("fixed"): + finding = findings[3] + self.assertEqual(True, finding.active) + self.assertEqual(True, finding.verified) + self.assertEqual(False, finding.false_p) + self.assertEqual(False, finding.out_of_scope) + self.assertEqual(False, finding.is_mitigated) + + with self.subTest("under_investigation"): + finding = findings[4] + self.assertEqual(True, finding.active) + self.assertEqual(False, finding.verified) + self.assertEqual(False, finding.false_p) + self.assertEqual(False, finding.out_of_scope) + self.assertEqual(False, finding.is_mitigated) + + with self.subTest("will_not_fix"): + finding = findings[5] + self.assertEqual(True, finding.active) + self.assertEqual(True, finding.verified) + self.assertEqual(False, finding.false_p) + self.assertEqual(False, finding.out_of_scope) + self.assertEqual(False, finding.is_mitigated) + + with self.subTest("fix_deferred"): + finding = findings[6] + self.assertEqual(True, finding.active) + self.assertEqual(True, finding.verified) + self.assertEqual(False, finding.false_p) + self.assertEqual(False, finding.out_of_scope) + self.assertEqual(False, finding.is_mitigated) + + with self.subTest("end_of_life"): + finding = findings[7] + self.assertEqual(True, finding.active) + self.assertEqual(True, finding.verified) + self.assertEqual(False, finding.false_p) + self.assertEqual(False, finding.out_of_scope) + self.assertEqual(False, finding.is_mitigated) diff --git a/unittests/tools/test_twistlock_parser.py b/unittests/tools/test_twistlock_parser.py index 9d0b2788e2b..aa627a346df 100644 --- a/unittests/tools/test_twistlock_parser.py +++ b/unittests/tools/test_twistlock_parser.py @@ -20,8 +20,8 @@ def test_parse_file_with_one_vuln(self): self.assertEqual(1, len(findings[0].unsaved_vulnerability_ids)) self.assertEqual("CVE-2013-7459", findings[0].unsaved_vulnerability_ids[0]) - def test_parse_file_with_no_link(self): - testfile = (get_unit_tests_scans_path("twistlock") / "one_vuln_no_link.json").open(encoding="utf-8") + def test_parse_file_with_no_link_no_description(self): + testfile = (get_unit_tests_scans_path("twistlock") / "one_vuln_no_link_no_description.json").open(encoding="utf-8") parser = TwistlockParser() findings = parser.get_findings(testfile, Test()) testfile.close()