|
8 | 8 |
|
9 | 9 | import colrev.record.record |
10 | 10 | from colrev.constants import Fields |
| 11 | +from urllib.parse import urlsplit |
11 | 12 |
|
12 | 13 | # pylint: disable=invalid-name |
13 | 14 | # pylint: disable=too-many-public-methods |
14 | 15 | # pylint: disable=colrev-missed-constant-usage |
15 | 16 |
|
| 17 | +_ALLOWED_IEEE_HOST = "ieeexploreapi.ieee.org" |
| 18 | +_ALLOWED_IEEE_PATH_PREFIXES = ( |
| 19 | + "/api/v1/search/articles", |
| 20 | + "/api/v1/search/document/", |
| 21 | +) |
| 22 | + |
16 | 23 |
|
17 | 24 | class XPLORE: |
18 | 25 | """XPLORE API class.""" |
@@ -294,12 +301,32 @@ def _build_query(self) -> str: |
294 | 301 |
|
295 | 302 | return url |
296 | 303 |
|
| 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 | + |
297 | 323 | def _query_api(self, url: str) -> str: |
298 | 324 | """Creates the URL for the API call |
299 | 325 | string url Full URL to pass to API |
300 | 326 | return string: Results from API. |
301 | 327 | """ |
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 |
303 | 330 | content = con.read() |
304 | 331 | return content |
305 | 332 |
|
|
0 commit comments