Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions python/ql/lib/semmle/python/Frameworks.qll
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ private import semmle.python.frameworks.ServerLess
private import semmle.python.frameworks.Setuptools
private import semmle.python.frameworks.Simplejson
private import semmle.python.frameworks.SqlAlchemy
private import semmle.python.frameworks.SSRFSink
private import semmle.python.frameworks.Starlette
private import semmle.python.frameworks.Stdlib
private import semmle.python.frameworks.Streamlit
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
extensions:
- addsTo:
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']
34 changes: 34 additions & 0 deletions python/ql/lib/semmle/python/frameworks/Azure.Storage.model.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
extensions:
- addsTo:
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']
38 changes: 38 additions & 0 deletions python/ql/lib/semmle/python/frameworks/SSRFSink.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
private import python
private import semmle.python.Concepts
private import semmle.python.ApiGraphs
private import semmle.python.frameworks.data.ModelsAsData

/**
* INTERNAL: Do not use.
*
* Sets up SSRF sinks as Http::CLient::Request
*/
module SSRFMaDModel {
class SSRFSink extends Http::Client::Request::Range instanceof API::CallNode {
DataFlow::Node urlArg;

SSRFSink() {
(
this.getArg(_) = urlArg
or
this.getArgByName(_) = urlArg
) and
urlArg = ModelOutput::getASinkNode("ssrf").asSink()
}

override DataFlow::Node getAUrlPart() { result = urlArg }

override string getFramework() {
// TOOD: how to get type of this node?
result = "MaD"
}

override predicate disablesCertificateValidation(
DataFlow::Node disablingNode, DataFlow::Node argumentOrigin
) {
// TODO: if you need to define this, you have to special case it for every possible API in MaD
none()
}
}
}
Loading