>_ DevTrendsnl

Taal

Home

Talen

Secties

Frontend Backend Mobiel DevOps AI / ML GameDev Blockchain Embedded Beveiliging
Java

Snelle JSON-parsing in Java met nieuwe beveiligingsregels in Fastjson2

fastjson logo

Als je al meer dan vijf jaar met Java werkt, roept de naam Fastjson waarschijnlijk gemengde gevoelens op. Aan de ene kant was de library inderdaad sneller dan Jackson. Aan de andere kant zorgden regelmatige deserialisatiekwetsbaarheden via AutoType ervoor dat het gebruik ervan een constante hoofdpijn werd voor beveiligingsspecialisten.

Het Alibaba-team kende deze problemen beter dan wie dan ook. Twee jaar geleden herschreven ze de library in wezen helemaal opnieuw. Maak kennis met Fastjson2: een heruitgevonden engine voor het werken met JSON, waarbij beveiliging en prestaties op moderne Java-versies als fundament werden genomen.

Hoe beveiliging is veranderd

De belangrijkste zonde van de eerste versie was het AutoType-mechanisme. Het kon willekeurige Java-objecten maken uit JSON-payload direct tijdens het parsen. Aanvallers vonden regelmatig manieren om de ingebouwde lijst met geblokkeerde klassen te omzeilen en RCE te triggeren.

In Fastjson2 is de aanpak drastisch veranderd. AutoType is nu standaard uitgeschakeld en class scanning werkt zonder hardcoded whitelists. Er is een SafeMode geïntroduceerd, die het automatisch assembleren van willekeurige objecten volledig verbiedt.

Alle configuratievlaggen zijn nu standaard op OFF ingesteld. De library probeert niet langer types te raden waar dit schade zou kunnen veroorzaken.

Kernfuncties

De ontwikkelaars richtten zich op moderne JDK-versies, variërend van Java 8 tot Java 21. De engine is geoptimaliseerd voor Vector API-gebruik, Record-typen en compacte strings.

Hier is wat opvalt bij het kennismaken met de library:

  • Ondersteuning voor dual formaat. Zowel reguliere tekst-JSON als het binaire JSONB-protocol.
  • Snelle selectieve parsing via JSONPath zonder tussenliggende Java-objecten te maken.
  • Extensie-modules voor Kotlin met een handige DSL en volledige Spring Framework-ondersteuning voor versies 5 en 6.
  • Native compilatie met GraalVM Native Image out of the box.

Snelle start in code

Het toevoegen van de library houdt in dat je een enkele dependency opneemt in pom.xml:

<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2</artifactId>
    <version>2.0.61</version>
</dependency>

Een eenvoudig voorbeeld van parsing en serialisatie ziet er vertrouwd uit:

import com.alibaba.fastjson2.JSON;

// Парсинг строки в объект
User user = JSON.parseObject("{\"name\":\"John\",\"age\":25}", User.class);

// Сериализация объекта в JSON
String json = JSON.toJSONString(user);

Als je in Kotlin schrijft, biedt de fastjson2-kotlin module beknopte extensies. De code blijkt merkbaar schoner dankzij de to<T>() extension-functie:

import com.alibaba.fastjson2.*

val text = """{"id":1,"name":"John"}"""
val user = text.to<User>()

val jsonBytes = user.toJSONByteArray()

Binair JSONB-formaat voor microservices

Tekst-JSON blijft de standaard voor REST API's, maar in inter-servicecommunicatie verliest het terrein door overmatige grootte en overhead van stringconversie. Fastjson2 bevat een ingebouwde implementatie van het binaire JSONB-formaat.

JSONB codeert datatypes en structuur in een compacte byte-set. Dit zorgt voor aanzienlijke verkeersbesparingen en versnelt RPC-services.

User user = new User(1, "John");

// Сериализация в байтовый массив JSONB
byte[] bytes = JSONB.toBytes(user);

// Сериализация с дополнительным сжатием структурированных данных
byte[] compactBytes = JSONB.toBytes(user, JSONWriter.Feature.BeanToArray);

// Обратный парсинг
User parsedUser = JSONB.parseObject(bytes, User.class);

Compressie met de BeanToArray optie transformeert een object naar een value-array zonder veldnamen te herhalen, waardoor de efficiëntie van het formaat dichter bij Protobuf of Kryo komt.

Selectief lezen via JSONPath

Vaak heb je uit een enorme JSON-response van een microservice maar één of twee velden nodig. Klassieke parsers zoals Jackson bouwen eerst een complete boom in het geheugen of maken een object met alle velden, wat CPU en geheugen verbruikt.

Fastjson2 lost dit probleem op met een implementatie van de SQL:2016 standaard JSONPath. Het kan data direct uit een raw byte stream extraheren:

byte[] payload = fetchLargeJsonFromNetwork();

// Создаём и кэшируем путь
JSONPath path = JSONPath.of("$.data.user.id");

// Извлекаем значение напрямую из байтового массива
JSONReader reader = JSONReader.of(payload);
Object userId = path.extract(reader);

Deze truc is nuttig in data processing pipelines met hoge belasting waar onnodige objectallocaties in de JVM onmiddellijk leiden tot frequente Garbage Collector-pauzes.

Migreren vanaf de eerste versie

Volledige achterwaartse compatibiliteit bij het wijzigen van majorversies is onmogelijk, maar de auteurs hebben geprobeerd de overgang te vergemakkelijken. Er is een compatibiliteitsmodule gemaakt voor projecten die afhankelijk zijn van de oude API:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>2.0.61</version>
</dependency>

Het gebruikt de oude groupId en com.alibaba.fastjson packages, maar draait intern op de nieuwe v2-engine. Dit maakt het mogelijk om te updaten zonder honderden imports in legacy code te herschrijven.

Bij het migreren moet je echter rekening houden met belangrijke wijzigingen:

  • Cyclische referentie-parsing is standaard uitgeschakeld.
  • Smart Match veldmatching werkt niet meer out of the box.
  • Alle serializer-opties moeten expliciet worden ingeschakeld via JSONWriter.Feature.

Fastjson2 blijkt een volwassen en solide product te zijn. De ontwikkelaars hebben geleerd van fouten uit het verleden, gevaarlijke standaardinstellingen geëlimineerd en het Java-ecosysteem een echt snel tool gegeven.

Geef Fastjson2 zeker een kans als je high-load services ontwikkelt, werkt met Spring 6 / GraalVM Native Image, of op zoek bent naar een alternatief voor zware serialisatieformaten in Kotlin-projecten.

Gerelateerde projecten