55 lines
1.8 KiB
Plaintext
55 lines
1.8 KiB
Plaintext
== How to fix it in Express.js
|
|
|
|
=== Code examples
|
|
|
|
include::../../common/fix/code-rationale.adoc[]
|
|
|
|
==== Noncompliant code example
|
|
|
|
[source,javascript,diff-id=1,diff-type=noncompliant]
|
|
----
|
|
async function (req, res) {
|
|
await execa.command('find /tmp/images/' + req.query.id); // Noncompliant
|
|
}
|
|
----
|
|
|
|
==== Compliant solution
|
|
|
|
[source,javascript,diff-id=1,diff-type=compliant]
|
|
----
|
|
async function (req, res) {
|
|
if (req.query.file && req.query.file.match(/^[A-Z]+$/i)) {
|
|
await execa('find', ['/tmp/images/' + req.query.file]);
|
|
} else {
|
|
await execa('find', ['/tmp/images/']);
|
|
}
|
|
}
|
|
----
|
|
|
|
=== How does this work?
|
|
|
|
include::../../common/fix/introduction.adoc[]
|
|
|
|
When this is not possible, strict measures should be applied to ensure a secure
|
|
implementation.
|
|
|
|
The proposed compliant solution makes use of the `execa` method. This one
|
|
separates the command to run from the arguments passed to it. It also ensures
|
|
that all arguments passed to the executed command are properly escaped. That way,
|
|
an attacker with control over a command parameter will not be able to inject
|
|
arbitrary new ones.
|
|
|
|
While this reduces the chances for an attacker to identify an exploitation
|
|
payload, the highest security level will only be reached by adding an additional
|
|
validation layer.
|
|
|
|
In the current example, an attacker with control over the first parameter of the
|
|
`find` command could still be able to inject special file path characters in it.
|
|
Indeed, passing `../../` string as a parameter would force the `find` command to
|
|
crawl the whole file system. This could lead to a denial of service or sensitive
|
|
data exposure.
|
|
|
|
Here, adding a regular-expression-based validation on the user-controled value
|
|
prevents this kind of issue. It ensures that the user-submitted parameter
|
|
contains a harmless value.
|