xss validation
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
package security
|
||||
|
||||
import (
|
||||
"html"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/microcosm-cc/bluemonday"
|
||||
)
|
||||
|
||||
// XSSPolicy defines the sanitization policy
|
||||
type XSSPolicy struct {
|
||||
policy *bluemonday.Policy
|
||||
}
|
||||
|
||||
// NewXSSPolicy creates a new XSS sanitization policy
|
||||
func NewXSSPolicy() *XSSPolicy {
|
||||
p := bluemonday.UGCPolicy()
|
||||
|
||||
// Allow basic formatting but strip scripts and dangerous attributes
|
||||
p.AllowAttrs("href", "target", "rel").OnElements("a")
|
||||
p.AllowAttrs("src", "alt", "width", "height").OnElements("img")
|
||||
p.AllowElements("p", "br", "strong", "em", "u", "h1", "h2", "h3", "h4", "h5", "h6")
|
||||
p.AllowElements("ul", "ol", "li")
|
||||
|
||||
return &XSSPolicy{policy: p}
|
||||
}
|
||||
|
||||
// SanitizeHTML sanitizes HTML input, allowing safe tags
|
||||
func (x *XSSPolicy) SanitizeHTML(input string) string {
|
||||
return x.policy.Sanitize(input)
|
||||
}
|
||||
|
||||
// SanitizeText completely escapes HTML entities for safe text display
|
||||
func (x *XSSPolicy) SanitizeText(input string) string {
|
||||
return html.EscapeString(input)
|
||||
}
|
||||
|
||||
// SanitizeEmail sanitizes input for use in email contexts
|
||||
func (x *XSSPolicy) SanitizeEmail(input string) string {
|
||||
// For emails, we want to allow basic formatting but be strict
|
||||
return strings.TrimSpace(x.SanitizeText(input))
|
||||
}
|
||||
|
||||
// SanitizeURL sanitizes URL input
|
||||
func (x *XSSPolicy) SanitizeURL(input string) string {
|
||||
// Remove javascript: and data: schemes
|
||||
dangerous := regexp.MustCompile(`(?i)^(javascript|data|vbscript):`)
|
||||
if dangerous.MatchString(input) {
|
||||
return ""
|
||||
}
|
||||
return strings.TrimSpace(input)
|
||||
}
|
||||
|
||||
// SanitizePhoneNumber sanitizes phone number input
|
||||
func (x *XSSPolicy) SanitizePhoneNumber(input string) string {
|
||||
// Remove any HTML tags and trim whitespace
|
||||
clean := regexp.MustCompile(`<[^>]*>`).ReplaceAllString(input, "")
|
||||
return strings.TrimSpace(clean)
|
||||
}
|
||||
|
||||
// ValidateAndSanitizeInput validates and sanitizes user input
|
||||
func (x *XSSPolicy) ValidateAndSanitizeInput(input string, fieldType string) (string, error) {
|
||||
if strings.TrimSpace(input) == "" {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
switch fieldType {
|
||||
case "text":
|
||||
return x.SanitizeText(input), nil
|
||||
case "html":
|
||||
return x.SanitizeHTML(input), nil
|
||||
case "email":
|
||||
return x.SanitizeEmail(input), nil
|
||||
case "url":
|
||||
return x.SanitizeURL(input), nil
|
||||
case "phone":
|
||||
return x.SanitizePhoneNumber(input), nil
|
||||
default:
|
||||
return x.SanitizeText(input), nil
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user