Compare commits

...

1 Commits

Author SHA1 Message Date
Jason Novinger
57fe5ee1ea Fixes #20442: Mark template-accessible methods with alters_data=True
Add alters_data=True to methods that modify database or filesystem state
and are accessible from Jinja2 sandbox template contexts:

- UserConfig.set(), clear(): Persist preference changes when commit=True
- ManagedFile.sync_data(): Writes files to scripts/reports storage
- ScriptModule.sync_classes(), sync_data(): Creates/deletes Script objects
- Job.start(), terminate(): Updates job status, creates notifications

Methods intentionally not protected:
- DataFile.refresh_from_disk(): Only modifies instance attributes in memory
- Overridden save()/delete(): Django's AltersData mixin auto-propagates
- Properties like Script.python_class: Not callable in template context

Ref: #20356 for exploit details demonstrating the vulnerability
2026-02-13 06:53:28 -06:00
4 changed files with 7 additions and 0 deletions

View File

@@ -89,6 +89,7 @@ class ManagedFile(SyncedDataMixin, models.Model):
with storage.open(self.full_path, 'wb+') as new_file:
new_file.write(self.data_file.data)
sync_data.alters_data = True
@cached_property
def storage(self):

View File

@@ -216,6 +216,7 @@ class Job(models.Model):
# Send signal
job_start.send(self)
start.alters_data = True
def terminate(self, status=JobStatusChoices.STATUS_COMPLETED, error=None):
"""
@@ -245,6 +246,7 @@ class Job(models.Model):
# Send signal
job_end.send(self)
terminate.alters_data = True
def log(self, record: logging.LogRecord):
"""

View File

@@ -178,9 +178,11 @@ class ScriptModule(PythonModuleMixin, JobsMixin, ManagedFile):
name=name,
is_executable=True,
)
sync_classes.alters_data = True
def sync_data(self):
super().sync_data()
sync_data.alters_data = True
def save(self, *args, **kwargs):
self.file_root = ManagedFileRootPathChoices.SCRIPTS

View File

@@ -113,6 +113,7 @@ class UserConfig(models.Model):
if commit:
self.save()
set.alters_data = True
def clear(self, path, commit=False):
"""
@@ -140,3 +141,4 @@ class UserConfig(models.Model):
if commit:
self.save()
clear.alters_data = True