From 7bf9ccd17d6d3bd2efb4d3a3772a5bdc69af131a Mon Sep 17 00:00:00 2001 From: momaek Date: Mon, 26 Feb 2018 18:24:41 +0800 Subject: [PATCH 1/2] add csrf --- Makefile | 3 ++ env.sh | 6 ++++ src/http/middleware/admin.go | 6 +--- src/http/middleware/csrf.go | 66 ++++++++++++++++++++++++++++++++++ src/server/studygolang/main.go | 1 + 5 files changed, 77 insertions(+), 5 deletions(-) create mode 100644 env.sh create mode 100644 src/http/middleware/csrf.go diff --git a/Makefile b/Makefile index 31080637..d7b55693 100644 --- a/Makefile +++ b/Makefile @@ -19,3 +19,6 @@ stop: migrate: ./bin/migrator --changeVersion=${v} + +run-studygolang: + cd src/server/studygolang; go run `ls | grep -v windows`; cd - diff --git a/env.sh b/env.sh new file mode 100644 index 00000000..69044b9d --- /dev/null +++ b/env.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +DIR=`pwd` +export GOPATH= +export GOPATH=$DIR +export PATH=$PATH:$DIR/bin diff --git a/src/http/middleware/admin.go b/src/http/middleware/admin.go index f16b057c..e72f4086 100644 --- a/src/http/middleware/admin.go +++ b/src/http/middleware/admin.go @@ -22,11 +22,7 @@ func AdminAuth() echo.MiddlewareFunc { return ctx.HTML(http.StatusForbidden, `403 Forbidden`) } - if err := next(ctx); err != nil { - return err - } - - return nil + return next(ctx) } } } diff --git a/src/http/middleware/csrf.go b/src/http/middleware/csrf.go new file mode 100644 index 00000000..946c44da --- /dev/null +++ b/src/http/middleware/csrf.go @@ -0,0 +1,66 @@ +// Copyright 2017 The StudyGolang Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// http://studygolang.com +// Author: momaek momaek17@gmail.com + +package middleware + +import ( + "net/http" + "net/url" + "util" + + "github.com/labstack/echo" +) + +// ErrorRet 如果是 ajax 请求,返回前端错误信息的通用结构体 +type ErrorRet struct { + OK int `json:"ok"` + Error string `json:"error"` +} + +// CsrfRefererFilter 通过 referer 过滤csrf请求 +func CsrfRefererFilter() echo.MiddlewareFunc { + return func(next echo.HandlerFunc) echo.HandlerFunc { + return func(ctx echo.Context) (err error) { + req := ctx.Request() + can := false + + defer func() { + if can { + err = next(ctx) + } else { + if util.IsAjax(ctx) { + ctx.JSON(499, &ErrorRet{0, "CSRF Detected"}) + } else { + ctx.String(499, "CSRF Detected") + } + } + }() + + switch req.Method() { + case http.MethodGet, http.MethodHead: + can = true + return + } + + referer := req.Referer() + if len(referer) == 0 { + return + } + + u, err := url.Parse(referer) + if err != nil { + return + } + + if u.Host != req.Host() { + return + } + + can = true + return + } + } +} diff --git a/src/server/studygolang/main.go b/src/server/studygolang/main.go index afca1848..1f965381 100644 --- a/src/server/studygolang/main.go +++ b/src/server/studygolang/main.go @@ -62,6 +62,7 @@ func main() { serveStatic(e) e.Use(thirdmw.EchoLogger()) + e.Use(pwm.CsrfRefererFilter()) e.Use(mw.Recover()) e.Use(pwm.Installed(filterPrefixs)) e.Use(pwm.HTTPError()) From ac01b21e00a264f6c43dfb696ac84201f70e366e Mon Sep 17 00:00:00 2001 From: momaek Date: Mon, 26 Feb 2018 18:53:29 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix=20login=20usename=20or=20pwd=20err=20no?= =?UTF-8?q?tice=20'=E7=94=A8=E6=88=B7=E5=90=8D=E6=88=96=E8=80=85=E5=AF=86?= =?UTF-8?q?=E7=A0=81=E9=94=99=E8=AF=AF'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/logic/user.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/logic/user.go b/src/logic/user.go index 33e2aee3..2ff14b8f 100644 --- a/src/logic/user.go +++ b/src/logic/user.go @@ -370,6 +370,8 @@ func (UserLogic) Total() int64 { var ( ErrUsername = errors.New("用户名不存在") ErrPasswd = errors.New("密码错误") + + ErrUnameOrPwd = errors.New("用户名或密码错误") ) // Login 登录;成功返回用户登录信息(user_login) @@ -385,7 +387,7 @@ func (self UserLogic) Login(ctx context.Context, username, passwd string) (*mode // 校验用户 if userLogin.Uid == 0 { objLog.Infof("user %q is not exists!", username) - return nil, ErrUsername + return nil, ErrUnameOrPwd } // 检验用户状态是否正常(未激活的可以登录,但不能发布信息) @@ -405,7 +407,7 @@ func (self UserLogic) Login(ctx context.Context, username, passwd string) (*mode objLog.Debugf("passwd: %s, passcode: %s, md5passwd: %s, dbpasswd: %s", passwd, userLogin.Passcode, md5Passwd, userLogin.Passwd) if md5Passwd != userLogin.Passwd { objLog.Infof("用户名 %q 填写的密码错误", username) - return nil, ErrPasswd + return nil, ErrUnameOrPwd } go func() {