|
10 | 10 | from ddtrace.appsec._iast.constants import VULN_HEADER_INJECTION |
11 | 11 | from ddtrace.appsec._iast.constants import VULN_INSECURE_COOKIE |
12 | 12 | from ddtrace.appsec._iast.constants import VULN_SQL_INJECTION |
| 13 | +from ddtrace.appsec._iast.constants import VULN_SSRF |
13 | 14 | from ddtrace.appsec._iast.constants import VULN_STACKTRACE_LEAK |
14 | 15 | from ddtrace.appsec._iast.constants import VULN_UNVALIDATED_REDIRECT |
15 | 16 | from ddtrace.settings.asm import config as asm_config |
@@ -1467,3 +1468,74 @@ def test_django_iast_sampling_by_route_method(client, test_spans_2_vuln_per_requ |
1467 | 1468 | assert ( |
1468 | 1469 | len(list_vulnerabilities) == 16 |
1469 | 1470 | ), f"Num vulnerabilities: ({len(list_vulnerabilities)}): {list_vulnerabilities}" |
| 1471 | + |
| 1472 | + |
| 1473 | +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") |
| 1474 | +def test_django_ssrf_safe_path(client, iast_span, tracer): |
| 1475 | + tainted_value = "path_param" |
| 1476 | + root_span, _ = _aux_appsec_get_root_span( |
| 1477 | + client, iast_span, tracer, url=f"/appsec/ssrf_requests/?url={tainted_value}" |
| 1478 | + ) |
| 1479 | + loaded = root_span.get_tag(IAST.JSON) |
| 1480 | + assert loaded is None |
| 1481 | + |
| 1482 | + |
| 1483 | +@pytest.mark.parametrize( |
| 1484 | + ("option", "url", "value_parts"), |
| 1485 | + [ |
| 1486 | + ("path", "url-path/", [{"value": "http://localhost:8080/"}, {"value": "url-path/", "source": 0}]), |
| 1487 | + ("safe_path", "url-path/", None), |
| 1488 | + ("protocol", "http", [{"value": "http", "source": 0}, {"value": "://localhost:8080/"}]), |
| 1489 | + ("host", "localhost", [{"value": "http://"}, {"value": "localhost", "source": 0}, {"value": ":8080/"}]), |
| 1490 | + ("urlencode_single", "value1", None), |
| 1491 | + ("urlencode_multiple", "value1", None), |
| 1492 | + ("urlencode_nested", "value1", None), |
| 1493 | + ("urlencode_with_fragment", "value1", None), |
| 1494 | + ("urlencode_doseq", "value1", None), |
| 1495 | + ("safe_host", "localhost", None), |
| 1496 | + ("port", "8080", [{"value": "http://localhost:"}, {"value": "8080", "source": 0}, {"value": "/"}]), |
| 1497 | + ( |
| 1498 | + "query", |
| 1499 | + "param1=value1¶m2=value2", |
| 1500 | + [ |
| 1501 | + {"value": "http://localhost:8080/?"}, |
| 1502 | + {"source": 0, "value": "param1="}, |
| 1503 | + {"redacted": True, "source": 0, "pattern": "hijklm"}, |
| 1504 | + ], |
| 1505 | + ), |
| 1506 | + ( |
| 1507 | + "query_with_fragment", |
| 1508 | + "param1=value_with_%23hash%23¶m2=value2", |
| 1509 | + [ |
| 1510 | + {"value": "http://localhost:8080/?"}, |
| 1511 | + {"source": 0, "value": "param1="}, |
| 1512 | + {"redacted": True, "source": 0, "pattern": "hijklmnopqr"}, |
| 1513 | + {"source": 0, "value": "#hash#"}, |
| 1514 | + ], |
| 1515 | + ), |
| 1516 | + ("fragment1", "fragment_value1", None), |
| 1517 | + ("fragment2", "fragment_value1", None), |
| 1518 | + ("fragment3", "fragment_value1", None), |
| 1519 | + ("query_param", "param1=value1¶m2=value2", None), |
| 1520 | + ], |
| 1521 | +) |
| 1522 | +def test_django_ssrf_url(client, iast_span, tracer, option, url, value_parts): |
| 1523 | + root_span, response = _aux_appsec_get_root_span( |
| 1524 | + client, iast_span, tracer, url=f"/appsec/ssrf_requests/?option={option}&url={url}" |
| 1525 | + ) |
| 1526 | + |
| 1527 | + assert response.status_code == 200 |
| 1528 | + assert response.content == b"OK" |
| 1529 | + |
| 1530 | + if value_parts is None: |
| 1531 | + assert root_span.get_tag(IAST.JSON) is None |
| 1532 | + else: |
| 1533 | + loaded = json.loads(root_span.get_tag(IAST.JSON)) |
| 1534 | + |
| 1535 | + line, hash_value = get_line_and_hash(f"ssrf_requests_{option}", VULN_SSRF, filename=TEST_FILE) |
| 1536 | + |
| 1537 | + assert loaded["vulnerabilities"][0]["type"] == VULN_SSRF |
| 1538 | + assert loaded["vulnerabilities"][0]["evidence"] == {"valueParts": value_parts} |
| 1539 | + assert loaded["vulnerabilities"][0]["location"]["path"] == TEST_FILE |
| 1540 | + assert loaded["vulnerabilities"][0]["location"]["line"] == line |
| 1541 | + assert loaded["vulnerabilities"][0]["hash"] == hash_value |
0 commit comments