defectdojo / defectdojo_api Goto Github PK
View Code? Open in Web Editor NEWPython API library for DefectDojo
License: MIT License
Python API library for DefectDojo
License: MIT License
create_finding() method gives error "found_by field is required"
Code :
from defectdojo_api.defectdojo_api import defectdojo_apiv2
host = 'http://localhost:8080/'
api_key = 'xxxx..xxxx'
user = 'User1'
dd = defectdojo_apiv2.DefectDojoAPIv2(host, api_key, user, debug=False)
res = dd.create_finding(title = 'Test8', description = 'Test', severity = 'Critical', cwe = 3, date = '2021-11-09',
product_id = 12, engagement_id = 25, test_id = 47, user_id = 8, impact = 'Test',
active = True, verified = False, mitigation = 'Test', numerical_severity='S0')
print(res.__dict__)
Output :
{'message': 'Error occured in API.',
'data': '{"found_by":["This field is required."],"message":"{\'found_by\': [ErrorDetail(string=\'This field is required.\', code=\'required\')]}"}',
'success': False,
'response_code': 400,
'logger': <Logger defectdojo_api (WARNING)>}
Since we no longer support this api wrapper we might best remove it so people cannot advertently install it via pip
?
apiv2 python method takes finding_id and three other positional arguments: product_id, engagement_id and test_id.
They can be set to None to be omitted from update, but the backend responds that actually required fields are title, severity, description and numerical_severity.
Title, severity and description can be copied from existing values, but looks like numerical_severity cannot be set with APIv2 python method, preventing use of set_finding.
Unsure yet what this could look like. Maybe requiring finding id, title, severity and description as positional arguments. Setting both severity & numerical severity feels redundant, maybe that could be checked from backend side.
There should be the option to disable the sleep after uploading in case a user with "block execution" is used.
Hello, everyone, thank you very much for maintaining the DefectDOJO project. I have been using it a lot, congratulations on the excellent work.
I would like to contribute by suggesting that, if possible, support for Swagger be added for the API. It is much easier to test using Swagger.
See issue initially reported here:
DefectDojo/django-DefectDojo#8154
It appears version 2.22.3 of DefectDojo no longer works for generic findings using the python API wrapper version 2. Version 2.18.0 was working with the wrapper. I manually create the product and engagement and map the IDs.
Attached file for import is here:
generic_HONGGFUZZ.REPORT.csv
Using curl I can get the file to import:
curl -X POST "http://" -H "accept: application/json" -H "Content-Type: multipart/form-data" -H "User-Agent: DefectDojo_api/1.2.0." -H "Authorization: Token <auth_token_here>" -F "minimum_severity=Info" -F "active=true" -F "scan_type=Generic Findings Import" -F "push_to_jira=false" -F "file=@generic_HONGGFUZZ.REPORT.csv" -F "product_name=Test" -F "scan_date=2023-05-24" -F "engagement=7"
Using the API as follows:
from defectdojo_api import defectdojo_apiv2
host = 'http:/dojo.url.goes.here'
api_key = '<api_key_goes_here>'
user = '<admin_name_goes_here>'
proxy = None
engagement_id = '11'
scanner = 'Generic Findings Import'
file = 'generic_HONGGFUZZ.REPORT.csv'
verified = None
close_old_findings = None
skip_duplicates = None
dojoDate = '2023-05-24'
build = None
tags = None
minimum_severity = 'Info'
dd = defectdojo_apiv2.DefectDojoAPIv2(host, api_key, user, verify_ssl=False, timeout=360, debug=True)
scanner = "Generic Findings Import"
print ("Uploading " + tool + " scan: " + file)
test_id = dd.upload_scan(engagement_id, scanner, file, "true", verified, close_old_findings, skip_duplicates, dojoDate, build=build,
tags=tags, minimum_severity=minimum_severity)
I get the following error message:
An error occured while uploading the scan: Error occured in API.
The DefectDojo log shows the following with more information:
django-defectdojo-2223-uwsgi-1 | [pid: 37|app: -|req: -/-] 172.18.0.1 (-) {30 vars in 366 bytes} [Wed May 24 18:51:54 2023] GET / => generated 0 bytes in 28 msecs (HTTP/1.0 500) 0 headers in 0 bytes (0 switches on core 0)
django-defectdojo-2223-uwsgi-1 | [pid: 37|app: -|req: -/-] 172.18.0.1 (-) {40 vars in 657 bytes} [Wed May 24 18:53:16 2023] GET //api/v2/users/?limit=20&username=dojoadmin => generated 254 bytes in 37 msecs (HTTP/1.1 200) 8 headers in 246 bytes (1 switches on core 1)
django-defectdojo-2223-uwsgi-1 | [pid: 37|app: -|req: -/-] 172.18.0.1 (-) {42 vars in 644 bytes} [Wed May 24 18:53:17 2023] POST //api/v2/engagements/ => generated 809 bytes in 131 msecs (HTTP/1.1 201) 8 headers in 251 bytes (1 switches on core 0)
django-defectdojo-2223-uwsgi-1 | [24/May/2023 18:53:17] WARNING [dojo.importers.importer.importer:260] Expecting value: line 1 column 1 (char 0)
django-defectdojo-2223-uwsgi-1 | [24/May/2023 18:53:17] WARNING [django.request:241] Bad Request: /api/v2/import-scan/
I tried running this example defectdojo_api/examples/v2/dojo_ci_cd.py and it says cannot load module
ImportError: No module named defectdojo_apiv2. I saw that python package doesn't have the respective file. Could you please add it and publish the pip package again?
Hi Aaron,
create_finding does not include all attributes of the REST-API. Can you add the new attributes?
Python-API
:param id: Engagement id.
:param name: Engagement name.
:param product_id: Product key id..
:param lead_id: Testing lead from the user table.
:param status: Engagement Status: In Progress, On Hold, Completed.
:param target_start: Engagement start date.
:param target_end: Engagement end date.
:param active: Active
:param pen_test: Pen test for engagement.
:param check_list: Check list for engagement.
:param threat_model: Thread Model for engagement.
:param risk_path: risk_path
:param test_strategy: Test Strategy URLs
:param progress: Engagement progresss measured in percent.
REST-API
{
"line_number": "",
"product": "related",
"description": "",
"reporter": "related",
"sourcefile": "",
"under_review": false,
"thread_id": 0,
"mitigated": "datetime",
"references": "",
"date": "date",
"active": false,
"payload": "",
"under_defect_review": false,
"impact": "",
"false_p": false,
"verified": false,
"severity": "",
"is_template": false,
"title": "",
"url": "",
"engagement": "related",
"duplicate": false,
"param": "",
"id": 0,
"sourcefilepath": "",
"mitigation": "",
"numerical_severity": "",
"test": "related",
"out_of_scope": false,
"cwe": 0,
"last_reviewed": "datetime",
"resource_uri": ""
}
Version 1.1.4:
In defectdojo.py there is on lines 37ff the following code:
if host.split('/') > 3:
self.custom_path ='/' + '/'.join(host.split('/')[3:]).rstrip('/')
else:
self.custom_path = ''
These leads to errors like:
"Couldn't match resource_uri //api/v1/engagements/7/ with /api/v1/engagements/",
when called. The two slashes seem a bit too much.
If I change the line 38 to:
self.custom_path ='/'.join(host.split('/')[3:]).rstrip('/')
it works.
regards
sirferl
Hi,
seems the create_finding is incomplete, or i miss something, like:
{"defect_review_requested_by":["This field is required."],"review_requested_by":["This field is required."],"url":["This field is required."],"reviewers":["This field is required."],"thread_id":["This field is required."],"test":["Incorrect type. Expected URL string, received int."],"numerical_severity":["This field may not be null."],"found_by":["This field is required."]}
Regards,
I am using [swagger-codegen] (https://github.com/swagger-api/swagger-codegen) to generate a better mirror of defectdojo API.
This way it is not needed to add manually new paths, actions, payload, etc It is needed just to run swagger-codegen using the latest version of swagger file provided by defectdojo in /api/v2/doc/?format=openapi
Here is my project running with this purpose https://github.com/William-Hill-Online/defectdojo-api-swagger
The upload_scan method does not specify a file name, leaving requests to use the generic value of 'file' in the multipart form upload. Recent changes to DefectDojo have made it so the Generic Findings Import no longer accepts a filename without a file extension. The requests sent via the v2 api fail with a 400 error.
`--dc1b35f1cdc7acb8055be35b6168dd63
Content-Disposition: form-data; name="file"; filename="file"
Date,Title,CweId,CVE,Url,Severity,Description,Mitigation,Impact,References,Active,Verified,FalsePositive,Duplicate,CVSSV3`
Hi i am getting following error while trying to upload snyk scan result:
i am getting the error both through api and UI , i am using laters Docker image
My target app is Owasp JuiceShop which is an node.js project
I have attached the snyk json file below:
Could someone guide me what is going wrong here.
I try to upload a file and receive a http-status 400 bad request. The API does not check for 400 and states a success. Check errorhandling starting at line 865.
Hello! I've installed a test instance of Defect Dojo and installed this client API using pip. Unfortunately, the example code provided in the README.rst does not seem to work as expected, and I'm not sure why. Here's what I'm seeing:
>>> from defectdojo_api import defectdojo
>>> host = 'http://localhost:8000/'
>>> api_key = '<removed key for posting issue on github>'
>>> user = 'admin'
>>> dd = defectdojo.DefectDojoAPI(host, api_key, user, debug=False)
>>> prod_type = 1
>>> product = dd.create_product("API Product Test", "This is a detailed product description.", prod_type)
>>> if product.success:
... product_id = product.id()
... print "Product successfully created with an id: " + str(product_id)
...
>>>
>>> if not product.success:
... print "Something failed."
...
Something failed.
>>>
The terminal window running the Defect Dojo server shows the following:
[21/Jul/2017 18:59:18] "POST //api/v1/products/ HTTP/1.1" 404 35510
Another set of eyes might see where I've made a mistake as compared to the example code, so please feel free to tell me if I'm being dumb here.
Maybe the double '/' is causing a problem? Unfortunately my python skills are not exactly advanced, so I'm having some trouble figuring out what I should do here.
Thanks for whatever help you can offer!
Hi,
There is a hard coding in the dojo_cd_ci.py example where the user is always "admin" and the user_id is taken in a wrong way. It would be great if we could find the user list based on the username that we pass in the arguments.
dd.list_users(user) on line 72
In the list_users() function under defectdojo_api, even though you pass username and limit, it is ignored.
The request sent as of now:
return self._request('GET', 'users/')
This can be the new request
return self._request('GET', 'users/', params)
Thanks!
Hi guys
I am Looking for a way to automatically import scan files
I have followed the quickstart on https://github.com/aaronweaver/defectdojo_api/tree/master/examples and I am using the dojo_ci_cd.py with scan files that are imported perfectly when using the GUI. It does not work. I have tried every advice on here, including using defectdojo_api==1.1.3
Am I using the wrong tool or method ? Is there a prerequisite that I don't know of ? Am I just stupid, or is the API broken ? Can someone help me with a basic setup to make this work ?
I have posted in a number of issues on here, but there seems to be no resolution or updates in a good while, in particular:
TypeError: string indices must be integers from #13
AttributeError: 'NoneType' object has no attribute 'success' from #14
Any feedback appreciated
Hi,
Can you help me to set the environment for the test from the CI/CD defect dojo api .
Thanks,
Kondal
Per our conversation in OWASP Slack, I am trying to import the sample scan file without our evaluation deployment of v.1.5.4rc6 as we slowly move up changes. Using the current master branch of the code in defectdojo_api, we encounter an uncaught exception and our Nessus imports do not work.
uwsgi_1 | Internal Server Error: /api/v2/import-scan/
uwsgi_1 | Traceback (most recent call last):
uwsgi_1 | File "/usr/local/lib/python3.5/site-packages/django/core/handlers/exception.py", line 34, in inner
uwsgi_1 | response = get_response(request)
uwsgi_1 | File "/usr/local/lib/python3.5/site-packages/django/core/handlers/base.py", line 115, in _get_response
uwsgi_1 | response = self.process_exception_by_middleware(e, request)
uwsgi_1 | File "/usr/local/lib/python3.5/site-packages/django/core/handlers/base.py", line 113, in _get_response
uwsgi_1 | response = wrapped_callback(request, *callback_args, **callback_kwargs)
uwsgi_1 | File "/usr/local/lib/python3.5/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
uwsgi_1 | return view_func(*args, **kwargs)
uwsgi_1 | File "/usr/local/lib/python3.5/site-packages/rest_framework/viewsets.py", line 114, in view
uwsgi_1 | return self.dispatch(request, *args, **kwargs)
uwsgi_1 | File "/usr/local/lib/python3.5/site-packages/rest_framework/views.py", line 505, in dispatch
uwsgi_1 | response = self.handle_exception(exc)
uwsgi_1 | File "/usr/local/lib/python3.5/site-packages/rest_framework/views.py", line 465, in handle_exception
uwsgi_1 | self.raise_uncaught_exception(exc)
uwsgi_1 | File "/usr/local/lib/python3.5/site-packages/rest_framework/views.py", line 476, in raise_uncaught_exception
uwsgi_1 | raise exc
uwsgi_1 | File "/usr/local/lib/python3.5/site-packages/rest_framework/views.py", line 502, in dispatch
uwsgi_1 | response = handler(request, *args, **kwargs)
uwsgi_1 | File "/usr/local/lib/python3.5/site-packages/rest_framework/mixins.py", line 19, in create
uwsgi_1 | self.perform_create(serializer)
uwsgi_1 | File "/usr/local/lib/python3.5/site-packages/rest_framework/mixins.py", line 24, in perform_create
uwsgi_1 | serializer.save()
uwsgi_1 | File "./dojo/api_v2/serializers.py", line 576, in save
uwsgi_1 | data['scan_type'],)
uwsgi_1 | File "./dojo/tools/factory.py", line 233, in import_parser_factory
uwsgi_1 | return parser
uwsgi_1 | UnboundLocalError: local variable 'parser' referenced before assignment
uwsgi_1 | Internal Server Error: /api/v2/import-scan/
uwsgi_1 | Traceback (most recent call last):
uwsgi_1 | File "/usr/local/lib/python3.5/site-packages/django/core/handlers/exception.py", line 34, in inner
uwsgi_1 | response = get_response(request)
uwsgi_1 | File "/usr/local/lib/python3.5/site-packages/django/core/handlers/base.py", line 115, in _get_response
uwsgi_1 | response = self.process_exception_by_middleware(e, request)
uwsgi_1 | File "/usr/local/lib/python3.5/site-packages/django/core/handlers/base.py", line 113, in _get_response
uwsgi_1 | response = wrapped_callback(request, *callback_args, **callback_kwargs)
uwsgi_1 | File "/usr/local/lib/python3.5/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
uwsgi_1 | return view_func(*args, **kwargs)
uwsgi_1 | File "/usr/local/lib/python3.5/site-packages/rest_framework/viewsets.py", line 114, in view
uwsgi_1 | return self.dispatch(request, *args, **kwargs)
uwsgi_1 | File "/usr/local/lib/python3.5/site-packages/rest_framework/views.py", line 505, in dispatch
uwsgi_1 | response = self.handle_exception(exc)
uwsgi_1 | File "/usr/local/lib/python3.5/site-packages/rest_framework/views.py", line 465, in handle_exception
uwsgi_1 | self.raise_uncaught_exception(exc)
uwsgi_1 | File "/usr/local/lib/python3.5/site-packages/rest_framework/views.py", line 476, in raise_uncaught_exception
uwsgi_1 | raise exc
uwsgi_1 | File "/usr/local/lib/python3.5/site-packages/rest_framework/views.py", line 502, in dispatch
uwsgi_1 | response = handler(request, *args, **kwargs)
uwsgi_1 | File "/usr/local/lib/python3.5/site-packages/rest_framework/mixins.py", line 19, in create
uwsgi_1 | self.perform_create(serializer)
uwsgi_1 | File "/usr/local/lib/python3.5/site-packages/rest_framework/mixins.py", line 24, in perform_create
uwsgi_1 | serializer.save()
uwsgi_1 | File "./dojo/api_v2/serializers.py", line 576, in save
uwsgi_1 | data['scan_type'],)
uwsgi_1 | File "./dojo/tools/factory.py", line 233, in import_parser_factory
uwsgi_1 | return parser
uwsgi_1 | UnboundLocalError: local variable 'parser' referenced before assignment
The UnboundLocalError
is caused by importing this .nessus file from the sample_scan_file collection for unit testing using the following script that imports said file with the defectdojo_api.
import importlib
import json
import logging
import os
#import boto3
from datetime import date, timedelta
from defectdojo_api.defectdojo_api import defectdojo_apiv2 as defectdojo
import json
REPORT_TYPE = 'Nessus Scan'
ACTIVE = True
VERIFIED = False
CLOSE_OLD_FINDINGS = True
SKIP_DUPLICATES = True
LOGGER = logging.getLogger()
LOGGER.setLevel(logging.INFO)
def dd_connection():
# setup DefectDojo connection information
dd_host = os.environ['dd_host']
api_token = os.environ['api_token']
user = os.environ['dd_user']
# instantiate the DefectDojo api wrapper
connection_obj = defectdojo.DefectDojoAPIv2(dd_host, api_token, user, debug=False, verify_ssl=False)
return connection_obj
dd = dd_connection()
d = date.today()
report_date = d.strftime("%Y-%m-%d")
test = dd.upload_scan(2, REPORT_TYPE, 'local/path/to/DefectDojo/sample-scan-files/nessus/nessus_v_unknown.nessus', ACTIVE, VERIFIED, CLOSE_OLD_FINDINGS, SKIP_DUPLICATES, report_date, tags="Lambda")
print(test.message)
# product_id = get_projects(dd)
# engagements = dd.list_engagements(product_id=product_id, limit=100)
By stepping through the debugger it appears that the DefectDojo API attempts to conditionally parse the file based on the extension of the filename provided. The relevant function in defectdojo_api uses the requests library and the function style used here will not pass in the filename in the Content-Disposition
header as explained here.
def upload_scan(self, engagement_id, scan_type, file, active, verified, close_old_findings, skip_duplicates, scan_date, tags=None, build=None, minimum_severity="Info"):
"""Uploads and processes a scan file.
:param application_id: Application identifier.
:param file_path: Path to the scan file to be uploaded.
"""
if tags is None:
tags = ''
if build is None:
build = ''
with open(file, 'rb') as f:
filedata = f.read()
if self.debug:
print("filedata:")
print(filedata)
data = {
'file': filedata,
'engagement': ('', engagement_id),
'scan_type': ('', scan_type),
'active': ('', active),
'verified': ('', verified),
'close_old_findings': ('', close_old_findings),
'skip_duplicates': ('', skip_duplicates),
'scan_date': ('', scan_date),
'tags': ('', tags),
'build_id': ('', build),
'minimum_severity': ('', minimum_severity)
}
"""
TODO: implement these parameters:
lead
test_type
scan_date
"""
return self._request(
'POST', 'import-scan/',
files=data
)
Changing the code to this style appears to resolve the issue, where we adapt the script about to pass in the data and filename into a tuple, and pass that into the upload_scan()
function, and that dd_api upload_scan()
function does not open the file and buffer itself. This way, the file data and name is passed.
def upload_scan(self, engagement_id, scan_type, filedata, active, verified, close_old_findings, skip_duplicates, scan_date, tags=None, build=None, minimum_severity="Info"):
"""Uploads and processes a scan file.
:param application_id: Application identifier.
:param file: Tuple with name and contents of (filename, open(filename, 'rb'))
"""
if tags is None:
tags = ''
if build is None:
build = ''
if self.debug:
print("filedata:")
print(filedata)
data = {
'file': filedata,
'engagement': ('', engagement_id),
'scan_type': ('', scan_type),
'active': ('', active),
'verified': ('', verified),
'close_old_findings': ('', close_old_findings),
'skip_duplicates': ('', skip_duplicates),
'scan_date': ('', scan_date),
'tags': ('', tags),
'build_id': ('', build),
'minimum_severity': ('', minimum_severity)
}
"""
TODO: implement these parameters:
lead
test_type
scan_date
"""
return self._request(
'POST', 'import-scan/',
files=data
)
import importlib
import json
import logging
import os
#import boto3
from datetime import date, timedelta
from defectdojo_api.defectdojo_api import defectdojo_apiv2 as defectdojo
import json
REPORT_TYPE = 'Nessus Scan'
ACTIVE = True
VERIFIED = False
CLOSE_OLD_FINDINGS = True
SKIP_DUPLICATES = True
LOGGER = logging.getLogger()
LOGGER.setLevel(logging.INFO)
def dd_connection():
# setup DefectDojo connection information
dd_host = os.environ['dd_host']
api_token = os.environ['api_token']
user = os.environ['dd_user']
# instantiate the DefectDojo api wrapper
connection_obj = defectdojo.DefectDojoAPIv2(dd_host, api_token, user, debug=False, verify_ssl=False)
return connection_obj
dd = dd_connection()
d = date.today()
report_date = d.strftime("%Y-%m-%d")
test = dd.upload_scan(2, REPORT_TYPE, ('nessus_v_unknown.nessus', open('local/path/to/DefectDojo/sample-scan-files/nessus/nessus_v_unknown.nessus', 'rb')), ACTIVE, VERIFIED, CLOSE_OLD_FINDINGS, SKIP_DUPLICATES, report_date, tags="Lambda")
print(test.message)
# product_id = get_projects(dd)
# engagements = dd.list_engagements(product_id=product_id, limit=100)
If amenable to this approach, I will draft a PR to fix this issue.
Hello,
The version installed through Pip (here: https://pypi.org/project/defectdojo_api/) includes the reverted "Add support for custom DefectDojo URL prefix" commit, it appears that v1.1.4 on there doesn't match the version 1.1.4 here - is there any chance it could be republished with those changes?
Thanks
Our instance of DefectDojo is installed at https://domain.com/dojo , such that the API is found at https://domain.com/dojo/api/v1/
It appears that the /dojo root path is not observed by the helper functions in defectdojo.py.
For example:
In defectdojo.py,
create_enagement() calls get_user_uri(), which returns /api/v1/users/$user_id
In my case, this user URI should be /dojo/api/v1/users/$user_id
The error that DefectDojo returns when creating an engagement is below. I'll submit a PR shortly with a proposed fix.
{"error_message": "Couldn't match resource_uri /api/v1/users/19/ with /dojo/api/v1/users/", "traceback": "Traceback (most recent call last):\n\n File \"/usr/local/lib/python2.7/dist-packages/tastypie/resources.py\", line 219, in wrapper\n response = callback(request, *args, **kwargs)\n\n File \"/usr/local/lib/python2.7/dist-packages/tastypie/resources.py\", line 450, in dispatch_list\n return self.dispatch('list', request, **kwargs)\n\n File \"/usr/local/lib/python2.7/dist-packages/tastypie/resources.py\", line 482, in dispatch\n response = method(request, **kwargs)\n\n File \"/usr/local/lib/python2.7/dist-packages/tastypie/resources.py\", line 1384, in post_list\n updated_bundle = self.obj_create(bundle, **self.remove_api_resource_names(kwargs))\n\n File \"/usr/local/lib/python2.7/dist-packages/tastypie/resources.py\", line 2175, in obj_create\n return self.save(bundle)\n\n File \"/usr/local/lib/python2.7/dist-packages/tastypie/resources.py\", line 2310, in save\n self.is_valid(bundle)\n\n File \"/usr/local/lib/python2.7/dist-packages/tastypie/resources.py\", line 1296, in is_valid\n errors = self._meta.validation.is_valid(bundle, bundle.request)\n\n File \"/usr/local/lib/python2.7/dist-packages/tastypie/validation.py\", line 73, in is_valid\n form = self.form_class(**self.form_args(bundle))\n\n File \"./dojo/api.py\", line 79, in form_args\n pk = self._get_pk_from_resource_uri(rel_field, resource_uri)\n\n File \"./dojo/api.py\", line 64, in _get_pk_from_resource_uri\n resource_uri, base_resource_uri))\n\nException: Couldn't match resource_uri /api/v1/users/19/ with /dojo/api/v1/users/\n"}
Hi,
I get the following error trying to create an engagement over the API.
Traceback (most recent call last):
File "/home/xxx/PycharmProjects/blub/upload.py", line 54, in
upload_scanreport(1, "opt/zap/xxx.xml", "ZAP Scan")
File "/home/xxx/PycharmProjects/blub/upload.py", line 34, in upload_scanreport
engagement_id = engagement.id()
File "/usr/local/lib/python2.7/dist-packages/defectdojo_api/defectdojo.py", line 744, in id
raise ValueError('Object not created:' + json.dumps(self.data, sort_keys=True, indent=4, separators=(',', ': ')))
ValueError: Object not created:{
"error": "[u"'true' value must be either True or False."]"
It looks like the API is using strings for booleans objects ('true') and that defect dojo changed the REST service to use actual booleans. -> true instead of 'true'.
Can you fix that?
Regards,
Horst
Hello,
I am trying to use the defectdojo_api file provided with this package instead of the default installation in the library package.
I tried appending the os.path of the defectdojo module in init.py inside examples folder.
I tried to manually add the path in the dojo_ci_cd.py file itself.
Basically I have tried these things: https://stackoverflow.com/questions/14132789/relative-imports-for-the-billionth-time
None of the methods are working. It is still picking the default installation of defectdojo.
Hi,
in main api file: https://github.com/aaronweaver/defectdojo_api/blob/master/defectdojo_api/defectdojo.py
The method list_findings allows the mitigated field with boolean format, but if you use True or False, the response fails. This issue is due to to that mitigated field only allow Datetime format (Response ex: {"error": "[u"'1' value has an invalid format. It must be in YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] format."]"}). In consequence is not possible to get all mitigated findings with this api request.
Regards,
The documentation below the definition says product_in
but the definition says product_id
Just a typo in the doc?
def list_engagements(self, status=None, product_id=None, name_contains=None,limit=20):
"""Retrieves all the engagements.
:param product_in: List of product ids (1,2).
:param name_contains: Engagement name
:param limit: Number of records to return.
"""
Hi,
so turning on debug I get this message, can you add the missing field to the error?
Loading scanner results from scanner export
POST importscan/
{}
400
{"error": "[u'This field cannot be blank.']"}
the pypi published version for deefectdojo_api is 1.1.4 and not the latest (1.1.5 as of writing).
DefectDojo fails to authenticate while parsing host address
Python 3.6.6
defectdojo-api-1.1.4
from defectdojo_api import defectdojo
api = defectdojo.DefectDojoAPI('https://localhost:8000', '123', 'admin', debug=False)
File "/usr/local/lib/python3.6/dist-packages/defectdojo_api/defectdojo.py", line 37, in init
if host.split('/') > 3:
TypeError: '>' not supported between instances of 'list' and 'int'
Change to
len(host.split('/')) > 3:
There are different check that intend to validate whether a parameter needs to be added to the request or not. However for boolean parameters the condition should check whether the value is None or not. Otherwise it is not possible to specify False values, as they will not be added to the request. Below is an example:
I am trying to run the dojo_ci_cd.py file in my local environment and it is prompting with the below error. Please could you check? ( or probably it could be a defectdojo bug)
Defectdojo=lastest master
Defectdojo_api 1.1.4
Command & Output:
python dojo_ci_cd.py --product=1 --file "~/Dev/misc/defectdojo_api/tests/scans/Bodgeit-burp.xml" --scanner="Burp Scan" --high=0 --host=http://192.168.13.37:8000 —api_key=xxxx --user=admin
Traceback (most recent call last):
File "dojo_ci_cd.py", line 241, in <module>
class Main:
File "dojo_ci_cd.py", line 282, in Main
test_ids = processFiles(dd, engagement_id, file, scanner=scanner)
File "dojo_ci_cd.py", line 144, in processFiles
if test_id.success == False:
AttributeError: 'NoneType' object has no attribute 'success'
Output of defectdojo logs:
[11/Jul/2018 05:29:06] "GET /api/v1/users/?username=admin&limit=20 HTTP/1.1" 200 246
Internal Server Error: /api/v1/engagements/
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/tastypie/resources.py", line 227, in wrapper
response = callback(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/tastypie/resources.py", line 467, in dispatch_list
return self.dispatch('list', request, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/tastypie/resources.py", line 499, in dispatch
response = method(request, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/tastypie/resources.py", line 1408, in post_list
updated_bundle = self.obj_create(bundle, **self.remove_api_resource_names(kwargs))
File "/usr/local/lib/python2.7/dist-packages/tastypie/resources.py", line 2245, in obj_create
return self.save(bundle)
File "/usr/local/lib/python2.7/dist-packages/tastypie/resources.py", line 2380, in save
self.is_valid(bundle)
File "/usr/local/lib/python2.7/dist-packages/tastypie/resources.py", line 1320, in is_valid
errors = self._meta.validation.is_valid(bundle, bundle.request)
File "/usr/local/lib/python2.7/dist-packages/tastypie/validation.py", line 73, in is_valid
form = self.form_class(**self.form_args(bundle))
File "/vagrant/dojo/api.py", line 85, in form_args
pk = self._get_pk_from_resource_uri(rel_field, resource_uri)
File "/vagrant/dojo/api.py", line 70, in _get_pk_from_resource_uri
resource_uri, base_resource_uri))
Exception: Couldn't match resource_uri //api/v1/users/1/ with /api/v1/users/
Internal Server Error: /api/v1/engagements/
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/tastypie/resources.py", line 227, in wrapper
response = callback(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/tastypie/resources.py", line 467, in dispatch_list
return self.dispatch('list', request, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/tastypie/resources.py", line 499, in dispatch
response = method(request, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/tastypie/resources.py", line 1408, in post_list
updated_bundle = self.obj_create(bundle, **self.remove_api_resource_names(kwargs))
File "/usr/local/lib/python2.7/dist-packages/tastypie/resources.py", line 2245, in obj_create
return self.save(bundle)
File "/usr/local/lib/python2.7/dist-packages/tastypie/resources.py", line 2380, in save
self.is_valid(bundle)
File "/usr/local/lib/python2.7/dist-packages/tastypie/resources.py", line 1320, in is_valid
errors = self._meta.validation.is_valid(bundle, bundle.request)
File "/usr/local/lib/python2.7/dist-packages/tastypie/validation.py", line 73, in is_valid
form = self.form_class(**self.form_args(bundle))
File "/vagrant/dojo/api.py", line 85, in form_args
pk = self._get_pk_from_resource_uri(rel_field, resource_uri)
File "/vagrant/dojo/api.py", line 70, in _get_pk_from_resource_uri
resource_uri, base_resource_uri))
Exception: Couldn't match resource_uri //api/v1/users/1/ with /api/v1/users/
list_findings method accepts filters in fields severity_contains
and title_contains and adds them to query as severity__contains
and title__contains.
However, the related ApiFindingFilter entries do not have
__contains postfixes:
https://github.com/DefectDojo/django-DefectDojo/blob/master/dojo/filters.py#L1020
https://github.com/DefectDojo/django-DefectDojo/blob/master/dojo/filters.py#L1026
When trying to create a new angagement via API I have encountered issue described below.
URL used: /api/v1/doc/#!/engagements/engagements_list_0
JSON used:
{
"status": "Not Started",
"build_id": "",
"updated": "",
"source_code_management_uri": "",
"description": "",
"product": "/api/v1/products/4/",
"pen_test": false,
"reason": "",
"branch_tag": "",
"commit_hash": "",
"risk_path": "",
"orchestration_engine": "",
"first_contacted": "",
"active": false,
"done_testing": false,
"deduplication_on_engagement": false,
"target_end": "2019-07-07",
"tmodel_path": "",
"build_server": "",
"source_code_management_server": "",
"name": "",
"lead": "",
"created": "",
"check_list": false,
"target_start": "2019-06-06",
"version": "",
"tracker": "",
"api_test": false,
"progress": "",
"threat_model": false,
"engagement_type": "",
"test_strategy": ""
}
{"error": "Could not find the provided tool_configurations object via resource URI ''."}
There is no such key as tool_configurations
in the engagements Model Schema.
Here is the output after calling tool_configurations endpoint:
/api/v1/tool_configurations/
{"meta": {"limit": 20, "next": null, "offset": 0, "previous": null, "total_count": 0}, "objects": []}
200
{
"date": "Fri, 07 Jun 2019 15:59:37 GMT",
"vary": "Accept, Cookie",
"server": "nginx/1.15.11",
"x-frame-options": "SAMEORIGIN",
"content-type": "application/json",
"cache-control": "no-cache",
"connection": "keep-alive",
"content-length": "101"
}
Hi,
I got this running example, after adding () to print() in dojo_populate.py, i got this one.
» ❯ python3 dojo_populate.py
Traceback (most recent call last):
File "dojo_populate.py", line 27, in <module>
dd = defectdojo.DefectDojoAPI(host, api_key, user, debug=False)
File "/home/cyril/trydefectdojoapi/venv/lib/python3.7/site-packages/defectdojo_api/defectdojo.py", line 37, in __init__
if host.split('/') > 3:
TypeError: '>' not supported between instances of 'list' and 'int'
Thanks for help
Trying to upload the arachni scan results into local setup of defectdojo and facing the below type error. Any idea how to resolve?
pip status:
defectdojo_api 1.1.4
Command:
python defectdojo_api/examples/dojo_ci_cd.py --product 1 --file "defectdojo_api/examples/sample-scan-files/arachni/arachni.afr.json" --scanner=“Arachni Scan" --host="http://192.168.9.9/" --api_key="xxx" --user=“admin"
Output:
Traceback (most recent call last):
File "dojo_ci_cd.py", line 241, in <module>
class Main:
File "dojo_ci_cd.py", line 290, in Main
summary(dd, engagement_id, test_ids, max_critical, max_high, max_medium)
File "dojo_ci_cd.py", line 166, in summary
print "Total Number of Vulnerabilities: " + str(findings.data["meta"]["total_count"])
TypeError: string indices must be integers
I tried running this example defectdojo_api/examples/v2/dojo_ci_cd.py and it says cannot load module ImportError: No module named defectdojo_apiv2. Please guide me for this issues. Many Thanks!
Importing a scan report via defectdojo_apiv2.upload_scan(...)
without specifying a tags
results in a 400 Bad Request response from the server.
Error message:
ERROR:Error occured in API.
DEBUG:{"tags":["This field may not be blank."],"message":"{'tags': [ErrorDetail(string='This field may not be blank.', code='blank')]}"}
Server logs:
nginx_1 | 172.21.0.1 - - [29/Nov/2021:11:06:13 +0000] "POST //api/v2/import-scan/ HTTP/1.1" 400 130 "-" "DefectDojo_api/1.1.6.dev2" "-"
uwsgi_1 | [29/Nov/2021 11:06:13] WARNING [django.request:224] Bad Request: /api/v2/import-scan/
uwsgi_1 | WARNING:django.request:Bad Request: /api/v2/import-scan/
nginx_1 | 172.21.0.1 - - [29/Nov/2021:11:06:13 +0000] "POST //api/v2/import-scan/ HTTP/1.1" 400 130 "-" "DefectDojo_api/1.1.6.dev2" "-"
uwsgi_1 | [pid: 1|app: 0|req: 2443/6841] 172.21.0.1 () {42 vars in 700 bytes} [Mon Nov 29 11:06:13 2021] POST //api/v2/import-scan/ => generated 130 bytes in 8 msecs (HTTP/1.1 400) 7 headers in 203 bytes (1 switches on core 0)
Environment:
django-DefectDojo v. 2.4.1 via docker-compose.
Version 1.1.4.
In defectdojo.py the function "set_finding" is missing the parameter "build".
This leads to error:
File "/home/dojomgr/.local/lib/python2.7/site-packages/defectdojo_api/defectdojo.py", line 706, in set_finding
if build:
NameError: global name 'build' is not defined
I added "build=None" to the definition of set_finding and then it works.
regards
sirferl
Path: defectdojo_api/defectdojo_apiv2.py
Lines: 399 and 416
There are 2 create_product methods that are exact duplicates of each-other
Some finding fields seem to change no matter what I specify. When I send my request, Defect Dojo server sends me response with data that actually gets uploaded, here are some changes/issues I've spotted at first glance:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.