Skip to content

Commit 7e04b5c

Browse files
authored
Merge branch 'bugfix' into movingparserdocs
2 parents a8b60f6 + 1ba1122 commit 7e04b5c

14 files changed

Lines changed: 369 additions & 30 deletions

File tree

docs/content/en/connecting_your_tools/connectors/connectors_tool_reference.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ The SonarQube Connector can fetch data from either a SonarCloud account or from
172172
1. Enter the base url of your SonarQube instance in the Location field: for example `https://my.sonarqube.com/`
173173
2. Enter a valid **API key** in the Secret field. This will need to be a **[User](https://docs.sonarsource.com/sonarqube/latest/user-guide/user-account/generating-and-using-tokens/)** [API Token Type](https://docs.sonarsource.com/sonarqube/latest/user-guide/user-account/generating-and-using-tokens/).
174174

175+
The token will need to have access to Projects, Vulnerabilities and Hotspots within Sonar.
176+
175177
API tokens can be found and generated via **My Account \-\> Security \-\> Generate Token** in the SonarQube app. For more information, [see SonarQube documentation](https://docs.sonarsource.com/sonarqube/latest/user-guide/user-account/generating-and-using-tokens/).
176178

177179
## **Snyk**
@@ -187,7 +189,7 @@ See the [Snyk API documentation](https://docs.snyk.io/snyk-api) for more info.
187189

188190
## Tenable
189191

190-
The Tenable connector uses the **Tenable.io** REST API to fetch data.
192+
The Tenable connector uses the **Tenable.io** REST API to fetch data. Currently, only vulnerability scans are imported - Web App Scans cannot be imported with the Connector.
191193

192194
On\-premise Tenable Connectors are not available at this time.
193195

docs/content/en/share_your_findings/integrations.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Supported Integrations:
99
- [Azure Devops](/en/share_your_findings/integrations_toolreference/#azure-devops-boards)
1010
- [GitHub](/en/share_your_findings/integrations_toolreference/#github)
1111
- [GitLab Boards](/en/share_your_findings/integrations_toolreference/#gitlab)
12-
- ServiceNow (Coming Soon)
12+
- [ServiceNow](/en/share_your_findings/integrations_toolreference/#servicenow)
1313

1414
## Opening the Integrations page
1515

docs/content/en/share_your_findings/integrations_toolreference.md

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: "Integrators Tool Reference"
3-
description: "Beta Feature"
3+
description: "Detailed setup guides for Integrators"
44
weight: 1
55
---
66

@@ -101,7 +101,7 @@ The GitLab integration allows you to add issues to a [GitLab Project](https://do
101101

102102
### Issue Tracker Mapping
103103

104-
- **Project Name**: The name of the project in GitLab that you want to send issues to
104+
- **Project Name**: The name of the project in GitLab that you want to send issues to.
105105

106106
### Severity Mapping Details
107107

@@ -122,3 +122,62 @@ By default, GitLab has statuses of 'opened' and 'closed'. Additional status lab
122122
- **Closed Mapping**: `closed`
123123
- **False Positive Mapping**: `closed`
124124
- **Risk Accepted Mapping**: `closed`
125+
126+
## ServiceNow
127+
128+
The ServiceNow Integration allows you to push DefectDojo Findings as ServiceNow Incidents.
129+
130+
### Instance Setup
131+
132+
Your ServiceNow instance will require you to obtain a Refresh Token, associated with the User or Service account that will push Incidents to ServiceNow.
133+
134+
You'll need to start by creating an OAuth registration on your ServiceNow instance for DefectDojo:
135+
136+
1. In the left-hand navigation bar, search for “Application Registry” and select it.
137+
2. Click “New”.
138+
3. Choose “Create an OAuth API endpoint for external clients”.
139+
4. Fill in the required fields:
140+
* Name: Provide a meaningful name for your application (e.g., Vulnerability Integration Client).
141+
* (Optional) Adjust the Token Lifespan:
142+
* Access Token Lifespan: Default is 1800 seconds (30 minutes).
143+
* Refresh Token Lifespan: The default is 8640000 seconds (approximately 100 days).
144+
5. Click Submit to create the application record.
145+
6. After submission, select the application from the list and take note of the **Client ID and Client Secret** fields.
146+
147+
You will then need to use this registration to obtain a Refresh Token, which can only be obtained through the ServiceNow API. Open a terminal window and paste the following (substituting the variables wrapped in `{{}}` with your user's actual information)
148+
149+
```
150+
curl --request POST \
151+
--url {{INSTANCE_HOST}}/oauth_token.do \
152+
--header 'content-type: application/x-www-form-urlencoded' \
153+
--data grant_type=password \
154+
--data 'client_id={{CLIENT_ID}}' \
155+
--data 'client_secret={{CLIENT_SECRET}}' \
156+
--data 'username={{USERNAME}}' \
157+
--data 'password={{PASSWORD}}'
158+
```
159+
160+
If your ServiceNow credentials are correct, and allow for admin level-access to ServiceNow, you should receive a response with a RefreshToken. You'll need that token to complete integration with DefectDojo.
161+
162+
- **Instance Label** should be the label that you want to use to identify this integration.
163+
- **Location** should be set to the URL for your ServiceNow server, for example `https://your-organization.service-now.com/`.
164+
- **Refresh Token** is where the Refresh Token should be entered.
165+
- **Client ID** should be the Client ID set in the OAuth App Registration.
166+
- **Client ID** should be the Client Secret set in the OAuth App Registration.
167+
168+
### Severity Mapping Details
169+
170+
This maps to the ServiceNow Impact field.
171+
- **Info Mapping**: `1`
172+
- **Low Mapping**: `1`
173+
- **Medium Mapping**: `2`
174+
- **High Mapping**: `3`
175+
- **Critical Mapping**: `3`
176+
177+
### Status Mapping Details
178+
179+
- **Status Field Name**: `State`
180+
- **Active Mapping**: `New`
181+
- **Closed Mapping**: `Closed`
182+
- **False Positive Mapping**: `Resolved`
183+
- **Risk Accepted Mapping**: `Resolved`

docs/package-lock.json

Lines changed: 10 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/package.json

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,18 @@
1616
"preview": "vite preview --outDir public"
1717
},
1818
"dependencies": {
19-
"@docsearch/css": "^4.2.0",
20-
"@docsearch/js": "^4.2.0",
21-
"@tabler/icons": "^3.34.1",
22-
"@thulite/doks-core": "^1.8.3",
23-
"@thulite/images": "^3.3.1",
24-
"@thulite/inline-svg": "^1.2.0",
25-
"@thulite/seo": "^2.4.1",
26-
"thulite": "^2.6.3"
19+
"@docsearch/css": "4.2.0",
20+
"@docsearch/js": "4.2.0",
21+
"@tabler/icons": "3.35.0",
22+
"@thulite/doks-core": "1.8.3",
23+
"@thulite/images": "3.3.3",
24+
"@thulite/inline-svg": "1.2.1",
25+
"@thulite/seo": "2.4.2",
26+
"thulite": "2.6.3"
2727
},
2828
"devDependencies": {
29-
"prettier": "^3.6.2",
30-
"vite": "^7.0.6"
29+
"prettier": "3.6.2",
30+
"vite": "7.1.11"
3131
},
3232
"engines": {
3333
"node": ">=20.11.0"

dojo/api_v2/views.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,8 @@ def close(self, request, pk=None):
933933
context={"request": request},
934934
)
935935
if finding_close.is_valid():
936+
# Remove the prefetched tags to avoid issues with delegating to celery
937+
finding.tags._remove_prefetched_objects()
936938
# Use shared helper to perform close operations
937939
finding_helper.close_finding(
938940
finding=finding,

dojo/middleware.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,18 @@
66
from urllib.parse import quote
77

88
import pghistory.middleware
9+
import requests
910
from auditlog.context import set_actor
1011
from auditlog.middleware import AuditlogMiddleware as _AuditlogMiddleware
1112
from django.conf import settings
13+
from django.contrib import messages
1214
from django.db import models
1315
from django.http import HttpResponseRedirect
16+
from django.shortcuts import redirect
1417
from django.urls import reverse
1518
from django.utils.functional import SimpleLazyObject
19+
from social_core.exceptions import AuthCanceled, AuthFailed, AuthForbidden
20+
from social_django.middleware import SocialAuthExceptionMiddleware
1621
from watson.middleware import SearchContextMiddleware
1722
from watson.search import search_context_manager
1823

@@ -75,6 +80,23 @@ def __call__(self, request):
7580
return self.get_response(request)
7681

7782

83+
class CustomSocialAuthExceptionMiddleware(SocialAuthExceptionMiddleware):
84+
def process_exception(self, request, exception):
85+
if isinstance(exception, requests.exceptions.RequestException):
86+
messages.error(request, "Please use the standard login below.")
87+
return redirect("/login?force_login_form")
88+
if isinstance(exception, AuthCanceled):
89+
messages.warning(request, "Social login was canceled. Please try again or use the standard login.")
90+
return redirect("/login?force_login_form")
91+
if isinstance(exception, AuthFailed):
92+
messages.error(request, "Social login failed. Please try again or use the standard login.")
93+
return redirect("/login?force_login_form")
94+
if isinstance(exception, AuthForbidden):
95+
messages.error(request, "You are not authorized to log in via this method. Please contact support or use the standard login.")
96+
return redirect("/login?force_login_form")
97+
return super().process_exception(request, exception)
98+
99+
78100
class DojoSytemSettingsMiddleware:
79101
_thread_local = local()
80102

dojo/notifications/helper.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,10 @@ def __init__(self, *args: list, **kwargs: dict) -> None:
627627
def create_notification(self, event: str | None = None, **kwargs: dict) -> None:
628628
# Process the notifications for a given list of recipients
629629
if kwargs.get("recipients") is not None:
630+
recipients = kwargs.get("recipients", [])
631+
if not recipients:
632+
logger.debug("No recipients provided for event: %s", event)
633+
return
630634
self._process_recipients(event=event, **kwargs)
631635
else:
632636
logger.debug("creating system notifications for event: %s", event)

dojo/settings/settings.dist.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -936,7 +936,7 @@ def generate_url(scheme, double_slashes, user, password, host, port, path, param
936936
"django.middleware.clickjacking.XFrameOptionsMiddleware",
937937
"dojo.middleware.LoginRequiredMiddleware",
938938
"dojo.middleware.AdditionalHeaderMiddleware",
939-
"social_django.middleware.SocialAuthExceptionMiddleware",
939+
"dojo.middleware.CustomSocialAuthExceptionMiddleware",
940940
"crum.CurrentRequestUserMiddleware",
941941
"dojo.middleware.AuditlogMiddleware",
942942
"dojo.middleware.AsyncSearchContextMiddleware",

dojo/tools/wazuh/v4_7.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,19 @@ def parse_findings(self, test, data):
2525
agent_ip = item.get("agent_ip")
2626
detection_time = item.get("detection_time").split("T")[0]
2727

28+
# Map Wazuh severity to its equivalent in DefectDojo
29+
SEVERITY_MAP = {
30+
"Critical": "Critical",
31+
"High": "High",
32+
"Medium": "Medium",
33+
"Low": "Low",
34+
"Info": "Info",
35+
"Informational": "Info",
36+
"Untriaged": "Info",
37+
}
38+
# Get DefectDojo severity and default to "Info" if severity is not in the mapping
39+
severity = SEVERITY_MAP.get(severity, "Info")
40+
2841
references = "\n".join(links) if links else None
2942

3043
title = (

0 commit comments

Comments
 (0)