You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Here are some notes on sandboxing Power Fx execution for safely executing arbitrary expressions in a multi-user server.
Assume the host is a server and each incoming request is a executing a power fx expression.
Practically, this means:
An expression can only access the data explicitly provided to it via the host.
An expression can't DOS the host.
This means the host can govern resource execution of the expression and reliably abort the expression at any point. Particularly interesting resources are:
CPU time
memory consumption
network consumption.
stack depth
Principles to enable safety
Power Fx has design and implementation principles to ensure safety:
The language design:
strongly typed,
Can only manipulate data explicitly provided to them by the host. For example, Power Fx does not have any equivalent to C#'s reflection that would let it read arbitrary data from the host or other expressions.
The implementation has several design principles:
All I/O is done via host-provided interfaces. Power Fx never makes a direct network call - it always goes via a host callback. This means the host can always throttle and limit.
Single threaded. Library functions avoid fanning out to multiple threads - for example, we explicitly avoid a builtin automatic "parallel for" as that would allow a single request
Fully cooperative
Hosting APIs
Here's guidance to a host to enforce safe execution, in recommended priority order:
Provide a cancellation token to Eval() APIs. This protects against long-running expressions. But it also implicitly mitigates against DOS because given Power Fx's careful restrictions, it's very difficult to get an expression that will DOS without running for a long time.
Ensure all callback objects that do network requests include both logging and timeout abilities. Power Fx won't directly make any network operations - any network requests are done via callback objects from the host. This applies to both httpclients, but also callback objects like an IOrganizationService used to talk to dataverse.
Host should catch and log any exceptions coming from Eval(). User errors from the expression (like divide-by-zero) will generate an ErrorValue and not throw ("soft error", like a 400), but throttling/governing/timouts/etc will generate exceptions ("hard errors", like a 500) which the host should catch and log.
Consider issuing each eval on its own thread, and leverage OS facilities for thread priority. Running the thread at lower priority can mitigate CPU starvation against other priority tasks. A separate thread can also make it easier to abort the expression.
Limit expression length - This is set in ParserOptions. There is a default limit.
The host should be careful of what data and custom functions it passes an expression.
By default, Power Fx expressions are very constrained and have no I/O, and then the host enables additional abilities:
passing in variables
enabling builtin functions like Json and RegEx.
adding custom functions provided by the host
enabling major features like Connectors or Dataverse. - the host controls the auth and abilities here.
For example, if the host provided a custom function that allowed reading arbitrary files, then the expression could use that to read arbitrary files and break out of the sandbox.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Here are some notes on sandboxing Power Fx execution for safely executing arbitrary expressions in a multi-user server.
Assume the host is a server and each incoming request is a executing a power fx expression.
Practically, this means:
An expression can only access the data explicitly provided to it via the host.
An expression can't DOS the host.
This means the host can govern resource execution of the expression and reliably abort the expression at any point. Particularly interesting resources are:
Principles to enable safety
Power Fx has design and implementation principles to ensure safety:
The language design:
The implementation has several design principles:
Hosting APIs
Here's guidance to a host to enforce safe execution, in recommended priority order:
There are some unit tests demonstrating how the host can configure these:
https://github.com/microsoft/Power-Fx/blob/main/src/tests/Microsoft.PowerFx.Interpreter.Tests.Shared/SandboxTests.cs
Hosting design guidance
The host should be careful of what data and custom functions it passes an expression.
By default, Power Fx expressions are very constrained and have no I/O, and then the host enables additional abilities:
For example, if the host provided a custom function that allowed reading arbitrary files, then the expression could use that to read arbitrary files and break out of the sandbox.
Beta Was this translation helpful? Give feedback.
All reactions