Skip to content

Conversation

@daniel-kmiecik
Copy link
Contributor

@daniel-kmiecik daniel-kmiecik commented Aug 27, 2025

The current implementation of the URL validation logic bypasses the security controls of setSafelyResolveURL when an HTTP redirect is encountered. This allows a malicious OpenAPI specification to force the validator's host to connect to internal network resources, creating a significant security risk. This is a fix for this securrity issue.

if (connection instanceof HttpsURLConnection) {
final HttpsURLConnection httpsConnection = (HttpsURLConnection) connection;
httpsConnection.setSSLSocketFactory(sf);
httpsConnection.setHostnameVerifier(trustAllNames);

Check warning

Code scanning / CodeQL

Unsafe hostname verification Medium

The
hostname verifier
defined by
this type
always accepts any certificate, even if the hostname does not match.

Copilot Autofix

AI 3 months ago

The best way to fix the problem is to remove the insecure HostnameVerifier that returns true and instead use the default hostname verifier provided by the JVM, ensuring proper hostname validation. If you must customize the verifier, it should fully validate the hostname according to RFC 2818 and relevant standards (e.g., by using Java's built-in HttpsURLConnection.getDefaultHostnameVerifier()).

In RemoteUrl.java:

  • Remove or replace the trustAllNames verifier.
  • Use HttpsURLConnection.getDefaultHostnameVerifier() when configuring HTTPS connections, even if the TRUST_ALL system property is set.
  • If certificate trust needs to be loosened for particular use-cases (testing), this should not disable hostname verification.
  • The actual code change is in the block that configures HttpsURLConnection in createConnectionConfigurator() to avoid the insecure verifier.

No changes are required in RemoteUrlTest.java, as the test logic does not reference custom hostname verifiers directly.

Suggested changeset 1
modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/RemoteUrl.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/RemoteUrl.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/RemoteUrl.java
--- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/RemoteUrl.java
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/RemoteUrl.java
@@ -67,14 +67,14 @@
                 sc.init(null, trustAllCerts, new java.security.SecureRandom());
                 final SSLSocketFactory sf = sc.getSocketFactory();
 
-                // Create all-trusting host name verifier
-                final HostnameVerifier trustAllNames = (hostname, session) -> true;
+                // Use JVM default HostnameVerifier to ensure hostnames are properly validated
+                final HostnameVerifier defaultHostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
 
                 return connection -> {
                     if (connection instanceof HttpsURLConnection) {
                         final HttpsURLConnection httpsConnection = (HttpsURLConnection) connection;
                         httpsConnection.setSSLSocketFactory(sf);
-                        httpsConnection.setHostnameVerifier(trustAllNames);
+                        httpsConnection.setHostnameVerifier(defaultHostnameVerifier);
                         httpsConnection.setConnectTimeout(CONNECTION_TIMEOUT);
                         httpsConnection.setReadTimeout(READ_TIMEOUT);
                         httpsConnection.setInstanceFollowRedirects(false);
EOF
@@ -67,14 +67,14 @@
sc.init(null, trustAllCerts, new java.security.SecureRandom());
final SSLSocketFactory sf = sc.getSocketFactory();

// Create all-trusting host name verifier
final HostnameVerifier trustAllNames = (hostname, session) -> true;
// Use JVM default HostnameVerifier to ensure hostnames are properly validated
final HostnameVerifier defaultHostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();

return connection -> {
if (connection instanceof HttpsURLConnection) {
final HttpsURLConnection httpsConnection = (HttpsURLConnection) connection;
httpsConnection.setSSLSocketFactory(sf);
httpsConnection.setHostnameVerifier(trustAllNames);
httpsConnection.setHostnameVerifier(defaultHostnameVerifier);
httpsConnection.setConnectTimeout(CONNECTION_TIMEOUT);
httpsConnection.setReadTimeout(READ_TIMEOUT);
httpsConnection.setInstanceFollowRedirects(false);
Copilot is powered by AI and may make mistakes. Always verify output.
@ewaostrowska ewaostrowska self-requested a review September 1, 2025 06:21
@ewaostrowska
Copy link
Contributor

Looks good :)

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements security measures to prevent Server-Side Request Forgery (SSRF) attacks via remote $ref in the Swagger parser by introducing URL validation and restricting access to potentially dangerous network locations.

Key changes:

  • Adds PermittedUrlsChecker functionality to validate URLs before making remote requests
  • Implements redirect limits and protocol validation to prevent abuse
  • Updates test infrastructure to support HTTPS and handle URL security checks

Reviewed Changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
pom.xml Removes commented dependencies and adds system property for testing
RemoteUrl.java Refactors URL handling with redirect limits, security checks, and improved error handling
RefUtils.java Updates method signatures to include PermittedUrlsChecker parameter
Multiple test files Updates tests to use HTTPS, adds security validation, and improves test structure
PermittedUrlsCheckerAllowLocal.java New test utility class to allow local connections during testing

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@daniel-kmiecik daniel-kmiecik merged commit 5dc2aae into master Sep 1, 2025
5 checks passed
@daniel-kmiecik daniel-kmiecik deleted the bug-bounty-fix-redirections branch September 1, 2025 14:00
@rootxjs
Copy link

rootxjs commented Sep 25, 2025

Fixes #2206

@daniel-kmiecik
Copy link
Contributor Author

@rootxjs, thank you for bringing this to our attention! I am closing the issue :)

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.

5 participants