-
Notifications
You must be signed in to change notification settings - Fork 424
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(iast): xss vulnerability for django applications (#12116)
XSS vulnerability detection. System tests (merge after this PR): DataDog/system-tests#3923 ## Checklist - [x] PR author has checked that all the criteria below are met - The PR description includes an overview of the change - The PR description articulates the motivation for the change - The change includes tests OR the PR description describes a testing strategy - The PR description notes risks associated with the change, if any - Newly-added code is easy to change - The change follows the [library release note guidelines](https://ddtrace.readthedocs.io/en/stable/releasenotes.html) - The change includes or references documentation updates if necessary - Backport labels are set (if [applicable](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)) ## Reviewer Checklist - [x] Reviewer has checked that all the criteria below are met - Title is accurate - All changes are related to the pull request's stated goal - Avoids breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes - Testing strategy adequately addresses listed risks - Newly-added code is easy to change - Release note makes sense to a user of the library - If necessary, author has acknowledged and discussed the performance implications of this PR as reported in the benchmarks PR comment - Backport labels are set in a manner that is consistent with the [release branch maintenance policy](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting) --------- Co-authored-by: Federico Mon <[email protected]>
- Loading branch information
Showing
17 changed files
with
736 additions
and
511 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ | |
"header_injection": True, | ||
"weak_cipher": True, | ||
"weak_hash": True, | ||
"xss": True, | ||
} | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
from typing import Text | ||
|
||
from ddtrace.appsec._common_module_patches import try_unwrap | ||
from ddtrace.appsec._constants import IAST_SPAN_TAGS | ||
from ddtrace.appsec._iast import oce | ||
from ddtrace.appsec._iast._iast_request_context import is_iast_request_enabled | ||
from ddtrace.appsec._iast._metrics import _set_metric_iast_executed_sink | ||
from ddtrace.appsec._iast._metrics import _set_metric_iast_instrumented_sink | ||
from ddtrace.appsec._iast._metrics import increment_iast_span_metric | ||
from ddtrace.appsec._iast._patch import set_and_check_module_is_patched | ||
from ddtrace.appsec._iast._patch import set_module_unpatched | ||
from ddtrace.appsec._iast._patch import try_wrap_function_wrapper | ||
from ddtrace.appsec._iast._taint_tracking._taint_objects import is_pyobject_tainted | ||
from ddtrace.appsec._iast.constants import VULN_XSS | ||
from ddtrace.appsec._iast.taint_sinks._base import VulnerabilityBase | ||
from ddtrace.internal.logger import get_logger | ||
from ddtrace.settings.asm import config as asm_config | ||
|
||
|
||
log = get_logger(__name__) | ||
|
||
|
||
@oce.register | ||
class XSS(VulnerabilityBase): | ||
vulnerability_type = VULN_XSS | ||
|
||
|
||
def get_version() -> Text: | ||
return "" | ||
|
||
|
||
def patch(): | ||
if not asm_config._iast_enabled: | ||
return | ||
|
||
if not set_and_check_module_is_patched("flask", default_attr="_datadog_xss_patch"): | ||
return | ||
if not set_and_check_module_is_patched("django", default_attr="_datadog_xss_patch"): | ||
return | ||
if not set_and_check_module_is_patched("fastapi", default_attr="_datadog_xss_patch"): | ||
return | ||
|
||
try_wrap_function_wrapper( | ||
"django.utils.safestring", | ||
"mark_safe", | ||
_iast_django_xss, | ||
) | ||
|
||
try_wrap_function_wrapper( | ||
"django.template.defaultfilters", | ||
"mark_safe", | ||
_iast_django_xss, | ||
) | ||
|
||
_set_metric_iast_instrumented_sink(VULN_XSS) | ||
|
||
|
||
def unpatch(): | ||
try_unwrap("django.utils.safestring", "mark_safe") | ||
try_unwrap("django.template.defaultfilters", "mark_safe") | ||
|
||
set_module_unpatched("flask", default_attr="_datadog_xss_patch") | ||
set_module_unpatched("django", default_attr="_datadog_xss_patch") | ||
set_module_unpatched("fastapi", default_attr="_datadog_xss_patch") | ||
|
||
|
||
def _iast_django_xss(wrapped, instance, args, kwargs): | ||
if args and len(args) >= 1: | ||
_iast_report_xss(args[0]) | ||
return wrapped(*args, **kwargs) | ||
|
||
|
||
def _iast_report_xss(code_string: Text): | ||
increment_iast_span_metric(IAST_SPAN_TAGS.TELEMETRY_EXECUTED_SINK, XSS.vulnerability_type) | ||
_set_metric_iast_executed_sink(XSS.vulnerability_type) | ||
if is_iast_request_enabled(): | ||
if is_pyobject_tainted(code_string): | ||
XSS.report(evidence_value=code_string) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 6 additions & 0 deletions
6
releasenotes/notes/iast-feat-xss-django-6781a8b9a4092832.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
features: | ||
- | | ||
Code Security (IAST): XSS detection for Django applications, | ||
which will be displayed on your DataDog Vulnerability Explorer dashboard. | ||
See the `Application Vulnerability Management <https://docs.datadoghq.com/security/application_security/vulnerability_management/>`_ documentation for more information about this feature. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import os | ||
|
||
import pytest | ||
|
||
from ddtrace.appsec._iast._taint_tracking import origin_to_str | ||
from ddtrace.appsec._iast._taint_tracking import str_to_origin | ||
from ddtrace.appsec._iast.constants import VULN_XSS | ||
from ddtrace.appsec._iast.taint_sinks.xss import XSS | ||
from tests.appsec.iast.taint_sinks._taint_sinks_utils import _taint_pyobject_multiranges | ||
from tests.appsec.iast.taint_sinks._taint_sinks_utils import get_parametrize | ||
from tests.appsec.iast.taint_sinks.conftest import _get_iast_data | ||
|
||
|
||
ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"evidence_input, sources_expected, vulnerabilities_expected,element", list(get_parametrize(VULN_XSS)) | ||
) | ||
def test_xss_redaction_suite( | ||
evidence_input, sources_expected, vulnerabilities_expected, iast_context_defaults, element | ||
): | ||
tainted_object = evidence_input_value = evidence_input.get("value", "") | ||
if evidence_input_value: | ||
tainted_object = _taint_pyobject_multiranges( | ||
evidence_input_value, | ||
[ | ||
( | ||
input_ranges["iinfo"]["parameterName"], | ||
input_ranges["iinfo"]["parameterValue"], | ||
str_to_origin(input_ranges["iinfo"]["type"]), | ||
input_ranges["start"], | ||
input_ranges["end"] - input_ranges["start"], | ||
) | ||
for input_ranges in evidence_input.get("ranges", {}) | ||
], | ||
) | ||
|
||
XSS.report(tainted_object) | ||
|
||
data = _get_iast_data() | ||
vulnerability = list(data["vulnerabilities"])[0] | ||
source = list(data["sources"])[0] | ||
source["origin"] = origin_to_str(source["origin"]) | ||
|
||
assert vulnerability["type"] == VULN_XSS | ||
assert vulnerability["evidence"] == vulnerabilities_expected["evidence"] | ||
assert source == sources_expected |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 5 additions & 0 deletions
5
tests/appsec/integrations/django_tests/django_app/templates/index.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<html> | ||
<body> | ||
<p>Input: {{ user_input }}</p> | ||
</body> | ||
</html> |
7 changes: 7 additions & 0 deletions
7
tests/appsec/integrations/django_tests/django_app/templates/index_autoescape.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
<html> | ||
<body> | ||
<p>{% autoescape on %} | ||
{{ user_input }} | ||
{% endautoescape %}</p> | ||
</body> | ||
</html> |
5 changes: 5 additions & 0 deletions
5
tests/appsec/integrations/django_tests/django_app/templates/index_safe.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<html> | ||
<body> | ||
<p>Input: {{ user_input|safe }}</p> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.