Golang常见漏洞代码

收集遇到了Golang开发过程中的一些常见漏洞代码,方便大家学习和避免。

_updatePersonInfo = `
        INSERT INTO people (id, name, age, email)  
		VALUES(%d, '%s', %d, %d, %d) 
		ON DUPLICATE KEY UPDATE 
		name=VALUES(name), age=VALUES(age), email=VALUES(email)
`

func (d *Dao) UpdatePersonInfo(ctx context.Context, req *PersonUpdateReq) error {
	sql := fmt.Sprintf(_updatePersonInfo, req.ID, req.Name, req.Age, req.Email)
	return errors.WithStack(d.DB.Exec(sql).Error)
}

直接采用Sprintf的方式组装SQL语句,容易受到SQL注入攻击。

使用PrepareExec的方式来执行SQL语句,如下:

const _updatePersonInfo = `
	INSERT INTO people (id, name, age, email) 
	VALUES (?, ?, ?, ?) 
	ON DUPLICATE KEY UPDATE 
	name=VALUES(name), age=VALUES(age), email=VALUES(email)
`

type PersonUpdateReq struct {
	ID    int
	Name  string
	Age   int
	Email string
}

func (d *Dao) UpdatePersonInfo(ctx context.Context, req *PersonUpdateReq) error {
	// Prepare the statement
	stmt, err := d.DB.PrepareContext(ctx, _updatePersonInfo)
	if err != nil {
		return errors.WithStack(err)
	}
	defer stmt.Close()

	// Execute the statement with the provided parameters
	_, err = stmt.ExecContext(ctx, req.ID, req.Name, req.Age, req.Email)
	if err != nil {
		return errors.WithStack(err)
	}

	return nil
}
func (s *Service) ListPeople(c *gin.Context, p *http.ListPeopleReq) (resp *http.ListPeopleResp, err error) {
    resp = new(http.ListPeopleResp)
    
    // Query to get the list of people based on the request parameters
    if err = s.d.DB.Order(p.Sort()).Limit(p.Limit()).Offset(p.Offset()).Where("department_id=?", p.DepartmentID).Find(&resp.Records).Error; err != nil {
        return
    }
    
    // Query to count the total number of people in the specified department
    err = s.d.DB.Table("people").Where("department_id=?", p.DepartmentID).Count(&resp.Total).Error
    return
}
// ListPeopleInfo lists people's information from the database.
func (s *Service) ListPeopleInfo(c *gin.Context, req *ListPeopleInfoRequest) (resp *ListPeopleInfoResponse, err error) {
	resp = new(ListPeopleInfoResponse)

	// Sanitize and validate the sort parameter
	sortColumn, sortOrder := sanitizeSort(req.Sort)
	if sortColumn == "" || sortOrder == "" {
		return nil, fmt.Errorf("invalid sort parameter")
	}

	// Ensure limit and offset are valid integers
	// omit for brevity

	// Perform the query with sanitized inputs
	if err = s.d.DB.Order(fmt.Sprintf("%s %s", sortColumn, sortOrder)).Limit(limit).Offset(offset).Where("cluster_id=?", req.ClusterID).Find(&resp.Records).Error; err != nil {
		return
	}
	err = s.d.DB.Table("people").Where("cluster_id=?", req.ClusterID).Count(&resp.Total).Error
	return
}

// sanitizeSort sanitizes and validates the sort parameter
func sanitizeSort(sort string) (column, order string) {
	// Define allowed columns and sort orders
	allowedColumns := map[string]bool{
		"id": true, "name": true, "age": true, "email": true, // Add other allowed columns
	}
	allowedOrders := map[string]bool{
		"asc": true, "desc": true,
	}

	// Split the sort string into column and order
	parts := strings.Split(sort, " ")
	if len(parts) != 2 {
		return "", ""
	}
	column, order = parts[0], parts[1]

	// Validate the column and order
	if !allowedColumns[column] || !allowedOrders[order] {
		return "", ""
	}
	return column, order
}