Skip to content

Latest commit

 

History

History
57 lines (44 loc) · 2.83 KB

File metadata and controls

57 lines (44 loc) · 2.83 KB

4.4 Duplicate submissions

I don't know if you have ever seen some blogs or BBS have more then one posts are exactly same, but I can tell you it's because users did duplicate submissions of post form at that time. There are batch of reasons can cause duplicate submissions, sometimes users just double click the submit button, or they want to modify some content after post and press back button, or it's by purpose of malicious users in some vote websites. It's easy to see how the duplicate submissions lead to many problems, so we have to use effective means to prevent it.

The solution is that add a hidden field with unique token to your form, and check this token every time before processing data. Also, if you are using Ajax to submit form, use JavaScript to disable submit button once submitted.

Let's improve example in section 4.2:

<input type="checkbox" name="interest" value="football">Football
<input type="checkbox" name="interest" value="basketball">Basketball
<input type="checkbox" name="interest" value="tennis">Tennis
Username:<input type="text" name="username">
Password:<input type="password" name="password">
<input type="hidden" name="token" value="{{.}}">
<input type="submit" value="Login">

We used MD5(time stamp) to generate token, and added to hidden field and session in server side(Chapter 6), then we can use this token to check if this form was submitted.

func login(w http.ResponseWriter, r *http.Request) {
	fmt.Println("method:", r.Method) // get request method
	if r.Method == "GET" {
    	crutime := time.Now().Unix()
    	h := md5.New()
    	io.WriteString(h, strconv.FormatInt(crutime, 10))
    	token := fmt.Sprintf("%x", h.Sum(nil))

    	t, _ := template.ParseFiles("login.gtpl")
    	t.Execute(w, token)
	} else {
    	// log in request
    	r.ParseForm()
    	token := r.Form.Get("token")
    	if token != "" {
    	    // check token validity
    	} else {
    	    // give error if no token
    	}
    	fmt.Println("username length:", len(r.Form["username"][0]))
    	fmt.Println("username:", template.HTMLEscapeString(r.Form.Get("username"))) // print in server side
    	fmt.Println("password:", template.HTMLEscapeString(r.Form.Get("password")))
    	template.HTMLEscape(w, []byte(r.Form.Get("username"))) // respond to client
	}
}

Figure 4.4 The content in browser after added token

You can refresh this page and you will see different token every time, so this keeps every form is unique.

For now you can prevent many of duplicate submissions attacks by adding token to your form, but it cannot prevent all the deceptive attacks, there is much more work should be done.

Links