Skip to content
This repository was archived by the owner on Nov 5, 2024. It is now read-only.

Commit 669995e

Browse files
committed
[waf]POST验证通过后跳转到表单提交前的页面
1 parent 9774d14 commit 669995e

4 files changed

Lines changed: 113 additions & 55 deletions

File tree

teatesting/server.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ func StartTestServer() {
120120

121121
}).
122122
Get("/cookie", func(req *http.Request, resp http.ResponseWriter) {
123-
resp.Header().Add("Set-Cookie", "Asset_UserId=1; expires=Sun, 05-May-2019 14:42:21 GMT; path=/", )
123+
resp.Header().Add("Set-Cookie", "Asset_UserId=1; expires=Sun, 05-May-2019 14:42:21 GMT; path=/")
124124
_, _ = resp.Write([]byte("set cookie"))
125125
}).
126126
GetPost("/json", func(req *http.Request, resp http.ResponseWriter) {
@@ -146,6 +146,14 @@ func StartTestServer() {
146146
_, _ = resp.Write(data)
147147
}
148148
}).
149+
Post("/post", func(req *http.Request, resp http.ResponseWriter) {
150+
data, err := httputil.DumpRequest(req, true)
151+
if err != nil {
152+
_, _ = resp.Write([]byte(err.Error()))
153+
return
154+
}
155+
_, _ = resp.Write(data)
156+
}).
149157
Put("/put", func(req *http.Request, resp http.ResponseWriter) {
150158
data, err := httputil.DumpRequest(req, true)
151159
if err != nil {
@@ -174,6 +182,12 @@ func StartTestServer() {
174182
</head>
175183
<body>
176184
<strong>THIS IS HTML BODY</strong>
185+
186+
<form action="/post" method="post">
187+
<input type="text" name="name"/>
188+
<button type="submit">Submit</button>
189+
</form>
190+
177191
</body>
178192
</html>
179193
`))

teawaf/action_captcha.go

Lines changed: 5 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
package teawaf
22

33
import (
4-
"bytes"
5-
"encoding/base64"
6-
"fmt"
74
"github.com/TeaWeb/code/teawaf/requests"
8-
"github.com/dchest/captcha"
9-
"github.com/iwind/TeaGo/logs"
105
"github.com/iwind/TeaGo/types"
116
stringutil "github.com/iwind/TeaGo/utils/string"
127
"net/http"
8+
"net/url"
139
"time"
1410
)
1511

@@ -33,56 +29,11 @@ func (this *CaptchaAction) Perform(waf *WAF, request *requests.Request, writer h
3329
}
3430
}
3531

36-
// verify
37-
if request.Method == http.MethodPost {
38-
captchaId := request.FormValue("TEAWEB_WAF_CAPTCHA_ID")
39-
if len(captchaId) > 0 {
40-
captchaCode := request.FormValue("TEAWEB_WAF_CAPTCHA_CODE")
41-
if captcha.VerifyString(captchaId, captchaCode) {
42-
// set cookie
43-
timestamp := fmt.Sprintf("%d", time.Now().Unix()+CaptchaSeconds)
44-
m := stringutil.Md5(captchaSalt + timestamp)
45-
http.SetCookie(writer, &http.Cookie{
46-
Name: "TEAWEB_WAF_CAPTCHA",
47-
Value: m + timestamp,
48-
MaxAge: CaptchaSeconds,
49-
Path: "/", // all of dirs
50-
})
51-
52-
http.Redirect(writer, request.Raw(), request.URL.String(), http.StatusTemporaryRedirect)
53-
54-
return false
55-
}
56-
}
57-
}
58-
59-
// show captcha
60-
captchaId := captcha.NewLen(6)
61-
buf := bytes.NewBuffer([]byte{})
62-
err = captcha.WriteImage(buf, captchaId, 200, 100)
63-
if err != nil {
64-
logs.Error(err)
65-
return true
32+
refURL := request.URL.String()
33+
if len(request.Referer()) > 0 {
34+
refURL = request.Referer()
6635
}
36+
http.Redirect(writer, request.Raw(), "/WAFCAPTCHA?url="+url.QueryEscape(refURL), http.StatusTemporaryRedirect)
6737

68-
_, _ = writer.Write([]byte(`<!DOCTYPE html>
69-
<html>
70-
<head>
71-
<title>Verify Yourself</title>
72-
</head>
73-
<body>
74-
<form method="POST">
75-
<input type="hidden" name="TEAWEB_WAF_CAPTCHA_ID" value="` + captchaId + `"/>
76-
<img src="data:image/png;base64, ` + base64.StdEncoding.EncodeToString(buf.Bytes()) + `"/>
77-
<div>
78-
<p>Input verify code above:</p>
79-
<input type="text" name="TEAWEB_WAF_CAPTCHA_CODE" maxlength="6" size="18" autocomplete="off" z-index="1" style="font-size:16px;line-height:24px; letter-spacing: 15px; padding-left: 4px"/>
80-
</div>
81-
<div>
82-
<button type="submit" style="line-height:24px;margin-top:10px">Verify Yourself</button>
83-
</div>
84-
</form>
85-
</body>
86-
</html>`))
8738
return false
8839
}

teawaf/captcha_validator.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package teawaf
2+
3+
import (
4+
"bytes"
5+
"encoding/base64"
6+
"fmt"
7+
"github.com/TeaWeb/code/teawaf/requests"
8+
"github.com/dchest/captcha"
9+
"github.com/iwind/TeaGo/logs"
10+
stringutil "github.com/iwind/TeaGo/utils/string"
11+
"net/http"
12+
"time"
13+
)
14+
15+
var captchaValidator = &CaptchaValidator{}
16+
17+
type CaptchaValidator struct {
18+
}
19+
20+
func (this *CaptchaValidator) Run(request *requests.Request, writer http.ResponseWriter) {
21+
if request.Method == http.MethodPost && len(request.FormValue("TEAWEB_WAF_CAPTCHA_ID")) > 0 {
22+
this.validate(request, writer)
23+
} else {
24+
this.show(request, writer)
25+
}
26+
}
27+
28+
func (this *CaptchaValidator) show(request *requests.Request, writer http.ResponseWriter) {
29+
// show captcha
30+
captchaId := captcha.NewLen(6)
31+
buf := bytes.NewBuffer([]byte{})
32+
err := captcha.WriteImage(buf, captchaId, 200, 100)
33+
if err != nil {
34+
logs.Error(err)
35+
return
36+
}
37+
38+
_, _ = writer.Write([]byte(`<!DOCTYPE html>
39+
<html>
40+
<head>
41+
<title>Verify Yourself</title>
42+
</head>
43+
<body>
44+
<form method="POST">
45+
<input type="hidden" name="TEAWEB_WAF_CAPTCHA_ID" value="` + captchaId + `"/>
46+
<img src="data:image/png;base64, ` + base64.StdEncoding.EncodeToString(buf.Bytes()) + `"/>` + `
47+
<div>
48+
<p>Input verify code above:</p>
49+
<input type="text" name="TEAWEB_WAF_CAPTCHA_CODE" maxlength="6" size="18" autocomplete="off" z-index="1" style="font-size:16px;line-height:24px; letter-spacing: 15px; padding-left: 4px"/>
50+
</div>
51+
<div>
52+
<button type="submit" onclick="window.location = '/webhook'" style="line-height:24px;margin-top:10px">Verify Yourself</button>
53+
</div>
54+
</form>
55+
</body>
56+
</html>`))
57+
}
58+
59+
func (this *CaptchaValidator) validate(request *requests.Request, writer http.ResponseWriter) (allow bool) {
60+
captchaId := request.FormValue("TEAWEB_WAF_CAPTCHA_ID")
61+
if len(captchaId) > 0 {
62+
captchaCode := request.FormValue("TEAWEB_WAF_CAPTCHA_CODE")
63+
if captcha.VerifyString(captchaId, captchaCode) {
64+
// set cookie
65+
timestamp := fmt.Sprintf("%d", time.Now().Unix()+CaptchaSeconds)
66+
m := stringutil.Md5(captchaSalt + timestamp)
67+
http.SetCookie(writer, &http.Cookie{
68+
Name: "TEAWEB_WAF_CAPTCHA",
69+
Value: m + timestamp,
70+
MaxAge: CaptchaSeconds,
71+
Path: "/", // all of dirs
72+
})
73+
74+
rawURL := request.URL.Query().Get("url")
75+
http.Redirect(writer, request.Raw(), rawURL, http.StatusSeeOther)
76+
77+
return false
78+
} else {
79+
http.Redirect(writer, request.Raw(), request.URL.String(), http.StatusSeeOther)
80+
}
81+
}
82+
83+
return true
84+
}

teawaf/waf.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,16 @@ func (this *WAF) MatchRequest(rawReq *http.Request, writer http.ResponseWriter)
256256
if !this.hasInboundRules {
257257
return true, nil, nil, nil
258258
}
259+
259260
req := requests.NewRequest(rawReq)
261+
262+
// validate captcha
263+
if rawReq.URL.Path == "/WAFCAPTCHA" {
264+
captchaValidator.Run(req, writer)
265+
return
266+
}
267+
268+
// match rules
260269
for _, group := range this.Inbound {
261270
if !group.On {
262271
continue

0 commit comments

Comments
 (0)