Skip to content

Add InetAddressMatcher#18633

Closed
rwinch wants to merge 37 commits into
mainfrom
google-ssrf
Closed

Add InetAddressMatcher#18633
rwinch wants to merge 37 commits into
mainfrom
google-ssrf

Conversation

@rwinch

@rwinch rwinch commented Feb 2, 2026

Copy link
Copy Markdown
Member

No description provided.

Gábor Vaspöri and others added 30 commits October 31, 2024 16:35
* Upgrade to more current version of Gradle

* Rename ssrf -> client package

If this is indeed for client side use only, then it should
be under a client package. Whether there should be a further
ssrf remains to be seen depending on what other security
feature are added, and how they are configured.

* Rename CustomDnsResolver to SsrfDnsResolver
* Introducing adapters to decouple underlying clients and prevent dependency bloat

* Minor cleanups, comments added, naming for Apache HTTP client specific classes changed

---------

Co-authored-by: Gábor Vaspöri <vaspori@google.com>
…r custom DNS (#6)

Co-authored-by: Kian Jamali <kjamali@google.com>
Fix bug: Make sure that a customConnectionManager can be used
* Enable hostname matching in IpOrRange allowlist

Previously, IpOrRange would resolve all input addresses (including hostnames)
to IP addresses, discarding the original hostname. This prevented direct
hostname-to-hostname matching if a hostname was used in an allowlist.

This change introduces the following modifications:

1.  `IpOrRange.java`:
    *   Now stores the original input string as `hostname` if it appears to be a
        hostname (contains letters, no colons). Otherwise, `hostname` is null.
    *   The `matches` method signature is changed to
        `matches(String toCheckAddressString, InetAddress toCheckInetAddress)`.
    *   New matching logic:
        *   If `IpOrRange` has a `hostname` stored:
            *   If `toCheckAddressString` is also a hostname, they are compared
              (case-insensitive). A match here returns true.
            *   If `toCheckAddressString` is an IP, `IpOrRange` falls back to
              comparing its resolved IP with `toCheckInetAddress`.
        *   If `IpOrRange` has no `hostname` (was initialized with an IP), it
            performs an IP-based match as before.

2.  `ListedSsrfProtectionFilter.java`:
    *   Updated to call the new `IpOrRange.matches` method. It now passes
        `addr.getHostName()` as `toCheckAddressString` and `addr` as
        `toCheckInetAddress`. This allows `IpOrRange` to use the hostname
        of the address being checked if available via rDNS.

3.  `IpOrRangeTest.java`:
    *   Existing tests updated to conform to the new `matches` signature.
    *   Added new unit tests using Mockito to cover various scenarios of
        hostname and IP matching, including cases where:
        *   Allowlist entry is a hostname, checked address is a matching/non-matching hostname.
        *   Allowlist entry is a hostname, checked address is an IP (matching/non-matching the resolved IP of the allowlist hostname).
        *   Allowlist entry is an IP, checked address is a hostname (resolving to matching/non-matching IP).
    *   The `mockito-inline` dependency was added to `ssrf/build.gradle` to
        support static mocking of `InetAddress`.

These changes allow for more flexible allowlist configurations where specific
hostnames can be targeted, rather than just their underlying IP addresses,
which can change.

* Fixing the tests

* Fix a bug related to www in domain names

* Uncomment all example usages

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
…13)

