Skip to content

C#: Add experimental SSRF IPv6-transition incomplete-guard query (CWE-918/CWE-1389)#148

Open
tonghuaroot wants to merge 1 commit into
GitHubSecurityLab:mainfrom
tonghuaroot:experimental-ssrf-ipv6-transition-csharp
Open

C#: Add experimental SSRF IPv6-transition incomplete-guard query (CWE-918/CWE-1389)#148
tonghuaroot wants to merge 1 commit into
GitHubSecurityLab:mainfrom
tonghuaroot:experimental-ssrf-ipv6-transition-csharp

Conversation

@tonghuaroot

Copy link
Copy Markdown

Summary

Adds a new experimental C# query, githubsecuritylab/cs/ssrf-ipv6-transition-incomplete-guard, that flags SSRF host-validation guards which reject private / loopback / cloud-metadata IPv4 ranges but never unwrap IPv6-transition representations.

When a guard inspects only the dotted-quad IPv4 form, an attacker can wrap an internal IPv4 address in a transition literal so the validator classifies the host as public while the OS still routes the connection to the embedded internal endpoint. The affected forms are:

  • IPv4-mapped IPv6 — ::ffff:169.254.169.254
  • NAT64 — 64:ff9b::a9fe:a9fe
  • 6to4 — 2002::

A URL such as http://[::ffff:169.254.169.254]/ passes a dotted-quad denylist unchanged while still reaching the internal address. Calling IPAddress.MapToIPv4() / testing IPAddress.IsIPv4MappedToIPv6 only canonicalizes the ::ffff:0:0/96 prefix, so NAT64 / 6to4 / IPv4-compatible forms remain live (CWE-918 / CWE-1389).

Origin

This was originally proposed in github/codeql#21964. @michaelnebel suggested moving it to the Community Packs rather than landing it as an experimental query in github/codeql, so this PR ports it here.

Contents

  • csharp/src/security/CWE-918/SsrfIpv6TransitionIncompleteGuard.ql — the query (@kind problem, import csharp only, autoformatted)
  • csharp/src/security/CWE-918/SsrfIpv6TransitionIncompleteGuard.qhelp — query help
  • csharp/src/security/CWE-918/examples/SsrfIpv6TransitionIncompleteGuard{Bad,Good}.cs — qhelp examples
  • csharp/test/security/CWE-918/SsrfIpv6TransitionIncompleteGuard/ — unit test (.cs / .qlref / .expected / options)

Adapted to Community Packs conventions: @id namespace githubsecuritylab/cs/..., query under csharp/src/security/CWE-918/, test under csharp/test/security/CWE-918/ with a ${testdir}/.../codeql/... stub options path matching the existing tests. The github/codeql-specific change-note and integration-test (not_included_in_qls.expected) files were dropped.

Verification

Verified locally with CodeQL CLI 2.25.6:

  • codeql query compile csharp/src/security/CWE-918/SsrfIpv6TransitionIncompleteGuard.ql — compiles clean, no warnings.
  • codeql query format — idempotent (autoformatted).
  • codeql test run csharp/test/security/CWE-918/SsrfIpv6TransitionIncompleteGuardpasses (2 expected true positives flagged, 4 transition-aware / out-of-scope callables correctly suppressed).

Adds githubsecuritylab/cs/ssrf-ipv6-transition-incomplete-guard, which
flags SSRF host-validation guards that reject private/loopback IPv4
ranges but never unwrap IPv6-transition forms (IPv4-mapped ::ffff:,
NAT64 64:ff9b::, 6to4 2002::). Such guards can be bypassed by wrapping
an internal IPv4 address in a transition literal, so the validator
classifies the host as public while the OS still routes to the internal
endpoint (CWE-918 / CWE-1389).

Includes qhelp, good/bad examples, and a unit test.
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.

1 participant