Skip to content

Conversation

@munishchouhan
Copy link
Member

Summary

Added Server-Side Request Forgery (SSRF) protection to the /validate-creds endpoints to prevent malicious users from making the Wave service connect to internal/private network resources. The implementation uses a lightweight utility class approach to avoid performance overhead on other endpoints.

Changes

Core Implementation

  • SsrfValidator (src/main/groovy/io/seqera/wave/util/SsrfValidator.groovy):
    • Simple static utility class for validating registry hostnames
    • Validates against multiple threat vectors:
      • Private IP ranges (RFC 1918): 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
      • Loopback addresses: 127.0.0.0/8, ::1
      • Link-local addresses: 169.254.0.0/16
      • Cloud metadata service IPs: 169.254.169.254 (AWS/GCP/Azure), 169.254.170.2 (AWS ECS)
      • Localhost variations: localhost, localhost.localdomain, 0.0.0.0
      • IPv6 unique local addresses: fc00::/7
    • Performs DNS resolution to catch domains that resolve to private IPs
    • Validates both direct IP addresses and hostnames

Integration Points

  • ValidateController (src/main/groovy/io/seqera/wave/controller/ValidateController.groovy):
    • Added SsrfValidator.validateHost() call in both endpoints:
      • /validate-creds (deprecated)
      • /v1alpha2/validate-creds
    • Validation runs before registry authentication attempts
    • Throws IllegalArgumentException with descriptive error message if validation fails

Test Coverage

  • SsrfValidatorTest (src/test/groovy/io/seqera/wave/util/SsrfValidatorTest.groovy):
    • Comprehensive test suite with 23 tests (100% passing)
    • Tests for blocking private IPs (10 test cases)
    • Tests for blocking localhost variations (3 test cases)
    • Tests for allowing public hostnames (8 test cases)
    • Tests for cloud metadata service blocking
    • Tests for null/empty input handling

Security Impact

Threats Mitigated

  1. Internal Network Scanning: Prevents attackers from using Wave to probe internal networks
  2. Metadata Service Access: Blocks access to cloud provider metadata services (AWS/GCP/Azure)
  3. Localhost Exploitation: Prevents attempts to access services on the Wave server itself
  4. DNS Rebinding: Validates resolved IPs to prevent DNS-based attacks

Signed-off-by: munishchouhan <hrma017@gmail.com>
Signed-off-by: munishchouhan <hrma017@gmail.com>
Signed-off-by: munishchouhan <hrma017@gmail.com>
Signed-off-by: munishchouhan <hrma017@gmail.com>
Signed-off-by: munishchouhan <hrma017@gmail.com>
Signed-off-by: munishchouhan <hrma017@gmail.com>
Signed-off-by: munishchouhan <hrma017@gmail.com>
@munishchouhan munishchouhan changed the title Comp 1145 fix ssrf Comp 1145 Added Server-Side Request Forgery (SSRF) protection to the /validate-creds Jan 14, 2026
@munishchouhan munishchouhan changed the title Comp 1145 Added Server-Side Request Forgery (SSRF) protection to the /validate-creds Comp 1145 Added Server-Side Request Forgery (SSRF) protection to the validate-creds API Jan 15, 2026
munishchouhan and others added 5 commits January 15, 2026 06:58
Signed-off-by: munishchouhan <hrma017@gmail.com>
Signed-off-by: munishchouhan <hrma017@gmail.com>
Signed-off-by: munishchouhan <hrma017@gmail.com>
Signed-off-by: munishchouhan <hrma017@gmail.com>
@munishchouhan
Copy link
Member Author

Tested locally:

  1. invalid registry
wave %  curl -X POST http://localhost:9090/v1alpha2/validate-creds \
    -H "Content-Type: application/json" \
    -d '{
      "userName": "test",
      "password": "test",
      "registry": "localhost"
    }'

{"message":"Access to localhost is not allowed: localhost - Error ID: a8562c2af15c"}

wave % curl -X POST http://localhost:9090/v1alpha2/validate-creds \
    -H "Content-Type: application/json" \
    -d '{
      "userName": "test",
      "password": "test",
      "registry": "10.0.0.1"
    }'

{"message":"Access to private IP range is not allowed: 10.0.0.1 - Error ID: f5c9bc154a46"}

wave %  curl -X POST http://localhost:9090/v1alpha2/validate-creds \
    -H "Content-Type: application/json" \
    -d '{
      "userName": "test",
      "password": "test",
      "registry": "169.254.169.254"
    }'

{"message":"Access to cloud metadata service is not allowed: 169.254.169.254 - Error ID: 4fce98fc28b4"}

wave %  curl -X POST http://localhost:9090/v1alpha2/validate-creds \
    -H "Content-Type: application/json" \
    -d '{
      "userName": "test",
      "password": "test",
      "registry": "169.254.169.254"
    }'

{"message":"Access to cloud metadata service is not allowed: 169.254.169.254 - Error ID: 4fce98fc28b4"}
  1. valid registry
wave % curl -X POST http://localhost:9090/v1alpha2/validate-creds \
    -H "Content-Type: application/json" \
    -d '{
      "userName": "test",
      "password": "test",
      "registry": "docker.io"
    }'

false%    

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.

2 participants