如何在 Golang 条带化 html、javascript、sql 等中清理字符串

How to sanitize strings in Golang striping html, javascript, sql etc

提问人:Bryan 提问时间:7/12/2022 更新时间:7/12/2022 访问量:1614

问:

我正在编写一个 REST API,用户可以通过它注册/登录以及许多其他需要他们在请求正文中发送 JSON 的东西。在请求正文中发送的 JSON 将如下所示,用于注册:

{
    "name": "luke",
    "email": "[email protected]",
    "date_of_birth": "2012-04-23T18:25:43.511Z",
    "location": "Galway",
    "profile_image_id": 1,
    "password": "password",
    "is_subscribee_account": false,
    "broker_id": 1
}

然后,这些数据将被解码为一个结构,并将各个项目插入到数据库中。我不熟悉我应该如何清理数据以删除任何可能干扰应用程序正确运行并可能导致系统受损的 Javascript、HTML、SQL 等。

下面的代码是我目前必须读入和验证数据的代码,但它没有清理 html、javascript、sql 等的数据。 关于我应该如何对其进行消毒的任何意见将不胜感激。REST API 是用 Go 编写的。

以下代码将 JSON 解码为 dst 变量。

func (app *application) readJSON(w http.ResponseWriter, r *http.Request, dst interface{}) error {
    maxBytes := 1_048_576
    r.Body = http.MaxBytesReader(w, r.Body, int64(maxBytes))

    dec := json.NewDecoder(r.Body)
    dec.DisallowUnknownFields()

    err := dec.Decode(dst)
    if err != nil {
        var syntaxError *json.SyntaxError
        var unmarshalTypeError *json.UnmarshalTypeError
        var invalidUnmarshalError *json.InvalidUnmarshalError

        switch {
        case errors.As(err, &syntaxError):
            return fmt.Errorf("body contains badly-formed JSON (at character %d)", syntaxError.Offset)

        case errors.Is(err, io.ErrUnexpectedEOF):
            return errors.New("body contains badly-formed JSON")

        case errors.As(err, &unmarshalTypeError):
            if unmarshalTypeError.Field != "" {
                return fmt.Errorf("body contains incorrect JSON type for field %q", unmarshalTypeError.Field)
            }
            return fmt.Errorf("body contains incorrect JSON type (at character %d)", unmarshalTypeError.Offset)

        case errors.Is(err, io.EOF):
            return errors.New("body must not be empty")

        case strings.HasPrefix(err.Error(), "json: unknown field "):
            fieldName := strings.TrimPrefix(err.Error(), "json: unknown field ")
            return fmt.Errorf("body contains unknown key %s", fieldName)

        case err.Error() == "http: request body too large":
            return fmt.Errorf("body must not be larger than %d bytes", maxBytes)

        case errors.As(err, &invalidUnmarshalError):
            panic(err)

        default:
            return err
        }
    }

    err = dec.Decode(&struct{}{})
    if err != io.EOF {
        return errors.New("body must only contain a single JSON value")
    }

    return nil
}

以下代码验证电子邮件、密码和用户。如果 V.Check() 中的第一个参数为 false,则在对用户的响应中返回以下两个参数。

func ValidateEmail(v *validator.Validator, email string) {
    v.Check(email != "", "email", "must be provided")
    v.Check(validator.Matches(email, validator.EmailRX), "email", "must be a valid email address")
}

func ValidatePasswordPlaintext(v *validator.Validator, password string) {
    v.Check(password != "", "password", "must be provided")
    v.Check(len(password) >= 8, "password", "must be at least 8 bytes long")
    v.Check(len(password) <= 72, "password", "must not be more than 72 bytes long")
}

func ValidateUser(v *validator.Validator, user *User) {
    v.Check(user.Name != "", "name", "must be provided")
    v.Check(len(user.Name) <= 500, "name", "must not be more than 500 bytes long")

    ValidateEmail(v, user.Email)

    if user.Password.plaintext != nil {
        ValidatePasswordPlaintext(v, *user.Password.plaintext)
    }

    if user.Password.hash == nil {
        panic("missing password hash for user")
    }
}

考虑到这一点,如何序列化结构数据?因此,如果以后插入网页,它不会引起问题。是否有可以将字符串数据传递给的包函数将返回安全数据?

GO 序列化 条带标签

评论

3赞 kostix 7/12/2022
库存 html/template 通过对 HTML 和 JS 的转义提供适当的清理。
4赞 mkopriva 7/12/2022
为了防止 SQL 注入,您应该使用适合您正在使用的特定数据库后端的参数占位符。
0赞 Adrian 7/12/2022
看起来像 ,并且是您在任何位置输出到需要清理的唯一自由格式字段。我希望并假设你会加盐和散列,这样内容就不需要消毒了。名称、电子邮件地址和位置应该可以安全地清除任何会使 HTML/JS/SQL 变得危险的字符 - 单引号/双引号、分号、尖括号。即使您不担心注入攻击,这些可能也不应该出现在这些领域中。nameemaillocation
0赞 Suzu Hirose 7/12/2022
这个问题太模糊了,无法回答。
1赞 Peter 7/12/2022
您无法在输入端为所有可能的用途清理数据,因为您最终可能希望以尚未发明的格式使用它(例如,YAML 相对较年轻)。如果将此数据用于使用它的上下文,则必须进行转义。正如其他人已经评论的那样,html/template 和 database/sql 包提供了安全处理用户提供的数据的工具。

答: 暂无答案