Skip to content

Decode stored parameter sets without importing modules named by files - #408

Merged
PierreRaybaut merged 3 commits into
developfrom
fix/407-stored-parameter-classes
Oct 20, 2026
Merged

PierreRaybaut merged 3 commits into
developfrom
fix/407-stored-parameter-classes

Conversation

@PierreRaybaut

Copy link
Copy Markdown
Contributor

Fixes #407.

Problem

DataLab decoded the parameter sets stored in workspaces with guidata's permissive json_to_dataset. This concerns object processing parameters, analysis-result parameters, creation parameters and History arguments. That decoder imports the module named by the stored class_module and calls the object named by class_name, so a modified workspace could make DataLab import any installed module and call any zero-argument callable, for example to make it quit. Selecting an object of such a workspace was enough.

Fix

  • New datalab.utils.datasetjson.decode_dataset_json, used by the 9 former call sites:
    • ProcessingParameters.set_param_from_json
    • BaseResultAdapter.get_param
    • extract_creation_parameters and convert_legacy_creation_parameters
    • decode_kwargs and copy_history_value
  • The stored class must be a guidata DataSet subclass, defined either in a module already loaded by DataLab (DataLab, Sigima, guidata, installed plugins) or in a public module of datalab, guidata, sigima or sigimax, which is then imported.
  • Private modules (such as __main__) and test modules are never imported for a file. Nothing else is imported or called.
  • A refused class raises ParameterClassError (a ValueError), so every caller reports it as it already reported unreadable parameters. BaseResultAdapter.get_param now warns and returns None instead of raising, so the Properties panel still shows the object.
  • Fields are read as before: unknown fields are ignored and missing fields keep their defaults. Parameters saved by earlier versions therefore stay readable, which a strict field validation (json_to_dataset(strict=True)) would not guarantee when parameter classes evolve.

Behaviour change

The parameters of a plugin that is not loaded (removed or disabled) are now reported as unreadable instead of importing the plugin module.

Tests

New datalab/tests/features/common/stored_parameters_unit_test.py (24 tests):

  • The reproduction of the issue and crafted payloads are refused for each call site: no module is imported and no callable is called.
  • Legitimate Sigima parameters are decoded exactly as guidata decoded them; plugin parameter classes stay usable; fields are read tolerantly.
  • A guard test fails if json_to_dataset is used again anywhere in the datalab package outside tests.
  • Without the fix, the five call-site and guard tests fail.

Regression: datalab/tests/features/common and datalab/tests/features/hdf5. Ruff format and check, Pylint 10/10 on the changed modules (no new message in processor/base.py).

Translations and documentation

  • French UI translation of the new warning ("Failed to deserialize analysis parameters from JSON.").
  • Release notes 1.4 (Bug Fixes, "Security") with their French translation. Only this entry was added to the catalogue; the pending translation of the remote-control entries of Remote load_from_files / load_from_directory intermittently ignored #398 is left to its own change.

Out of scope

  • Remote control (XML-RPC): its clients can already import and run macros by design.
  • NativeH5Reader callable references: they are restricted to packages named datalab*, and are returned, not called.

Follow-up once merged: DataLab-Capsule doc/security.md lists this as a residual risk of DataLab Desktop and can then state that it is fixed in DataLab 1.4.0.

… named by files (#407)

Parameters stored with objects, analysis results, creation metadata and History actions were decoded with guidata's permissive json_to_dataset, which imports the module named in the file and calls the object it names. A modified workspace could thus make DataLab import any installed module and call any zero-argument callable when an object was selected.

decode_dataset_json only builds guidata DataSet subclasses from modules already loaded (DataLab, Sigima, guidata, installed plugins) or from public modules of DataLab's own packages; nothing else is imported or called. Fields are still read tolerantly, so parameters saved by earlier versions stay readable.

Assisted-by: Claude Opus 5.5
Crafted payloads are refused at every call site without importing or calling anything, legitimate and plugin parameters are decoded as before, and a guard fails if json_to_dataset is used again in the datalab package.

Assisted-by: Claude Opus 5.5
English entry and its French translation; only this entry is added to the French catalogue.

Assisted-by: Claude Opus 5.5
@PierreRaybaut PierreRaybaut added the bug Something isn't working label Oct 20, 2026
@PierreRaybaut
PierreRaybaut merged commit b6d78b3 into develop Oct 20, 2026
6 checks passed
@PierreRaybaut
PierreRaybaut deleted the fix/407-stored-parameter-classes branch October 23, 2026 14:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant