Skip to content

Commit 97192d2

Browse files
committed
ieee: validate api-url
1 parent 9e355ab commit 97192d2

1 file changed

Lines changed: 28 additions & 1 deletion

File tree

colrev/packages/ieee/src/ieee_api.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,18 @@
88

99
import colrev.record.record
1010
from colrev.constants import Fields
11+
from urllib.parse import urlsplit
1112

1213
# pylint: disable=invalid-name
1314
# pylint: disable=too-many-public-methods
1415
# pylint: disable=colrev-missed-constant-usage
1516

17+
_ALLOWED_IEEE_HOST = "ieeexploreapi.ieee.org"
18+
_ALLOWED_IEEE_PATH_PREFIXES = (
19+
"/api/v1/search/articles",
20+
"/api/v1/search/document/",
21+
)
22+
1623

1724
class XPLORE:
1825
"""XPLORE API class."""
@@ -294,12 +301,32 @@ def _build_query(self) -> str:
294301

295302
return url
296303

304+
def _validate_ieee_api_url(self, url: str) -> None:
305+
"""Validate that the URL targets the expected IEEE API endpoint."""
306+
parsed_url = urlsplit(url)
307+
308+
if parsed_url.scheme != "https":
309+
raise ValueError("IEEE API requests must use HTTPS.")
310+
311+
if parsed_url.hostname != _ALLOWED_IEEE_HOST:
312+
raise ValueError(f"Unexpected IEEE API host: {parsed_url.hostname!r}")
313+
314+
if not any(
315+
parsed_url.path.startswith(path_prefix)
316+
for path_prefix in _ALLOWED_IEEE_PATH_PREFIXES
317+
):
318+
raise ValueError(f"Unexpected IEEE API path: {parsed_url.path!r}")
319+
320+
if parsed_url.username is not None or parsed_url.password is not None:
321+
raise ValueError("IEEE API URLs must not include credentials.")
322+
297323
def _query_api(self, url: str) -> str:
298324
"""Creates the URL for the API call
299325
string url Full URL to pass to API
300326
return string: Results from API.
301327
"""
302-
with urllib.request.urlopen(url) as con:
328+
self._validate_ieee_api_url(url)
329+
with urllib.request.urlopen(url) as con: # nosec B310
303330
content = con.read()
304331
return content
305332

0 commit comments

Comments
 (0)