Python: Altering SSRF MaD to use 'request-forgery' tag. Update to test cases expected results, off by one line. Changed to using ModelOutput::sinkNode.

This commit is contained in:
REDMOND\brodes
2026-02-04 09:04:22 -05:00
parent cd73dcfb04
commit 0a88425170
5 changed files with 43 additions and 43 deletions

View File

@@ -3,7 +3,7 @@ extensions:
pack: codeql/python-all
extensible: sinkModel
data:
- ['azure.keyvault.certificates.CertificateClient!', 'Call.Argument[0,vault_url:]', 'ssrf']
- ['azure.keyvault.certificates.DeletedCertificate!', 'Call.Argument[recovery_id:]', 'ssrf']
- ['azure.keyvault.keys.KeyClient!', 'Call.Argument[0,vault_url:]', 'ssrf']
- ['azure.keyvault.secrets.SecretClient!', 'Call.Argument[0,vault_url:]', 'ssrf']
- ['azure.keyvault.certificates.CertificateClient!', 'Call.Argument[0,vault_url:]', 'request-forgery']
- ['azure.keyvault.certificates.DeletedCertificate!', 'Call.Argument[recovery_id:]', 'request-forgery']
- ['azure.keyvault.keys.KeyClient!', 'Call.Argument[0,vault_url:]', 'request-forgery']
- ['azure.keyvault.secrets.SecretClient!', 'Call.Argument[0,vault_url:]', 'request-forgery']

View File

