
TL;DR
Biblioteka expr‑eval (oraz fork expr‑eval‑fork) pozwala — z powodu niewystarczającej walidacji wejścia — przekazać do evaluate() spreparowany obiekt zmiennych/kontekstu i wywołać dowolne funkcje, co w środowisku Node.js może prowadzić do zdalnego wykonania kodu (RCE). Fork został załatany (v3.0.0); w oryginalnym repo trwa proces patchowania (PR #288, brak wydania). Priorytet: krytyczny dla backendów Node i funkcji serverless korzystających z expr‑eval.
Krótka definicja techniczna
CVE‑2025‑12735 to luka typu CWE‑94 (Improper Control of Generation of Code / Code Injection) w bibliotece expr‑eval, która umożliwia przekazanie własnych funkcji w obiekcie variables/context do evaluate(). Brak restrykcji/allowlisty funkcji pozwala w Node.js dotrzeć do API procesu (np. pośrednio do child_process) i doprowadzić do wykonania komend systemowych.
Gdzie występuje / przykłady platform
- Aplikacje Node.js (monolity i mikroserwisy) — API, boty, serwery WWW.
- Serverless: AWS Lambda/Azure Functions/Cloud Run z runtime Node.
- Kontenery/Kubernetes: obrazy z zależnością expr-eval.
- Przeglądarka: wpływ ograniczony (brak process/require), przez cały czas możliwe nadużycia logiki/dane.
- Fork: expr-eval-fork — załatany w 3.0.0.
Szczegółowy opis techniki (jak działa, cele, skuteczność)
expr-eval parsuje i ocenia wyrażenia matematyczne. Luka polega na tym, iż funkcje dostępne w czasie ewaluacji nie były odpowiednio ograniczone i można je było wstrzyknąć poprzez obiekt zmiennych (evaluate(vars)), co narusza założenia „bezpiecznej alternatywy dla eval”. W środowisku Node.js skutkiem jest możliwość eskalacji do prymitywów wykonania (np. wywołania interpretera lub komend systemowych), gdy aplikacja przekazuje niezaufane wyrażenia/zmienne do parsera. CERT/CC odnotował wprowadzenie łat poprzez PR #288 (allowlista funkcji, mechanizm rejestracji), a GitHub Advisory formalnie klasyfikuje słabość jako CWE‑94. expr‑eval‑fork 3.0.0 zawiera poprawkę; w oryginalnym repo brak wydanego release’u w momencie publikacji.
Zakres wersji (według GH Advisories):
- expr-eval ≤ 2.0.2 — podatne; brak opublikowanej wersji naprawczej.
- expr-eval-fork ≤ 2.0.2 — podatne; naprawiono w 3.0.0.
Ocena ryzyka: CISA‑ADP ocenia na CVSS 9.8 (sieć, brak uprawnień/UI), GitHub na 8.6 (CVSS v4.0); różnica wynika z przyjętego modelu wektorów i założeń dot. kontekstu wykonania.
Artefakty i logi (co szukać)
| Windows | Security EID 4688, Sysmon EID 1 | Dziecko procesu node.exe → cmd.exe/powershell.exe; nietypowe -c//c | ParentImage = \node.exe, Image = \cmd.exe, CommandLine zawiera /c |
| Sysmon EID 3 | Nowe połączenia sieciowe z procesu aplikacji Node | Nietypowe dest. IP/AS, brak w allowliście egress | |
| Sysmon EID 11/13 | Tworzenie/zmiana plików/kluczy rejestru przez node.exe | Drop plików w temp/autoruns | |
| Linux | auditd (EXECVE), journald | node uruchamia sh/bash/python z parametrem -c | /usr/bin/node … → /bin/sh -c … |
| Container/K8s | K8s audit (create na pods/exec, ephemeralcontainers) | Próby ucieczki/utrzymania kontroli po RCE | Użytkownik SA aplikacji inicjuje pods/exec |
| Cloud (AWS) | CloudTrail | Nietypowe UpdateFunctionCode, CreateFunction, modyfikacje env/secrets przez role aplikacji | Koreluj z IP/UA i oknem incydentu |
| M365/Entra (po wtórnej kompromitacji) | Unified Audit Log | „Consent to application”, „Add service principal”, „Add app role assignment to service principal” | Weryfikuj nieoczekiwane zgody/role w czasie incydentu |
Detekcja (praktyczne reguły)
Sigma (Windows / Sysmon — „Node → shell”)
title: Suspicious Shell Spawned by Node.js (possible expr-eval abuse) id: 7b3fbf8c-2c7a-4d37-9b7a-ef3a6c1b57a8 status: experimental logsource: product: windows category: process_creation detection: parent_node: ParentImage|endswith: '\node.exe' child_shell: Image|endswith: - '\cmd.exe' - '\powershell.exe' cli_flags: CommandLine|contains: - ' /c ' - ' -c ' condition: parent_node and child_shell and cli_flags fields: - Image - CommandLine - ParentImage falsepositives: - Legit. task runners/installer scripts level: high tags: - attack.t1059.003 - attack.t1059.001 - attack.t1203 - attack.t1190Splunk (Sysmon EID=1)
index=your_sysmon_index EventCode=1 ParentImage="*\\node.exe" | search Image="*\\cmd.exe" OR Image="*\\powershell.exe" | search CommandLine="* /c *" OR CommandLine="* -c *" | stats count min(_time) max(_time) by Computer, User, ParentImage, Image, CommandLineKQL (Microsoft Defender for Endpoint)
DeviceProcessEvents | where InitiatingProcessFileName =~ "node.exe" | where FileName in~ ("cmd.exe","powershell.exe","bash","sh") | where ProcessCommandLine has_any (" /c ", " -c ") | summarize cnt=count(), firstTime=min(Timestamp), lastTime=max(Timestamp) by DeviceName, FileName, ProcessCommandLine, InitiatingProcessCommandLineCloudTrail (CloudWatch Logs Insights)
fields @timestamp, eventSource, eventName, userIdentity.type, userIdentity.arn, sourceIPAddress | filter eventSource="lambda.amazonaws.com" and eventName in ["UpdateFunctionCode","CreateFunction","UpdateFunctionConfiguration"] | sort @timestamp descCel: wychwycić nieoczekiwane zmiany kodu/konfiguracji funkcji wykonywane przez role/podmioty powiązane z usługą korzystającą z expr-eval.
Elastic EQL
process where process.parent.name == "node" and process.name in ("cmd.exe","powershell.exe","sh","bash","python") and process.args in ("-c","/c","-e")Heurystyki / korelacje
- SBOM/SCA telemetry: stwierdzona zależność expr-eval (<=2.0.2) lub expr-eval-fork (<=2.0.2) + anomalia „Node → shell”.
- Wzorce ruchu: nagły egress z procesu aplikacji (nowe domeny/ASN) w pobliżu czasu wywołań evaluate().
- Zmiany w infrastrukturze: CloudTrail UpdateFunctionCode/modyfikacje env/secret po zdarzeniach aplikacji.
- M365/Entra: niespodziewane „Consent to application” / „Add service principal” po incydencie (możliwa eskalacja OAuth).
False positives / tuning
- Legit. narzędzia Node uruchamiające powłokę (instalatory, task‑runnery) — obwiedniaj detekcję listą dozwolonych ścieżek/usług, oknem czasowym (CI/CD), użytkownikiem i komendami (blokuj -c poza maintenance).
- Środowiska dev — wydzielone indeksy/logsource, niższy poziom alertowania.
- Serwisy, które w ogóle nie powinny odpalać powłoki — alert krytyczny.
Playbook reagowania (IR)
- Triaging: korelacja alertu (Node→shell / CloudTrail / M365) + potwierdzenie zależności w SBOM (npm ls expr-eval).
- Izolacja: odłącz instancję/poda (K8s: kubectl cordon/drain serwis, tymczasowe NetworkPolicy egress‑deny).
- Ograniczanie szkód: rotacja secretów/tokenów używanych przez serwis; w chmurze — blokada roli/aplikacji zaufania.
- Forensyka: zachowaj dysk/pamięć, eksportuj dzienniki (Sysmon/auditd/CloudTrail/M365 UAL).
- Eradykacja:
- Migracja do expr-eval-fork 3.0.0 lub wdrożenie łatki po publikacji release oryginału; tymczasowo usuń/wyłącz niestandardowe funkcje i wdroż allowlistę funkcji.
- Weryfikacja: testy regresji, monitoring post‑incident (szczególnie „Consent to application” w M365).
- Lessons learned: reguły pre‑commit/CI (npm audit, SCA), polityki review zmian zależności.
Przykłady z kampanii / case studies
Na dzień 11 lis 2025 brak potwierdzonej eksploatacji „in the wild”; Tenable klasyfikuje CVE jako „not exploited (being monitored)”. Rekomendowane jest pilne łatanie/migracja.
Lab (bezpieczne testy)
A. Weryfikacja zależności
# sprawdź wersję npm ls expr-eval expr-eval-fork # o ile obecne i podatne, przygotuj hotfix/migrację (fork 3.0.0)B. Generowanie sygnałów do reguł (symulacja „Node → shell”) — bez użycia luki:
# Linux node -e "require('child_process').spawn('/bin/sh',['-c','echo ok'],{stdio:'inherit'})" # Windows (PowerShell) node -e "require('child_process').spawn('cmd.exe',['/c','echo ok'])"Następnie zweryfikuj dopasowania: Sysmon EID=1, auditd EXECVE, oraz reguły Sigma/SPL/KQL.
C. K8s/CloudTrail
- W K8s odpal kubectl auth can-i dla SA serwisu i potwierdź brak uprawnień do pods/exec.
- W AWS przepuść kontrolowany UpdateFunctionConfiguration (np. dummy tag), aby potwierdzić zadziałanie zapytania CloudWatch Insights.
Mapowania (Mitigations, powiązane techniki)
Mitigations (ATT&CK):
- M1038 Execution Prevention (application allowlisting, blokada interpreterów w usługach).
- M1054 Software Configuration (wyłącz/ogranicz niestandardowe funkcje, hardening konfigu).
- M1045 Code Signing (wymuszaj podpisy/CI deklaratywny deployment).
- M1047 Audit (regularny audyt zależności i uprawnień).
Powiązane techniki: T1190, T1203, T1059(.003/.004/.007)
Źródła / dalsza literatura
- NVD: opis, CVSS CISA‑ADP 9.8, referencje (w tym PR #288, npm). (NVD)
- CERT/CC VU#263614: opis wektora, stan łat (PR #288), identyfikatory (GHSA). (CERT Coordination Center)
- GitHub Advisory (GHSA‑jc85‑fpwf‑qm7x): zakres wersji podatnych i wersje naprawcze (fork 3.0.0), CWE‑94, CVSS v4.0. (GitHub)
- PR #288 (silentmatt/expr‑eval): propozycja poprawki (allowlista, testy), status Open. (GitHub)
- BleepingComputer — materiał prasowy o RCE i rekomendacji migracji do forka. (BleepingComputer)
- Tenable Research — status „not exploited” (monitorowane). (Tenable®)
- ATT&CK v18 — wersjonowanie i strony technik. (MITRE ATT&CK)
Checklisty dla SOC / CISO
SOC (operacyjna)
- Aktywuj/zweryfikuj telemetry: Sysmon (Win), auditd (Linux), K8s Audit, CloudTrail.
- Wdroż reguły: Sigma/KQL/SPL/EQL z tej noty.
- Przekrój SBOM/SCA: znajdź expr-eval/expr-eval-fork ≤ 2.0.2.
- Koreluj „Node → shell” oraz nietypowy egress z procesów aplikacji.
- Monitoruj M365 UAL pod kątem „Consent to application”/„Add service principal”.
CISO / AppSec (strategiczna)
- Migracja: expr-eval-fork 3.0.0 lub oczekuj na oficjalny release oryginału (po weryfikacji PR #288).
- Polityki wejścia: zakaz ewaluacji niezweryfikowanych wyrażeń; allowlista funkcji.
- CI/CD: blok w PR na dodanie podatnych wersji (SCA), podpisy artefaktów (M1045).
- Least privilege dla ról chmurowych usług korzystających z expr‑eval; segmentacja egress.
- Plan IR: playbook z rotacją sekretów i sanityzacją środowiska po incydencie.
Uwaga dot. łat: wg GHSA fork expr‑eval‑fork ma poprawkę w 3.0.0; w oryginalnym expr‑eval trwa proces patchowania (PR #288, w momencie pisania Open). Planiści powinni rozważyć pilną migrację do forka i later ew. powrót po publikacji stabilnego wydania z łatą.














