The root cause of the vulnerability is a missing authorization check on the restoreTenant GraphQL mutation. The adminMutationMWConfig map in graphql/admin/admin.go defines the middleware (including authentication and IP whitelisting) for each administrative mutation. The restoreTenant mutation was absent from this map, causing the middleware chain to be empty and allowing unauthenticated execution.
An attacker can send a crafted restoreTenant mutation to a vulnerable Dgraph instance. This call is processed without any authentication, directly invoking the admin.RestoreTenant resolver. This resolver, in turn, calls other functions like worker.ProcessRestoreRequest, which handle the backup and restore logic.
By controlling the parameters of the restoreTenant mutation, an attacker can:
- Overwrite the database: By providing an S3 URL to a malicious backup.
- Read local files: By using a
file:// URL in the location parameter, which triggers fileHandler.Read and fileHandler.ListPaths to access the filesystem. Further file reads are possible via the encryptionKeyFile and vaultRoleIDFile parameters, which are processed by functions like worker.BuildEncFlag.
- Perform SSRF: By providing an internal IP address as the S3 endpoint or in the
vaultAddr parameter.
The identified vulnerable functions are the key components in this exploit chain, starting from the unauthenticated entry point (admin.RestoreTenant) to the functions that perform the malicious actions (worker.ProcessRestoreRequest, fileHandler.Read, etc.).