Skip to content

Commit 0a56124

Browse files
authored
docs(core): add security warnings and best practices for deserialization (#35282)
1 parent f7dbdab commit 0a56124

1 file changed

Lines changed: 52 additions & 10 deletions

File tree

  • libs/core/langchain_core/load

libs/core/langchain_core/load/load.py

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@
1313
1414
## Security model
1515
16+
!!! warning "Do not use with untrusted input"
17+
18+
These functions instantiate Python objects and can trigger side effects
19+
such as network calls, file operations, or environment variable access
20+
during deserialization. **Never call `load()` or `loads()` on data from an
21+
untrusted or unauthenticated source.** Even with the allowlist, allowed
22+
classes may perform dangerous operations during `__init__`.
23+
1624
The `allowed_objects` parameter controls which classes can be deserialized:
1725
1826
- **`'core'` (default)**: Allow classes defined in the serialization mappings for
@@ -35,6 +43,16 @@
3543
Import paths are also validated against trusted namespaces before any module is
3644
imported.
3745
46+
### Best practices
47+
48+
- Use the most restrictive `allowed_objects` possible. Prefer an explicit list
49+
of classes over `'core'` or `'all'`.
50+
- Keep `secrets_from_env` set to `False` (the default). If you must use it,
51+
ensure the serialized data comes from a fully trusted source, as a crafted
52+
payload can read arbitrary environment variables.
53+
- When using `secrets_map`, include only the specific secrets that the
54+
serialized object requires.
55+
3856
### Injection protection (escape-based)
3957
4058
During serialization, plain dicts that contain an `'lc'` key are escaped by wrapping
@@ -299,11 +317,18 @@ def __init__(
299317
`langchain_core.load.mapping` for the full list.
300318
- Explicit list of classes: Only those specific classes are allowed.
301319
secrets_map: A map of secrets to load.
302-
If a secret is not found in the map, it will be loaded from the
303-
environment if `secrets_from_env` is `True`.
320+
321+
Only include the specific secrets the serialized object
322+
requires. If a secret is not found in the map, it will be loaded
323+
from the environment if `secrets_from_env` is `True`.
304324
valid_namespaces: Additional namespaces (modules) to allow during
305325
deserialization, beyond the default trusted namespaces.
306326
secrets_from_env: Whether to load secrets from the environment.
327+
328+
A crafted payload can name arbitrary environment variables in
329+
its `secret` fields, so enabling this on untrusted data can leak
330+
sensitive values. Keep this `False` (the default) unless the
331+
serialized data is fully trusted.
307332
additional_import_mappings: A dictionary of additional namespace mappings.
308333
309334
You can use this to override default mappings or add new mappings.
@@ -490,10 +515,12 @@ def loads(
490515
core LangChain types (messages, prompts, documents, etc.). See
491516
`langchain_core.load.mapping` for the full list.
492517
493-
!!! warning "Beta feature"
518+
!!! warning "Do not use with untrusted input"
494519
495-
This is a beta feature. Please be wary of deploying experimental code to
496-
production unless you've taken appropriate precautions.
520+
This function instantiates Python objects and can trigger side effects
521+
during deserialization. **Never call `loads()` on data from an untrusted
522+
or unauthenticated source.** See the module-level security model
523+
documentation for details and best practices.
497524
498525
Args:
499526
text: The string to load.
@@ -511,11 +538,17 @@ def loads(
511538
- `[]`: Disallow all deserialization (will raise on any object).
512539
secrets_map: A map of secrets to load.
513540
514-
If a secret is not found in the map, it will be loaded from the environment
515-
if `secrets_from_env` is `True`.
541+
Only include the specific secrets the serialized object requires. If
542+
a secret is not found in the map, it will be loaded from the
543+
environment if `secrets_from_env` is `True`.
516544
valid_namespaces: Additional namespaces (modules) to allow during
517545
deserialization, beyond the default trusted namespaces.
518546
secrets_from_env: Whether to load secrets from the environment.
547+
548+
A crafted payload can name arbitrary environment variables in its
549+
`secret` fields, so enabling this on untrusted data can leak
550+
sensitive values. Keep this `False` (the default) unless the
551+
serialized data is fully trusted.
519552
additional_import_mappings: A dictionary of additional namespace mappings.
520553
521554
You can use this to override default mappings or add new mappings.
@@ -573,10 +606,12 @@ def load(
573606
core LangChain types (messages, prompts, documents, etc.). See
574607
`langchain_core.load.mapping` for the full list.
575608
576-
!!! warning "Beta feature"
609+
!!! warning "Do not use with untrusted input"
577610
578-
This is a beta feature. Please be wary of deploying experimental code to
579-
production unless you've taken appropriate precautions.
611+
This function instantiates Python objects and can trigger side effects
612+
during deserialization. **Never call `load()` on data from an untrusted
613+
or unauthenticated source.** See the module-level security model
614+
documentation for details and best practices.
580615
581616
Args:
582617
obj: The object to load.
@@ -594,11 +629,18 @@ def load(
594629
- `[]`: Disallow all deserialization (will raise on any object).
595630
secrets_map: A map of secrets to load.
596631
632+
Only include the specific secrets the serialized object requires.
633+
597634
If a secret is not found in the map, it will be loaded from the environment
598635
if `secrets_from_env` is `True`.
599636
valid_namespaces: Additional namespaces (modules) to allow during
600637
deserialization, beyond the default trusted namespaces.
601638
secrets_from_env: Whether to load secrets from the environment.
639+
640+
A crafted payload can name arbitrary environment variables in its
641+
`secret` fields, so enabling this on untrusted data can leak
642+
sensitive values. Keep this `False` (the default) unless the
643+
serialized data is fully trusted.
602644
additional_import_mappings: A dictionary of additional namespace mappings.
603645
604646
You can use this to override default mappings or add new mappings.

0 commit comments

Comments
 (0)