@@ -3,32 +3,32 @@ extensions:
pack: codeql/python-all
extensible: sinkModel
data:
- ['azure.storage.blob.BlobClient!', 'Call.Argument[0,account_url:]', 'ssrf']
- ['azure.storage.blob.BlobClient', 'Member[append_block_from_url].Argument[0,copy_source_url:]', 'ssrf']
- ['azure.storage.blob.BlobClient', 'Member[get_page_range_diff_for_managed_disk].Argument[0,previous_snapshot_url:]', 'ssrf']
- ['azure.storage.blob.BlobClient', 'Member[stage_block_from_url].Argument[1,source_url:]', 'ssrf']
- ['azure.storage.blob.BlobClient', 'Member[start_copy_from_url].Argument[0,source_url:]', 'ssrf']
- ['azure.storage.blob.BlobClient', 'Member[upload_blob_from_url].Argument[0,source_url:]', 'ssrf']
- ['azure.storage.blob.BlobClient', 'Member[upload_pages_from_url].Argument[0,source_url:]', 'ssrf']
- ['azure.storage.blob.BlobClient!', 'Member[from_blob_url].Argument[0,blob_url:]', 'ssrf']
- ['azure.storage.blob.BlobServiceClient!', 'Call.Argument[0,account_url:]', 'ssrf']
- ['azure.storage.blob.ContainerClient!', 'Call.Argument[0,account_url:]', 'ssrf']
- ['azure.storage.blob.ContainerClient!', 'Member[from_container_url].Argument[0,container_url:]', 'ssrf']
- ['azure', 'Member[storage].Member[blob].Member[download_blob_from_url].Argument[0,blob_url:]', 'ssrf']
- ['azure', 'Member[storage].Member[blob].Member[upload_blob_to_url].Argument[0,blob_url:]', 'ssrf']
- ['azure.storage.filedatalake.DataLakeDirectoryClient!', 'Call.Argument[0,account_url:]', 'ssrf']
- ['azure.storage.filedatalake.DataLakeFileClient!', 'Call.Argument[0,account_url:]', 'ssrf']
- ['azure.storage.filedatalake.DataLakeServiceClient!', 'Call.Argument[0,account_url:]', 'ssrf']
- ['azure.storage.filedatalake.FileSystemClient!', 'Call.Argument[0,account_url:]', 'ssrf']
- ['azure.storage.fileshare.ShareClient!', 'Call.Argument[0,account_url:]', 'ssrf']
- ['azure.storage.fileshare.ShareClient!', 'Member[from_share_url].Argument[0,share_url:]', 'ssrf']
- ['azure.storage.fileshare.ShareDirectoryClient!', 'Call.Argument[0,account_url:]', 'ssrf']
- ['azure.storage.fileshare.ShareDirectoryClient!', 'Member[from_directory_url].Argument[0,directory_url:]', 'ssrf']
- ['azure.storage.fileshare.ShareFileClient!', 'Call.Argument[0,account_url:]', 'ssrf']
- ['azure.storage.fileshare.ShareFileClient!', 'Member[from_file_url].Argument[0,file_url:]', 'ssrf']
- ['azure.storage.fileshare.ShareFileClient', 'Member[start_copy_from_url].Argument[0,source_url:]', 'ssrf']
- ['azure.storage.fileshare.ShareFileClient', 'Member[upload_range_from_url].Argument[0,source_url:]', 'ssrf']
- ['azure.storage.fileshare.ShareServiceClient!', 'Call.Argument[0,account_url:]', 'ssrf']
- ['azure.storage.queue.QueueClient!', 'Call.Argument[0,account_url:]', 'ssrf']
- ['azure.storage.queue.QueueClient', 'Member[from_queue_url].Argument[0,queue_url:]', 'ssrf']
- ['azure.storage.queue.QueueServiceClient!', 'Call.Argument[0,account_url:]', 'ssrf']
- ['azure.storage.blob.BlobClient!', 'Call.Argument[0,account_url:]', 'request-forgery']
- ['azure.storage.blob.BlobClient', 'Member[append_block_from_url].Argument[0,copy_source_url:]', 'request-forgery']
- ['azure.storage.blob.BlobClient', 'Member[get_page_range_diff_for_managed_disk].Argument[0,previous_snapshot_url:]', 'request-forgery']
- ['azure.storage.blob.BlobClient', 'Member[stage_block_from_url].Argument[1,source_url:]', 'request-forgery']
- ['azure.storage.blob.BlobClient', 'Member[start_copy_from_url].Argument[0,source_url:]', 'request-forgery']
- ['azure.storage.blob.BlobClient', 'Member[upload_blob_from_url].Argument[0,source_url:]', 'request-forgery']
- ['azure.storage.blob.BlobClient', 'Member[upload_pages_from_url].Argument[0,source_url:]', 'request-forgery']
- ['azure.storage.blob.BlobClient!', 'Member[from_blob_url].Argument[0,blob_url:]', 'request-forgery']
- ['azure.storage.blob.BlobServiceClient!', 'Call.Argument[0,account_url:]', 'request-forgery']
- ['azure.storage.blob.ContainerClient!', 'Call.Argument[0,account_url:]', 'request-forgery']
- ['azure.storage.blob.ContainerClient!', 'Member[from_container_url].Argument[0,container_url:]', 'request-forgery']
- ['azure', 'Member[storage].Member[blob].Member[download_blob_from_url].Argument[0,blob_url:]', 'request-forgery']
- ['azure', 'Member[storage].Member[blob].Member[upload_blob_to_url].Argument[0,blob_url:]', 'request-forgery']
- ['azure.storage.filedatalake.DataLakeDirectoryClient!', 'Call.Argument[0,account_url:]', 'request-forgery']
- ['azure.storage.filedatalake.DataLakeFileClient!', 'Call.Argument[0,account_url:]', 'request-forgery']
- ['azure.storage.filedatalake.DataLakeServiceClient!', 'Call.Argument[0,account_url:]', 'request-forgery']
- ['azure.storage.filedatalake.FileSystemClient!', 'Call.Argument[0,account_url:]', 'request-forgery']
- ['azure.storage.fileshare.ShareClient!', 'Call.Argument[0,account_url:]', 'request-forgery']
- ['azure.storage.fileshare.ShareClient!', 'Member[from_share_url].Argument[0,share_url:]', 'request-forgery']
- ['azure.storage.fileshare.ShareDirectoryClient!', 'Call.Argument[0,account_url:]', 'request-forgery']
- ['azure.storage.fileshare.ShareDirectoryClient!', 'Member[from_directory_url].Argument[0,directory_url:]', 'request-forgery']
- ['azure.storage.fileshare.ShareFileClient!', 'Call.Argument[0,account_url:]', 'request-forgery']
- ['azure.storage.fileshare.ShareFileClient!', 'Member[from_file_url].Argument[0,file_url:]', 'request-forgery']
- ['azure.storage.fileshare.ShareFileClient', 'Member[start_copy_from_url].Argument[0,source_url:]', 'request-forgery']
- ['azure.storage.fileshare.ShareFileClient', 'Member[upload_range_from_url].Argument[0,source_url:]', 'request-forgery']
- ['azure.storage.fileshare.ShareServiceClient!', 'Call.Argument[0,account_url:]', 'request-forgery']
- ['azure.storage.queue.QueueClient!', 'Call.Argument[0,account_url:]', 'request-forgery']
- ['azure.storage.queue.QueueClient', 'Member[from_queue_url].Argument[0,queue_url:]', 'request-forgery']
- ['azure.storage.queue.QueueServiceClient!', 'Call.Argument[0,account_url:]', 'request-forgery']

