Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions ssrf-guard-demo/README.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

하나의 Spring Boot 앱에 **3종 Spring HTTP 클라이언트**가 모두 동일 `UrlPolicy`를 통해 wiring됨:

- `RestClient` (Spring 6.1+) — 메타 아티팩트 `kr.devslab:ssrf-guard:3.1.0`
- `RestTemplate` — `kr.devslab:ssrf-guard-resttemplate:3.1.0`
- `WebClient` (WebFlux) — `kr.devslab:ssrf-guard-webclient:3.1.0`
- `RestClient` (Spring 6.1+) — 메타 아티팩트 `kr.devslab:ssrf-guard:3.1.1`
- `RestTemplate` — `kr.devslab:ssrf-guard-resttemplate:3.1.1`
- `WebClient` (WebFlux) — `kr.devslab:ssrf-guard-webclient:3.1.1`

추가로 `/attacks` 엔드포인트는 가드가 차단하는 모든 SSRF 우회 패턴 목록을 각 모듈별 curl 예제와 함께 제공합니다.

Expand Down Expand Up @@ -146,7 +146,7 @@ curl -s http://localhost:8080/actuator/prometheus | grep ssrf_guard

| 파일 | 왜 |
| --- | --- |
| `build.gradle.kts` | 표준 스타터 외 의존성은 `kr.devslab:ssrf-guard:3.1.0`, `:ssrf-guard-resttemplate:3.1.0`, `:ssrf-guard-webclient:3.1.0` 셋뿐 — 별도 configuration 클래스 불필요 |
| `build.gradle.kts` | 표준 스타터 외 의존성은 `kr.devslab:ssrf-guard:3.1.1`, `:ssrf-guard-resttemplate:3.1.1`, `:ssrf-guard-webclient:3.1.1` 셋뿐 — 별도 configuration 클래스 불필요 |
| `application.yml` | 모든 `ssrf.guard.*` 옵션이 한 곳에 주석과 함께 |
| `web/FetchController.java` | RestClient 전체 — 3줄 setup, 가드는 보이지 않게 실행 |
| `web/FetchResttemplateController.java` | RestTemplate 동일 — 레거시 코드 마이그레이션 불필요 |
Expand Down
8 changes: 4 additions & 4 deletions ssrf-guard-demo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ Runnable example for [`ssrf-guard`](https://github.com/devslab-kr/ssrf-guard)

One Spring Boot app shows **all three Spring HTTP clients** wired through the same `UrlPolicy`:

- `RestClient` (Spring 6.1+) via the meta `kr.devslab:ssrf-guard:3.1.0` artifact
- `RestTemplate` via `kr.devslab:ssrf-guard-resttemplate:3.1.0`
- `WebClient` (WebFlux) via `kr.devslab:ssrf-guard-webclient:3.1.0`
- `RestClient` (Spring 6.1+) via the meta `kr.devslab:ssrf-guard:3.1.1` artifact
- `RestTemplate` via `kr.devslab:ssrf-guard-resttemplate:3.1.1`
- `WebClient` (WebFlux) via `kr.devslab:ssrf-guard-webclient:3.1.1`

Plus a `/attacks` endpoint that lists every SSRF bypass pattern the guard catches, with copy-paste curls for each.

Expand Down Expand Up @@ -147,7 +147,7 @@ You'll see counters per `reason` tag (`blocked_host`, `blocked_ip_literal`, `blo

| File | Why |
| --- | --- |
| `build.gradle.kts` | The only dependencies beyond the standard starters are `kr.devslab:ssrf-guard:3.1.0`, `kr.devslab:ssrf-guard-resttemplate:3.1.0`, `kr.devslab:ssrf-guard-webclient:3.1.0` — no manual configuration class needed |
| `build.gradle.kts` | The only dependencies beyond the standard starters are `kr.devslab:ssrf-guard:3.1.1`, `kr.devslab:ssrf-guard-resttemplate:3.1.1`, `kr.devslab:ssrf-guard-webclient:3.1.1` — no manual configuration class needed |
| `application.yml` | Every `ssrf.guard.*` knob in one place with comments |
| `web/FetchController.java` | The whole RestClient story — three lines of setup, the guard runs invisibly |
| `web/FetchResttemplateController.java` | Same shape for RestTemplate — no migration needed for legacy code |
Expand Down
6 changes: 3 additions & 3 deletions ssrf-guard-demo/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ dependencies {
// The meta `ssrf-guard` artifact transitively pulls in `-core`, `-httpclient5`,
// and `-restclient`. The `-resttemplate` and `-webclient` modules are
// additive and reuse the same UrlPolicy / SsrfGuardMetrics beans.
implementation("kr.devslab:ssrf-guard:3.1.0")
implementation("kr.devslab:ssrf-guard-resttemplate:3.1.0")
implementation("kr.devslab:ssrf-guard-webclient:3.1.0")
implementation("kr.devslab:ssrf-guard:3.1.1")
implementation("kr.devslab:ssrf-guard-resttemplate:3.1.1")
implementation("kr.devslab:ssrf-guard-webclient:3.1.1")

// Micrometer Prometheus registry — turns SSRF Guard's counters into
// /actuator/prometheus output so you can curl the metrics in the demo.
Expand Down
4 changes: 2 additions & 2 deletions ssrf-guard-feign-demo/README.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,12 @@ curl http://localhost:8080/feign/evil | jq

| 파일 | 왜 |
| --- | --- |
| `build.gradle.kts` | `kr.devslab:ssrf-guard-feign:3.1.0` + `spring-cloud-starter-openfeign` |
| `build.gradle.kts` | `kr.devslab:ssrf-guard-feign:3.1.1` + `spring-cloud-starter-openfeign` |
| `HttpBinClient.java` / `EvilClient.java` | 평범한 `@FeignClient` 인터페이스 2개 — 가드 코드 없음 |
| `FeignDemoController.java` | `SsrfGuardException` catch (Feign이 한 단계 wrap — 컨트롤러가 unwrap) |
| `application.yml` | `ssrf.guard.exact-hosts: [httpbin.org]` — 그 한 줄이 화이트리스트 |

Feign 인터셉터는 자동 등록됨 — `ssrf-guard-feign-3.1.0`이 Spring 자동설정으로 `feign.RequestInterceptor` 빈을 publish하고, Spring Cloud OpenFeign이 모든 `@FeignClient`에 적용.
Feign 인터셉터는 자동 등록됨 — `ssrf-guard-feign-3.1.1`이 Spring 자동설정으로 `feign.RequestInterceptor` 빈을 publish하고, Spring Cloud OpenFeign이 모든 `@FeignClient`에 적용.

## 빌드 검증

Expand Down
4 changes: 2 additions & 2 deletions ssrf-guard-feign-demo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,12 @@ curl http://localhost:8080/feign/evil | jq

| File | Why |
| --- | --- |
| `build.gradle.kts` | `kr.devslab:ssrf-guard-feign:3.1.0` + `spring-cloud-starter-openfeign` |
| `build.gradle.kts` | `kr.devslab:ssrf-guard-feign:3.1.1` + `spring-cloud-starter-openfeign` |
| `HttpBinClient.java` / `EvilClient.java` | Two normal `@FeignClient` interfaces — no guard code |
| `FeignDemoController.java` | Catches `SsrfGuardException` (wrapped one level deep by Feign — the controller unwraps) |
| `application.yml` | `ssrf.guard.exact-hosts: [httpbin.org]` — that one line is the whitelist |

The Feign interceptor registers itself automatically — `ssrf-guard-feign-3.1.0` provides a Spring autoconfig that publishes a `feign.RequestInterceptor` bean, which Spring Cloud OpenFeign then applies to every `@FeignClient`.
The Feign interceptor registers itself automatically — `ssrf-guard-feign-3.1.1` provides a Spring autoconfig that publishes a `feign.RequestInterceptor` bean, which Spring Cloud OpenFeign then applies to every `@FeignClient`.

## Verify the build

Expand Down
2 changes: 1 addition & 1 deletion ssrf-guard-feign-demo/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ dependencies {
implementation("org.springframework.cloud:spring-cloud-starter-openfeign")

// The library this demo showcases. Pulls in ssrf-guard-core transitively.
implementation("kr.devslab:ssrf-guard-feign:3.1.0")
implementation("kr.devslab:ssrf-guard-feign:3.1.1")

testImplementation("org.springframework.boot:spring-boot-starter-test")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
Expand Down
2 changes: 1 addition & 1 deletion ssrf-guard-httpclient5-demo/README.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ curl 'http://localhost:8080/fetch?url=https://evil.com/' | jq

| 파일 | 왜 |
| --- | --- |
| `build.gradle.kts` | 의존성 둘: `kr.devslab:ssrf-guard-httpclient5:3.1.0` + `org.apache.httpcomponents.client5:httpclient5:5.4.1` |
| `build.gradle.kts` | 의존성 둘: `kr.devslab:ssrf-guard-httpclient5:3.1.1` + `org.apache.httpcomponents.client5:httpclient5:5.4.1` |
| `SsrfGuardHttpClient5DemoApplication.java` | `@SpringBootApplication`만. 모듈의 자동 설정이 가드된 `CloseableHttpClient` 빈을 wire — **wiring 코드 0줄**. |
| `HttpClient5DemoController.java` | 표준 `client.execute(get, handler)` 호출 — 가드 참조 0 |
| `application.yml` | `ssrf.guard.*` 키: 화이트리스트, `block-private-networks`, `follow-redirects`, `allowed-schemes` |
Expand Down
2 changes: 1 addition & 1 deletion ssrf-guard-httpclient5-demo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ Blocked responses look like:

| File | Why |
| --- | --- |
| `build.gradle.kts` | Two deps: `kr.devslab:ssrf-guard-httpclient5:3.1.0` + `org.apache.httpcomponents.client5:httpclient5:5.4.1` |
| `build.gradle.kts` | Two deps: `kr.devslab:ssrf-guard-httpclient5:3.1.1` + `org.apache.httpcomponents.client5:httpclient5:5.4.1` |
| `SsrfGuardHttpClient5DemoApplication.java` | Just `@SpringBootApplication`. The module's autoconfig wires the guarded `CloseableHttpClient` bean — **zero lines of wiring code**. |
| `HttpClient5DemoController.java` | Standard `client.execute(get, handler)` call — no reference to the guard at all |
| `application.yml` | `ssrf.guard.*` keys: whitelist, `block-private-networks`, `follow-redirects`, `allowed-schemes` |
Expand Down
2 changes: 1 addition & 1 deletion ssrf-guard-httpclient5-demo/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ dependencies {
// constructed by hand — see the README's "Without Spring" section.
implementation("org.springframework.boot:spring-boot-starter-web")

implementation("kr.devslab:ssrf-guard-httpclient5:3.1.0")
implementation("kr.devslab:ssrf-guard-httpclient5:3.1.1")
// The Apache HttpClient 5 runtime. Versions 5.3+ ship the
// DnsResolver / RedirectStrategy interfaces the module plugs into.
implementation("org.apache.httpcomponents.client5:httpclient5:5.4.1")
Expand Down
2 changes: 1 addition & 1 deletion ssrf-guard-jdkhttp-demo/README.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ curl 'http://localhost:8080/fetch?url=https://evil.com/' | jq

| 파일 | 왜 |
| --- | --- |
| `build.gradle.kts` | 의존성 하나: `kr.devslab:ssrf-guard-jdkhttp:3.1.0` |
| `build.gradle.kts` | 의존성 하나: `kr.devslab:ssrf-guard-jdkhttp:3.1.1` |
| `SsrfGuardJdkHttpDemoApplication.java` | 전체 스토리: `HostPolicy` → `UrlPolicy` → `HttpClient` wrap |
| `JdkHttpDemoController.java` | 평범한 `client.send(req, ...)` — 호출부에서 wrap은 보이지 않음 |

Expand Down
2 changes: 1 addition & 1 deletion ssrf-guard-jdkhttp-demo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ curl 'http://localhost:8080/fetch?url=https://evil.com/' | jq

| File | Why |
| --- | --- |
| `build.gradle.kts` | One dep: `kr.devslab:ssrf-guard-jdkhttp:3.1.0` |
| `build.gradle.kts` | One dep: `kr.devslab:ssrf-guard-jdkhttp:3.1.1` |
| `SsrfGuardJdkHttpDemoApplication.java` | The whole story: build `HostPolicy` → `UrlPolicy` → wrap `HttpClient` |
| `JdkHttpDemoController.java` | Calls `client.send(req, ...)` like any other HttpClient — the wrap is invisible at the call site |

Expand Down
2 changes: 1 addition & 1 deletion ssrf-guard-jdkhttp-demo/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ dependencies {
// dependency itself; the Spring Boot framing is just the demo's UX.
implementation("org.springframework.boot:spring-boot-starter-web")

implementation("kr.devslab:ssrf-guard-jdkhttp:3.1.0")
implementation("kr.devslab:ssrf-guard-jdkhttp:3.1.1")
// ssrf-guard-core's @ConfigurationProperties pulls in spring-boot
// (transitively from -jdkhttp's API), so we get the SsrfGuardProperties
// binding for free.
Expand Down
2 changes: 1 addition & 1 deletion ssrf-guard-langchain4j-demo/README.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ curl -X POST http://localhost:8080/agent/chat \

| 파일 | 왜 |
| --- | --- |
| `build.gradle.kts` | 의존성 — `kr.devslab:ssrf-guard-langchain4j:3.1.0` + `dev.langchain4j:langchain4j:1.15.0`. 끝 |
| `build.gradle.kts` | 의존성 — `kr.devslab:ssrf-guard-langchain4j:3.1.1` + `dev.langchain4j:langchain4j:1.15.0`. 끝 |
| `application.yml` | `ssrf.guard.langchain4j.wrap-tool-executors=true` — 마스터 스위치 (기본 true, 명시적 표기) |
| `agent/FetchUrlTool.java` | 원시 executor — **보안 코드 0줄**. wrap은 빈 후처리 시점에 일어남 |
| `agent/FakeLlmService.java` | 가짜 LLM 드라이버. 프로덕션에선 `AiServices` 어시스턴트. 교체, 재컴파일, 끝 |
Expand Down
2 changes: 1 addition & 1 deletion ssrf-guard-langchain4j-demo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ curl -X POST http://localhost:8080/agent/chat \

| File | Why |
| --- | --- |
| `build.gradle.kts` | The dependencies — `kr.devslab:ssrf-guard-langchain4j:3.1.0` + `dev.langchain4j:langchain4j:1.15.0`. That's it |
| `build.gradle.kts` | The dependencies — `kr.devslab:ssrf-guard-langchain4j:3.1.1` + `dev.langchain4j:langchain4j:1.15.0`. That's it |
| `application.yml` | `ssrf.guard.langchain4j.wrap-tool-executors=true` — the master switch (default true, shown for clarity) |
| `agent/FetchUrlTool.java` | The raw executor — note there's **zero** security code here. The wrap happens at bean post-processing time |
| `agent/FakeLlmService.java` | The fake-LLM driver. In production this is an `AiServices`-built assistant. Swap, recompile, done |
Expand Down
4 changes: 2 additions & 2 deletions ssrf-guard-langchain4j-demo/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ dependencies {
// - ssrf-guard-langchain4j: registers a BeanPostProcessor that wraps every
// ToolExecutor bean automatically — the "secure-by-default" pitch
// mirrored from ssrf-guard-springai, just for the LangChain4j community.
implementation("kr.devslab:ssrf-guard:3.1.0")
implementation("kr.devslab:ssrf-guard-langchain4j:3.1.0")
implementation("kr.devslab:ssrf-guard:3.1.1")
implementation("kr.devslab:ssrf-guard-langchain4j:3.1.1")

// LangChain4j 1.x. We don't actually call an LLM in this demo — the
// FakeLlmService stands in for one — but we pull the API in so the
Expand Down
8 changes: 4 additions & 4 deletions ssrf-guard-native-image-demo/README.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

[English](README.md) · **한국어**

[`ssrf-guard 3.1.0`](https://github.com/devslab-kr/ssrf-guard)의 **GraalVM 네이티브 이미지 힌트**가 동작함을 end-to-end로 증명 — Spring Boot 앱에 라이브러리 drop, `./gradlew nativeCompile`, 나온 네이티브 바이너리가 JVM 빌드와 동일한 게이트에서 SSRF 시도를 차단.
[`ssrf-guard 3.1.1`](https://github.com/devslab-kr/ssrf-guard)의 **GraalVM 네이티브 이미지 힌트**가 동작함을 end-to-end로 증명 — Spring Boot 앱에 라이브러리 drop, `./gradlew nativeCompile`, 나온 네이티브 바이너리가 JVM 빌드와 동일한 게이트에서 SSRF 시도를 차단.

## 이 데모가 증명하는 것

ssrf-guard 3.1.0은 각 모듈에서 `META-INF/spring/aot.factories`로 `RuntimeHintsRegistrar` 엔트리를 발행합니다. 커버 범위:
ssrf-guard 3.1.1은 각 모듈에서 `META-INF/spring/aot.factories`로 `RuntimeHintsRegistrar` 엔트리를 발행합니다. 커버 범위:

| 타입 | 힌트가 필요한 이유 |
| --- | --- |
Expand Down Expand Up @@ -127,7 +127,7 @@ find build/generated -name 'reflect-config.json' -exec head -30 {} \;

| 파일 | 왜 |
| --- | --- |
| `build.gradle.kts` | 2줄 셋업: `kr.devslab:ssrf-guard:3.1.0` + `org.graalvm.buildtools.native` plugin |
| `build.gradle.kts` | 2줄 셋업: `kr.devslab:ssrf-guard:3.1.1` + `org.graalvm.buildtools.native` plugin |
| `SsrfGuardNativeImageDemoApplication.java` | `@SpringBootApplication` + `RestClient` bean만 — 나머지는 자동 설정 처리 |
| `NativeImageDemoController.java` | `/fetch` + `/attacks` — `runtime` 필드 (jvm vs graalvm-native)로 시각적 확인 |
| `application.yml` | `ssrf.guard.*` 키 — `@ConfigurationProperties` 바인딩 경로가 AOT 힌트가 필요한 그 경로 |
Expand All @@ -145,4 +145,4 @@ GraalVM 네이티브 이미지는 JVM cold-start 비용 문제의 답:
- Kubernetes pod scale-to-zero
- 100 ms 미만 시작 필요한 CLI 도구

라이브러리 측 힌트 없으면 사용자가 끌어오는 모든 의존성이 네이티브 이미지 지뢰. ssrf-guard 3.1.0은 힌트를 ship해서 사용자가 우리 타입에 대한 `reflect-config.json` 안 쓰고도 `nativeCompile` 가능.
라이브러리 측 힌트 없으면 사용자가 끌어오는 모든 의존성이 네이티브 이미지 지뢰. ssrf-guard 3.1.1은 힌트를 ship해서 사용자가 우리 타입에 대한 `reflect-config.json` 안 쓰고도 `nativeCompile` 가능.
8 changes: 4 additions & 4 deletions ssrf-guard-native-image-demo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

**English** · [한국어](README.ko.md)

End-to-end proof that [`ssrf-guard 3.1.0`](https://github.com/devslab-kr/ssrf-guard)'s **GraalVM native-image hints** work — drop the library into a Spring Boot app, run `./gradlew nativeCompile`, and the resulting native binary blocks SSRF attempts at the same gates the JVM build does.
End-to-end proof that [`ssrf-guard 3.1.1`](https://github.com/devslab-kr/ssrf-guard)'s **GraalVM native-image hints** work — drop the library into a Spring Boot app, run `./gradlew nativeCompile`, and the resulting native binary blocks SSRF attempts at the same gates the JVM build does.

## What this demo proves

ssrf-guard 3.1.0 ships `RuntimeHintsRegistrar` entries through `META-INF/spring/aot.factories` in each module. The hints cover:
ssrf-guard 3.1.1 ships `RuntimeHintsRegistrar` entries through `META-INF/spring/aot.factories` in each module. The hints cover:

| Type | Why it needs a hint |
| --- | --- |
Expand Down Expand Up @@ -127,7 +127,7 @@ You should see entries for `UrlPolicy`, `HostPolicy`, `SsrfBlockPayload`, `Block

| File | Why |
| --- | --- |
| `build.gradle.kts` | The two-line setup: `kr.devslab:ssrf-guard:3.1.0` + `org.graalvm.buildtools.native` plugin |
| `build.gradle.kts` | The two-line setup: `kr.devslab:ssrf-guard:3.1.1` + `org.graalvm.buildtools.native` plugin |
| `SsrfGuardNativeImageDemoApplication.java` | Just `@SpringBootApplication` + a `RestClient` bean — autoconfig handles the rest |
| `NativeImageDemoController.java` | `/fetch` + `/attacks` — surfaces `runtime` (jvm vs graalvm-native) for visual confirmation |
| `application.yml` | `ssrf.guard.*` keys — bound via `@ConfigurationProperties`, which is the path that needs the AOT hints |
Expand All @@ -145,4 +145,4 @@ GraalVM native images are the answer to JVM cold-start cost in:
- Kubernetes pods that scale to zero
- CLI tools that need to start in <100 ms

Without library-side hints, every dependency the consumer pulls in is a potential native-image landmine. ssrf-guard 3.1.0 ships the hints so consumers can `nativeCompile` without writing `reflect-config.json` for our types.
Without library-side hints, every dependency the consumer pulls in is a potential native-image landmine. ssrf-guard 3.1.1 ships the hints so consumers can `nativeCompile` without writing `reflect-config.json` for our types.
4 changes: 2 additions & 2 deletions ssrf-guard-native-image-demo/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
id("io.spring.dependency-management") version "1.1.7"
// GraalVM Native Image — provides `nativeCompile` + `nativeRun` tasks,
// and the `processAot` task that exercises every RuntimeHintsRegistrar
// contributed by libraries on the classpath. ssrf-guard 3.1.0 ships
// contributed by libraries on the classpath. ssrf-guard 3.1.1 ships
// hints for UrlPolicy / HostPolicy / SsrfBlockPayload / BlockReason
// + the LLM JSON-walking path + Micrometer reflective bean; this demo
// is the end-to-end proof those hints actually let a native image
Expand Down Expand Up @@ -32,7 +32,7 @@ dependencies {
// hints transitively. Everything ssrf-guard contributes to the native
// image (reflection / proxies / resources) flows through this single
// dep.
implementation("kr.devslab:ssrf-guard:3.1.0")
implementation("kr.devslab:ssrf-guard:3.1.1")

testImplementation("org.springframework.boot:spring-boot-starter-test")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
Expand Down
2 changes: 1 addition & 1 deletion ssrf-guard-okhttp-demo/README.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ curl 'http://localhost:8080/fetch?url=https://evil.com/' | jq

| 파일 | 왜 |
| --- | --- |
| `build.gradle.kts` | `kr.devslab:ssrf-guard-okhttp:3.1.0` + `com.squareup.okhttp3:okhttp:4.12.0` |
| `build.gradle.kts` | `kr.devslab:ssrf-guard-okhttp:3.1.1` + `com.squareup.okhttp3:okhttp:4.12.0` |
| `SsrfGuardOkHttpDemoApplication.java` | OkHttp 빌더에 3줄 — `.addInterceptor(...)`, `.dns(...)`, `.followRedirects(...)` |
| `OkHttpDemoController.java` | 표준 OkHttp `newCall().execute()` — 호출부에서 wrap은 보이지 않음 |

Expand Down
2 changes: 1 addition & 1 deletion ssrf-guard-okhttp-demo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ curl 'http://localhost:8080/fetch?url=https://evil.com/' | jq

| File | Why |
| --- | --- |
| `build.gradle.kts` | `kr.devslab:ssrf-guard-okhttp:3.1.0` + `com.squareup.okhttp3:okhttp:4.12.0` |
| `build.gradle.kts` | `kr.devslab:ssrf-guard-okhttp:3.1.1` + `com.squareup.okhttp3:okhttp:4.12.0` |
| `SsrfGuardOkHttpDemoApplication.java` | Three lines on the OkHttp builder — `.addInterceptor(...)`, `.dns(...)`, `.followRedirects(...)` |
| `OkHttpDemoController.java` | Standard OkHttp `newCall().execute()` — the wrap is invisible at the call site |

Expand Down
2 changes: 1 addition & 1 deletion ssrf-guard-okhttp-demo/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ dependencies {
// (ssrf-guard-okhttp) has no Spring dependency.
implementation("org.springframework.boot:spring-boot-starter-web")

implementation("kr.devslab:ssrf-guard-okhttp:3.1.0")
implementation("kr.devslab:ssrf-guard-okhttp:3.1.1")
implementation("com.squareup.okhttp3:okhttp:4.12.0")

testImplementation("org.springframework.boot:spring-boot-starter-test")
Expand Down
Loading
Loading