diff --git a/FAQ.md b/FAQ.md index 1473b302..6276073d 100644 --- a/FAQ.md +++ b/FAQ.md @@ -44,6 +44,7 @@ or the `environment:` section in `compose.yaml` file. | YTP_PLAYLIST_ITEMS_CONCURRENCY | The number of playlist items be to processed at same time | `1` | | YTP_TEMP_DISABLED | Disable temp files handling. | `false` | | YTP_DOWNLOAD_PATH_DEPTH | How many subdirectories to show in auto complete. | `1` | +| YTP_ALLOW_INTERNAL_URLS | Allow requests to internal URLs | `false` | > [!NOTE] > To raise the maximum workers for specific extractor, you need to add a ENV variable that follows the pattern `YTP_MAX_WORKERS_FOR_`. @@ -479,3 +480,10 @@ For more information about the supported codecs, please refer to the [SegmentEnc If GPU encoding fails and software encoding is used, you will have to restart the container to try GPU encoding again. as we only test for GPU encoding once on first video stream. + +# Allowing internal URLs requests + +By default, YTPTube prevents requests to internal resources, for security reasons. However, if you want to allow requests to internal URLs, you can set the `YTP_ALLOW_INTERNAL_URLS` environment variable to `true`. This will allow requests to internal URLs. + +We do not recommend enabling this option unless you know what you are doing, as it can expose your internal network to +potential security risks. This should only be used if it's truly needed. diff --git a/app/library/config.py b/app/library/config.py index 25287879..bb744967 100644 --- a/app/library/config.py +++ b/app/library/config.py @@ -51,6 +51,9 @@ class Config(metaclass=Singleton): temp_disabled: bool = False """Disable the temporary files feature.""" + allow_internal_urls: bool = False + """Allow requests to internal URLs.""" + output_template: str = "%(title)s.%(ext)s" """The output template to use for the downloaded files.""" @@ -240,6 +243,7 @@ class Config(metaclass=Singleton): "ytdlp_auto_update", "prevent_premiere_live", "temp_disabled", + "allow_internal_urls", ) "The variables that are booleans." @@ -433,7 +437,7 @@ class Config(metaclass=Singleton): if "dev-master" == self.app_version: self._version_via_git() - def set_app_path(self, path: Path|str) -> "Config": + def set_app_path(self, path: Path | str) -> "Config": """ Set the root path of the application. diff --git a/app/routes/api/images.py b/app/routes/api/images.py index d88b99e7..db7c92b3 100644 --- a/app/routes/api/images.py +++ b/app/routes/api/images.py @@ -40,7 +40,7 @@ async def get_thumbnail(request: Request, config: Config) -> Response: return web.json_response(data={"error": "URL is required."}, status=web.HTTPForbidden.status_code) try: - validate_url(url) + validate_url(url, allow_internal=config.allow_internal_urls) except ValueError as e: return web.json_response(data={"error": str(e)}, status=web.HTTPForbidden.status_code) diff --git a/app/routes/api/tasks.py b/app/routes/api/tasks.py index 2c52ff6d..75e66d91 100644 --- a/app/routes/api/tasks.py +++ b/app/routes/api/tasks.py @@ -4,6 +4,7 @@ import uuid from aiohttp import web from aiohttp.web import Request, Response +from app.library.config import Config from app.library.encoder import Encoder from app.library.router import route from app.library.Tasks import Task, TaskFailure, TaskResult, Tasks @@ -13,14 +14,14 @@ LOG: logging.Logger = logging.getLogger(__name__) @route("POST", "api/tasks/inspect", "task_handler_inspect") -async def task_handler_inspect(request: Request, tasks: Tasks, encoder: Encoder) -> Response: +async def task_handler_inspect(request: Request, tasks: Tasks, encoder: Encoder, config: Config) -> Response: data = await request.json() url: str | None = data.get("url") if isinstance(data, dict) else None if not url: return web.json_response({"error": "url is required."}, status=web.HTTPBadRequest.status_code) try: - validate_url(url) + validate_url(url, allow_internal=config.allow_internal_urls) except ValueError as e: return web.json_response({"error": str(e)}, status=web.HTTPBadRequest.status_code) diff --git a/app/routes/api/yt_dlp.py b/app/routes/api/yt_dlp.py index f0b8ccdd..72144e92 100644 --- a/app/routes/api/yt_dlp.py +++ b/app/routes/api/yt_dlp.py @@ -102,7 +102,7 @@ async def get_info(request: Request, cache: Cache, config: Config) -> Response: ) try: - validate_url(url) + validate_url(url, allow_internal=config.allow_internal_urls) except ValueError as e: return web.json_response( data={"status": False, "message": str(e), "error": str(e)}, @@ -242,7 +242,7 @@ async def get_options() -> Response: @route("POST", "api/yt-dlp/archive_id/", "get_archive_ids") -async def get_archive_ids(request: Request) -> Response: +async def get_archive_ids(request: Request, config: Config) -> Response: """ Get the yt-dlp CLI options. @@ -264,7 +264,7 @@ async def get_archive_ids(request: Request) -> Response: for i, url in enumerate(data): dct = {"index": i, "url": url} try: - validate_url(url) + validate_url(url, allow_internal=config.allow_internal_urls) dct.update(get_archive_id(url)) except ValueError as e: dct.update({"id": None, "ie_key": None, "archive_id": None, "error": str(e)})