2023-03-07 17:16:47 +01:00

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.