
Wprowadzenie do problemu / definicja luki
W bibliotece expr-eval (popularny parser i ewaluator wyrażeń matematycznych w JavaScript) ujawniono krytyczną podatność pozwalającą na zdalne wykonanie kodu (RCE) po przekazaniu złośliwego obiektu „kontekstu” do funkcji evaluate(). Problem został oznaczony jako CVE-2025-12735, a według oceny CISA (CVSS 3.1) ma wagę 9.8 – CRITICAL. Luka dotyczy zarówno oryginalnego pakietu expr-eval, jak i aktywnie utrzymywanego forka expr-eval-fork (naprawa dostępna od wersji 3.0.0).
W skrócie
- Co: RCE poprzez złośliwe funkcje w obiekcie kontekstu przekazywanym do Parser.evaluate().
- Zakres: expr-eval (oryginalny projekt) i expr-eval-fork (fork).
- Nasilenie: CVSS 9.8 (CISA ADP).
- Status poprawek: stabilna poprawka w expr-eval-fork v3.0.0; dla oryginalnego repo istnieje PR z łatą (#288), ale brak nowego wydania. Rekomendowana migracja do forka 3.0.0+.
Kontekst / historia / powiązania
expr-eval jest powszechnie używany w kalkulatorach webowych, narzędziach edukacyjnych, finansowych oraz – coraz częściej – w systemach NLP/AI, które parsują fragmenty matematyczne z tekstu. Oryginalne repozytorium jest rozwijane nieregularnie; społeczność utrzymuje forka expr-eval-fork, który wcześniej rozwiązywał inne kwestie bezpieczeństwa i utrzymania. CERT-CC i NVD odnotowują, iż biblioteka ma setki zależności pośrednich, co zwiększa zasięg oddziaływania podatności.
Analiza techniczna / szczegóły luki
Przyczyna: Funkcja evaluate() przyjmuje obiekt context (zbiór zmiennych i funkcji dostępnych w wyrażeniu). Brak prawidłowej walidacji/ograniczeń umożliwia przekazanie obiektów-funkcji, które parser następnie wywołuje w trakcie ewaluacji. To otwiera drogę do wykonywania niepożądanego kodu – w środowisku Node.js choćby do wywołań systemowych. NVD klasyfikuje problem jako skutkujący przejęciem poufności, integralności i dostępności (C:H/I:H/A:H).
Stan poprawek:
- expr-eval-fork: wydanie 3.0.0 zawiera allowlist bezpiecznych funkcji, mechanizm rejestracji funkcji użytkownika i testy wymuszające ograniczenia.
- expr-eval (oryginalne): istnieje Pull Request #288 od CERT-CC z analogiczną łatą; brak potwierdzanej publikacji nowej wersji w npm.
Identyfikatory i doradztwa: CVE-2025-12735, GHSA-jc85-fpwf-qm7x (GitHub Advisory).
Minimalny przykład zagrożonego wzorca (edukacyjnie, bez payloadu)
import { Parser } from 'expr-eval'; // Niebezpieczne: bezkrytyczne przekazywanie "context" z funkcjami od użytkownika const parser = new Parser(); const expr = parser.parse('customFn(x) + y'); // "context" pochodzi np. z wejścia użytkownika (to błąd!) const unsafeContext = { x: 2, y: 3, // użytkownik może wstrzyknąć dowolną funkcję customFn: (n) => n * 10, }; console.log(expr.evaluate(unsafeContext));Wniosek: Sam fakt, iż funkcje z kontekstu są wywoływane, stanowi wektor wykonania kodu. W Node.js zamiast nieszkodliwego n * 10 atakujący może próbować odwołań do zasobów środowiska. Naprawa polega na odrzuceniu funkcji z kontekstu, whitelisting i jawnej rejestracji dopuszczalnych funkcji.
Praktyczne konsekwencje / ryzyko
- Aplikacje serwerowe (Node.js): ryzyko RCE i dostępu do zasobów hosta, w tym plików, poświadczeń czy usług sieciowych. CVSS 9.8 od CISA odzwierciedla pełen kompromis (C/I/A = H).
- Front-end (przeglądarka): brak bezpośredniego dostępu do systemu, ale możliwość nadużyć (kradzież tokenów, interakcje z API w kontekście użytkownika).
- Łańcuch dostaw: biblioteka jest zależnością pośrednią w wielu projektach — podatność może „dotrzeć” do Was nawet, jeżeli nie importujecie jej wprost.
Rekomendacje operacyjne / co zrobić teraz
1) Szybka weryfikacja zależności
- SBOM/grep: # npm npm ls expr-eval expr-eval-fork || true # pnpm pnpm ls expr-eval expr-eval-fork || true # yarn yarn why expr-eval || true
- Skan doradztw: sprawdź GHSA i CVE w pipeline (np. npm audit, GitHub Dependabot).
2) Aktualizacja i pinning
- Preferowany wariant: natychmiast **migruj do expr-eval-fork ≥ 3.0.0. npm i expr-eval-fork@^3.0.0 # lub w package.json ustaw: # "overrides": { "expr-eval": "npm:expr-eval-fork@^3.0.0" } jeżeli używacie pakietu, który pośrednio ciągnie expr-eval, rozważcie overrides/resolutions albo zgłoście issue do maintenera.
- Oryginalny expr-eval: dopóki nie ma wydania z łatą, nie polegajcie na tym pakiecie w kontekście niezaufanego wejścia. PR #288 istnieje, ale brak gwarancji release’u.
3) Dodatkowe twarde zabezpieczenia (defense-in-depth)
- Blokada funkcji w kontekście: nie przekazuj żadnych funkcji z danych użytkownika; jeżeli musisz, stosuj allowlistę i własną fabrykę funkcji.
- Sandboxing: w Node.js rozważ izolację ewaluacji (np. oddzielny proces/VM, worker_threads, ograniczone uprawnienia).
- WAF / filtrowanie: ogranicz długość, znaki i słowa najważniejsze w wyrażeniach, o ile użytkownicy dostarczają stringi do ewaluacji.
- Logowanie i detekcja anomalii: monitoruj nietypowe wyrażenia i błędy parsera.
4) Testy regresyjne – przykład „bezpiecznego” wzorca po aktualizacji
import { Parser } from 'expr-eval-fork'; // jawna rejestracja dopuszczalnych funkcji const allowed = { abs: Math.abs, ceil: Math.ceil, floor: Math.floor, // ...lista minimalna, bez funkcji dostępowych }; const parser = new Parser({ functions: allowed }); // Do wyrażenia przekazujemy wyłącznie PRYMITYWY (liczby/napisy/boole) // i ewentualnie nazwy dopuszczonych funkcji; brak dowolnych obiektów-funkcji const expr = parser.parse('abs(x) + ceil(y)'); const safeContext = { x: -3.14, y: 2.2 }; console.log(expr.evaluate(safeContext)); // 65) Działania w CI/CD
- Wymuś fail build przy wykryciu expr-eval < bezpiecznych wersji (policy as code).
- Dodaj overrides/resolutions w monorepo i lockfile maintenance.
- Publikuj nową wersję swoich bibliotek, aby konsumenci dostali zależność z poprawką (tzw. republish chain).
Różnice / porównania z innymi przypadkami
- Analogiczne klasy błędów: CWE-94 („Improper Control of Code Generation”) – sytuacje, gdy system pozwala na wstrzyknięcie kodu poprzez „rozszerzalne” mechanizmy (np. eval-like, dynamiczne funkcje, konteksty). W expr-eval problem był subtelny, bo dotyczył wywoływania funkcji z kontekstu, a nie tylko parsowania tekstu. (Por. wpisy doradcze GHSA/NVD.)
- Różnica do klasycznych XSS/RCE: tu łańcuch dostaw oraz biblioteka „bezpieczna zamiast eval” paradoksalnie stała się wektorem RCE przy niewłaściwej walidacji/konfiguracji.
Podsumowanie / najważniejsze wnioski
- CVE-2025-12735 to krytyczna luka w expr-eval umożliwiająca RCE przez złośliwe funkcje w kontekście evaluate().
- Najbezpieczniejsza ścieżka: migracja do expr-eval-fork 3.0.0+, pinning i republish bibliotek zależnych.
- Nawet po aktualizacji stosuj zasadę najmniejszego zaufania wobec wejścia użytkownika i allowlistę funkcji.
- Zweryfikuj łańcuch zależności – podatność często wchodzi pośrednio.
Źródła / bibliografia
- BleepingComputer: pierwsze doniesienia, status patchy i rekomendacja migracji do expr-eval-fork 3.0.0. (BleepingComputer)
- NVD (CVE-2025-12735) – opis, metryki, referencje, CVSS 9.8 wg CISA-ADP. (NVD)
- CERT-CC Vulnerability Note VU#263614 – opis techniczny, wpływ na projekty AI/NLP, zalecenia. (kb.cert.org)
- GitHub PR #288 (silentmatt/expr-eval) – propozycja łaty od CERT-CC, status w oryginalnym repo. (GitHub)
- GitHub Advisory (GHSA-jc85-fpwf-qm7x) – doradztwo bezpieczeństwa. (GitHub)






![Krytyczna podatność w Androidzie umożliwia zdalne wykonanie kodu, bez interakcji ze strony użytkownika [CVE-2025-48593]](https://sekurak.pl/wp-content/uploads/2025/11/Zrzut-ekranu-2025-11-7-o-13.55.14.png)