Prevent timing attacks to guess Gradio passwords (#7440)

* secure timing

* add changeset

* format

* add changeset

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
This commit is contained in:
Abubakar Abid 2024-02-15 12:59:08 -08:00 committed by GitHub
parent 6b8a7e5d36
commit e329f1fd38
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 26 additions and 3 deletions

View File

@ -0,0 +1,5 @@
---
"gradio": patch
---
feat:Prevent timing attacks to guess Gradio passwords

View File

@ -1,6 +1,7 @@
from __future__ import annotations
import hashlib
import hmac
import json
import shutil
from collections import deque
@ -569,8 +570,12 @@ def update_root_in_config(config: dict, root: str) -> dict:
root url has changed, all of the urls in the config that correspond to component
file urls are updated to use the new root url.
"""
previous_root = config.get("root", None)
previous_root = config.get("root")
if previous_root is None or previous_root != root:
config["root"] = root
config = processing_utils.add_root_url(config, root, previous_root)
return config
def compare_passwords_securely(input_password: str, correct_password: str) -> bool:
return hmac.compare_digest(input_password.encode(), correct_password.encode())

View File

@ -63,6 +63,7 @@ from gradio.route_utils import ( # noqa: F401
GradioUploadFile,
MultiPartException,
Request,
compare_passwords_securely,
move_uploaded_files_to_cache,
)
from gradio.state_holder import StateHolder
@ -271,7 +272,7 @@ class App(FastAPI):
if (
not callable(app.auth)
and username in app.auth
and app.auth[username] == password
and compare_passwords_securely(password, app.auth[username]) # type: ignore
) or (callable(app.auth) and app.auth.__call__(username, password)):
token = secrets.token_urlsafe(16)
app.tokens[token] = username

View File

@ -25,7 +25,11 @@ from gradio import (
routes,
wasm_utils,
)
from gradio.route_utils import FnIndexInferError, get_root_url
from gradio.route_utils import (
FnIndexInferError,
compare_passwords_securely,
get_root_url,
)
@pytest.fixture()
@ -921,3 +925,11 @@ def test_component_server_endpoints(connect):
def test_get_root_url(request_url, route_path, root_path, expected_root_url):
request = Request({"path": request_url, "type": "http", "headers": {}})
assert get_root_url(request, route_path, root_path) == expected_root_url
def test_compare_passwords_securely():
password1 = "password"
password2 = "pässword"
assert compare_passwords_securely(password1, password1)
assert not compare_passwords_securely(password1, password2)
assert compare_passwords_securely(password2, password2)