Skip to content

Commit a35603c

Browse files
authored
Merge pull request #3264 from DefectDojo/release/1.9.3
Release: Merge release into master from: release/1.9.3
2 parents d7523e1 + a1d4890 commit a35603c

File tree

9 files changed

+89
-9
lines changed

9 files changed

+89
-9
lines changed

components/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "DefectDojo",
3-
"version": "1.9.2",
3+
"version": "1.9.3",
44
"dependencies": {
55
"JUMFlot": "jumjum123/JUMFlot#*",
66
"bootstrap": "^3.4.0",

dojo/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@
66

77
default_app_config = 'dojo.apps.DojoAppConfig'
88

9-
__version__ = '1.9.2'
9+
__version__ = '1.9.3'
1010
__url__ = 'https://github.com/DefectDojo/django-DefectDojo'
1111
__docs__ = 'http://defectdojo.readthedocs.io/'

dojo/api.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ def get_fields(cls, fields=None, excludes=None):
111111
res_field = fields.get(django_field.name, None)
112112
if res_field:
113113
res_field.blank = True
114+
114115
return fields
115116

116117

@@ -493,6 +494,7 @@ class Meta:
493494
}
494495
authentication = DojoApiKeyAuthentication()
495496
authorization = DjangoAuthorization()
497+
excludes = ['password', 'ssh', 'api_key']
496498
serializer = Serializer(formats=['json'])
497499

498500
@property
@@ -851,6 +853,7 @@ class Meta:
851853
}
852854
authentication = DojoApiKeyAuthentication()
853855
authorization = DjangoAuthorization()
856+
excludes = ['password']
854857
serializer = Serializer(formats=['json'])
855858

856859
@property

dojo/api_v2/serializers.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,11 @@ class ToolConfigurationSerializer(serializers.ModelSerializer):
401401
class Meta:
402402
model = Tool_Configuration
403403
fields = '__all__'
404+
extra_kwargs = {
405+
'password': {'write_only': True},
406+
'ssh': {'write_only': True},
407+
'api_key': {'write_only': True},
408+
}
404409

405410

406411
class ToolProductSettingsSerializer(serializers.ModelSerializer):
@@ -531,6 +536,9 @@ class JIRAConfSerializer(serializers.ModelSerializer):
531536
class Meta:
532537
model = JIRA_Conf
533538
fields = '__all__'
539+
extra_kwargs = {
540+
'password': {'write_only': True},
541+
}
534542

535543

536544
class JIRASerializer(serializers.ModelSerializer):

dojo/models.py

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,40 @@ def __str__(self):
918918
return self.name
919919

920920

921+
# declare form here as we can't import forms.py due to circular imports not even locally
922+
class ToolConfigForm_Admin(forms.ModelForm):
923+
password = forms.CharField(widget=forms.PasswordInput, required=False)
924+
api_key = forms.CharField(widget=forms.PasswordInput, required=False)
925+
ssh = forms.CharField(widget=forms.PasswordInput, required=False)
926+
927+
# django doesn't seem to have an easy way to handle password fields as PasswordInput requires reentry of passwords
928+
password_from_db = None
929+
ssh_from_db = None
930+
api_key_from_db = None
931+
932+
def __init__(self, *args, **kwargs):
933+
super().__init__(*args, **kwargs)
934+
if self.instance:
935+
# keep password from db to use if the user entered no password
936+
self.password_from_db = self.instance.password
937+
self.ssh_from_db = self.instance.ssh
938+
self.api_key = self.instance.api_key
939+
940+
def clean(self):
941+
# self.fields['endpoints'].queryset = Endpoint.objects.all()
942+
cleaned_data = super().clean()
943+
if not cleaned_data['password'] and not cleaned_data['ssh'] and not cleaned_data['api_key']:
944+
cleaned_data['password'] = self.password_from_db
945+
cleaned_data['ssh'] = self.ssh_from_db
946+
cleaned_data['api_key'] = self.api_key_from_db
947+
948+
return cleaned_data
949+
950+
951+
class Tool_Configuration_Admin(admin.ModelAdmin):
952+
form = ToolConfigForm_Admin
953+
954+
921955
class Network_Locations(models.Model):
922956
location = models.CharField(max_length=500, help_text="Location of network testing: Examples: VPN, Internet or Internal.")
923957

@@ -2634,6 +2668,33 @@ def get_priority(self, status):
26342668
return 'N/A'
26352669

26362670

