Skip to content

Commit 9bc973b

Browse files
sytelusclaude
andcommitted
harden yaml_ordered_load and fix file_stream bugs found in security audit
Remove Loader parameter from yaml_ordered_load to prevent callers from bypassing SafeLoader. Hardcode yaml.SafeLoader directly in the class definition. Fix two bugs in FileStream: save() referenced undefined variable `val` instead of `from_stream`, and close() accessed self._file.name after setting self._file to None. Update README security summary table to reflect RestrictedUnpickler mitigations. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent afe9390 commit 9bc973b

3 files changed

Lines changed: 7 additions & 6 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ TensorWatch supports Python 3.x and is tested with PyTorch 0.4-1.x. Most feature
9090
> | Risk | Mitigation | User Action |
9191
> |------|-----------|-------------|
9292
> | `eval()` on expressions from clients | HMAC auth + localhost binding | Never expose ports to untrusted networks |
93-
> | `pickle.loads()` from ZMQ | HMAC verification before deserialization | Keep HMAC key secret |
94-
> | `pickle.load()` from files | None (user-controlled file paths) | Only load trusted files |
93+
> | `pickle.loads()` from ZMQ | HMAC + RestrictedUnpickler | Keep HMAC key secret |
94+
> | `pickle.load()` from files | RestrictedUnpickler (defense-in-depth) | Only load trusted files |
9595
> | ZMQ port exposure | Binds to `127.0.0.1` by default | Do not change to `0.0.0.0` in untrusted environments |
9696
9797
## How to Use It

tensorwatch/file_stream.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ def __init__(self, for_write:bool, file_name:str, stream_name:str=None, console_
1919

2020
def close(self):
2121
if not self._file.closed:
22+
file_name = os.path.realpath(self._file.name)
2223
self._file.close()
2324
self._file = None
24-
utils.debug_log('FileStream is closed', os.path.realpath(self._file.name), verbosity=0)
25+
utils.debug_log('FileStream is closed', file_name, verbosity=0)
2526
super(FileStream, self).close()
2627

2728
def write(self, val:Any, from_stream:'Stream'=None):
@@ -56,5 +57,5 @@ def load(self, from_stream:'Stream'=None):
5657
def save(self, from_stream:'Stream'=None):
5758
if not self._file.closed:
5859
self._file.flush()
59-
super(FileStream, self).save(val)
60+
super(FileStream, self).save(from_stream)
6061

tensorwatch/model_graph/hiddenlayer/distiller_utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -665,12 +665,12 @@ def set_deterministic(seed=0):
665665
torch.backends.cudnn.benchmark = False
666666

667667

668-
def yaml_ordered_load(stream, Loader=yaml.SafeLoader, object_pairs_hook=OrderedDict):
668+
def yaml_ordered_load(stream, object_pairs_hook=OrderedDict):
669669
"""Function to load YAML file using an OrderedDict
670670
671671
See: https://stackoverflow.com/questions/5121931/in-python-how-can-you-load-yaml-mappings-as-ordereddicts
672672
"""
673-
class OrderedLoader(Loader):
673+
class OrderedLoader(yaml.SafeLoader):
674674
pass
675675

676676
def construct_mapping(loader, node):

0 commit comments

Comments
 (0)