Frictionless reads local files and downloads remote resources as instructed by the provided metadata (a resource path, a package profile, a remote reference $ref inside the profile, etc.). This page explains the risks and best practices to follow for untrusted metadata (e.g. for a validation API).
In the context of a local user validating their own trusted data, the command line frictionless validate --trusted flag, or the system context provides a way to disable overly cautious security checks.
In the context of validation of untrusted input, trusted must stay False (the default), and in case of a service, deployment measures described below are recommanded.
Note that the safety checks validate descriptors (the metadata provided as a dictionary, a file, or a URL). Values you pass yourself in the Python API, such as Resource('/any/path.csv'), are under your own responsibility.
When trusted is False (the default), local disk access provided by the metadata must stay inside the working directory. For a resource, the path, extrapaths, profile, dialect, and schema properties must be relative paths, without .., ~, or environment variables. The same rule applies to a package profile. A rejected path yields a path "..." is not safe error.
For a profile "$ref", additional rules apply:
"$ref" is only followed from a local profile, and only within the working directory;file:// URI is refusedhttp(s) and local "$ref"s are supported: other schemes, such as data: or ftp:, are refused.When a profile "$ref" points to a non-existent JSON pointer or anchor, the error message names the pointer, but does not disclose the content of the referenced document: a "$ref" can target any file of the working directory, whose content may be confidential.
"$ref". In presence of untrusted input, do not run the framework from a directory that contains secrets.validate_descriptor, which returns a report instead of raising, for predictable error handling:from frictionless import Package
report = Package.validate_descriptor(descriptor)
for error in report.errors:
print(error.note)
trusted at its default (False) for any user-provided inputTo protect against Server-Side Request Forgery, here are some suggestions :
system.use_context(http_session=...) is used for every remote metadata download. Resolve and validate the IP at the moment of connection, not beforehand, to defeat DNS rebinding: a check done before the request is sent can be bypassed by a DNS response that flips between a public and a private address. Use the standard-library ipaddress module for the check; the OWASP SSRF Prevention Cheat Sheet describes this pattern.System representation This class provides an ability to make system Frictionless calls. It's available as `frictionless.system` singletone.
A flag that indicates if resource, path or package is trusted.
ClassVar[List[str]]
A flag that indicates if resource, path or package is trusted.
bool
Type of action to take on Error such as "warn", "raise" or "ignore".
types.IOnerror
Setting this value user can use feature of the specific version. The default value is v2.
types.IStandards
Return a HTTP session This method will return a new session or the session from `system.use_http_session` context manager
Create adapter
(source: Any, *, control: Optional[Control] = None, basepath: Optional[str] = None, packagify: bool = False) -> Optional[Adapter]
Create loader
(resource: Resource) -> Loader
Create parser
(resource: Resource) -> Parser
Deregister a plugin
(name: str)
Create candidates
() -> List[dict[str, Any]]
Hook into resource detection
(resource: Resource) -> None
Register a plugin
(name: str, plugin: Plugin)