github.com/greenpau/go-authcrunch@v1.1.4/pkg/waf/malformed_input_check.go (about)

     1  // Copyright 2022 Paul Greenberg greenpau@outlook.com
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package waf
    16  
    17  import (
    18  	"strconv"
    19  	"unicode"
    20  )
    21  
    22  var protoCharsetTable = &unicode.RangeTable{
    23  	R16: []unicode.Range16{
    24  		{0x0061, 0x007a, 1}, // a-z, where a is hex 61
    25  		{0x0030, 0x0039, 1}, // 0-9, where 0 is hex 30
    26  	},
    27  	R32: []unicode.Range32{
    28  		{0x0061, 0x007a, 1}, // a-z, where a is hex 61
    29  		{0x0030, 0x0039, 1}, // 0-9, where 0 is hex 30
    30  	},
    31  	LatinOffset: 1,
    32  }
    33  
    34  var fwdAddrCharsetTable = &unicode.RangeTable{
    35  	R16: []unicode.Range16{
    36  		{0x0020, 0x0020, 1}, // space
    37  		{0x002c, 0x002c, 1}, // comma
    38  		{0x002e, 0x002e, 1}, // dot
    39  		{0x0030, 0x0039, 1}, // 0-9
    40  		{0x003a, 0x003a, 1}, // colon
    41  		{0x0041, 0x0046, 1}, // A-F
    42  		{0x0061, 0x0066, 1}, // a-f
    43  	},
    44  	LatinOffset: 1,
    45  }
    46  
    47  var realAddrCharsetTable = &unicode.RangeTable{
    48  	R16: []unicode.Range16{
    49  		{0x002e, 0x002e, 1}, // dot
    50  		{0x0030, 0x0039, 1}, // 0-9
    51  		{0x003a, 0x003a, 1}, // colon
    52  		{0x0041, 0x0046, 1}, // A-F
    53  		{0x005b, 0x005b, 1}, // Left square bracket
    54  		{0x005d, 0x005d, 1}, // Right square bracket
    55  		{0x0061, 0x0066, 1}, // a-f
    56  	},
    57  	LatinOffset: 1,
    58  }
    59  
    60  // IsMalformedForwardedHost checks whether the provided X-Forwarded-Host
    61  // string is malformed.
    62  func IsMalformedForwardedHost(s string, a, b int) bool {
    63  	switch {
    64  	case len(s) == 0:
    65  		return false
    66  	case (len(s) < a) || (len(s) > b):
    67  		return true
    68  	}
    69  	for _, char := range s {
    70  		if unicode.IsLetter(char) {
    71  			continue
    72  		}
    73  		if unicode.IsNumber(char) {
    74  			continue
    75  		}
    76  		if char == '.' || char == ':' || char == '-' {
    77  			continue
    78  		}
    79  		return true
    80  	}
    81  	return false
    82  }
    83  
    84  // IsMalformedForwardedProto checks whether the provided X-Forwarded-Proto
    85  // string is malformed.
    86  func IsMalformedForwardedProto(s string, a, b int) bool {
    87  	switch {
    88  	case len(s) == 0:
    89  		return false
    90  	case (len(s) < a) || (len(s) > b):
    91  		return true
    92  	}
    93  	for _, char := range s {
    94  		if unicode.In(char, protoCharsetTable) {
    95  			continue
    96  		}
    97  		return true
    98  	}
    99  	switch s {
   100  	case "http", "https":
   101  	default:
   102  		return true
   103  	}
   104  	return false
   105  }
   106  
   107  // IsMalformedForwardedPort checks whether the provided X-Forwarded-Port
   108  // string is malformed.
   109  func IsMalformedForwardedPort(s string, a, b int) bool {
   110  	switch {
   111  	case len(s) == 0:
   112  		return false
   113  	case (len(s) < a) || (len(s) > b):
   114  		return true
   115  	}
   116  	for _, char := range s {
   117  		if !unicode.IsNumber(char) {
   118  			return true
   119  		}
   120  	}
   121  	// Check the bounds 80 - 65535
   122  	i, _ := strconv.Atoi(s)
   123  	if i > 65535 || i < 80 {
   124  		return true
   125  	}
   126  	return false
   127  }
   128  
   129  // IsMalformedRealIP checks whether the provided X-Real-IP
   130  // string is malformed.
   131  func IsMalformedRealIP(s string, a, b int) bool {
   132  	switch {
   133  	case len(s) == 0:
   134  		return false
   135  	case (len(s) < a) || (len(s) > b):
   136  		return true
   137  	}
   138  	for _, char := range s {
   139  		if unicode.In(char, realAddrCharsetTable) {
   140  			continue
   141  		}
   142  		return true
   143  	}
   144  	return false
   145  }
   146  
   147  // IsMalformedForwardedFor checks whether the provided X-Forwarded-For
   148  // string is malformed.
   149  func IsMalformedForwardedFor(s string, a, b int) bool {
   150  	switch {
   151  	case len(s) == 0:
   152  		return false
   153  	case (len(s) < a) || (len(s) > b):
   154  		return true
   155  	}
   156  	for _, char := range s {
   157  		if unicode.In(char, fwdAddrCharsetTable) {
   158  			continue
   159  		}
   160  		return true
   161  	}
   162  	return false
   163  }