Procházet zdrojové kódy

Fixes #20442: Mark template-accessible methods with alters_data=True (#21431)

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
Jason Novinger před 15 hodinami
rodič
revize
d6b9d30086

+ 1 - 0
netbox/core/models/files.py

@@ -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):

+ 2 - 0
netbox/core/models/jobs.py

@@ -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):
         """

+ 2 - 0
netbox/extras/models/scripts.py

@@ -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

+ 2 - 0
netbox/users/models/preferences.py

@@ -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