2671+
# declare form here as we can't import forms.py due to circular imports not even locally
2672+
class JIRAForm_Admin(forms.ModelForm):
2673+
password = forms.CharField(widget=forms.PasswordInput, required=True)
2674+
2675+
# django doesn't seem to have an easy way to handle password fields as PasswordInput requires reentry of passwords
2676+
password_from_db = None
2677+
2678+
def __init__(self, *args, **kwargs):
2679+
super().__init__(*args, **kwargs)
2680+
if self.instance:
2681+
# keep password from db to use if the user entered no password
2682+
self.password_from_db = self.instance.password
2683+
self.fields['password'].required = False
2684+
2685+
def clean(self):
2686+
# self.fields['endpoints'].queryset = Endpoint.objects.all()
2687+
cleaned_data = super().clean()
2688+
if not cleaned_data['password']:
2689+
cleaned_data['password'] = self.password_from_db
2690+
2691+
return cleaned_data
2692+
2693+
2694+
class JIRA_Conf_Admin(admin.ModelAdmin):
2695+
form = JIRAForm_Admin
2696+
2697+
26372698
class JIRA_Issue(models.Model):
26382699
jira_id = models.CharField(max_length=200)
26392700
jira_key = models.CharField(max_length=200)
@@ -3481,11 +3542,11 @@ def enable_disable_auditlog(enable=True):
34813542
admin.site.register(IPScan)
34823543
admin.site.register(Alerts)
34833544
admin.site.register(JIRA_Issue)
3484-
admin.site.register(JIRA_Conf)
3545+
admin.site.register(JIRA_Conf, JIRA_Conf_Admin)
34853546
admin.site.register(JIRA_PKey)
34863547
admin.site.register(GITHUB_Conf)
34873548
admin.site.register(GITHUB_PKey)
3488-
admin.site.register(Tool_Configuration)
3549+
admin.site.register(Tool_Configuration, Tool_Configuration_Admin)
34893550
admin.site.register(Tool_Product_Settings)
34903551
admin.site.register(Tool_Type)
34913552
admin.site.register(Cred_User)

dojo/reports/views.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from django.http import HttpResponse
1515
from django.shortcuts import render, get_object_or_404
1616
from django.utils import timezone
17+
from django.db.models import Q
1718

1819
from dojo.celery import app
1920
from dojo.endpoint.views import get_endpoint_ids

dojo/unittests/test_rest_framework.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010
ScansViewSet, StubFindingsViewSet, TestsViewSet, \
1111
ToolConfigurationsViewSet, ToolProductSettingsViewSet, ToolTypesViewSet, \
1212
UsersViewSet, ImportScanView, NoteTypeViewSet, AppAnalysisViewSet, \
13-
EndpointStatusViewSet, SonarqubeIssueViewSet, SonarqubeIssueTransitionViewSet, \
14-
SonarqubeProductViewSet, NotesViewSet
13+
EndpointStatusViewSet, SonarqubeIssueViewSet, NotesViewSet
1514
from json import dumps
1615
from django.urls import reverse
1716
from rest_framework.authtoken.models import Token
@@ -74,6 +73,11 @@ def test_detail(self):
7473
relative_url = self.url + '%s/' % current_objects['results'][0]['id']
7574
response = self.client.get(relative_url)
7675
self.assertEqual(200, response.status_code)
76+
# sensitive data must be set to write_only so those are not returned in the response
77+
# https://github.com/DefectDojo/django-DefectDojo/security/advisories/GHSA-8q8j-7wc4-vjg5
78+
self.assertFalse('password' in response.data)
79+
self.assertFalse('ssh' in response.data)
80+
self.assertFalse('api_key' in response.data)
7781

7882
@skipIfNotSubclass('DestroyModelMixin')
7983
def test_delete(self):
@@ -90,9 +94,12 @@ def test_update(self):
9094
relative_url, self.update_fields)
9195
for key, value in self.update_fields.items():
9296
# some exception as push_to_jira has been implemented strangely in the update methods in the api
93-
if key != 'push_to_jira':
97+
if key not in ['push_to_jira', 'ssh', 'password', 'api_key']:
9498
self.assertEqual(value, response.data[key])
9599
self.assertFalse('push_to_jira' in response.data)
100+
self.assertFalse('ssh' in response.data)
101+
self.assertFalse('password' in response.data)
102+
self.assertFalse('api_key' in response.data)
96103
response = self.client.put(
97104
relative_url, self.payload)
98105
self.assertEqual(200, response.status_code)

helm/defectdojo/Chart.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
apiVersion: v1
2-
appVersion: "1.9.2"
2+
appVersion: "1.9.3"
33
description: A Helm chart for Kubernetes to installs DefectDojo
44
name: defectdojo
55
version: 1.4.0

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
setup(
66
name='DefectDojo',
7-
version='1.9.2',
7+
version='1.9.3',
88
author='Greg Anderson',
99
description="Tool for managing vulnerability engagements",
1010
install_requires=[

0 commit comments

Comments
 (0)