Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to verify the IPv4 mapped IPv6 address #1311

Open
2 tasks done
TeqGin opened this issue Aug 21, 2024 · 0 comments
Open
2 tasks done

Unable to verify the IPv4 mapped IPv6 address #1311

TeqGin opened this issue Aug 21, 2024 · 0 comments

Comments

@TeqGin
Copy link

TeqGin commented Aug 21, 2024

  • I have looked at the documentation here first?
  • I have looked at the examples provided that may showcase my question here?

Package version eg. v9, v10:

v10.14.0

Issue, Question or Enhancement:

Unable to verify the IPv4 mapped IPv6 address

Code sample, to showcase or reproduce:

package main

import (
	"fmt"

	"github.com/go-playground/validator/v10"
)

func main() {
	v := validator.New()
        // fail
	err := v.Var("::ffff:c0a8:0101", "ipv6")
	if err != nil {
		fmt.Println(err)
	}
        // fail
	err = v.Var("::ffff:192.168.1.1", "ipv6")
	if err != nil {
		fmt.Println(err)
	}
        // fail
	err = v.Var("::ffff:c0a8:0101", "ip6_addr")
	if err != nil {
		fmt.Println(err)
	}
        // fail
	err = v.Var("::ffff:192.168.1.1", "ip6_addr")
	if err != nil {
		fmt.Println(err)
	}
}
Key: '' Error:Field validation for '' failed on the 'ipv6' tag
Key: '' Error:Field validation for '' failed on the 'ipv6' tag
Key: '' Error:Field validation for '' failed on the 'ip6_addr' tag
Key: '' Error:Field validation for '' failed on the 'ip6_addr' tag

I checked the source code, for ipv6 tag the root cause is when we check a valid ip is IPv4 or IPv6, we used the To4() function in net package:

// isIPv6 is the validation function for validating if the field's value is a valid v6 IP address.
func isIPv6(fl FieldLevel) bool {
	ip := net.ParseIP(fl.Field().String())

	return ip != nil && ip.To4() == nil
}

but in net package, it automatically covert the IPv4 mapped IPv6 address to IPv4, so the To4() function return value will not be nil, which make the isIPv6 return false. But I think this is not expected.

func (ip IP) To4() IP {
	if len(ip) == IPv4len {
		return ip
	}
        // covert the IPv4 mapped IPv6 address to IPv4 such as ::ffff:192.168.1.1 to 192.168.1.1
	if len(ip) == IPv6len &&
		isZeros(ip[0:10]) &&
		ip[10] == 0xff &&
		ip[11] == 0xff {
		return ip[12:16]
	}
	return nil
}

we can simply fix this by check the raw ip string's format, for ipv4 it only can contains ".", for ipv6 it must contains ":" and it can optional contains "."(dot is for IPv4 mapped IPv6 address) but cannot only contains ".".

and corresponding issue also happens in ipv4 tag and ip4_addr tag, the the IPv4 mapped IPv6 address can successfully pass by the ipv4 validation.

package main

import (
	"fmt"

	"github.com/go-playground/validator/v10"
)

func main() {
	v := validator.New()
        // pass
	err := v.Var("::ffff:c0a8:0101", "ipv4")
	if err != nil {
		fmt.Println(err)
	}
        // pass
	err = v.Var("::ffff:192.168.1.1", "ipv4")
	if err != nil {
		fmt.Println(err)
	}
        // pass
	err = v.Var("::ffff:c0a8:0101", "ip4_addr")
	if err != nil {
		fmt.Println(err)
	}
        // pass
	err = v.Var("::ffff:192.168.1.1", "ip4_addr")
	if err != nil {
		fmt.Println(err)
	}
}

submit a pull request to simply fix this: #1312 please review it,

Please take care of this, thanks.

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

No branches or pull requests

1 participant