Skip to content

Conversation

@bdrodes
Copy link
Contributor

@bdrodes bdrodes commented Feb 6, 2026

  • Clean up of test cases to use postprocessing
  • Adding full ssrf path sanitization for the new AntiSSRF python API.

bdrodes and others added 11 commits February 6, 2026 11:18
…orgery/test_azure_client.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…orgery/test_azure_client.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…caes to use postprocessing results. Currently results for partial ssrf still need work, it is flagging cases where the URL is fully controlled, but is sanitized. I'm not sure if this should be flagged yet.
@github-actions github-actions bot added the Python label Feb 6, 2026
@bdrodes bdrodes marked this pull request as ready for review February 9, 2026 18:23
@bdrodes bdrodes requested a review from a team as a code owner February 9, 2026 18:23
Copilot AI review requested due to automatic review settings February 9, 2026 18:23
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the Python SSRF (CWE-918) query tests to use inline-expectations postprocessing and adds modeling/tests for the AntiSSRF library’s URI validation as a sanitizer for full URL control.

Changes:

  • Migrate SSRF query-tests to utils/test/InlineExpectationsTestQuery.ql postprocessing.
  • Expand SSRF test coverage for requests, http.client, Azure SDK sinks, and new AntiSSRF validation APIs.
  • Add an AntiSSRF URIValidator barrier/sanitizer to SSRF dataflow customizations and record the change in change notes.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 15 comments.

Show a summary per file
File Description
python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_requests.py Adds more requests SSRF cases and AntiSSRFPolicy-based safe/unsafe session scenarios with inline expectations.
python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py New tests covering AntiSSRF URIValidator domain checks and how they interact with SSRF sink classification.
python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_http_client.py Updates http.client SSRF tests to inline expectations and adds sink annotations.
python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_azure_client.py Converts Azure SSRF sink tests to inline expectations and simplifies call formatting.
python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/full_partial_test.py Refactors existing full/partial SSRF test cases to inline expectations and adds explicit alert annotations.
python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/PartialServerSideRequestForgery.qlref Switches to query:/postprocess: format to enable inline expectations postprocessing.
python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/PartialServerSideRequestForgery.expected Regenerated expected output for postprocessed partial SSRF tests.
python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/FullServerSideRequestForgery.qlref Switches to query:/postprocess: format to enable inline expectations postprocessing.
python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/FullServerSideRequestForgery.expected Regenerated expected output for postprocessed full SSRF tests.
python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgeryCustomizations.qll Adds AntiSSRF URIValidator barrier/guard modeling for full URL control sanitization.
python/ql/lib/change-notes/2026-02-09-ssrf_test_case_cleanup_and_new_ssrf_barriers.md Documents the SSRF test cleanup and new AntiSSRF barrier behavior.
Comments suppressed due to low confidence (47)

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:21

  • Variable c is not used.
        c = SecretClient(vault_url=full_url, credential=credential) # $ Alert[py/full-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:35

  • Variable c is not used.
        c = KeyClient(vault_url=full_url, credential=credential)  # $ Alert[py/partial-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:37

  • Variable c is not used.
        c = KeyClient(vault_url=full_url, credential=credential)  # $ Alert[py/full-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:51

  • Variable c is not used.
        c = ShareFileClient.from_file_url(full_url) # $ Alert[py/partial-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:53

  • Variable c is not used.
        c = ShareFileClient.from_file_url(full_url) # $ Alert[py/full-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:130

  • Variable c is not used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/partial-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:132

  • Variable c is not used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/full-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_requests.py:29

  • Variable response is not used.
    response = session.get(user_input)

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_requests.py:39

  • Variable response is not used.
    response = session.get(user_input) # $ Alert[py/full-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_requests.py:49

  • Variable response is not used.
    response = session.get(user_input) # $ Alert[py/full-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_azure_client.py:16

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    c = SecretClient(vault_url=full_url, credential=credential) # $ Alert[py/full-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_azure_client.py:17

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    c = ShareFileClient.from_file_url(url) # $ Alert[py/partial-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_azure_client.py:18

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    c = ShareFileClient.from_file_url(full_url) # $ Alert[py/full-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_azure_client.py:19

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    c = KeyClient(url, credential) # $ Alert[py/partial-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_azure_client.py:20

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    c = KeyClient(full_url, credential) # $ Alert[py/full-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_azure_client.py:21

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    c = ContainerClient.from_container_url(container_url=url, credential=credential) # $ Alert[py/partial-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:16

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/partial-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:30

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = KeyClient(vault_url=url, credential=credential) # $ Alert[py/partial-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:32

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = KeyClient(vault_url=url, credential=credential)  # $ Alert[py/partial-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:46

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = ShareFileClient.from_file_url(url) # $ Alert[py/partial-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:48

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = ShareFileClient.from_file_url(url) # $ Alert[py/partial-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:64

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/full-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:66

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/partial-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:69

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/partial-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:71

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/full-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:74

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/full-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:76

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/partial-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:79

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/full-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:81

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/partial-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:85

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/partial-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:87

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/full-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:90

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/full-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:92

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/partial-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:95

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/full-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:97

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/partial-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:100

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/partial-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:102

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/full-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:105

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/partial-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:107

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/full-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:110

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/full-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:112

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/partial-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:115

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/full-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:117

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/partial-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:120

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/partial-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:122

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/full-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:125

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/full-ssrf]

python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/test_path_validation.py:127

  • This assignment to 'c' is unnecessary as it is redefined before this value is used.
    This assignment to 'c' is unnecessary as it is redefined before this value is used.
        c = SecretClient(vault_url=url, credential=credential) # $ Alert[py/partial-ssrf]

@@ -1,11 +1,49 @@
from flask import request
from flask import request # $ Source
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The # $ Source annotation on the Flask import appears to be unmatched by the postprocessed query output (the generated .expected for the partial SSRF test reports it as a missing Source). Since this file is used by both the full and partial SSRF query tests, consider removing this Source annotation here or rewriting it to attach to a node that is actually emitted as a Source for both queries.

Suggested change
from flask import request # $ Source
from flask import request

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant