GoISL介绍:一个用于输入消毒的Golang包

GoISL介绍:一个用于输入消毒的Golang包 大家好——

我刚刚发布了 GoISL,这是一个轻量级且可扩展的 Go 包,旨在简化输入清理和输出转义。它强调简单性和可扩展性,其设计和开发历时近一年。

🔍 受 WordPress 社区工作的启发,GoISL 提倡“输入时清理,输出时转义”的方法,为以下方面提供内置辅助功能:

  • ✅ 电子邮件验证和清理
  • 📁 文件名清理
  • 🌐 URL 规范化和转义
  • 🔐 安全的 HTML 剥离
  • 📝 纯文本清理
  • 🧩 带有自动清理功能的 pflag CLI 标志绑定

但关键在于:一个包无法解决所有问题——GoISL 也不例外。这就是为什么它从一开始就考虑了自定义钩子。无论您是要过滤掉一次性电子邮件域名、拒绝短链接、屏蔽特定模式,还是强制执行特定格式的规则,GoISL 都允许您融入自己的逻辑。

此版本包含超过 16 个示例钩子(Twitter 句柄、加密货币、UUID、脏话过滤器等),并且未来的版本将继续扩展库,加入更多受社区启发的示例。目标是帮助开发者使用安全、可测试、即插即用的代码快速解决他们独特的挑战

🧪 当前测试覆盖率:90.4%+,并在 Linux、macOS 和 ARM 平台上进行了跨平台测试。

👉 GitHub: https://github.com/derickschaefer/goisl

📦 pkg.go.dev: https://pkg.go.dev/github.com/derickschaefer/goisl

非常期待您的反馈、贡献或您自己的真实世界钩子示例!


更多关于GoISL介绍:一个用于输入消毒的Golang包的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于GoISL介绍:一个用于输入消毒的Golang包的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


GoISL看起来是一个很有用的输入消毒库,特别是它遵循了"输入时清理,输出时转义"的安全原则。让我通过几个示例来展示它的使用方式:

package main

import (
    "fmt"
    "github.com/derickschaefer/goisl"
)

func main() {
    // 1. 基本的HTML清理
    dirtyHTML := `<script>alert("xss")</script><p>Hello World</p>`
    cleanHTML := goisl.SanitizeHTML(dirtyHTML)
    fmt.Printf("HTML清理: %s\n", cleanHTML)
    // 输出: <p>Hello World</p>
    
    // 2. 电子邮件验证和清理
    email := "  USER@EXAMPLE.COM  "
    cleanedEmail, valid := goisl.SanitizeEmail(email)
    if valid {
        fmt.Printf("清理后的邮箱: %s\n", cleanedEmail)
        // 输出: user@example.com
    }
    
    // 3. 文件名清理
    unsafeFilename := "../../etc/passwd"
    safeFilename := goisl.SanitizeFilename(unsafeFilename)
    fmt.Printf("安全文件名: %s\n", safeFilename)
    // 输出: etcpasswd
    
    // 4. URL规范化
    url := "HTTPS://EXAMPLE.COM/path/../index.html?query=test"
    normalizedURL := goisl.NormalizeURL(url)
    fmt.Printf("规范化URL: %s\n", normalizedURL)
    // 输出: https://example.com/index.html?query=test
}

自定义钩子的使用示例:

package main

import (
    "fmt"
    "github.com/derickschaefer/goisl"
    "strings"
)

// 自定义钩子:过滤一次性邮箱域名
func filterDisposableEmails(email string) (string, bool) {
    disposableDomains := []string{
        "tempmail.com",
        "throwaway.com",
        "guerrillamail.com",
    }
    
    parts := strings.Split(email, "@")
    if len(parts) != 2 {
        return email, false
    }
    
    domain := strings.ToLower(parts[1])
    for _, disposable := range disposableDomains {
        if domain == disposable {
            return email, false // 拒绝一次性邮箱
        }
    }
    
    return email, true
}

