You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ssrf-guard 3.0.0 released β split into 9 modules, added Spring AI tool URL validation for LLM agents, hardened the IP-bypass defenses, added Micrometer metrics.
ssrf-guard 3.0.1 quick patch β ClassNotFoundException when consumers don't have micrometer-core on the classpath (the autoconfig referenced MeterRegistry by type instead of by class-presence). Fixed by gating the metrics bean with @ConditionalOnClass(MeterRegistry.class).
Five new demos in this repo cover every shipped module.
v3.0.0 highlights
New modules (opt-in)
Module
Use case
ssrf-guard-core
Policy / NetUtil / Micrometer metrics interface β no Spring
java.lang.TypeNotPresentException: Type io.micrometer.core.instrument.MeterRegistry not present
That's the bug 3.0.1 fixes. The autoconfig declared ObjectProvider<MeterRegistry> as a method parameter β ObjectProvider handles missing beans gracefully but the JVM still resolves the parameter type at class-load time, so consumers without micrometer-core blew up.
Fix: moved the Micrometer-backed metrics bean into a static inner @Configuration class gated by @ConditionalOnClass(name = "io.micrometer.core.instrument.MeterRegistry") with a NoOp fallback. Drop in 3.0.1 β no consumer changes needed.
The meta artifact transitively pulls -core + -httpclient5 + -restclient β the entire v2.0.0 surface. Direct imports of kr.devslab.ssrfguard.security.* need updates per the v3.0.0 changelog.
SsrfGuardException extends SecurityException, so existing catch (SecurityException e) keeps working. Catch the new type to read e.reason() (a BlockReason enum).
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
English Β· νκ΅μ΄
TL;DR
ssrf-guard 3.0.0released β split into 9 modules, added Spring AI tool URL validation for LLM agents, hardened the IP-bypass defenses, added Micrometer metrics.ssrf-guard 3.0.1quick patch βClassNotFoundExceptionwhen consumers don't havemicrometer-coreon the classpath (the autoconfig referencedMeterRegistryby type instead of by class-presence). Fixed by gating the metrics bean with@ConditionalOnClass(MeterRegistry.class).v3.0.0 highlights
New modules (opt-in)
ssrf-guard-coressrf-guard-httpclient5DnsResolver+RedirectStrategy(TOCTOU closure)ssrf-guard-restclientRestClientautoconfig (the v2.0.0 surface, now its own module)ssrf-guard-resttemplateRestTemplateautoconfigssrf-guard-webclientWebClientExchangeFilterFunctionssrf-guard-feignRequestInterceptorssrf-guard-springaiToolCallbackURL validation β closes the LLM-agent SSRF surfacessrf-guard-jdkhttpjava.net.http.HttpClientwrapper (no Spring)ssrf-guard-okhttpInterceptor+Dns(no Spring)ssrf-guard-core+-httpclient5+-restclientfor v2.0.0 back-compatDefense-in-depth hardening
2130706433), hex (0x7f000001), octal-style (0177.0.0.1), partial (127.1), IPv6 ([::1]) β all rejected at the URL-time check.https://user:pass@host/...blocked (known SSRF bypass + credential-leak risk).::ffff:10.0.0.5and2002:0a00::now correctly classified as private.Observability
Auto-wired with Micrometer:
v3.0.1 fix
If you bumped to 3.0.0 and got this:
That's the bug 3.0.1 fixes. The autoconfig declared
ObjectProvider<MeterRegistry>as a method parameter βObjectProviderhandles missing beans gracefully but the JVM still resolves the parameter type at class-load time, so consumers withoutmicrometer-coreblew up.Fix: moved the Micrometer-backed metrics bean into a static inner
@Configurationclass gated by@ConditionalOnClass(name = "io.micrometer.core.instrument.MeterRegistry")with aNoOpfallback. Drop in 3.0.1 β no consumer changes needed.New demos
All in
devslab-examples:ssrf-guard-demoβ RestClient + RestTemplate + WebClient all wired through oneUrlPolicy. 15-pattern attack matrix endpoint, Micrometer metrics.ssrf-guard-springai-demoβ β LLM agent SSRF defense. Fake-LLM driver β runnable offline, no API key.ssrf-guard-feign-demoβ Spring Cloud OpenFeign integration.ssrf-guard-jdkhttp-demoβjava.net.http.HttpClientwithout Spring.ssrf-guard-okhttp-demoβ OkHttp without Spring.Every demo: clone,
./gradlew bootRun, curl. Smoke tests included.Migration (v2.0.0 β v3.0.1)
Most consumers:
The meta artifact transitively pulls
-core+-httpclient5+-restclientβ the entire v2.0.0 surface. Direct imports ofkr.devslab.ssrfguard.security.*need updates per the v3.0.0 changelog.SsrfGuardException extends SecurityException, so existingcatch (SecurityException e)keeps working. Catch the new type to reade.reason()(aBlockReasonenum).Links
v3.0.0Β·v3.0.1kr.devslab:ssrf-guard:3.0.1νκ΅μ΄
μμ½
ssrf-guard 3.0.0λ¦΄λ¦¬μ¦ β 9κ° λͺ¨λλ‘ λΆν , LLM μμ΄μ νΈμ© Spring AI ν΄ URL κ²μ¦ μΆκ°, IP μ°ν λ°©μ΄ κ°ν, Micrometer λ©νΈλ¦ μΆκ°.ssrf-guard 3.0.1λΉ λ₯Έ ν¨μΉ β μλΉμκ°micrometer-coreλ₯Ό ν΄λμ€ν¨μ€μ μ κ°μ§λ©΄ λ°μνλClassNotFoundException. μλμ€μ μ΄MeterRegistryλ₯Ό νμ μΌλ‘ μ§μ λ ΈμΆμμΌμ λ°μ.@ConditionalOnClass(MeterRegistry.class)κ²μ΄νΈλ‘ 격리ν΄μ μμ .v3.0.0 μ£Όμ λ³κ²½
μ λͺ¨λ (opt-in)
ssrf-guard-coressrf-guard-httpclient5DnsResolver+RedirectStrategy(TOCTOU μ°¨λ¨)ssrf-guard-restclientRestClientμλμ€μ (v2.0.0μ surfaceκ° λ³λ λͺ¨λλ‘)ssrf-guard-resttemplateRestTemplateμλμ€μ ssrf-guard-webclientWebClientExchangeFilterFunctionssrf-guard-feignRequestInterceptorssrf-guard-springaiToolCallbackURL κ²μ¦ β LLM μμ΄μ νΈ SSRF μ°¨λ¨ssrf-guard-jdkhttpjava.net.http.HttpClientλνΌ (Spring μμ)ssrf-guard-okhttpInterceptor+Dns(Spring μμ)ssrf-guard-core+-httpclient5+-restclientλ¬ΆμμΌλ‘ v2.0.0 νΈνλ°©μ΄ κ°ν
2130706433), 16μ§μ (0x7f000001), 8μ§μ μ€νμΌ (0177.0.0.1), λΆλΆ (127.1), IPv6 ([::1]) β URL λ¨κ³μμ λͺ¨λ κ±°λΆ.https://user:pass@host/...μ°¨λ¨ (μλ €μ§ SSRF μ°ν + μ격μ¦λͺ λμΆ λ¦¬μ€ν¬).::ffff:10.0.0.5μ2002:0a00::μ΄ μ¬μ€λ‘ μ νν λΆλ₯.κ΄μ°°μ±
Micrometerλ‘ μλ μμ΄μ΄:
v3.0.1 fix
3.0.0μΌλ‘ μ¬λ¦° ν μ΄ μλ¬λ₯Ό λ΄€λ€λ©΄:
3.0.1μ΄ κ·Έ λ²κ·Έλ₯Ό κ³ μ³€μ΅λλ€. μλμ€μ μ΄
ObjectProvider<MeterRegistry>λ₯Ό λ©μλ νλΌλ―Έν°λ‘ μ μΈνμμ βObjectProviderλ μλ λΉμ μ°μνκ² μ²λ¦¬νμ§λ§ JVMμ ν΄λμ€ λ‘λ μμ μ νλΌλ―Έν° νμ μ κ·Έλλ resolveν©λλ€. κ·Έλμmicrometer-coreμλ μλΉμκ° λΆν μ νλ°.μμ : Micrometer κΈ°λ° λ©νΈλ¦ λΉμ
@ConditionalOnClass(name = "io.micrometer.core.instrument.MeterRegistry")λ‘ κ²μ΄νΈλ static inner@Configurationν΄λμ€λ‘ 격리νκ³NoOpfallback λ±λ‘. 3.0.1λ‘ λ°λ‘ μ¬λ¦¬λ©΄ λ¨ β μλΉμ μ½λ λ³κ²½ λΆνμ.μ λ°λͺ¨
λͺ¨λ
devslab-examplesμ:ssrf-guard-demoβ RestClient + RestTemplate + WebClientκ° λͺ¨λ νλμUrlPolicyλ‘ wiring. 15κ°μ§ 곡격 λ§€νΈλ¦μ€ μλν¬μΈνΈ, Micrometer λ©νΈλ¦.ssrf-guard-springai-demoβ β LLM μμ΄μ νΈ SSRF λ°©μ΄. κ°μ§ LLM λλΌμ΄λ² β μ€νλΌμΈ μ€ν, API ν€ λΆνμ.ssrf-guard-feign-demoβ Spring Cloud OpenFeign ν΅ν©.ssrf-guard-jdkhttp-demoβ Spring μμ΄java.net.http.HttpClient.ssrf-guard-okhttp-demoβ Spring μμ΄ OkHttp.λ°λͺ¨λ§λ€: clone,
./gradlew bootRun, curl. μ€λͺ¨ν¬ ν μ€νΈ ν¬ν¨.λ§μ΄κ·Έλ μ΄μ (v2.0.0 β v3.0.1)
λλΆλΆμ μ¬μ©μ:
λ©ν μν°ν©νΈκ°
-core+-httpclient5+-restclientλ₯Ό transitiveλ‘ λμ΄μ΄ β v2.0.0 μ 체 surface κ·Έλλ‘.kr.devslab.ssrfguard.security.*μ§μ importν μ½λλ v3.0.0 changelogμ λ§€ν μ°Έκ³ .SsrfGuardException extends SecurityExceptionβ κΈ°μ‘΄catch (SecurityException e)μ½λλ κ·Έλλ‘ λμ. μ νμ μΌλ‘ catchνλ©΄e.reason()(BlockReasonenum) μ κ·Ό κ°λ₯.λ§ν¬
v3.0.0Β·v3.0.1kr.devslab:ssrf-guard:3.0.1Beta Was this translation helpful? Give feedback.
All reactions