View File

@@ -14,7 +14,7 @@ private import semmle.python.frameworks.data.ModelsAsData
*/
module SsrfMaDModel {
/**
* An HTTP request modeled from `ssrf` sinks, modeled using MaD.
* An HTTP request modeled from `request-forgery` sinks, modeled using MaD.
*/
class SsrfSink extends Http::Client::Request::Range instanceof API::CallNode {
DataFlow::Node urlArg;
@@ -25,7 +25,7 @@ module SsrfMaDModel {
or
this.getArgByName(_) = urlArg
) and
urlArg = ModelOutput::getASinkNode("ssrf").asSink()
ModelOutput::sinkNode(urlArg, "request-forgery")
}
override DataFlow::Node getAUrlPart() { result = urlArg }

View File

@@ -45,7 +45,7 @@ edges
| test_azure_client.py:14:5:14:12 | ControlFlowNode for full_url | test_azure_client.py:19:39:19:46 | ControlFlowNode for full_url | provenance | Sink:MaD:38 |
| test_azure_client.py:14:5:14:12 | ControlFlowNode for full_url | test_azure_client.py:21:19:21:26 | ControlFlowNode for full_url | provenance | Sink:MaD:14 |
| test_azure_client.py:14:5:14:12 | ControlFlowNode for full_url | test_azure_client.py:23:58:23:65 | ControlFlowNode for full_url | provenance | Sink:MaD:26 |
| test_azure_client.py:14:5:14:12 | ControlFlowNode for full_url | test_azure_client.py:33:18:33:25 | ControlFlowNode for full_url | provenance | Sink:MaD:27 |
| test_azure_client.py:14:5:14:12 | ControlFlowNode for full_url | test_azure_client.py:32:18:32:25 | ControlFlowNode for full_url | provenance | Sink:MaD:27 |
| test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:1:26:1:32 | ControlFlowNode for request | provenance | |
| test_http_client.py:1:26:1:32 | ControlFlowNode for request | test_http_client.py:9:19:9:25 | ControlFlowNode for request | provenance | |
| test_http_client.py:1:26:1:32 | ControlFlowNode for request | test_http_client.py:10:19:10:25 | ControlFlowNode for request | provenance | |
@@ -110,7 +110,7 @@ nodes
| test_azure_client.py:19:39:19:46 | ControlFlowNode for full_url | semmle.label | ControlFlowNode for full_url |
| test_azure_client.py:21:19:21:26 | ControlFlowNode for full_url | semmle.label | ControlFlowNode for full_url |
| test_azure_client.py:23:58:23:65 | ControlFlowNode for full_url | semmle.label | ControlFlowNode for full_url |
| test_azure_client.py:33:18:33:25 | ControlFlowNode for full_url | semmle.label | ControlFlowNode for full_url |
| test_azure_client.py:32:18:32:25 | ControlFlowNode for full_url | semmle.label | ControlFlowNode for full_url |
| test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember |
| test_http_client.py:1:26:1:32 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| test_http_client.py:9:5:9:15 | ControlFlowNode for unsafe_host | semmle.label | ControlFlowNode for unsafe_host |
@@ -148,7 +148,7 @@ subpaths
| test_azure_client.py:19:9:19:47 | ControlFlowNode for Attribute() | test_azure_client.py:7:19:7:25 | ControlFlowNode for ImportMember | test_azure_client.py:19:39:19:46 | ControlFlowNode for full_url | The full URL of this request depends on a $@. | test_azure_client.py:7:19:7:25 | ControlFlowNode for ImportMember | user-provided value |
| test_azure_client.py:21:9:21:39 | ControlFlowNode for KeyClient() | test_azure_client.py:7:19:7:25 | ControlFlowNode for ImportMember | test_azure_client.py:21:19:21:26 | ControlFlowNode for full_url | The full URL of this request depends on a $@. | test_azure_client.py:7:19:7:25 | ControlFlowNode for ImportMember | user-provided value |
| test_azure_client.py:23:9:23:89 | ControlFlowNode for Attribute() | test_azure_client.py:7:19:7:25 | ControlFlowNode for ImportMember | test_azure_client.py:23:58:23:65 | ControlFlowNode for full_url | The full URL of this request depends on a $@. | test_azure_client.py:7:19:7:25 | ControlFlowNode for ImportMember | user-provided value |
| test_azure_client.py:32:5:37:5 | ControlFlowNode for download_blob_from_url() | test_azure_client.py:7:19:7:25 | ControlFlowNode for ImportMember | test_azure_client.py:33:18:33:25 | ControlFlowNode for full_url | The full URL of this request depends on a $@. | test_azure_client.py:7:19:7:25 | ControlFlowNode for ImportMember | user-provided value |
| test_azure_client.py:31:5:36:5 | ControlFlowNode for download_blob_from_url() | test_azure_client.py:7:19:7:25 | ControlFlowNode for ImportMember | test_azure_client.py:32:18:32:25 | ControlFlowNode for full_url | The full URL of this request depends on a $@. | test_azure_client.py:7:19:7:25 | ControlFlowNode for ImportMember | user-provided value |
| test_http_client.py:14:5:14:36 | ControlFlowNode for Attribute() | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:13:27:13:37 | ControlFlowNode for unsafe_host | The full URL of this request depends on a $@. | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value |
| test_http_client.py:14:5:14:36 | ControlFlowNode for Attribute() | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:14:25:14:35 | ControlFlowNode for unsafe_path | The full URL of this request depends on a $@. | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value |
| test_http_client.py:19:5:19:36 | ControlFlowNode for Attribute() | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:18:27:18:37 | ControlFlowNode for unsafe_host | The full URL of this request depends on a $@. | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value |

View File

@@ -89,12 +89,12 @@ edges
| test_azure_client.py:13:5:13:7 | ControlFlowNode for url | test_azure_client.py:18:39:18:41 | ControlFlowNode for url | provenance | Sink:MaD:38 |
| test_azure_client.py:13:5:13:7 | ControlFlowNode for url | test_azure_client.py:20:19:20:21 | ControlFlowNode for url | provenance | Sink:MaD:14 |
| test_azure_client.py:13:5:13:7 | ControlFlowNode for url | test_azure_client.py:22:58:22:60 | ControlFlowNode for url | provenance | Sink:MaD:26 |
| test_azure_client.py:13:5:13:7 | ControlFlowNode for url | test_azure_client.py:27:18:27:20 | ControlFlowNode for url | provenance | Sink:MaD:27 |
| test_azure_client.py:13:5:13:7 | ControlFlowNode for url | test_azure_client.py:26:18:26:20 | ControlFlowNode for url | provenance | Sink:MaD:27 |
| test_azure_client.py:14:5:14:12 | ControlFlowNode for full_url | test_azure_client.py:17:32:17:39 | ControlFlowNode for full_url | provenance | Sink:MaD:15 |
| test_azure_client.py:14:5:14:12 | ControlFlowNode for full_url | test_azure_client.py:19:39:19:46 | ControlFlowNode for full_url | provenance | Sink:MaD:38 |
| test_azure_client.py:14:5:14:12 | ControlFlowNode for full_url | test_azure_client.py:21:19:21:26 | ControlFlowNode for full_url | provenance | Sink:MaD:14 |
| test_azure_client.py:14:5:14:12 | ControlFlowNode for full_url | test_azure_client.py:23:58:23:65 | ControlFlowNode for full_url | provenance | Sink:MaD:26 |
| test_azure_client.py:14:5:14:12 | ControlFlowNode for full_url | test_azure_client.py:33:18:33:25 | ControlFlowNode for full_url | provenance | Sink:MaD:27 |
| test_azure_client.py:14:5:14:12 | ControlFlowNode for full_url | test_azure_client.py:32:18:32:25 | ControlFlowNode for full_url | provenance | Sink:MaD:27 |
| test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:1:26:1:32 | ControlFlowNode for request | provenance | |
| test_http_client.py:1:26:1:32 | ControlFlowNode for request | test_http_client.py:9:19:9:25 | ControlFlowNode for request | provenance | |
| test_http_client.py:1:26:1:32 | ControlFlowNode for request | test_http_client.py:10:19:10:25 | ControlFlowNode for request | provenance | |
@@ -207,8 +207,8 @@ nodes
| test_azure_client.py:21:19:21:26 | ControlFlowNode for full_url | semmle.label | ControlFlowNode for full_url |
| test_azure_client.py:22:58:22:60 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
| test_azure_client.py:23:58:23:65 | ControlFlowNode for full_url | semmle.label | ControlFlowNode for full_url |
| test_azure_client.py:27:18:27:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
| test_azure_client.py:33:18:33:25 | ControlFlowNode for full_url | semmle.label | ControlFlowNode for full_url |
| test_azure_client.py:26:18:26:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url |
| test_azure_client.py:32:18:32:25 | ControlFlowNode for full_url | semmle.label | ControlFlowNode for full_url |
| test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember |
| test_http_client.py:1:26:1:32 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| test_http_client.py:9:5:9:15 | ControlFlowNode for unsafe_host | semmle.label | ControlFlowNode for unsafe_host |
@@ -245,7 +245,7 @@ subpaths
| test_azure_client.py:18:9:18:42 | ControlFlowNode for Attribute() | test_azure_client.py:7:19:7:25 | ControlFlowNode for ImportMember | test_azure_client.py:18:39:18:41 | ControlFlowNode for url | Part of the URL of this request depends on a $@. | test_azure_client.py:7:19:7:25 | ControlFlowNode for ImportMember | user-provided value |
| test_azure_client.py:20:9:20:34 | ControlFlowNode for KeyClient() | test_azure_client.py:7:19:7:25 | ControlFlowNode for ImportMember | test_azure_client.py:20:19:20:21 | ControlFlowNode for url | Part of the URL of this request depends on a $@. | test_azure_client.py:7:19:7:25 | ControlFlowNode for ImportMember | user-provided value |
| test_azure_client.py:22:9:22:84 | ControlFlowNode for Attribute() | test_azure_client.py:7:19:7:25 | ControlFlowNode for ImportMember | test_azure_client.py:22:58:22:60 | ControlFlowNode for url | Part of the URL of this request depends on a $@. | test_azure_client.py:7:19:7:25 | ControlFlowNode for ImportMember | user-provided value |
| test_azure_client.py:26:5:31:5 | ControlFlowNode for download_blob_from_url() | test_azure_client.py:7:19:7:25 | ControlFlowNode for ImportMember | test_azure_client.py:27:18:27:20 | ControlFlowNode for url | Part of the URL of this request depends on a $@. | test_azure_client.py:7:19:7:25 | ControlFlowNode for ImportMember | user-provided value |
| test_azure_client.py:25:5:30:5 | ControlFlowNode for download_blob_from_url() | test_azure_client.py:7:19:7:25 | ControlFlowNode for ImportMember | test_azure_client.py:26:18:26:20 | ControlFlowNode for url | Part of the URL of this request depends on a $@. | test_azure_client.py:7:19:7:25 | ControlFlowNode for ImportMember | user-provided value |
| test_http_client.py:22:5:22:31 | ControlFlowNode for Attribute() | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:18:27:18:37 | ControlFlowNode for unsafe_host | Part of the URL of this request depends on a $@. | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value |
| test_http_client.py:26:5:26:31 | ControlFlowNode for Attribute() | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:25:27:25:37 | ControlFlowNode for unsafe_host | Part of the URL of this request depends on a $@. | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value |
| test_http_client.py:29:5:29:36 | ControlFlowNode for Attribute() | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:29:25:29:35 | ControlFlowNode for unsafe_path | Part of the URL of this request depends on a $@. | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value |