Skip to content

Unable to verify the IPv4 mapped IPv6 address #1311

Open
@TeqGin

Description

@TeqGin
  • 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions