Security
You should not pass untrusted FTL code to FluentBundle
. This is because
carefully constructed messages could potentially cause large resource usage (CPU
time and memory). The fluent.runtime
implementation does have some
protection against these attacks, although it may not be foolproof, while
fluent_compiler
does not currently have any protection against these
attacks, either at compile time or run time.
We do protect against infinite loops caused by cycles in message references, but that is not enough to protect against things like the billion laughs attack which have no loops.
fluent_compiler
works by compiling FTL messages to Python ast, which is passed to compile and then exec. The use of exec
like this is an established technique for high performance Python code, used in
template engines like Mako, Jinja2 and Genshi.
However, there can understandably be some concerns around the use of exec
which can open up remote execution vulnerabilities. If this is of paramount
concern to you, you should consider using fluent.runtime
instead.
To reduce the possibility of our use of exec
harbouring security issues, the
following things are in place:
We generate ast objects and not strings. This greatly reduces the security problems, since there is no possibility of a vulnerability due to incorrect string interpolation.
We use
exec
only on AST derived from FTL files, never on “end user input” (such as the arguments passed intoFluentBundle.format
). This reduces the attack vector to only the situation where the source of your FTL files is potentially malicious or compromised.We employ defence-in-depth techniques in our code generation and compiler implementation to reduce the possibility of cleverly crafted FTL code producing security holes, and ensure these techniques have full test coverage. These include:
blacklisting sensitive functions in our function call code generation.
doing many assertions in our codegen module and not assuming the higher level compiler code is using it correctly.
being careful to avoid aliasing builtins and keywords in generated names, at multiple levels.