mirror of
https://github.com/simonw/dclient.git
synced 2026-09-22 00:14:15 +02:00
More secure URL matching for auth tokens
This commit is contained in:
parent
5a370b725e
commit
7807b8363f
3 changed files with 73 additions and 1 deletions
|
|
@ -2,6 +2,7 @@ import click
|
|||
import httpx
|
||||
import json
|
||||
import pathlib
|
||||
from .utils import url_matches_prefix
|
||||
|
||||
|
||||
def get_config_dir():
|
||||
|
|
@ -79,7 +80,7 @@ def query(url, sql, token):
|
|||
def _token_for_url_from_auth(url, auth_file):
|
||||
auths = _load_auths(auth_file)
|
||||
for auth_url, token in auths.items():
|
||||
if url.startswith(auth_url):
|
||||
if url_matches_prefix(url, auth_url):
|
||||
return token
|
||||
|
||||
|
||||
|
|
|
|||
30
dclient/utils.py
Normal file
30
dclient/utils.py
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
from urllib.parse import urlparse
|
||||
|
||||
|
||||
def url_matches_prefix(url: str, prefix: str) -> bool:
|
||||
url_parsed = urlparse(url)
|
||||
prefix_parsed = urlparse(prefix)
|
||||
|
||||
if (
|
||||
url_parsed.scheme != prefix_parsed.scheme
|
||||
or url_parsed.netloc != prefix_parsed.netloc
|
||||
):
|
||||
return False
|
||||
|
||||
if url_parsed.path == prefix_parsed.path:
|
||||
return True
|
||||
|
||||
url_path = url_parsed.path
|
||||
|
||||
# Add '/' to the end of the paths if they don't already end with '/'
|
||||
prefix_path = prefix_parsed.path
|
||||
|
||||
# Special treatment for /foo.json
|
||||
if url_path.endswith(".json"):
|
||||
if prefix_path + ".json" == url_path:
|
||||
return True
|
||||
|
||||
if not prefix_path.endswith("/"):
|
||||
prefix_path += "/"
|
||||
|
||||
return url_path.startswith(prefix_path)
|
||||
41
tests/test_utils.py
Normal file
41
tests/test_utils.py
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
from dclient.utils import url_matches_prefix
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"url,prefix_url,expected",
|
||||
(
|
||||
("https://example.com/foo/bar", "https://example.com/foo", True),
|
||||
("https://example.com/foo/bar2", "https://example.com/foo/bar", False),
|
||||
("https://example.com/foo/bar/baz", "https://example.com/foo/bar", True),
|
||||
("https://example.com/foo/bar/baz", "https://example.com/foo", True),
|
||||
("https://example.com/foo.json", "https://example.com/foo", True),
|
||||
# different scheme
|
||||
(
|
||||
"http://example.com/foo/bar",
|
||||
"https://example.com/foo",
|
||||
False,
|
||||
),
|
||||
# different netloc
|
||||
(
|
||||
"https://example.org/foo/bar",
|
||||
"https://example.com/foo",
|
||||
False,
|
||||
),
|
||||
# exactly the same
|
||||
("https://example.com/foo", "https://example.com/foo", True),
|
||||
# trailing '/'
|
||||
(
|
||||
"https://example.com/foo/bar",
|
||||
"https://example.com/foo/bar/",
|
||||
False,
|
||||
),
|
||||
(
|
||||
"https://example.com/foo/bar/baz",
|
||||
"https://example.com/foo/bar/",
|
||||
True,
|
||||
),
|
||||
),
|
||||
)
|
||||
def test_url_matches_prefix(url, prefix_url, expected):
|
||||
assert url_matches_prefix(url, prefix_url) == expected
|
||||
Loading…
Add table
Add a link
Reference in a new issue