♻️(back) validate url used in cors_proxy endpoint

The url used by the cors_proxy was not validated, other value than a
http url can be used. We use the built in URLValidator to validate it is
a valid url.
This commit is contained in:
Manuel Raynaud
2025-08-25 16:15:16 +02:00
parent 781c85b66b
commit 247550fc13
2 changed files with 31 additions and 0 deletions

View File

@@ -13,6 +13,7 @@ from django.contrib.postgres.search import TrigramSimilarity
from django.core.cache import cache from django.core.cache import cache
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.files.storage import default_storage from django.core.files.storage import default_storage
from django.core.validators import URLValidator
from django.db import connection, transaction from django.db import connection, transaction
from django.db import models as db from django.db import models as db
from django.db.models.expressions import RawSQL from django.db.models.expressions import RawSQL
@@ -1441,6 +1442,15 @@ class DocumentViewSet(
url = unquote(url) url = unquote(url)
url_validator = URLValidator(schemes=["http", "https"])
try:
url_validator(url)
except drf.exceptions.ValidationError as e:
return drf.response.Response(
{"detail": str(e)},
status=drf.status.HTTP_400_BAD_REQUEST,
)
try: try:
response = requests.get( response = requests.get(
url, url,

View File

@@ -149,3 +149,24 @@ def test_api_docs_cors_proxy_unsupported_media_type():
f"/api/v1.0/documents/{document.id!s}/cors-proxy/?url={url_to_fetch}" f"/api/v1.0/documents/{document.id!s}/cors-proxy/?url={url_to_fetch}"
) )
assert response.status_code == 415 assert response.status_code == 415
@pytest.mark.parametrize(
"url_to_fetch",
[
"ftp://external-url.com/assets/index.html",
"ftps://external-url.com/assets/index.html",
"invalid-url.com",
"ssh://external-url.com/assets/index.html",
],
)
def test_api_docs_cors_proxy_invalid_url(url_to_fetch):
"""Test the CORS proxy API for documents with an invalid URL."""
document = factories.DocumentFactory(link_reach="public")
client = APIClient()
response = client.get(
f"/api/v1.0/documents/{document.id!s}/cors-proxy/?url={url_to_fetch}"
)
assert response.status_code == 400
assert response.json() == ["Enter a valid URL."]