forked from Significant-Gravitas/AutoGPT
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Validate URLs in web commands before execution (Significant-Gravitas#…
…2616) Co-authored-by: Reinier van der Leer <[email protected]>
- Loading branch information
Showing
7 changed files
with
120 additions
and
82 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import functools | ||
from typing import Any, Callable | ||
from urllib.parse import urljoin, urlparse | ||
|
||
from requests.compat import urljoin | ||
|
||
|
||
def validate_url(func: Callable[..., Any]) -> Any: | ||
"""The method decorator validate_url is used to validate urls for any command that requires | ||
a url as an arugment""" | ||
|
||
@functools.wraps(func) | ||
def wrapper(url: str, *args, **kwargs) -> Any: | ||
"""Check if the URL is valid using a basic check, urllib check, and local file check | ||
Args: | ||
url (str): The URL to check | ||
Returns: | ||
the result of the wrapped function | ||
Raises: | ||
ValueError if the url fails any of the validation tests | ||
""" | ||
# Most basic check if the URL is valid: | ||
if not url.startswith("http://") and not url.startswith("https://"): | ||
raise ValueError("Invalid URL format") | ||
if not is_valid_url(url): | ||
raise ValueError("Missing Scheme or Network location") | ||
# Restrict access to local files | ||
if check_local_file_access(url): | ||
raise ValueError("Access to local files is restricted") | ||
|
||
return func(sanitize_url(url), *args, **kwargs) | ||
|
||
return wrapper | ||
|
||
|
||
def is_valid_url(url: str) -> bool: | ||
"""Check if the URL is valid | ||
Args: | ||
url (str): The URL to check | ||
Returns: | ||
bool: True if the URL is valid, False otherwise | ||
""" | ||
try: | ||
result = urlparse(url) | ||
return all([result.scheme, result.netloc]) | ||
except ValueError: | ||
return False | ||
|
||
|
||
def sanitize_url(url: str) -> str: | ||
"""Sanitize the URL | ||
Args: | ||
url (str): The URL to sanitize | ||
Returns: | ||
str: The sanitized URL | ||
""" | ||
return urljoin(url, urlparse(url).path) | ||
|
||
|
||
def check_local_file_access(url: str) -> bool: | ||
"""Check if the URL is a local file | ||
Args: | ||
url (str): The URL to check | ||
Returns: | ||
bool: True if the URL is a local file, False otherwise | ||
""" | ||
local_prefixes = [ | ||
"file:///", | ||
"file://localhost/", | ||
"file://localhost", | ||
"http://localhost", | ||
"http://localhost/", | ||
"https://localhost", | ||
"https://localhost/", | ||
"http://2130706433", | ||
"http://2130706433/", | ||
"https://2130706433", | ||
"https://2130706433/", | ||
"http://127.0.0.1/", | ||
"http://127.0.0.1", | ||
"https://127.0.0.1/", | ||
"https://127.0.0.1", | ||
"https://0.0.0.0/", | ||
"https://0.0.0.0", | ||
"http://0.0.0.0/", | ||
"http://0.0.0.0", | ||
"http://0000", | ||
"http://0000/", | ||
"https://0000", | ||
"https://0000/", | ||
] | ||
return any(url.startswith(prefix) for prefix in local_prefixes) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters