[SECURITY] Bind relevant cached file downloads to the current session

This commit is contained in:
Raphael Michel
2020-12-18 19:17:23 +01:00
parent a3dd015c23
commit c60a25f2bc
11 changed files with 42 additions and 9 deletions

View File

@@ -0,0 +1,23 @@
# Generated by Django 3.0.11 on 2020-12-18 18:10
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('pretixbase', '0173_auto_20201211_1648'),
]
operations = [
migrations.AddField(
model_name='cachedfile',
name='session_key',
field=models.TextField(null=True),
),
migrations.AddField(
model_name='cachedfile',
name='web_download',
field=models.BooleanField(default=True),
),
]

View File

@@ -28,6 +28,8 @@ class CachedFile(models.Model):
filename = models.CharField(max_length=255)
type = models.CharField(max_length=255)
file = models.FileField(null=True, blank=True, upload_to=cachedfile_name, max_length=255)
web_download = models.BooleanField(default=True) # allow web download, True for backwards compatibility in plugins
session_key = models.TextField(null=True, blank=True) # only allow download in this session
@receiver(post_delete, sender=CachedFile)

View File

@@ -17,7 +17,7 @@ from pretix.celery_app import app
@app.task(base=ProfiledEventTask)
def export(event: Event, shredders: List[str]) -> None:
def export(event: Event, shredders: List[str], session_key=None) -> None:
known_shredders = event.get_data_shredders()
with NamedTemporaryFile() as rawfile:
@@ -55,6 +55,8 @@ def export(event: Event, shredders: List[str]) -> None:
cf.date = now()
cf.filename = event.slug + '.zip'
cf.type = 'application/zip'
cf.session_key = session_key
cf.web_download = True
cf.expires = now() + timedelta(hours=1)
cf.save()
cf.file.save(cachedfile_name(cf, cf.filename), rawfile)

View File

@@ -13,7 +13,11 @@ class DownloadView(TemplateView):
@cached_property
def object(self) -> CachedFile:
try:
return get_object_or_404(CachedFile, id=self.kwargs['id'])
o = get_object_or_404(CachedFile, id=self.kwargs['id'], web_download=True)
if o.session_key:
if o.session_key != self.request.session.session_key:
raise Http404()
return o
except ValueError: # Invalid URLs
raise Http404()