Skip to content

Commit

Permalink
updating problem_id, filter problem and setting problem variable
Browse files Browse the repository at this point in the history
  • Loading branch information
LeoOMaia authored Dec 23, 2024
1 parent f833581 commit 710f21e
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 33 deletions.
4 changes: 2 additions & 2 deletions dojo/db_migrations/0219_problem_finding_problem.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by Django 5.0.8 on 2024-12-22 19:33
# Generated by Django 5.0.8 on 2024-12-23 22:35

import django.db.models.deletion
from django.db import migrations, models
Expand All @@ -16,7 +16,7 @@ class Migration(migrations.Migration):
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(help_text='A short name or title for the problem.', max_length=255, verbose_name='Name')),
('problem_id', models.TextField(help_text='Problem identifier. This field is used to uniquely identify the problem.', verbose_name='Problem ID')),
('problem_id', models.CharField(help_text='Problem identifier. This field is used to uniquely identify the problem.', max_length=255, unique=True, verbose_name='Problem ID')),
('created_at', models.DateTimeField(auto_now_add=True, help_text='Timestamp when this problem was created.', verbose_name='Created At')),
('updated_at', models.DateTimeField(auto_now=True, help_text='Timestamp when this problem was last updated.', verbose_name='Updated At')),
('severity', models.CharField(choices=[('Critical', 'Critical'), ('High', 'High'), ('Medium', 'Medium'), ('Low', 'Low'), ('Info', 'Info')], help_text='The severity level of this problem.', max_length=50, verbose_name='Severity')),
Expand Down
9 changes: 6 additions & 3 deletions dojo/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2261,9 +2261,12 @@ class Problem(models.Model):
name = models.CharField(max_length=255,
verbose_name=_("Name"),
help_text=_("A short name or title for the problem."))
problem_id = models.TextField(
verbose_name=_("Problem ID"),
help_text=_("Problem identifier. This field is used to uniquely identify the problem."))
problem_id = models.CharField(max_length=255,
unique=True,
null=True,
blank=True,
verbose_name=_("Problem ID"),
help_text=_("Problem identifier. This field is used to uniquely identify the problem."))
created_at = models.DateTimeField(auto_now_add=True,
verbose_name=_("Created At"),
help_text=_("Timestamp when this problem was created."))
Expand Down
41 changes: 25 additions & 16 deletions dojo/problem/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,20 @@ def download_json(json_url):
return response.json()

def load_cached_json():
try:
if os.path.exists(CACHED_JSON_FILE):
if os.path.exists(CACHED_JSON_FILE):
try:
with open(CACHED_JSON_FILE, 'r') as f:
data = json.load(f)
if validate_json(data):
return data
except (ValueError, json.JSONDecodeError):
pass
else:
logger.warning('Cached JSON failed validation.')
except json.JSONDecodeError:
logger.error('Error decoding JSON from cache.')
except Exception as e:
logger.error(f'Unexpected error loading JSON from cache: {e}')
else:
logger.info('Cached JSON file does not exist.')
return None

def save_json_to_cache(data):
Expand All @@ -59,22 +65,26 @@ def mapping_script_problem_id(mappings_json_findings):
}
return script_to_problem_mapping

def load_json(check_cash=True):
def load_json(check_cache=True):
try:
if check_cash:
if check_cache:
cached_data = load_cached_json()
if cached_data and validate_json(cached_data):
return mapping_script_problem_id(cached_data)

data = download_json(settings.PROBLEM_MAPPINGS_JSON_URL)
if validate_json(data):
save_json_to_cache(data)
return mapping_script_problem_id(data)

except (requests.RequestException, ValueError, json.JSONDecodeError) as e:
logger.error('Error loading disambiguator JSON: %s', e)
pass

if settings.PROBLEM_MAPPINGS_JSON_URL:
data = download_json(settings.PROBLEM_MAPPINGS_JSON_URL)
if validate_json(data):
save_json_to_cache(data)
return mapping_script_problem_id(data)
else:
logger.error('No disambiguator JSON URL provided.')
except requests.RequestException as e:
logger.error('HTTP error while loading JSON: %s', e)
except json.JSONDecodeError as e:
logger.error('JSON decoding error: %s', e)
except Exception as e:
logger.error('Unexpected error: %s', e)
return {}

def find_or_create_problem(finding, script_to_problem_mapping):
Expand Down Expand Up @@ -108,7 +118,6 @@ def _get_or_create_problem_by_script_id(finding):