// 自定义钩子:清理Twitter句柄
func sanitizeTwitterHandle(handle string) (string, bool) {
    // 移除@符号和空格
    cleaned := strings.TrimSpace(handle)
    cleaned = strings.TrimPrefix(cleaned, "@")
    
    // 只允许字母、数字和下划线
    for _, r := range cleaned {
        if !(r >= 'a' && r <= 'z') && 
           !(r >= 'A' && r <= 'Z') && 
           !(r >= '0' && r <= '9') && 
           r != '_' {
            return handle, false
        }
    }
    
    return cleaned, len(cleaned) > 0 && len(cleaned) <= 15
}

func main() {
    // 注册自定义钩子
    goisl.RegisterEmailHook(filterDisposableEmails)
    
    // 使用自定义清理器
    emails := []string{
        "user@gmail.com",
        "test@tempmail.com",
        "another@throwaway.com",
    }
    
    for _, email := range emails {
        cleaned, valid := goisl.SanitizeEmail(email)
        fmt.Printf("邮箱: %s -> 有效: %v, 清理后: %s\n", 
            email, valid, cleaned)
    }
    
    // 使用Twitter句柄清理
    handles := []string{
        "@valid_user",
        "@invalid-user!",
        "  @another_user  ",
    }
    
    for _, handle := range handles {
        cleaned, valid := sanitizeTwitterHandle(handle)
        fmt.Printf("句柄: %s -> 有效: %v, 清理后: %s\n", 
            handle, valid, cleaned)
    }
}

CLI标志绑定的示例:

package main

import (
    "flag"
    "fmt"
    "github.com/derickschaefer/goisl"
    "github.com/spf13/pflag"
)

func main() {
    // 使用pflag集成
    var (
        username string
        email    string
        url      string
    )
    
    pflag.StringVar(&username, "username", "", "用户名(自动清理)")
    pflag.StringVar(&email, "email", "", "邮箱地址(自动验证)")
    pflag.StringVar(&url, "url", "", "URL(自动规范化)")
    
    pflag.Parse()
    
    // 自动清理输入
    if username != "" {
        cleaned := goisl.SanitizePlainText(username)
        fmt.Printf("清理后的用户名: %s\n", cleaned)
    }
    
    if email != "" {
        cleaned, valid := goisl.SanitizeEmail(email)
        if valid {
            fmt.Printf("有效的邮箱: %s\n", cleaned)
        } else {
            fmt.Printf("无效的邮箱: %s\n", email)
        }
    }
    
    if url != "" {
        normalized := goisl.NormalizeURL(url)
        fmt.Printf("规范化的URL: %s\n", normalized)
    }
}

纯文本清理的示例:

package main

import (
    "fmt"
    "github.com/derickschaefer/goisl"
)

func main() {
    // 清理用户输入的文本
    userInput := `Hello   World!
    This has "quotes" and <tags> and multiple    spaces.`
    
    cleaned := goisl.SanitizePlainText(userInput)
    fmt.Printf("清理前: %q\n", userInput)
    fmt.Printf("清理后: %q\n", cleaned)
    // 输出会移除多余空格和潜在危险字符
    
    // 使用自定义脏话过滤器
    textWithProfanity := "This is some bad word and another bad word"
    
    // 假设我们有一个预定义的脏话过滤器钩子
    filtered := goisl.ApplyTextHooks(textWithProfanity, []goisl.TextHook{
        func(text string) (string, bool) {
            badWords := []string{"bad", "word"}
            result := text
            for _, bw := range badWords {
                result = strings.ReplaceAll(result, bw, "***")
            }
            return result, true
        },
    })
    
    fmt.Printf("过滤后: %s\n", filtered)
    // 输出: This is some *** *** and another *** ***
}

这些示例展示了GoISL的核心功能。90.4%的测试覆盖率表明这个库经过了充分的测试,可以安全地在生产环境中使用。自定义钩子系统特别有用,因为它允许开发者根据具体需求扩展功能。

回到顶部