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 }