return Problem.objects.create(
name=finding.title,
problem_id=finding.description,
severity=finding.severity
)

Expand Down
2 changes: 1 addition & 1 deletion dojo/problem/update_mappings.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@
@app.task
def daily_cache_update(**kwargs):
logger.info("Starting daily cache update")
load_json(check_cash=False)
load_json(check_cache=False)
12 changes: 4 additions & 8 deletions dojo/settings/settings.dist.py
Original file line number Diff line number Diff line change
Expand Up @@ -1748,14 +1748,10 @@ def saml2_attrib_map_format(dict):
# see https://github.com/laymonage/django-jsonfield-backport
SILENCED_SYSTEM_CHECKS = ["django_jsonfield_backport.W001"]

# Problem utilizes mappings from a JSON file to disambiguate Findings.
# The JSON file should have the following structure:
# {
# "problem_id_1": ["script_id_1", "script_id_2", "script_id_3"],
# "problem_id_2": ["script_id_4", "script_id_5"],
# "problem_id_3": ["script_id_6"]
# }
PROBLEM_MAPPINGS_JSON_URL = "https://homepages.dcc.ufmg.br/~leonardooliveira/disambiguator.json"
# By default, this mapping is not configured (set to None). If configured, it allows
# the "Problems" button to appear in Dojo's left toolbar.
# You can check more information in https://homepages.dcc.ufmg.br/~leonardooliveira/defectdojo/README.md
PROBLEM_MAPPINGS_JSON_URL = None

VULNERABILITY_URLS = {
"CVE": "https://nvd.nist.gov/vuln/detail/",
Expand Down
5 changes: 5 additions & 0 deletions dojo/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
{% load authorization_tags %}
{% load i18n %}
{% load static %}
{% load problem_tags %}
<!DOCTYPE html>
<html lang="en">
<head>
Expand Down Expand Up @@ -325,6 +326,7 @@
</ul>
<!-- /.nav-second-level -->
</li>
{% if None|check_problem_habilit %}
<li>
<a href="{% url 'open_problems' %}" aria-expanded="false" aria-label="Problems">
<i class="fa-solid fa-triangle-exclamation fa-fw"></i>
Expand All @@ -350,6 +352,7 @@
</ul>
<!-- /.nav-second-level -->
</li>
{% endif %}
<li>
<a href="{% url 'components' %}" id="product_component_view" aria-expanded="false" aria-label="Components">
<i class="fa-solid fa-table-cells-large fa-fw"></i>
Expand Down Expand Up @@ -796,6 +799,7 @@ <h3 class="no-margin-top" style="padding-bottom: 5px;">
{% endif %}
</ul>
</li>
{% if None|check_problem_habilit %}
<!-- Problems Tab -->
<li role="presentation" class="dropdown{% if product_tab.title == 'Problems' %} active active-color{% endif %}">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
Expand Down Expand Up @@ -826,6 +830,7 @@ <h3 class="no-margin-top" style="padding-bottom: 5px;">
</li>
</ul>
</li>
{% endif %}
<!-- Endpoints Tab -->
<li role="presentation" class="dropdown{% if product_tab.tab == 'endpoints' %} active active-color{% endif %}">
<a class="dropdown-toggle" data-toggle="dropdown" href="">
Expand Down
4 changes: 2 additions & 2 deletions dojo/templates/dojo/problems_list_snippet.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
{% load get_endpoint_status %}
{% load static %}
{% load i18n %}
{% load get_different_total_script_id %}
{% load problem_tags %}
{% block problems_list %}
<div class="row">
<div class="col-md-12">
Expand Down Expand Up @@ -59,7 +59,7 @@ <h3 class="has-filters">
</span>
</td>
<td>{{ problem.findings.count }}</td>
<td>{{ problem.findings.all|count_unique_vulns }}</td>
<td>{{ problem.findings.all|count_distinct_script_ids }}</td>
<td data-order="{{ problem.created_at|date:"Y-m-d H:i:s" }}">
{{ problem.created_at|date:"b. d, Y, H:i" }}
</td>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
from dojo.models import Finding

from django import template
from django.conf import settings

register = template.Library()

@register.filter
def count_unique_vulns(findings):
def count_distinct_script_ids(findings):
return len(set(finding.vuln_id_from_tool for finding in findings))

@register.filter
def check_problem_habilit(value):
return settings.PROBLEM_MAPPINGS_JSON_URL

0 comments on commit 710f21e

Please sign in to comment.