gradio-app / gradio

Build and share delightful machine learning apps, all in Python. 🌟 Star to support our work!
http://www.gradio.app
Apache License 2.0
32.26k stars 2.41k forks source link

Dropdown not working in Gradio app when served through Nginx with security headers #7775

Open llmwesee opened 6 months ago

llmwesee commented 6 months ago

Description

When serving a Gradio app through Nginx with security headers configured, the dropdown feature within the app becomes unresponsive and stuck. This issue persists despite providing a nonce in the headers.

My Nginix config

we have gradio app we have nginx file and dropdown is ont working nginx header:

server {
    listen 443 ssl;
    server_name localhost;

    ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
    ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;  # Fixed the key 
file path assuming it's .key, not .crt

    # # Set Content Security Policy (CSP) header

    add_header Content-Security-Policy "default-src 'self' ;worker-src 'self' bl
ob:;img-src 'self' data:; form-action 'self'; frame-ancestors 'self'; style-src 
'self' 'nonce-hello' ; frame-src 'self'; script-src 'self' 'nonce-script-hello';
";

    # Enable HTTP Strict Transport Security (HSTS) to force HTTPS
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" a
lways;

    # Prevent browsers from MIME sniffing
    add_header X-Content-Type-Options "nosniff" always;

    # Enable Cross-Origin Resource Sharing (CORS) for specific domains
    add_header Access-Control-Allow-Origin "https://localhost" always;

    # Prevent Clickjacking attacks
    add_header X-Frame-Options "SAMEORIGIN" always;

    # Enable XSS Protection
    add_header X-XSS-Protection "1; mode=block" always;

    location / {
        proxy_pass http://127.0.0.1:7860;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_buffering off;
        proxy_redirect off;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

}

we cant remnove header , because its for securtyy purpose i.e csp headres and many others issues when we run this porject droipdwon feature not working it get stucked.But without nginx configs it work perfectly fine

we provided nonce but its not working nonce is working in script tag but not in javascript functions

Steps to Reproduce

Set up Nginx server with the provided configuration file. Serve the Gradio app through this Nginx server. Access the Gradio app and attempt to use the dropdown feature. Expected Behavior The dropdown feature should work smoothly without any issues when served through Nginx with the provided security headers.

Actual Behavior

The dropdown feature becomes unresponsive and stuck when served through Nginx with the provided security headers.

Additional Context

The provided Nginx configuration file includes various security headers (such as CSP, HSTS, etc.) for security purposes, which cannot be removed. Nonce has been provided in the headers, and it's functioning correctly in script tags but not in JavaScript functions.

Have you searched existing issues? 🔎

Reproduction

server {
    listen 443 ssl;
    server_name localhost;

    ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
    ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;  # Fixed the key 
file path assuming it's .key, not .crt

    # # Set Content Security Policy (CSP) header

    add_header Content-Security-Policy "default-src 'self' ;worker-src 'self' bl
ob:;img-src 'self' data:; form-action 'self'; frame-ancestors 'self'; style-src 
'self' 'nonce-hello' ; frame-src 'self'; script-src 'self' 'nonce-script-hello';
";

    # Enable HTTP Strict Transport Security (HSTS) to force HTTPS
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" a
lways;

    # Prevent browsers from MIME sniffing
    add_header X-Content-Type-Options "nosniff" always;

    # Enable Cross-Origin Resource Sharing (CORS) for specific domains
    add_header Access-Control-Allow-Origin "https://localhost" always;

    # Prevent Clickjacking attacks
    add_header X-Frame-Options "SAMEORIGIN" always;

    # Enable XSS Protection
    add_header X-XSS-Protection "1; mode=block" always;

    location / {
        proxy_pass http://127.0.0.1:7860;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_buffering off;
        proxy_redirect off;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

}

we cant remnove header , because its for securtyy purpose i.e csp headres and many others issues when we run this porject droipdwon feature not working it get stucked.But without nginx configs it work perfectly fine

we provided nonce but its not working nonce is working in script tag but not in javascript functions


### Screenshot

_No response_

### Logs

_No response_

### System Info

```shell
Gradio Environment Information:
------------------------------
Operating System: Linux
gradio version: 4.19.2
gradio_client version: 0.10.1

------------------------------------------------
gradio dependencies in your environment:

aiofiles: 23.2.1
altair: 5.0.1
fastapi: 0.101.1
ffmpy: 0.3.1
gradio-client==0.10.1 is not installed.
httpx: 0.24.1
huggingface-hub: 0.19.4
importlib-resources: 6.1.0
jinja2: 3.1.2
markupsafe: 2.1.3
matplotlib: 3.7.1
numpy: 1.23.4
orjson: 3.9.15
packaging: 23.2
pandas: 2.0.2
pillow: 9.5.0
pydantic: 2.6.3
pydub: 0.25.1
python-multipart: 0.0.9
pyyaml: 6.0.1
ruff: 0.2.2
semantic-version: 2.10.0
tomlkit==0.12.0 is not installed.
typer: 0.9.0
typing-extensions: 4.7.1
uvicorn: 0.23.2
authlib; extra == 'oauth' is not installed.
itsdangerous; extra == 'oauth' is not installed.

gradio_client dependencies in your environment:

fsspec: 2023.6.0
httpx: 0.24.1
huggingface-hub: 0.19.4
packaging: 23.2
typing-extensions: 4.7.1
websockets: 11.0.3

Severity

I can work around it

abidlabs commented 6 months ago

@llmwesee do you see any errors in the console logs?

llmwesee commented 6 months ago

Sure, It look like this:

Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self' 'nonce-hello'". Either the 'unsafe-inline' keyword, a hash ('sha256-9OlNO0DNEeaVzHL4RZwCLsBHA8WBQ8toBp/4F5XV2nc='), or a nonce ('nonce-...') is required to enable inline execution.

append @ svelte.js:563 append_stylesheet @ svelte.js:617 append_empty_stylesheet @ svelte.js:607 create_style_information @ svelte.js:1663 create_rule @ svelte.js:1689 go @ svelte.js:2503 run @ svelte.js:2561 (anonymous) @ DropdownOptions.svelte:79 flush @ svelte.js:2108 svelte.js:1692 Uncaught (in promise) TypeError: Cannot read properties of null (reading 'insertRule') at create_rule (svelte.js:1692:14) at go (svelte.js:2503:22) at Object.run (svelte.js:2561:5) at DropdownOptions.svelte:79:40 at flush (svelte.js:2108:5) image

llmwesee commented 6 months ago

@abidlabs I have replicated the same error with latest gradio version: 4.22.0

import gradio as gr

print(gr.__file__)
# Define a function to be called when the dropdown selection changes
def greet(name):
    return f"Hello, {name}!"

# Create the Gradio interface with a dropdown menu
interface = gr.Interface(
    fn=greet,
    inputs=[gr.Dropdown(choices=["Alice", "Bob", "Charlie"], label="Select a name")],
    outputs="text",
    title="Dropdown Greeting App"
)

# Launch the interface
interface.launch()

I have used simple boilerplate dropdown with gradio, I simply just want to use this app with csp headers on, specifically script-src and style-src with self .Plz tell me feasible solution

image

pseudotensor commented 5 months ago

@abidlabs Is there something more you need for this issue?

abidlabs commented 5 months ago

Looking into it!