Skip to content

Commit bf5b515

Browse files
committed
update
2 parents c6e1403 + 9e42abc commit bf5b515

File tree

9 files changed

+496
-94
lines changed

9 files changed

+496
-94
lines changed

docs/content/en/open_source/upgrading/2.51.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ Sometimes it's easier to just perform the upgrade manually, which would look som
6868
It may need some tuning to your specific needs and docker compose setup. The guide is loosely based on https://simplebackups.com/blog/docker-postgres-backup-restore-guide-with-examples.
6969
If you already have a valid backup of the postgres 16 database, you can start at step 4.
7070

71+
_Note: If you are using a bound volume, the path has changed for Postgres18. It is now `/var/lib/postgresql/` instead of `/var/lib/postgresql/data`. Failure to change the path may result in errors about failure to create a shim task. See the discussion in [docker-library/postgres](https://github.com/docker-library/postgres/issues/1370)._
72+
7173
### 0. Backup
7274

7375
Always back up your data before starting and save it somewhere.

docs/content/en/working_with_findings/finding_deduplication/deduplication_algorithms.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,9 @@ Endpoints can influence deduplication in different ways depending on the algorit
3636
- Set it to a list of endpoint attributes (e.g. `["host", "port"]`). If at least one endpoint pair between the two findings matches on all listed attributes, deduplication can occur.
3737

3838
### Unique ID From Tool or Hash Code
39+
A finding is a duplicate with another if they have the same unique_id_from_tool OR the same hash_code.
3940

40-
- Intended flow:
41-
1) Try to deduplicate using the tool’s unique ID (endpoints ignored on this path).
42-
2) If no match by unique ID, fall back to the Hash Code path.
43-
- When falling back to hash code, endpoint behavior is identical to the Hash Code algorithm.
41+
The endpoints also have to match for the findings to be considered duplicates, see the Hash Code algorithm above.
4442

4543
### Legacy (OS only)
4644

