From 000728aca201bc8427a9673ea0bd0a7a4abdad58 Mon Sep 17 00:00:00 2001 From: Paul Osinski <42211303+paulOsinski@users.noreply.github.com> Date: Tue, 7 Jan 2025 14:41:58 -0500 Subject: [PATCH] Readme docs update (#11516) * add back ldap-authentication.md * add back api-v2-docs.md * update broken readme links --------- Co-authored-by: Paul Osinski --- README.md | 16 +- docs/content/en/open_source/api-v2-docs.md | 184 ++++++++++++++++++ .../en/open_source/ldap-authentication.md | 128 ++++++++++++ 3 files changed, 319 insertions(+), 9 deletions(-) create mode 100644 docs/content/en/open_source/api-v2-docs.md create mode 100644 docs/content/en/open_source/ldap-authentication.md diff --git a/README.md b/README.md index 8decfcd00d..25d4070a63 100644 --- a/README.md +++ b/README.md @@ -81,20 +81,18 @@ Navigate to `http://localhost:8080` to see your new instance! ## Documentation -* [Official Docs](https://documentation.defectdojo.com/) - * [Docs for our `dev` branch](https://documentation.defectdojo.com/dev/) -* [REST APIs](https://documentation.defectdojo.com/integrations/api-v2-docs/) -* [Client APIs and Wrappers](https://documentation.defectdojo.com/integrations/api-v2-docs/#clients--api-wrappers) +* [Official Docs](https://docs.defectdojo.com/) +* [REST APIs](https://docs.defectdojo.com/en/open_source/api-v2-docs/) +* [Client APIs and Wrappers](https://docs.defectdojo.com/en/open_source/api-v2-docs/#clients--api-wrappers) * Authentication options: - * [OAuth2/SAML2](https://documentation.defectdojo.com/integrations/social-authentication/) - * [LDAP](https://documentation.defectdojo.com/integrations/ldap-authentication/) -* [Supported tools](https://documentation.defectdojo.com/integrations/parsers/) + * [OAuth2/SAML2](https://docs.defectdojo.com/en/open_source/archived_docs/integrations/social-authentication/) + * [LDAP](https://docs.defectdojo.com/en/open_source/ldap-authentication/) +* [Supported tools](https://docs.defectdojo.com/en/connecting_your_tools/parsers/) ## Supported Installation Options * [Docker / Docker Compose](readme-docs/DOCKER.md) -* [SaaS](https://www.defectdojo.com/pricing) - Includes Support & Supports the Project -* [AWS AMI](https://aws.amazon.com/marketplace/pp/prodview-m2a25gr67xbzk) - Supports the Project +* [SaaS](https://www.defectdojo.com/) - Includes Support & Supports the Project ## Community, Getting Involved, and Updates diff --git a/docs/content/en/open_source/api-v2-docs.md b/docs/content/en/open_source/api-v2-docs.md new file mode 100644 index 0000000000..3627d3e426 --- /dev/null +++ b/docs/content/en/open_source/api-v2-docs.md @@ -0,0 +1,184 @@ +--- +title: "DefectDojo API v2" +description: "DefectDojo's API lets you automate tasks, e.g. uploading scan reports in CI/CD pipelines." +draft: false +weight: 2 +--- + + + + +DefectDojo\'s API is created using [Django Rest +Framework](http://www.django-rest-framework.org/). The documentation of +each endpoint is available within each DefectDojo installation at +[`/api/v2/doc/`](https://demo.defectdojo.org/api/v2/) and can be accessed by choosing the API v2 +Docs link on the user drop down menu in the header. + +![image](../../images/api_v2_1.png) + +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 +interactive. On the top of API v2 docs is a link that generates an OpenAPI v3 spec. + +To interact with the documentation, a valid Authorization header value +is needed. Visit the `/api/key-v2` view to generate your +API Key (`Token `) and copy the header value provided. + +![image](../../images/api_v2_2.png) + +Each section allows you to make calls to the API and view the Request +URL, Response Body, Response Code and Response Headers. + +![image](../../images/api_v2_3.png) + +If you're logged in to the Defect Dojo web UI, you do not need to provide the authorization token. + +## Authentication + +The API uses header authentication with API key. The format of the +header should be: : + + Authorization: Token + +For example: : + + Authorization: Token c8572a5adf107a693aa6c72584da31f4d1f1dcff + +### Alternative authentication method + +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. \ +Using of DefectDojo API tokens can be disabled by specifying the environment variable `DD_API_TOKENS_ENABLED` to `False`. +Or only `api/v2/api-token-auth/` endpoint can be disabled by setting `DD_API_TOKEN_AUTH_ENDPOINT_ENABLED` to `False`. + +## Sample Code + +Here are some simple python examples and their results produced against +the `/users` endpoint: : + +{{< highlight python >}} +import requests + +url = 'http://127.0.0.1:8000/api/v2/users' +headers = {'content-type': 'application/json', + 'Authorization': 'Token c8572a5adf107a693aa6c72584da31f4d1f1dcff'} +r = requests.get(url, headers=headers, verify=True) # set verify to False if ssl cert is self-signed + +for key, value in r.__dict__.items(): + print(f"'{key}': '{value}'") + print('------------------') +{{< /highlight >}} + +This code will return the list of all the users defined in DefectDojo. +The json object result looks like : : + +{{< highlight json >}} + [ + { + "first_name": "Tyagi", + "id": 22, + "last_login": "2019-06-18T08:05:51.925743", + "last_name": "Paz", + "username": "dev7958" + }, + { + "first_name": "saurabh", + "id": 31, + "last_login": "2019-06-06T11:44:32.533035", + "last_name": "", + "username": "saurabh.paz" + } + ] +{{< /highlight >}} + +Here is another example against the `/users` endpoint, this +time we will filter the results to include only the users whose user +name includes `jay`: + +{{< highlight python >}} +import requests + +url = 'http://127.0.0.1:8000/api/v2/users/?username__contains=jay' +headers = {'content-type': 'application/json', + 'Authorization': 'Token c8572a5adf107a693aa6c72584da31f4d1f1dcff'} +r = requests.get(url, headers=headers, verify=True) # set verify to False if ssl cert is self-signed + +for key, value in r.__dict__.items(): + print(f"'{key}': '{value}'") + print('------------------') +{{< /highlight >}} + +The json object result is: : + +{{< highlight json >}} +[ + { + "first_name": "Jay", + "id": 22, + "last_login": "2015-10-28T08:05:51.925743", + "last_name": "Paz", + "username": "jay7958" + }, + { + "first_name": "", + "id": 31, + "last_login": "2015-10-13T11:44:32.533035", + "last_name": "", + "username": "jay.paz" + } +] +{{< /highlight >}} + +See [Django Rest Framework\'s documentation on interacting with an +API](http://www.django-rest-framework.org/topics/api-clients/) for +additional examples and tips. + +## Manually calling the API + +Tools like Postman can be used for testing the API. + +Example for importing a scan result: + +- Verb: POST +- URI: +- Headers tab: + + add the authentication header + : - Key: Authorization + - Value: Token c8572a5adf107a693aa6c72584da31f4d1f1dcff + +- Body tab + + - select \"form-data\", click \"bulk edit\". Example for a ZAP scan: + + + + engagement:3 + verified:true + active:true + lead:1 + tags:test + scan_type:ZAP Scan + minimum_severity:Info + skip_duplicates:true + close_old_findings:false + +- Body tab + + - Click \"Key-value\" edit + - Add a \"file\" parameter of type \"file\". This will trigger + multi-part form data for sending the file content + - Browse for the file to upload + +- Click send + +## Clients / API Wrappers + +| Wrapper | Status | Notes | +| -----------------------------| ------------------------| ------------------------| +| [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 | +| [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 | +| [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) | +| [Image using the Java library](https://github.com/SDA-SE/defectdojo-client) | working (2021-08-30) | | +| [.Net/C# library](https://www.nuget.org/packages/DefectDojo.Api/) | working (2021-06-08) | | +| [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. | + +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). \ No newline at end of file diff --git a/docs/content/en/open_source/ldap-authentication.md b/docs/content/en/open_source/ldap-authentication.md new file mode 100644 index 0000000000..e97758e02e --- /dev/null +++ b/docs/content/en/open_source/ldap-authentication.md @@ -0,0 +1,128 @@ +--- +title: "Authentication via LDAP" +description: "Authenticate users using LDAP" +draft: false +weight: 4 +--- + +## LDAP Authentication + +Out of the box Defect Dojo does not support LDAP authentication. + +*However*, since Defect Dojo is built using Django, it isn't too difficult to add support for LDAP. +So long as you don't mind building your own Docker images... + +We will need to modify a grand total of 4-5 files, depending on how you want to pass Dojo your LDAP secrets. + + - Dockerfile.django-* + - Dockerfile.nginx-* + - requirements.txt + - settings.dist.py + - docker-compose.yml *(Optional)* + + +#### Dockerfile modifications + +In both Dockerfile.django and Dockerfile.nginx, you want to add the following lines to the apt-get install layers: + +```bash +libldap2-dev \ +libsasl2-dev \ +ldap-utils \ +``` + + +#### requirements.txt + +Please check for the latest version of these requirements at the time of implementation on pypi.org and use those if you can. + +- [https://pypi.org/project/python-ldap/](python-ldap) +- [https://pypi.org/project/django-auth-ldap/](django-auth-ldap) + +Otherwise add the following to requirements.txt: + +```python +python-ldap==3.4.2 +django-auth-ldap==4.1.0 +``` + + +#### settings.dist.py + +Find the settings file (hint: `/dojo/settings/settings.dist.py`) and add the following: + +At the top of the file: +```python +import ldap +from django_auth_ldap.config import LDAPSearch, GroupOfNamesType +``` + +Then further down add LDAP settings to the env dict: +```python +# LDAP +DD_LDAP_SERVER_URI=(str, 'ldap://ldap.example.com'), +DD_LDAP_BIND_DN=(str, ''), +DD_LDAP_BIND_PASSWORD=(str, ''), +``` + +Then under the env dict add: +```python +AUTH_LDAP_SERVER_URI = env('DD_LDAP_SERVER_URI') +AUTH_LDAP_BIND_DN = env('DD_LDAP_BIND_DN') +AUTH_LDAP_BIND_PASSWORD = env('DD_LDAP_BIND_PASSWORD') +AUTH_LDAP_USER_SEARCH = LDAPSearch( + "ou=Groups,dc=example,dc=com", ldap.SCOPE_SUBTREE, "(uid=%(user)s)" +) + +AUTH_LDAP_USER_ATTR_MAP = { + "first_name": "givenName", + "last_name": "sn", + "email": "mail", +} +``` +Please make sure to customise all of the LDAP search variables to match your company's configuration. + + +For additional group controls you can add: +```python +# Set up the basic group parameters. +AUTH_LDAP_GROUP_SEARCH = LDAPSearch( + "dc=example,dc=com", + ldap.SCOPE_SUBTREE, + "(objectClass=groupOfNames)", +) +AUTH_LDAP_GROUP_TYPE = GroupOfNamesType(name_attr="cn") + +# Simple group restrictions +AUTH_LDAP_REQUIRE_GROUP = "cn=DD_USER_ACTIVE,ou=Groups,dc=example,dc=com" + +AUTH_LDAP_USER_FLAGS_BY_GROUP = { + "is_active": "cn=DD_USER_ACTIVE,ou=Groups,dc=example,dc=com", + "is_staff": "cn=DD_USER_STAFF,ou=Groups,dc=example,dc=com", + "is_superuser": "cn=DD_USER_ADMIN,ou=Groups,dc=example,dc=com", +} +``` + +Then also add `'django_auth_ldap.backend.LDAPBackend'` to the `AUTHENTICATION_BACKENDS` variable, for example: +```python +AUTHENTICATION_BACKENDS = ( + 'django_auth_ldap.backend.LDAPBackend', + 'django.contrib.auth.backends.RemoteUserBackend', + 'django.contrib.auth.backends.ModelBackend', +) +``` + +Read the docs for Django Authentication with LDAP here: https://django-auth-ldap.readthedocs.io/en/latest/ + +#### docker-compose.yml + +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. + +You can do this by adding the following variables to the environment section for the uwsgi image: +```yaml +DD_LDAP_SERVER_URI: "${DD_LDAP_SERVER_URI:-ldap://ldap.example.com}" +DD_LDAP_BIND_DN: "${DD_LDAP_BIND_DN:-}" +DD_LDAP_BIND_PASSWORD: "${DD_LDAP_BIND_PASSWORD:-}" +``` + +Alternatively you can set these values in a local_settings.py file.