Care must be used when defining new {@link oaj.svl.Var Vars} using the SVL API since mistakes
could potentially expose system properties, environment variables, or even file system files.
For recap, the SVL support allows you to embed variables of the form "$X{key}" inside strings that
get resolved to other strings. The resolved strings themselves can also contain variables that also
get recursively resolved.
An example of a potential security hole is shown below that could potentially expose any file on a file
system through a REST request:
| public String doUnsafeGet(RestRequest req) {
| // Security hole!
| return req.getVarResolver().resolve("$RQ{foo}");
| }
This code is simply echoing the value of the foo query parameter.
Now say for example that a bad actor passes in the query string "foo=$F{/some/file/on/file/system}".
The $F variable allows you to resolve the contents of files using SVL, and is provided
by default using the built-in variable resolver returned by the RestRequest object.
You've potentially just exposed the contents of that file through your REST interface.
In reality, the above security hole does not exist because of the following restrictions:
-
Vars have two methods {@link oaj.svl.Var#allowNested()} and
{@link oaj.svl.Var#allowRecurse()} that can be overridden to prevent recursive processing
of string variables. These are both false for the $R variable, so the $F
variable in the result will never get processed and instead be treated as plain text.
-
The $F variable only allows you to retrieve files within the JVM starting directory.
Even though the built-in Juneau variables are safe, special care is needed when defining your own custom
variables. If your variable resolves user input in any way, it's HIGHLY recommended that you override the
{@link oaj.svl.Var#allowNested()} and {@link oaj.svl.Var#allowRecurse()}
methods to prevent recursive handling of variables.