Skip to content

Commit

Permalink
Prevent timing attacks to guess Gradio passwords (#7440)
Browse files Browse the repository at this point in the history
* secure timing

* add changeset

* format

* add changeset

---------

Co-authored-by: gradio-pr-bot <[email protected]>
  • Loading branch information
abidlabs and gradio-pr-bot authored Feb 15, 2024
1 parent 6b8a7e5 commit e329f1f
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/fine-pets-switch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"gradio": patch
---

feat:Prevent timing attacks to guess Gradio passwords
7 changes: 6 additions & 1 deletion gradio/route_utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

import hashlib
import hmac
import json
import shutil
from collections import deque
Expand Down Expand Up @@ -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())
3 changes: 2 additions & 1 deletion gradio/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
GradioUploadFile,
MultiPartException,
Request,
compare_passwords_securely,
move_uploaded_files_to_cache,
)
from gradio.state_holder import StateHolder
Expand Down Expand Up @@ -271,7 +272,7 @@ def login(form_data: OAuth2PasswordRequestForm = Depends()):
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
Expand Down
14 changes: 13 additions & 1 deletion test/test_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@
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()
Expand Down Expand Up @@ -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)

0 comments on commit e329f1f

Please sign in to comment.