Implementation of email validation to prevent registration with disposable email addresses
package main
import (
"github.com/gin-gonic/gin"
)
type User struct {
Email string `json:"email"`
}
func main() {
r := gin.Default()
r.POST("/register", func(c *gin.Context) {
var newUser User
if err := c.ShouldBindJSON(&newUser); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
// Registration logic here
// ...
c.JSON(200, gin.H{"message": "Registration successful"})
})
r.Run()
}
In this code, we have a simple Gin application in Go. The application has a single route
/register
which accepts POST requests for user registration. The request should contain a JSON payload with the
email
field.
The vulnerability lies in the fact that there is no validation performed on the
email
field of the incoming request in the
/register
route. The application accepts any string as an email, including those from disposable mailboxes such as yopmail.
This could lead to a variety of issues, including but not limited to:
1. Users registering with disposable emails and then abandoning them, leading to unverifiable user accounts.
2. Users using disposable emails to bypass email verification and perform malicious activities.
3. Increased spam accounts as disposable emails provide an easy way to create multiple accounts.
The lack of validation on the
email
field is the root cause of this vulnerability.
package main
import (
"github.com/gin-gonic/gin"
"net"
"strings"
)
type User struct {
Email string `json:"email"`
}
var disposableDomains = []string{
"yopmail.com",
// Add more disposable email domains here
}
func main() {
r := gin.Default()
r.POST("/register", func(c *gin.Context) {
var newUser User
if err := c.ShouldBindJSON(&newUser); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
// Validate email
if !isValidEmail(newUser.Email) {
c.JSON(400, gin.H{"error": "Invalid email address"})
return
}
// Registration logic here
// ...
c.JSON(200, gin.H{"message": "Registration successful"})
})
r.Run()
}
func isValidEmail(email string) bool {
// Check if email is in valid format
at := strings.LastIndex(email, "@")
if at <= 0 || at+1 >= len(email) {
return false
}
// Check if email domain is disposable
domain := email[at+1:]
if isDisposableDomain(domain) {
return false
}
return true
}
func isDisposableDomain(domain string) bool {
for _, disposableDomain := range disposableDomains {
if domain == disposableDomain {
return true
}
}
return false
}
The updated code includes a function
isValidEmail
that checks if the email provided by the user is in a valid format and does not belong to a disposable email domain. The function
isDisposableDomain
checks if the domain of the email is in the list of disposable email domains.
The
POST /register
endpoint now validates the email before proceeding with the registration logic. If the email is not valid, it responds with a 400 status code and an error message "Invalid email address".
The list of disposable email domains is currently hardcoded in the
disposableDomains
variable. This list can be expanded as needed or replaced with a more sophisticated check, such as a call to a third-party email validation service.
This solution helps prevent users from registering with disposable email addresses, which can be used to bypass email verification, spam the system, or evade bans or restrictions based on the email address.