IsValidOrigin validates origin based on ALLOWED_ORIGINS
(inputURL string, allowedOriginsConfig []string)
| 81 | |
| 82 | // IsValidOrigin validates origin based on ALLOWED_ORIGINS |
| 83 | func IsValidOrigin(inputURL string, allowedOriginsConfig []string) bool { |
| 84 | allowedOrigins := allowedOriginsConfig |
| 85 | if len(allowedOrigins) == 0 { |
| 86 | allowedOrigins = []string{"*"} |
| 87 | } |
| 88 | if len(allowedOrigins) == 1 && allowedOrigins[0] == "*" { |
| 89 | return true |
| 90 | } |
| 91 | |
| 92 | currentOrigin := normalizeOrigin(inputURL) |
| 93 | |
| 94 | for _, origin := range allowedOrigins { |
| 95 | // Normalize the allowed origin the same way as the input URL |
| 96 | pattern := normalizeOrigin(origin) |
| 97 | |
| 98 | // if has wildcard domains, convert to regex |
| 99 | if strings.Contains(origin, "*") { |
| 100 | pattern = strings.ReplaceAll(pattern, ".", "\\.") |
| 101 | // Subdomain wildcard: *.example.com must only match |
| 102 | // proper subdomains (sub.example.com), not evil-example.com |
| 103 | // or the bare domain (example.com). |
| 104 | if strings.HasPrefix(pattern, "*\\.") { |
| 105 | // Replace leading *\. with one or more dot-terminated DNS labels, |
| 106 | // ensuring a proper dot boundary before the base domain. |
| 107 | pattern = "([^.]+\\.)+" + pattern[3:] |
| 108 | } else { |
| 109 | pattern = strings.ReplaceAll(pattern, "*", "[^.]*") |
| 110 | } |
| 111 | } |
| 112 | |
| 113 | if matched, _ := regexp.MatchString("^"+pattern+"$", currentOrigin); matched { |
| 114 | return true |
| 115 | } |
| 116 | } |
| 117 | |
| 118 | return false |
| 119 | } |