[SECURITY] Allowlisting and changed salts for safelink and safelink_callback (CVE-2026-13602)

---------

Co-authored-by: Raphael Michel <michel@pretix.eu>
This commit is contained in:
Mira Weller
2026-07-01 15:15:43 +02:00
committed by Raphael Michel
co-authored by Raphael Michel
parent e42d3d632f
commit 000bf54105
3 changed files with 17 additions and 7 deletions
+14 -4
View File
@@ -19,6 +19,7 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
import logging
import urllib.parse
from django.core import signing
@@ -26,6 +27,8 @@ from django.http import HttpResponseBadRequest, HttpResponseRedirect
from django.shortcuts import render
from django.urls import reverse
logger = logging.getLogger(__name__)
def _is_samesite_referer(request):
referer = request.headers.get('referer')
@@ -42,11 +45,14 @@ def _is_samesite_referer(request):
def redir_view(request):
signer = signing.Signer(salt='safe-redirect')
try:
url = signer.unsign(request.GET.get('url', ''))
url = signing.Signer(salt='safelink-url').unsign(request.GET.get('url', ''))
except signing.BadSignature:
return HttpResponseBadRequest('Invalid parameter')
try:
# Backwards-compatibility for a change in 2026-06, remove after a while
url = signing.Signer(salt='safe-redirect').unsign(request.GET.get('url', ''))
except signing.BadSignature:
return HttpResponseBadRequest('Invalid parameter')
if not _is_samesite_referer(request):
u = urllib.parse.urlparse(url)
@@ -61,5 +67,9 @@ def redir_view(request):
def safelink(url):
signer = signing.Signer(salt='safe-redirect')
url = str(url)
if not (url.startswith('https://') or url.startswith('http://') or url.startswith("/")):
logger.warning('Invalid URL passed to safelink: %r', url)
return '#invalid-url'
signer = signing.Signer(salt='safelink-url')
return reverse('redirect') + '?url=' + urllib.parse.quote(signer.sign(url))