* Restructuring pr integration (WIP) (#7)

* Draft of restructuring

* Integration of Rossen's changes in the existing library

* Adding tests for JettyHttpClientDnsResolverTest

* Fix the implementation of JettyHttpClientDnsResolver

The resolve() method of JettyHttpClientDnsResolver was not propagating
the result to the outer promise. This change should fix the issue by
passing the result to the outer promise.

* Updating Jetty's DNS resolver  tests following the previous commit/fix

* Adding Netty client adapter

* Add getter in SecurityDnsHandler

* Fix logic in DefaultInetAddressFilter

* Refactor SecureRestTemplate

* Refactoring UsageExample

* First non-working implementation of example 8

* Fix example8() of UsageExample

* Nit improvements

* Renamed Hc5ClientAdapter to HttpComponentsAdapter

* Moving the resolvers to our internal client folder

* Moved resolvers tests

* Nit: Simplified DefaultInetAddressFilter

* Using Netty 1.2.6

* Nit refactoring of the gradle build file as we don't need snapshots anymore

* Fix the SecurityDnsHandler to ensure that the reportOnly mode does not filter any address

* Add tests for SecurityDnsHandler

* Refactoring client.dns package name

* Added example 9 to test out our new approach

* Uncomment example usages

---------

Co-authored-by: rstoyanchev <rossen.stoyanchev@broadcom.com>
Co-authored-by: Kian Jamali <kjamali@google.com>
Co-authored-by: Gábor Vaspöri <vaspori@google.com>

* Fix JUnit dependencies (#10)

* Fix JUnit dependencies

* Update JUnit dependencies to version 5.10.2

* Refactor the library with the new architecture (#11)

* Add overloaded constructor for HttpComponentsDnsResolver to support default DNS resolver

* Refactor JettyHttpClientDnsResolver to improve promise handling and add constructor with a default resolver

* Make DefaultInetAddressFilter public and update filtering logic for allow/deny lists

* Make SecurityDnsHandler constructor public and add a getter to get the reportOnly mode

* Update import statements in DNS resolver test files to use correct package paths

* Update UsageExample to only keep the relevant example for this new approach

* Remove obsolete classes and their associated tests due to architectural changes

* Update filterAddress's doc based on our recent changes

* Integrate Netty client (#12)

* feat: Add NettyHttpClientAddressSelector for Reactor Netty

This commit introduces NettyHttpClientAddressSelector, a component
that allows filtering of resolved IP addresses for Reactor Netty's
HttpClient. It leverages Netty's `resolvedAddressesSelector` API
and uses the existing `SecurityDnsHandler` for the filtering logic.

Key changes:
- Added `NettyHttpClientAddressSelector.java` implementing the
  `BiFunction` interface for address selection.
- Added `NettyHttpClientAddressSelectorTests.java` with comprehensive
  unit tests.
- Updated `README.md` to include documentation and usage examples
  for the new component, as well as for the existing
  JettyHttpClientDnsResolver.

* docs: Add usage examples for Netty and Jetty SSRF protection

This commit adds new example methods to `UsageExample.java` to
demonstrate the usage of:
- `NettyHttpClientAddressSelector` with Reactor Netty's HttpClient.
- `JettyHttpClientDnsResolver` with Jetty's HttpClient.

These examples provide practical guidance for users looking to
integrate SSRF protection with these HTTP clients. The main method
in `UsageExample.java` has been updated to run these new examples.

* Fixing build issues and tests

* Fixing tests

* Improve UsageExample.java debug msgs

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>

* Remove duplicated code

* Add missing import for HttpComponentsDnsResolver in UsageExample

* Enhance README with detailed use cases for the library

* Refactor NettyHttpClientAddressSelector and SecurityDnsHandler for improved socket address handling

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>

---------

Co-authored-by: rstoyanchev <rossen.stoyanchev@broadcom.com>
Co-authored-by: Kian Jamali <kjamali@google.com>
Co-authored-by: Gábor Vaspöri <vaspori@google.com>
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
KJ202 and others added 6 commits July 18, 2025 06:15
* Add draft of proposal for Spring Security

* Update draft of proposal for Spring Security
* Backporting test for Netty and Apache resolvers

* Update ssrf/src/main/java/org/springframework/boot/http/client/NettyHttpClientFilteringAddressSelector.java

Co-authored-by: Rossen Stoyanchev <rstoyanchev@users.noreply.github.com>

---------

Co-authored-by: Rossen Stoyanchev <rstoyanchev@users.noreply.github.com>
- Deleted InetAddressFilter interface and its implementation in SecurityDnsHandler.
- Removed package-info.java files for client and client.dns packages.
- Eliminated all test cases related to DNS filtering, including NettyHttpClientAddressSelectorTests, HttpComponentsDnsResolverTest, JettyHttpClientDnsResolverTest, and SecurityDnsHandlerTest.
- Removed example usage code demonstrating DNS filtering with various HTTP clients.
* Add InetAddressFilterBuilderTests

* Add Javadoc to InetAddressFilter.Builder

* Drop allow-deny list mutually exclusive assertion

* Remove remaining uses of "verifier" term

* Rename addCustomFilter to customFilter

* Polishing
@rwinch rwinch self-assigned this Feb 2, 2026
@rwinch rwinch requested a review from rstoyanchev February 2, 2026 16:07
@rwinch rwinch closed this Feb 2, 2026
@rwinch rwinch deleted the google-ssrf branch February 2, 2026 16:58
@rwinch rwinch restored the google-ssrf branch February 2, 2026 16:58
@rwinch rwinch reopened this Feb 2, 2026
@rwinch rwinch closed this Feb 2, 2026
@rwinch rwinch deleted the google-ssrf branch February 2, 2026 17:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants