Lack of data validation - Emails
Need
Implementation of email validation to prevent registration with disposable email addresses
Context
- Usage of Go 1.15 for developing high-performance and efficient applications
- Usage of gin-gonic/gin for building web applications in Go
Description
Non compliant code
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:
- Users registering with disposable emails and then abandoning them, leading to unverifiable user accounts.
- Users using disposable emails to bypass email verification and perform malicious activities.
- 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.
Steps
- Implement email validation to ensure that the email provided is in a valid format.
- Use a third-party email validation service or library to check if the email domain is disposable or belongs to a known disposable email provider.
- Consider implementing a whitelist of allowed email domains to restrict registration to specific domains.
- Provide clear error messages to the user when a disposable email is detected, indicating that they need to provide a valid email address.
- Consider implementing rate limiting or CAPTCHA to prevent abuse of the registration endpoint by automated scripts.
Compliant code
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.