From 768b3447b6f9d8b426c46993d70165285a821a97 Mon Sep 17 00:00:00 2001 From: Sin-Kang Date: Sat, 23 May 2026 20:00:35 +0900 Subject: [PATCH 1/2] docs: finalize CHANGELOG entries under [3.1.0] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [Unreleased] section's accumulated v3.1 entries promoted into a proper [3.1.0] heading. No content change — just structural cleanup before tagging: - docs/changelog.md (en, full): collapse the (continued) sub-sections, add Migration guide. - docs/changelog.ko.md (ko, full): mirror. - CHANGELOG.md (top-level): condensed summary + link to the docs/changelog detail. The tag v3.1.0 follows immediately after this lands on main. --- CHANGELOG.md | 22 +++++++++++++++++++++- docs/changelog.ko.md | 18 ++++++++++-------- docs/changelog.md | 18 ++++++++++-------- 3 files changed, 41 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 697c968..9440d7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,25 @@ The source of truth for the entries below is [docs/changelog.md](docs/changelog. ## [Unreleased] +## [3.1.0] — LLM core extraction, LangChain4j, WebClient DNS gap, GraalVM hints + +### Added + +- New module **`ssrf-guard-llm`** — framework-agnostic JSON tool-input validator (`ToolInputGuard` + `JsonToolInputGuard`). Holds the URL detection + policy validation logic the adapter modules share. +- New module **`ssrf-guard-langchain4j`** — wraps LangChain4j `ToolExecutor`. Same defense as `-springai` for the other major Java LLM framework. Spring auto-wrap via `BeanPostProcessor`; `SsrfGuardedToolExecutors.wrap(...)` for non-Spring. +- **GraalVM native-image hints** via `META-INF/spring/aot.factories` in `-llm`. Adapter modules get free AOT support from Spring Boot 3. + +### Changed + +- `ssrf-guard-springai` refactored to a ~30-line thin adapter over `-llm`. Public API unchanged. +- Error payload backed by typed `SsrfBlockPayload` record (was `Map.of`). Same JSON wire shape; better AOT introspection. + +### Fixed + +- **WebClient DNS-time defense gap closed.** `SsrfGuardReactorAddressResolverGroup` filters reactor-netty's resolved IPs against the private/loopback ranges — closes the v3.0.x DNS-rebinding window WebFlux apps had. + +Full notes in [docs/changelog.md](docs/changelog.md#310--llm-core-extraction-langchain4j-webclient-dns-gap-graalvm-hints). + ## [3.0.1] — Fix metrics bean classpath gate ### Fixed @@ -58,7 +77,8 @@ semantic-release rollup. Tagged but **never published to Maven Central**. Initial public release. Tagged but **never published to Maven Central**. -[Unreleased]: https://github.com/devslab-kr/ssrf-guard/compare/v3.0.1...HEAD +[Unreleased]: https://github.com/devslab-kr/ssrf-guard/compare/v3.1.0...HEAD +[3.1.0]: https://github.com/devslab-kr/ssrf-guard/releases/tag/v3.1.0 [3.0.1]: https://github.com/devslab-kr/ssrf-guard/releases/tag/v3.0.1 [3.0.0]: https://github.com/devslab-kr/ssrf-guard/releases/tag/v3.0.0 [2.0.0]: https://github.com/devslab-kr/ssrf-guard/releases/tag/v2.0.0 diff --git a/docs/changelog.ko.md b/docs/changelog.ko.md index aec0f8f..4a3f667 100644 --- a/docs/changelog.ko.md +++ b/docs/changelog.ko.md @@ -6,28 +6,30 @@ ssrf-guard의 주요 변경 사항을 기록합니다. ## [Unreleased] -v3.1.0 작업 추적. 릴리즈된 항목은 태그 시 별도 섹션으로 이동. +## [3.1.0] — LLM 코어 추출, LangChain4j, WebClient DNS 공백 메움, GraalVM hints ### Added -- **`ssrf-guard-llm`** — 신규. 모든 LLM 툴 어댑터가 공유하는 JSON 트리 walk + URL 추출 + 정책 검증을 담는 framework-agnostic 코어 모듈. `ToolInputGuard` (인터페이스)와 `JsonToolInputGuard` (기본 구현) 노출. 이전에 `SsrfGuardedToolCallback` 내부에 있던 ~200줄 로직을 이쪽으로 이동. +- **`ssrf-guard-llm`** — 신규. 모든 LLM 툴 어댑터가 공유하는 JSON 트리 walk + URL 추출 + 정책 검증을 담는 framework-agnostic 코어 모듈. `ToolInputGuard` (인터페이스)와 `JsonToolInputGuard` (기본 구현) 노출. 이전에 `SsrfGuardedToolCallback` 내부에 있던 ~200줄 로직을 이쪽으로 통합. - **`ssrf-guard-langchain4j`** — 신규. LangChain4j의 `ToolExecutor`를 wrap하는 어댑터 모듈. `ssrf-guard-springai`와 동일한 LLM 에이전트 SSRF 표면을 LangChain4j 생태계 (Java LLM 양대 프레임워크 중 다른 하나) 대응. Spring Boot 사용자는 `BeanPostProcessor`로 자동 wrap; 비-Spring/프로그래매틱 사용자용 `SsrfGuardedToolExecutors.wrap(...)` 헬퍼 제공. +- **GraalVM native-image 친화성.** `ssrf-guard-llm`이 `RuntimeHintsRegistrar`를 등록 (`META-INF/spring/aot.factories` 통해) — Spring Boot AOT 프로세서가 런타임 reflection surface (매 차단마다 Jackson이 직렬화하는 `SsrfBlockPayload` record, Jackson에 의해 `label`이 읽히는 `BlockReason` enum)를 인식. 어댑터 모듈 (`-springai`, `-langchain4j`, 모든 Spring 자동설정)은 Spring Boot 3 AOT가 무료로 처리 — `@Bean` 팩토리 메서드와 `BeanPostProcessor`만 호스팅하므로. ### Changed - **`ssrf-guard-springai`가 thin adapter (~30줄)로 리팩토링.** 새 `-llm` 모듈의 `JsonToolInputGuard`에 위임. Public API 변경 없음 — `SsrfGuardedToolCallback`의 모든 생성자/메서드 시그니처 유지. v3.0.x 소비자는 API 변경 못 느낌 — 단지 `ssrf-guard-llm`을 transitive로 받게 됨. +- **에러 payload 형태 안정화.** SSRF 차단 시 LLM이 보는 JSON 객체가 이제 typed `SsrfBlockPayload` record (`{error, reason, url, message, guidance}`) 기반. v3.0.x와 wire 호환 — 동일 필드명, 동일 값. 이전 `Map.of(...)` 형태의 JDK-내부 `ImmutableCollections.MapN` 백킹 타입이 AOT introspect 안 되던 문제 해결. wire shape에 의존한 스크립트 변경 불필요; 기존 substring 테스트도 그대로 통과. -### Added (이어서) +### Fixed -- **GraalVM native-image 친화성.** `ssrf-guard-llm`이 `RuntimeHintsRegistrar`를 등록 (`META-INF/spring/aot.factories` 통해) — Spring Boot AOT 프로세서가 런타임 reflection surface (매 차단마다 Jackson이 직렬화하는 `SsrfBlockPayload` record, 그리고 `label`이 Jackson에 의해 읽히는 `BlockReason` enum)를 인식. 이전 `Map.of(...)` payload 형태가 JVM-내부 `ImmutableCollections.MapN` 타입을 써서 AOT가 introspect 못 했던 문제 해결. 어댑터 모듈 (`-springai`, `-langchain4j`, 모든 Spring 자동설정)은 Spring Boot 3 AOT가 무료로 처리 — `@Bean` 팩토리 메서드와 `BeanPostProcessor`만 호스팅하므로. +- **WebClient DNS-time 방어 공백 메움.** v3.0.x의 `ssrf-guard-webclient`는 URL-time 필터만 실행 — 화이트리스트를 통과한 호스트가 DNS 시점에 사설 IP로 resolve될 수 있었음 (전형적인 DNS 리바인딩 → 메타데이터 공격). 새 `SsrfGuardReactorAddressResolverGroup`이 reactor-netty의 `AddressResolverGroup`에 후킹해서 RestClient 모듈이 Apache HttpClient `DnsResolver` 단계에서 적용하는 것과 동일한 사설 IP 필터를 적용. WebFlux 앱도 이제 차단형 RestClient 앱이 갖던 2단계 방어 (URL + DNS) 동등하게 받음. reactor-netty 클래스패스 의존 — 비-Netty WebFlux 백엔드 (Jetty Reactive, Helidon)는 URL-time 필터만 작동하고 connector 교체는 스킵. -### Changed (이어서) +### Migration -- **에러 payload 형태 안정화.** SSRF 차단 시 LLM이 보는 JSON 객체가 이제 typed `SsrfBlockPayload` record (`{error, reason, url, message, guidance}`) 기반. v3.0.x와 wire 호환 — 동일 필드명, 동일 값. 기존 테스트가 substring 매치로 검증하고 그대로 통과; wire shape에 의존한 스크립트도 변경 불필요. +v3.1.0로 그냥 올리기 — 소비자 코드 변경 없음. 메타 `kr.devslab:ssrf-guard:3.1.0`도 v3.0.x처럼 `-core`, `-httpclient5`, `-restclient`를 transitive로 끌어옴. 새 모듈 (`-llm`, `-langchain4j`)은 opt-in — 좌표 추가 안 하면 따라오지 않음. -### Fixed +기존 `SecurityException` catch 코드는 그대로 동작 (`SsrfGuardException`이 여전히 `SecurityException` 서브클래스). 구조화 `e.reason()` 접근하려면 `SsrfGuardException`을 catch. -- **WebClient DNS-time 방어 공백 메움.** v3.0.x의 `ssrf-guard-webclient`는 URL-time 필터만 실행 — 화이트리스트를 통과한 호스트가 DNS 시점에 사설 IP로 resolve될 수 있었음 (전형적인 DNS 리바인딩 → 메타데이터 공격). 새 `SsrfGuardReactorAddressResolverGroup`이 reactor-netty의 `AddressResolverGroup`에 후킹해서 RestClient 모듈이 Apache HttpClient `DnsResolver` 단계에서 적용하는 것과 동일한 사설 IP 필터를 적용. WebFlux 앱도 이제 차단형 RestClient 앱이 갖던 2단계 방어 (URL + DNS) 동등하게 받음. reactor-netty 클래스패스 의존 — 비-Netty WebFlux 백엔드 (Jetty Reactive, Helidon)는 URL-time 필터만 작동하고 connector 교체는 스킵. +Native-image 소비자: `kr.devslab:ssrf-guard-llm:3.1.0` (또는 transitive로 끌어오는 모듈) 추가하면 AOT 프로세서가 등록된 hints 자동 인식. ## [3.0.1] — 메트릭 빈 classpath 게이트 수정 diff --git a/docs/changelog.md b/docs/changelog.md index ceb35e6..6311303 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -6,28 +6,30 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and ## [Unreleased] -Tracking v3.1.0 work. Released items will move into their own section below when the tag lands. +## [3.1.0] — LLM core extraction, LangChain4j, WebClient DNS gap, GraalVM hints ### Added -- **`ssrf-guard-llm`** — new framework-agnostic core module holding the JSON walking + URL extraction + policy validation that every LLM tool adapter shares. Exposes `ToolInputGuard` (interface) and `JsonToolInputGuard` (default impl). Replaces ~200 lines of logic that previously lived inside `SsrfGuardedToolCallback`. +- **`ssrf-guard-llm`** — new framework-agnostic core module holding the JSON walking + URL extraction + policy validation that every LLM tool adapter shares. Exposes `ToolInputGuard` (interface) and `JsonToolInputGuard` (default impl). Holds the ~200 lines of logic that previously lived inside `SsrfGuardedToolCallback`. - **`ssrf-guard-langchain4j`** — new adapter module wrapping LangChain4j's `ToolExecutor`. Closes the same LLM-agent SSRF surface as `ssrf-guard-springai` but for the LangChain4j ecosystem (the other major Java LLM framework). Auto-wrap via `BeanPostProcessor` for Spring Boot users; `SsrfGuardedToolExecutors.wrap(...)` helpers for non-Spring / programmatic users. +- **GraalVM native-image friendliness.** `ssrf-guard-llm` registers a `RuntimeHintsRegistrar` (via `META-INF/spring/aot.factories`) so Spring Boot's AOT processor learns about the reflective surface this library uses at runtime: the new `SsrfBlockPayload` record (Jackson-serialised on every block) and the `BlockReason` enum (Jackson-touched for its `label`). Adapter modules (`-springai`, `-langchain4j`, all Spring autoconfigs) get free AOT coverage from Spring Boot 3 — they only host `@Bean` factory methods and a `BeanPostProcessor`, both of which the AOT processor already handles. ### Changed - **`ssrf-guard-springai` refactored to a thin adapter (~30 lines).** Delegates to `JsonToolInputGuard` from the new `-llm` module. Public API unchanged — every constructor and method on `SsrfGuardedToolCallback` keeps the same shape. v3.0.x consumers see no API change; they just pick up `ssrf-guard-llm` transitively. +- **Error-payload shape stabilised.** The JSON object an LLM sees on an SSRF block is now backed by the typed `SsrfBlockPayload` record (`{error, reason, url, message, guidance}`). Wire-compatible with v3.0.x — same field names, same values. Replaces the previous `Map.of(...)` form whose JDK-private `ImmutableCollections.MapN` backing types AOT couldn't introspect. If you scripted around the wire shape you don't need to change anything; substring assertions in existing tests keep passing. -### Added (continued) +### Fixed -- **GraalVM native-image friendliness.** `ssrf-guard-llm` registers a `RuntimeHintsRegistrar` (via `META-INF/spring/aot.factories`) so Spring Boot's AOT processor learns about the reflective surface this library uses at runtime: the new `SsrfBlockPayload` record (Jackson-serialised on every block) and the `BlockReason` enum (also Jackson-touched for its `label`). Replaces the previous `Map.of(...)` payload form, which used JVM-private `ImmutableCollections.MapN` types that AOT couldn't introspect. Adapter modules (`-springai`, `-langchain4j`, all Spring autoconfigs) get free AOT coverage from Spring Boot 3 — they only host `@Bean` factory methods and a `BeanPostProcessor`, both of which the AOT processor already handles. +- **WebClient DNS-time defense gap closed.** v3.0.x's `ssrf-guard-webclient` only ran the URL-time filter — a host that passed the whitelist could still resolve to a private IP at DNS time (the classic DNS-rebinding-to-metadata attack). The new `SsrfGuardReactorAddressResolverGroup` plugs into reactor-netty's `AddressResolverGroup` and filters resolved IPs against the same private-IP ranges the RestClient module checks at the Apache HttpClient `DnsResolver` step. WebFlux apps now get the same two-layer defense (URL + DNS) the blocking RestClient apps already had. Gated on reactor-netty being on the classpath — non-Netty WebFlux backends (Jetty Reactive, Helidon) still get the URL-time filter and just skip the connector swap. -### Changed (continued) +### Migration -- **Error-payload shape stabilised.** The JSON object an LLM sees on an SSRF block is now backed by the typed `SsrfBlockPayload` record (`{error, reason, url, message, guidance}`). Wire-compatible with v3.0.x — same field names, same values. Existing tests assert on substring matches against those names and keep passing; if you scripted around the wire shape you don't need to change anything. +Drop in v3.1.0 — no consumer code changes. The meta `kr.devslab:ssrf-guard:3.1.0` still transitively pulls in `-core`, `-httpclient5`, `-restclient` like v3.0.x. New modules (`-llm`, `-langchain4j`) are opt-in; consumers who don't add their coordinate don't pull the new jars. -### Fixed +If you previously caught `SecurityException` you still match `SsrfGuardException` (it's still a `SecurityException` subclass). Catch `SsrfGuardException` to read the structured `e.reason()`. -- **WebClient DNS-time defense gap closed.** v3.0.x's `ssrf-guard-webclient` only ran the URL-time filter — a host that passed the whitelist could still resolve to a private IP at DNS time (the classic DNS-rebinding-to-metadata attack). The new `SsrfGuardReactorAddressResolverGroup` plugs into reactor-netty's `AddressResolverGroup` and filters resolved IPs against the same private-IP ranges the RestClient module checks at the Apache HttpClient `DnsResolver` step. WebFlux apps now get the same two-layer defense (URL + DNS) the blocking RestClient apps already had. Gated on reactor-netty being on the classpath — non-Netty WebFlux backends (Jetty Reactive, Helidon) still get the URL-time filter and just skip the connector swap. +For native-image consumers: add `kr.devslab:ssrf-guard-llm:3.1.0` (or any module that depends on it transitively) and the AOT processor will pick up the registered hints automatically. ## [3.0.1] — Fix metrics bean classpath gate From 7add9bad7cbde3bff44ba69d38c3483aac9a3a12 Mon Sep 17 00:00:00 2001 From: Sin-Kang Date: Sat, 23 May 2026 20:04:51 +0900 Subject: [PATCH 2/2] =?UTF-8?q?docs:=20bump=20version=20literals=203.0.0?= =?UTF-8?q?=20=E2=86=92=203.1.0=20in=20README=20+=20installation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wire-format coordinates only — Gradle/Maven snippets and 'Replace 3.0.0 with the latest' callouts. Historical references stay intact: - 'NEW v3.0.0' annotations (features added in v3.0.0) - '[v3.0.0 changelog]#300-...' links (package rename mapping lives in the v3.0.0 changelog section) - 'Upgrading from v2.0.0?' headers Also rewords 'ssrf-guard v3.0.0 is split along HTTP-client boundaries' to 'ssrf-guard 3.0+ is split' — the splitting was introduced in v3.0.0 and persists, so present-tense + '3.0+' is more accurate than pinning to v3.0.0 in a doc that's read by v3.1.0+ consumers. --- README.ko.md | 6 +++--- README.md | 6 +++--- docs/getting-started/installation.ko.md | 18 +++++++++--------- docs/getting-started/installation.md | 18 +++++++++--------- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/README.ko.md b/README.ko.md index 9ba324c..5c7993c 100644 --- a/README.ko.md +++ b/README.ko.md @@ -87,17 +87,17 @@ ToolCallback[] safe = SsrfGuardedToolCallbacks.wrap(raw, urlPolicy); kr.devslab ssrf-guard - 3.0.0 + 3.1.0 ``` ### Gradle (Kotlin DSL) ```kotlin -implementation("kr.devslab:ssrf-guard:3.0.0") +implementation("kr.devslab:ssrf-guard:3.1.0") ``` -> **v2.0.0에서 업그레이드?** 메타 `kr.devslab:ssrf-guard:3.0.0`이 v2.0.0 API 유지 — `-core`, `-httpclient5`, `-restclient`를 transitive로 끌어옴. `kr.devslab.ssrfguard.security.*`를 직접 import한 코드는 업데이트 필요 — [v3.0.0 changelog](CHANGELOG.md#300--multi-module--llm-agent-ssrf-defense) 패키지 매핑 참고. +> **v2.0.0에서 업그레이드?** 메타 `kr.devslab:ssrf-guard:3.1.0`이 v2.0.0 API 유지 — `-core`, `-httpclient5`, `-restclient`를 transitive로 끌어옴. `kr.devslab.ssrfguard.security.*`를 직접 import한 코드는 업데이트 필요 — [v3.0.0 changelog](CHANGELOG.md#300--multi-module--llm-agent-ssrf-defense) 패키지 매핑 참고. ## 설정 diff --git a/README.md b/README.md index 0c99e90..3e079f9 100644 --- a/README.md +++ b/README.md @@ -87,17 +87,17 @@ Auto-config picks it up — any `@Bean ToolCallback` gets wrapped via a `BeanPos kr.devslab ssrf-guard - 3.0.0 + 3.1.0 ``` ### Gradle (Kotlin DSL) ```kotlin -implementation("kr.devslab:ssrf-guard:3.0.0") +implementation("kr.devslab:ssrf-guard:3.1.0") ``` -> **Upgrading from v2.0.0?** The meta `kr.devslab:ssrf-guard:3.0.0` keeps the v2.0.0 API working — pulls in `-core`, `-httpclient5`, `-restclient` transitively. Direct imports of `kr.devslab.ssrfguard.security.*` need updates — see the [v3.0.0 changelog](CHANGELOG.md#300--multi-module--llm-agent-ssrf-defense) for the package-rename mapping. +> **Upgrading from v2.0.0?** The meta `kr.devslab:ssrf-guard:3.1.0` keeps the v2.0.0 API working — pulls in `-core`, `-httpclient5`, `-restclient` transitively. Direct imports of `kr.devslab.ssrfguard.security.*` need updates — see the [v3.0.0 changelog](CHANGELOG.md#300--multi-module--llm-agent-ssrf-defense) for the package-rename mapping. ## Configuration diff --git a/docs/getting-started/installation.ko.md b/docs/getting-started/installation.ko.md index 7c98050..4a36c8e 100644 --- a/docs/getting-started/installation.ko.md +++ b/docs/getting-started/installation.ko.md @@ -9,7 +9,7 @@ ## 모듈 선택 -ssrf-guard v3.0.0은 HTTP 클라이언트 경계로 분리되어 있습니다. 실제로 쓰는 모듈만 고르면 됩니다. +ssrf-guard 3.0+은 HTTP 클라이언트 경계로 분리되어 있습니다. 실제로 쓰는 모듈만 고르면 됩니다. === "RestClient (Spring Boot 3.x 기본)" @@ -17,7 +17,7 @@ ssrf-guard v3.0.0은 HTTP 클라이언트 경계로 분리되어 있습니다. kr.devslab ssrf-guard - 3.0.0 + 3.1.0 ``` @@ -29,7 +29,7 @@ ssrf-guard v3.0.0은 HTTP 클라이언트 경계로 분리되어 있습니다. kr.devslab ssrf-guard-resttemplate - 3.0.0 + 3.1.0 ``` @@ -41,7 +41,7 @@ ssrf-guard v3.0.0은 HTTP 클라이언트 경계로 분리되어 있습니다. kr.devslab ssrf-guard-webclient - 3.0.0 + 3.1.0 ``` @@ -53,7 +53,7 @@ ssrf-guard v3.0.0은 HTTP 클라이언트 경계로 분리되어 있습니다. kr.devslab ssrf-guard-feign - 3.0.0 + 3.1.0 ``` @@ -65,7 +65,7 @@ ssrf-guard v3.0.0은 HTTP 클라이언트 경계로 분리되어 있습니다. kr.devslab ssrf-guard-springai - 3.0.0 + 3.1.0 ``` @@ -108,7 +108,7 @@ ssrf-guard v3.0.0은 HTTP 클라이언트 경계로 분리되어 있습니다. kr.devslab ssrf-guard-jdkhttp - 3.0.0 + 3.1.0 ``` @@ -123,7 +123,7 @@ ssrf-guard v3.0.0은 HTTP 클라이언트 경계로 분리되어 있습니다. kr.devslab ssrf-guard-okhttp - 3.0.0 + 3.1.0 ``` @@ -135,7 +135,7 @@ ssrf-guard v3.0.0은 HTTP 클라이언트 경계로 분리되어 있습니다. ``` !!! tip "최신 버전" - `3.0.0`을 [Maven Central](https://central.sonatype.com/artifact/kr.devslab/ssrf-guard) 최신으로 교체. + `3.1.0`을 [Maven Central](https://central.sonatype.com/artifact/kr.devslab/ssrf-guard) 최신으로 교체. !!! info "v2.0.0에서 올라온다면" `kr.devslab:ssrf-guard` 좌표는 여전히 동작 — 메타 아티팩트가 `-core`, `-httpclient5`, `-restclient`를 끌어옴. 대부분 버전만 올리고 다시 빌드하면 끝. `kr.devslab.ssrfguard.security.*` 직접 import한 코드는 [v3.0.0 changelog](../changelog.md#300--multi-module--llm-agent-ssrf-defense)의 패키지 매핑 참고. diff --git a/docs/getting-started/installation.md b/docs/getting-started/installation.md index 2df4953..0dd46e3 100644 --- a/docs/getting-started/installation.md +++ b/docs/getting-started/installation.md @@ -9,7 +9,7 @@ ## Picking your module -ssrf-guard v3.0.0 is split along HTTP-client boundaries — pick the module(s) matching what you actually use. Most consumers want just one. +ssrf-guard 3.0+ is split along HTTP-client boundaries — pick the module(s) matching what you actually use. Most consumers want just one. === "RestClient (Spring Boot 3.x default)" @@ -17,7 +17,7 @@ ssrf-guard v3.0.0 is split along HTTP-client boundaries — pick the module(s) m kr.devslab ssrf-guard - 3.0.0 + 3.1.0 ``` @@ -29,7 +29,7 @@ ssrf-guard v3.0.0 is split along HTTP-client boundaries — pick the module(s) m kr.devslab ssrf-guard-resttemplate - 3.0.0 + 3.1.0 ``` @@ -41,7 +41,7 @@ ssrf-guard v3.0.0 is split along HTTP-client boundaries — pick the module(s) m kr.devslab ssrf-guard-webclient - 3.0.0 + 3.1.0 ``` @@ -53,7 +53,7 @@ ssrf-guard v3.0.0 is split along HTTP-client boundaries — pick the module(s) m kr.devslab ssrf-guard-feign - 3.0.0 + 3.1.0 ``` @@ -65,7 +65,7 @@ ssrf-guard v3.0.0 is split along HTTP-client boundaries — pick the module(s) m kr.devslab ssrf-guard-springai - 3.0.0 + 3.1.0 ``` @@ -108,7 +108,7 @@ ssrf-guard v3.0.0 is split along HTTP-client boundaries — pick the module(s) m kr.devslab ssrf-guard-jdkhttp - 3.0.0 + 3.1.0 ``` @@ -123,7 +123,7 @@ ssrf-guard v3.0.0 is split along HTTP-client boundaries — pick the module(s) m kr.devslab ssrf-guard-okhttp - 3.0.0 + 3.1.0 ``` @@ -135,7 +135,7 @@ ssrf-guard v3.0.0 is split along HTTP-client boundaries — pick the module(s) m ``` !!! tip "Latest version" - Replace `3.0.0` with the latest from [Maven Central](https://central.sonatype.com/artifact/kr.devslab/ssrf-guard). + Replace `3.1.0` with the latest from [Maven Central](https://central.sonatype.com/artifact/kr.devslab/ssrf-guard). !!! info "Coming from v2.0.0?" The `kr.devslab:ssrf-guard` coordinate still works — it's a meta artifact that pulls in `-core`, `-httpclient5`, and `-restclient`. Most consumers can upgrade by changing the version and rebuilding. Direct imports of `kr.devslab.ssrfguard.security.*` need to be updated — see the [v3.0.0 changelog](../changelog.md#300--multi-module--llm-agent-ssrf-defense) for the package-rename mapping.