dojo/authorization/authorization.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
Product_Type,
2424
Product_Type_Group,
2525
Product_Type_Member,
26+
Risk_Acceptance,
2627
Stub_Finding,
2728
Test,
2829
)
@@ -95,6 +96,9 @@ def user_has_permission(user, obj, permission):
9596
if (
9697
isinstance(obj, Test)
9798
and permission in Permissions.get_test_permissions()
99+
) or (
100+
isinstance(obj, Risk_Acceptance)
101+
and permission == Permissions.Risk_Acceptance
98102
):
99103
return user_has_permission(user, obj.engagement.product, permission)
100104
if ((

dojo/fixtures/dojo_testdata.json

Lines changed: 320 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3071,5 +3071,325 @@
30713071
"note": null,
30723072
"owner": 6
30733073
}
3074+
},
3075+
{
3076+
"model": "dojo.test_type",
3077+
"pk": 1000,
3078+
"fields": {
3079+
"name": "SonarQube Scan detailed",
3080+
"static_tool": false,
3081+
"dynamic_tool": false,
3082+
"active": true,
3083+
"dynamically_generated": false
3084+
}
3085+
},
3086+
{
3087+
"model": "dojo.test",
3088+
"pk": 90,
3089+
"fields": {
3090+
"engagement": 5,
3091+
"lead": [
3092+
"admin"
3093+
],
3094+
"test_type": 1000,
3095+
"scan_type": "SonarQube Scan detailed",
3096+
"title": null,
3097+
"description": null,
3098+
"target_start": "2025-10-22T08:29:41.333Z",
3099+
"target_end": "2025-10-22T08:29:41.333Z",
3100+
"percent_complete": 100,
3101+
"environment": 1,
3102+
"updated": "2025-10-22T08:29:41.590Z",
3103+
"created": "2025-10-22T08:29:41.343Z",
3104+
"version": "",
3105+
"build_id": "",
3106+
"commit_hash": "",
3107+
"branch_tag": "",
3108+
"api_scan_configuration": null,
3109+
"notes": [],
3110+
"files": [],
3111+
"tags": [],
3112+
"inherited_tags": []
3113+
}
3114+
},
3115+
{
3116+
"model": "dojo.finding",
3117+
"pk": 232,
3118+
"fields": {
3119+
"title": "Disabling CSRF Protections Is Security-Sensitive",
3120+
"date": "2025-10-22",
3121+
"sla_start_date": null,
3122+
"sla_expiration_date": "2025-11-21",
3123+
"cwe": 352,
3124+
"cve": null,
3125+
"epss_score": null,
3126+
"epss_percentile": null,
3127+
"known_exploited": false,
3128+
"ransomware_used": false,
3129+
"kev_date": null,
3130+
"cvssv3": null,
3131+
"cvssv3_score": null,
3132+
"cvssv4": null,
3133+
"cvssv4_score": null,
3134+
"url": null,
3135+
"severity": "High",
3136+
"description": "A cross-site request forgery (CSRF) attack occurs when a trusted user of a web application can be forced, by an attacker, to perform sensitive\nactions that he didn’t intend, such as updating his profile or sending a message, more generally anything that can change the state of the\napplication.\nThe attacker can trick the user/victim to click on a link, corresponding to the privileged action, or to visit a malicious web site that embeds a\nhidden web request and as web browsers automatically include cookies, the actions can be authenticated and sensitive.\n**Ask Yourself Whether**\n\n The web application uses cookies to authenticate users. \n There exist sensitive operations in the web application that can be performed when the user is authenticated. \n The state / resources of the web application can be modified by doing HTTP POST or HTTP DELETE requests for example. \n\nThere is a risk if you answered yes to any of those questions.\n**Recommended Secure Coding Practices**\n\n Protection against CSRF attacks is strongly recommended:\n \n to be activated by default for all unsafe HTTP\n methods. \n implemented, for example, with an unguessable CSRF token \n \n Of course all sensitive operations should not be performed with safe HTTP methods like GET which are designed to be\n used only for information retrieval. \n\n**Sensitive Code Example**\nFor a Django application, the code is sensitive when,\n\n django.middleware.csrf.CsrfViewMiddleware is not used in the Django settings: \n\n\nMIDDLEWARE = [\n 'django.middleware.security.SecurityMiddleware',\n 'django.contrib.sessions.middleware.SessionMiddleware',\n 'django.middleware.common.CommonMiddleware',\n 'django.contrib.auth.middleware.AuthenticationMiddleware',\n 'django.contrib.messages.middleware.MessageMiddleware',\n 'django.middleware.clickjacking.XFrameOptionsMiddleware',\n] # Sensitive: django.middleware.csrf.CsrfViewMiddleware is missing\n\n\n the CSRF protection is disabled on a view: \n\n\n@csrf_exempt # Sensitive\ndef example(request):\n return HttpResponse(\"default\")\n\nFor a Flask application, the code is sensitive when,\n\n the WTF_CSRF_ENABLED setting is set to false: \n\n\napp = Flask(__name__)\napp.config['WTF_CSRF_ENABLED'] = False # Sensitive\n\n\n the application doesn’t use the CSRFProtect module: \n\n\napp = Flask(__name__) # Sensitive: CSRFProtect is missing\n\n@app.route('/')\ndef hello_world():\n return 'Hello, World!'\n\n\n the CSRF protection is disabled on a view: \n\n\napp = Flask(__name__)\ncsrf = CSRFProtect()\ncsrf.init_app(app)\n\n@app.route('/example/', methods=['POST'])\n@csrf.exempt # Sensitive\ndef example():\n return 'example '\n\n\n the CSRF protection is disabled on a form: \n\n\nclass unprotectedForm(FlaskForm):\n class Meta:\n csrf = False # Sensitive\n\n name = TextField('name')\n submit = SubmitField('submit')\n\n**Compliant Solution**\nFor a Django application,\n\n it is recommended to protect all the views with django.middleware.csrf.CsrfViewMiddleware: \n\n\nMIDDLEWARE = [\n 'django.middleware.security.SecurityMiddleware',\n 'django.contrib.sessions.middleware.SessionMiddleware',\n 'django.middleware.common.CommonMiddleware',\n 'django.middleware.csrf.CsrfViewMiddleware', # Compliant\n 'django.contrib.auth.middleware.AuthenticationMiddleware',\n 'django.contrib.messages.middleware.MessageMiddleware',\n 'django.middleware.clickjacking.XFrameOptionsMiddleware',\n]\n\n\n and to not disable the CSRF protection on specific views: \n\n\ndef example(request): # Compliant\n return HttpResponse(\"default\")\n\nFor a Flask application,\n\n the CSRFProtect module should be used (and not disabled further with WTF_CSRF_ENABLED set to false):\n \n\n\napp = Flask(__name__)\ncsrf = CSRFProtect()\ncsrf.init_app(app) # Compliant\n\n\n and it is recommended to not disable the CSRF protection on specific views or forms: \n\n\n@app.route('/example/', methods=['POST']) # Compliant\ndef example():\n return 'example '\n\nclass unprotectedForm(FlaskForm):\n class Meta:\n csrf = True # Compliant\n\n name = TextField('name')\n submit = SubmitField('submit')",
3137+
"mitigation": "Make sure disabling CSRF protection is safe here.",
3138+
"fix_available": null,
3139+
"impact": "No impact provided",
3140+
"steps_to_reproduce": null,
3141+
"severity_justification": null,
3142+
"references": "python:S4502\nunsafe HTTP\n methods\nsafe HTTP\nDjango\nDjango settings\nFlask\nDjango\nFlask\nOWASP Top 10 2021 Category A1\nMITRE, CWE-352\nOWASP Top 10 2017 Category A6\nOWASP: Cross-Site Request Forgery\nSANS Top 25",
3143+
"test": 90,
3144+
"active": true,
3145+
"verified": true,
3146+
"false_p": false,
3147+
"duplicate": false,
3148+
"duplicate_finding": null,
3149+
"out_of_scope": false,
3150+
"risk_accepted": false,
3151+
"under_review": false,
3152+
"last_status_update": "2025-10-22T08:29:41.361Z",
3153+
"review_requested_by": null,
3154+
"under_defect_review": false,
3155+
"defect_review_requested_by": null,
3156+
"is_mitigated": false,
3157+
"thread_id": 0,
3158+
"mitigated": null,
3159+
"mitigated_by": null,
3160+
"reporter": [
3161+
"admin"
3162+
],
3163+
"numerical_severity": "S1",
3164+
"last_reviewed": "2025-10-22T08:29:41.336Z",
3165+
"last_reviewed_by": [
3166+
"admin"
3167+
],
3168+
"param": null,
3169+
"payload": null,
3170+
"hash_code": "ed09b1b5980bd7b9d67b58ba3a3200b788b567a8b3359b5b66d861112b025b9e",
3171+
"line": 8,
3172+
"file_path": "vulnerable-flask-app.py",
3173+
"component_name": null,
3174+
"component_version": null,
3175+
"static_finding": true,
3176+
"dynamic_finding": false,
3177+
"created": "2025-10-22T08:29:41.361Z",
3178+
"scanner_confidence": null,
3179+
"sonarqube_issue": null,
3180+
"unique_id_from_tool": "AYvNd32RyD1npIoQXyT1",
3181+
"vuln_id_from_tool": null,
3182+
"sast_source_object": null,
3183+
"sast_sink_object": null,
3184+
"sast_source_line": null,
3185+
"sast_source_file_path": null,
3186+
"nb_occurences": null,
3187+
"publish_date": null,
3188+
"service": null,
3189+
"planned_remediation_date": null,
3190+
"planned_remediation_version": null,
3191+
"effort_for_fixing": null,
3192+
"reviewers": [],
3193+
"notes": [],
3194+
"files": [],
3195+
"found_by": [
3196+
1000
3197+
],
3198+
"tags": [],
3199+
"inherited_tags": []
3200+
}
3201+
},
3202+
{
3203+
"model": "dojo.test_import",
3204+
"pk": 6829,
3205+
"fields": {
3206+
"created": "2025-10-22T08:29:41.453Z",
3207+
"modified": "2025-10-22T08:29:41.453Z",
3208+
"test": 90,
3209+
"import_settings": {
3210+
"tags": [],
3211+
"active": true,
3212+
"verified": true,
3213+
"push_to_jira": false,
3214+
"minimum_severity": "Info",
3215+
"close_old_findings": false
3216+
},
3217+
"type": "import",
3218+
"version": "",
3219+
"build_id": "",
3220+
"commit_hash": "",
3221+
"branch_tag": ""
3222+
}
3223+
},
3224+
{
3225+
"model": "dojo.test_import_finding_action",
3226+
"pk": 80213,
3227+
"fields": {
3228+
"created": "2025-10-22T08:29:41.458Z",
3229+
"modified": "2025-10-22T08:29:41.458Z",
3230+
"test_import": 6829,
3231+
"finding": 232,
3232+
"action": "N"
3233+
}
3234+
},
3235+
{
3236+
"model": "dojo.test_type",
3237+
"pk": 1001,
3238+
"fields": {
3239+
"name": "HackerOne Cases",
3240+
"static_tool": false,
3241+
"dynamic_tool": false,
3242+
"active": true,
3243+
"dynamically_generated": false
3244+
}
3245+
},
3246+
{
3247+
"model": "dojo.test",
3248+
"pk": 91,
3249+
"fields": {
3250+
"engagement": 5,
3251+
"lead": [
3252+
"admin"
3253+
],
3254+
"test_type": 1001,
3255+
"scan_type": "HackerOne Cases",
3256+
"title": null,
3257+
"description": null,
3258+
"target_start": "2025-10-22T08:52:53.734Z",
3259+
"target_end": "2025-10-22T08:52:53.734Z",
3260+
"percent_complete": 100,
3261+
"environment": 1,
3262+
"updated": "2025-10-22T08:52:53.859Z",
3263+
"created": "2025-10-22T08:52:53.737Z",
3264+
"version": "",
3265+
"build_id": "",
3266+
"commit_hash": "",
3267+
"branch_tag": "",
3268+
"api_scan_configuration": null,
3269+
"notes": [],
3270+
"files": [],
3271+
"tags": [],
3272+
"inherited_tags": []
3273+
}
3274+
},
3275+
{
3276+
"model": "dojo.finding",
3277+
"pk": 233,
3278+
"fields": {
3279+
"title": "Sensitive Account Balance Information Exposure via Example's DaviPlata Payment Link Integration",
3280+
"date": "2025-10-22",
3281+
"sla_start_date": null,
3282+
"sla_expiration_date": "2026-01-20",
3283+
"cwe": 0,
3284+
"cve": null,
3285+
"epss_score": null,
3286+
"epss_percentile": null,
3287+
"known_exploited": false,
3288+
"ransomware_used": false,
3289+
"kev_date": null,
3290+
"cvssv3": null,
3291+
"cvssv3_score": null,
3292+
"cvssv4": null,
3293+
"cvssv4_score": null,
3294+
"url": null,
3295+
"severity": "Medium",
3296+
"description": "**ID**: 2501687\n**Weakness Category**: Information Disclosure\n**Substate**: triaged\n**Reporter**: reporter\n**Assigned To**: Group example.co Team\n**Public**: no\n**Awarded On**: 2024-08-28 19:40:24 UTC\n**Bounty Price**: 400.0\n**First Response On**: 2024-05-14 22:14:16 UTC\n**Structured Scope**: 1489537348\n",
3297+
"mitigation": null,
3298+
"fix_available": null,
3299+
"impact": null,
3300+
"steps_to_reproduce": null,
3301+
"severity_justification": null,
3302+
"references": null,
3303+
"test": 91,
3304+
"active": true,
3305+
"verified": true,
3306+
"false_p": false,
3307+
"duplicate": false,
3308+
"duplicate_finding": null,
3309+
"out_of_scope": false,
3310+
"risk_accepted": false,
3311+
"under_review": false,
3312+
"last_status_update": "2025-10-22T08:52:53.755Z",
3313+
"review_requested_by": null,
3314+
"under_defect_review": false,
3315+
"defect_review_requested_by": null,
3316+
"is_mitigated": false,
3317+
"thread_id": 0,
3318+
"mitigated": null,
3319+
"mitigated_by": null,
3320+
"reporter": [
3321+
"admin"
3322+
],
3323+
"numerical_severity": "S2",
3324+
"last_reviewed": "2025-10-22T08:52:53.735Z",
3325+
"last_reviewed_by": [
3326+
"admin"
3327+
],
3328+
"param": null,
3329+
"payload": null,
3330+
"hash_code": "684facb6f2fd8faa50a28637d4f7fc1ba9ad3d3a932d39960e99e3c10aec3495",
3331+
"line": null,
3332+
"file_path": null,
3333+
"component_name": null,
3334+
"component_version": null,
3335+
"static_finding": false,
3336+
"dynamic_finding": true,
3337+
"created": "2025-10-22T08:52:53.755Z",
3338+
"scanner_confidence": null,
3339+
"sonarqube_issue": null,
3340+
"unique_id_from_tool": null,
3341+
"vuln_id_from_tool": null,
3342+
"sast_source_object": null,
3343+
"sast_sink_object": null,
3344+
"sast_source_line": null,
3345+
"sast_source_file_path": null,
3346+
"nb_occurences": null,
3347+
"publish_date": null,
3348+
"service": null,
3349+
"planned_remediation_date": null,
3350+
"planned_remediation_version": null,
3351+
"effort_for_fixing": null,
3352+
"reviewers": [],
3353+
"notes": [],
3354+
"files": [],
3355+
"found_by": [
3356+
1001
3357+
],
3358+
"tags": [],
3359+
"inherited_tags": []
3360+
}
3361+
},
3362+
{
3363+
"model": "dojo.test_import",
3364+
"pk": 6830,
3365+
"fields": {
3366+
"created": "2025-10-22T08:52:53.797Z",
3367+
"modified": "2025-10-22T08:52:53.797Z",
3368+
"test": 91,
3369+
"import_settings": {
3370+
"tags": [],
3371+
"active": true,
3372+
"verified": true,
3373+
"push_to_jira": false,
3374+
"minimum_severity": "Info",
3375+
"close_old_findings": false
3376+
},
3377+
"type": "import",
3378+
"version": "",
3379+
"build_id": "",
3380+
"commit_hash": "",
3381+
"branch_tag": ""
3382+
}
3383+
},
3384+
{
3385+
"model": "dojo.test_import_finding_action",
3386+
"pk": 80214,
3387+
"fields": {
3388+
"created": "2025-10-22T08:52:53.798Z",
3389+
"modified": "2025-10-22T08:52:53.798Z",
3390+
"test_import": 6830,
3391+
"finding": 233,
3392+
"action": "N"
3393+
}
30743394
}
30753395
]

0 commit comments

Comments
 (0)