Skip to content

Commit 7cf2e11

Browse files
paulOsinskiPaul Osinski
andauthored
Readme docs update (#11516)
* add back ldap-authentication.md * add back api-v2-docs.md * update broken readme links --------- Co-authored-by: Paul Osinski <paul.m.osinski@gmail.com>
1 parent afa94d9 commit 7cf2e11

3 files changed

Lines changed: 319 additions & 9 deletions

File tree

README.md

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,20 +81,18 @@ Navigate to `http://localhost:8080` to see your new instance!
8181

8282
## Documentation
8383

84-
* [Official Docs](https://documentation.defectdojo.com/)
85-
* [Docs for our `dev` branch](https://documentation.defectdojo.com/dev/)
86-
* [REST APIs](https://documentation.defectdojo.com/integrations/api-v2-docs/)
87-
* [Client APIs and Wrappers](https://documentation.defectdojo.com/integrations/api-v2-docs/#clients--api-wrappers)
84+
* [Official Docs](https://docs.defectdojo.com/)
85+
* [REST APIs](https://docs.defectdojo.com/en/open_source/api-v2-docs/)
86+
* [Client APIs and Wrappers](https://docs.defectdojo.com/en/open_source/api-v2-docs/#clients--api-wrappers)
8887
* Authentication options:
89-
* [OAuth2/SAML2](https://documentation.defectdojo.com/integrations/social-authentication/)
90-
* [LDAP](https://documentation.defectdojo.com/integrations/ldap-authentication/)
91-
* [Supported tools](https://documentation.defectdojo.com/integrations/parsers/)
88+
* [OAuth2/SAML2](https://docs.defectdojo.com/en/open_source/archived_docs/integrations/social-authentication/)
89+
* [LDAP](https://docs.defectdojo.com/en/open_source/ldap-authentication/)
90+
* [Supported tools](https://docs.defectdojo.com/en/connecting_your_tools/parsers/)
9291

9392
## Supported Installation Options
9493

9594
* [Docker / Docker Compose](readme-docs/DOCKER.md)
96-
* [SaaS](https://www.defectdojo.com/pricing) - Includes Support & Supports the Project
97-
* [AWS AMI](https://aws.amazon.com/marketplace/pp/prodview-m2a25gr67xbzk) - Supports the Project
95+
* [SaaS](https://www.defectdojo.com/) - Includes Support & Supports the Project
9896

9997
## Community, Getting Involved, and Updates
10098

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
---
2+
title: "DefectDojo API v2"
3+
description: "DefectDojo's API lets you automate tasks, e.g. uploading scan reports in CI/CD pipelines."
4+
draft: false
5+
weight: 2
6+
---
7+
8+
9+
10+
11+
DefectDojo\'s API is created using [Django Rest
12+
Framework](http://www.django-rest-framework.org/). The documentation of
13+
each endpoint is available within each DefectDojo installation at
14+
[`/api/v2/doc/`](https://demo.defectdojo.org/api/v2/) and can be accessed by choosing the API v2
15+
Docs link on the user drop down menu in the header.
16+
17+
![image](../../images/api_v2_1.png)
18+
19+
The documentation is generated using [drf-spectacular](https://drf-spectacular.readthedocs.io/) at [`/api/v2/oa3/swagger-ui/`](https://demo.defectdojo.org/api/v2/oa3/swagger-ui/), and is
20+
interactive. On the top of API v2 docs is a link that generates an OpenAPI v3 spec.
21+
22+
To interact with the documentation, a valid Authorization header value
23+
is needed. Visit the `/api/key-v2` view to generate your
24+
API Key (`Token <api_key>`) and copy the header value provided.
25+
26+
![image](../../images/api_v2_2.png)
27+
28+
Each section allows you to make calls to the API and view the Request
29+
URL, Response Body, Response Code and Response Headers.
30+
31+
![image](../../images/api_v2_3.png)
32+
33+
If you're logged in to the Defect Dojo web UI, you do not need to provide the authorization token.
34+
35+
## Authentication
36+
37+
The API uses header authentication with API key. The format of the
38+
header should be: :
39+
40+
Authorization: Token <api.key>
41+
42+
For example: :
43+
44+
Authorization: Token c8572a5adf107a693aa6c72584da31f4d1f1dcff
45+
46+
### Alternative authentication method
47+
48+
If you use [an alternative authentication method](../social-authentication/) for users, you may want to disable DefectDojo API tokens because it could bypass your authentication concept. \
49+
Using of DefectDojo API tokens can be disabled by specifying the environment variable `DD_API_TOKENS_ENABLED` to `False`.
50+
Or only `api/v2/api-token-auth/` endpoint can be disabled by setting `DD_API_TOKEN_AUTH_ENDPOINT_ENABLED` to `False`.
51+
52+
## Sample Code
53+
54+
Here are some simple python examples and their results produced against
55+
the `/users` endpoint: :
56+
57+
{{< highlight python >}}
58+
import requests
59+
60+
url = 'http://127.0.0.1:8000/api/v2/users'
61+
headers = {'content-type': 'application/json',
62+
'Authorization': 'Token c8572a5adf107a693aa6c72584da31f4d1f1dcff'}
63+
r = requests.get(url, headers=headers, verify=True) # set verify to False if ssl cert is self-signed
64+
65+
for key, value in r.__dict__.items():
66+
print(f"'{key}': '{value}'")
67+
print('------------------')
68+
{{< /highlight >}}
69+
70+
This code will return the list of all the users defined in DefectDojo.
71+
The json object result looks like : :
72+
73+
{{< highlight json >}}
74+
[
75+
{
76+
"first_name": "Tyagi",
77+
"id": 22,
78+
"last_login": "2019-06-18T08:05:51.925743",
79+
"last_name": "Paz",
80+
"username": "dev7958"
81+
},
82+
{
83+
"first_name": "saurabh",
84+
"id": 31,
85+
"last_login": "2019-06-06T11:44:32.533035",
86+
"last_name": "",
87+
"username": "saurabh.paz"
88+
}
89+
]
90+
{{< /highlight >}}
91+
92+
Here is another example against the `/users` endpoint, this
93+
time we will filter the results to include only the users whose user
94+
name includes `jay`:
95+
96+
{{< highlight python >}}
97+
import requests
98+
99+
url = 'http://127.0.0.1:8000/api/v2/users/?username__contains=jay'
100+
headers = {'content-type': 'application/json',
101+
'Authorization': 'Token c8572a5adf107a693aa6c72584da31f4d1f1dcff'}
102+
r = requests.get(url, headers=headers, verify=True) # set verify to False if ssl cert is self-signed
103+
104+
for key, value in r.__dict__.items():
105+
print(f"'{key}': '{value}'")
106+
print('------------------')
107+
{{< /highlight >}}
108+
109+
The json object result is: :
110+
111+
{{< highlight json >}}
112+
[
113+
{
114+
"first_name": "Jay",
115+
"id": 22,
116+
"last_login": "2015-10-28T08:05:51.925743",
117+
"last_name": "Paz",
118+
"username": "jay7958"
119+
},
120+
{
121+
"first_name": "",
122+
"id": 31,
123+
"last_login": "2015-10-13T11:44:32.533035",
124+
"last_name": "",
125+
"username": "jay.paz"
126+
}
127+
]
128+
{{< /highlight >}}
129+
130+
See [Django Rest Framework\'s documentation on interacting with an
131+
API](http://www.django-rest-framework.org/topics/api-clients/) for
132+
additional examples and tips.
133+
134+
## Manually calling the API
135+
136+
Tools like Postman can be used for testing the API.
137+
138+
Example for importing a scan result:
139+
140+
- Verb: POST
141+
- URI: <http://localhost:8080/api/v2/import-scan/>
142+
- Headers tab:
143+
144+
add the authentication header
145+
: - Key: Authorization
146+
- Value: Token c8572a5adf107a693aa6c72584da31f4d1f1dcff
147+
148+
- Body tab
149+
150+
- select \"form-data\", click \"bulk edit\". Example for a ZAP scan:
151+
152+
<!-- -->
153+
154+
engagement:3
155+
verified:true
156+
active:true
157+
lead:1
158+
tags:test
159+
scan_type:ZAP Scan
160+
minimum_severity:Info
161+
skip_duplicates:true
162+
close_old_findings:false
163+
164+
- Body tab
165+
166+
- Click \"Key-value\" edit
167+
- Add a \"file\" parameter of type \"file\". This will trigger
168+
multi-part form data for sending the file content
169+
- Browse for the file to upload
170+
171+
- Click send
172+
173+
## Clients / API Wrappers
174+
175+
| Wrapper | Status | Notes |
176+
| -----------------------------| ------------------------| ------------------------|
177+
| [Specific python wrapper](https://github.com/DefectDojo/defectdojo_api) | working (2021-01-21) | API Wrapper including scripts for continous CI/CD uploading. Is lagging behind a bit on latest API features as we plan to revamp the API wrapper |
178+
| [Openapi python wrapper](https://github.com/alles-klar/defectdojo-api-v2-client) | | proof of concept only where we found out the the OpenAPI spec is not perfect yet |
179+
| [Java library](https://github.com/secureCodeBox/defectdojo-client-java) | working (2021-08-30) | Created by the kind people of [SecureCodeBox](https://github.com/secureCodeBox/secureCodeBox) |
180+
| [Image using the Java library](https://github.com/SDA-SE/defectdojo-client) | working (2021-08-30) | |
181+
| [.Net/C# library](https://www.nuget.org/packages/DefectDojo.Api/) | working (2021-06-08) | |
182+
| [dd-import](https://github.com/MaibornWolff/dd-import) | working (2021-08-24) | dd-import is not directly an API wrapper. It offers some convenience functions to make it easier to import findings and language data from CI/CD pipelines. |
183+
184+
Some of the api wrappers contain quite a bit of logic to ease scanning and importing in CI/CD environments. We are in the process of simplifying this by making the DefectDojo API smarter (so api wrappers / script can be dumber).
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
---
2+
title: "Authentication via LDAP"
3+
description: "Authenticate users using LDAP"
4+
draft: false
5+
weight: 4
6+
---
7+
8+
## LDAP Authentication
9+
10+
Out of the box Defect Dojo does not support LDAP authentication.
11+
12+
*However*, since Defect Dojo is built using Django, it isn't too difficult to add support for LDAP.
13+
So long as you don't mind building your own Docker images...
14+
15+
We will need to modify a grand total of 4-5 files, depending on how you want to pass Dojo your LDAP secrets.
16+
17+
- Dockerfile.django-*
18+
- Dockerfile.nginx-*
19+
- requirements.txt
20+
- settings.dist.py
21+
- docker-compose.yml *(Optional)*
22+
23+
24+
#### Dockerfile modifications
25+
26+
In both Dockerfile.django and Dockerfile.nginx, you want to add the following lines to the apt-get install layers:
27+
28+
```bash
29+
libldap2-dev \
30+
libsasl2-dev \
31+
ldap-utils \
32+
```
33+
34+
35+
#### requirements.txt
36+
37+
Please check for the latest version of these requirements at the time of implementation on pypi.org and use those if you can.
38+
39+
- [https://pypi.org/project/python-ldap/](python-ldap)
40+
- [https://pypi.org/project/django-auth-ldap/](django-auth-ldap)
41+
42+
Otherwise add the following to requirements.txt:
43+
44+
```python
45+
python-ldap==3.4.2
46+
django-auth-ldap==4.1.0
47+
```
48+
49+
50+
#### settings.dist.py
51+
52+
Find the settings file (hint: `/dojo/settings/settings.dist.py`) and add the following:
53+
54+
At the top of the file:
55+
```python
56+
import ldap
57+
from django_auth_ldap.config import LDAPSearch, GroupOfNamesType
58+
```
59+
60+
Then further down add LDAP settings to the env dict:
61+
```python
62+
# LDAP
63+
DD_LDAP_SERVER_URI=(str, 'ldap://ldap.example.com'),
64+
DD_LDAP_BIND_DN=(str, ''),
65+
DD_LDAP_BIND_PASSWORD=(str, ''),
66+
```
67+
68+
Then under the env dict add:
69+
```python
70+
AUTH_LDAP_SERVER_URI = env('DD_LDAP_SERVER_URI')
71+
AUTH_LDAP_BIND_DN = env('DD_LDAP_BIND_DN')
72+
AUTH_LDAP_BIND_PASSWORD = env('DD_LDAP_BIND_PASSWORD')
73+
AUTH_LDAP_USER_SEARCH = LDAPSearch(
74+
"ou=Groups,dc=example,dc=com", ldap.SCOPE_SUBTREE, "(uid=%(user)s)"
75+
)
76+
77+
AUTH_LDAP_USER_ATTR_MAP = {
78+
"first_name": "givenName",
79+
"last_name": "sn",
80+
"email": "mail",
81+
}
82+
```
83+
Please make sure to customise all of the LDAP search variables to match your company's configuration.
84+
85+
86+
For additional group controls you can add:
87+
```python
88+
# Set up the basic group parameters.
89+
AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
90+
"dc=example,dc=com",
91+
ldap.SCOPE_SUBTREE,
92+
"(objectClass=groupOfNames)",
93+
)
94+
AUTH_LDAP_GROUP_TYPE = GroupOfNamesType(name_attr="cn")
95+
96+
# Simple group restrictions
97+
AUTH_LDAP_REQUIRE_GROUP = "cn=DD_USER_ACTIVE,ou=Groups,dc=example,dc=com"
98+
99+
AUTH_LDAP_USER_FLAGS_BY_GROUP = {
100+
"is_active": "cn=DD_USER_ACTIVE,ou=Groups,dc=example,dc=com",
101+
"is_staff": "cn=DD_USER_STAFF,ou=Groups,dc=example,dc=com",
102+
"is_superuser": "cn=DD_USER_ADMIN,ou=Groups,dc=example,dc=com",
103+
}
104+
```
105+
106+
Then also add `'django_auth_ldap.backend.LDAPBackend'` to the `AUTHENTICATION_BACKENDS` variable, for example:
107+
```python
108+
AUTHENTICATION_BACKENDS = (
109+
'django_auth_ldap.backend.LDAPBackend',
110+
'django.contrib.auth.backends.RemoteUserBackend',
111+
'django.contrib.auth.backends.ModelBackend',
112+
)
113+
```
114+
115+
Read the docs for Django Authentication with LDAP here: https://django-auth-ldap.readthedocs.io/en/latest/
116+
117+
#### docker-compose.yml
118+
119+
In order to pass the variables to the settings.dist.py file via docker, it's a good idea to add these to the docker compose file.
120+
121+
You can do this by adding the following variables to the environment section for the uwsgi image:
122+
```yaml
123+
DD_LDAP_SERVER_URI: "${DD_LDAP_SERVER_URI:-ldap://ldap.example.com}"
124+
DD_LDAP_BIND_DN: "${DD_LDAP_BIND_DN:-}"
125+
DD_LDAP_BIND_PASSWORD: "${DD_LDAP_BIND_PASSWORD:-}"
126+
```
127+
128+
Alternatively you can set these values in a local_settings.py file.

0 commit comments

Comments
 (0)