Skip to main content

Business information leak - Credit Cards

Need

Protection of sensitive business and customer information

Context

  • Usage of Go 1.16 for developing high-performance and efficient applications
  • Usage of Gin for building web applications in Go

Description

Non compliant code

package main

import (
"github.com/gin-gonic/gin"
)

type CreditCard struct {
CardNumber string `json:"cardNumber"`
CVV string `json:"cvv"`
ExpiryDate string `json:"expiryDate"`
}

func main() {
r := gin.Default()

r.GET("/get-card/:cardId", func(c *gin.Context) {
cardId := c.Param("cardId")

// This is just a placeholder. In a real-world application, you would fetch the card information from your database.
card := CreditCard{
CardNumber: "1234-5678-9012-3456",
CVV: "123",
ExpiryDate: "01/23",
}

c.JSON(200, gin.H{
"cardId": cardId,
"card": card,
})
})

r.Run()
}

In the given code, we have a route /get-card/:cardId that returns the card information in the response. The CreditCard struct is used to represent a credit card, and it includes sensitive fields like CardNumber, CVV, and ExpiryDate.

The problem arises in the route handler function for /get-card/:cardId. Here, we are fetching the cardId from the route parameters and then returning a CreditCard object in the response. This object includes sensitive information like the card number, CVV, and expiry date.

This means that anyone who can make a GET request to this route can potentially access sensitive credit card information. This is a serious security issue as it can lead to data breaches and misuse of customer information.

Steps

  • Avoid exposing sensitive information in API responses.
  • Implement proper access controls to restrict access to sensitive data.
  • Ensure that credit card information is securely stored and encrypted in the database.
  • Implement tokenization or encryption techniques to protect credit card data in transit.
  • Regularly review and update security configurations to prevent misconfigurations.
  • Conduct regular security audits and penetration testing to identify and fix vulnerabilities.
  • Follow industry best practices and security guidelines for handling sensitive data.

Compliant code

package main

import (
"github.com/gin-gonic/gin"
)

type CreditCard struct {
CardNumber string `json:"cardNumber"`
CVV string `json:"cvv"`
ExpiryDate string `json:"expiryDate"`
}

func main() {
r := gin.Default()

r.GET("/get-card/:cardId", func(c *gin.Context) {
cardId := c.Param("cardId")

// This is just a placeholder. In a real-world application, you would fetch the card information from your database.
card := CreditCard{
CardNumber: "1234-5678-9012-3456",
CVV: "123",
ExpiryDate: "01/23",
}

c.JSON(200, gin.H{
"cardId": cardId,
"card": card,
})
})

r.Run()
}

The above code is a simple Go application using the Gin framework. It has a route /get-card/:cardId that returns a JSON response containing credit card information. The credit card information is hardcoded in this example, but in a real-world application, it would be fetched from a database.

The vulnerability lies in the fact that the credit card information (card number, CVV, and expiry date) is returned in the API response. This exposes sensitive customer information and can lead to a data breach.

To fix this vulnerability, we need to ensure that sensitive information is not exposed in API responses. We can do this by removing the sensitive fields from the API response. We should also implement proper access controls to restrict access to sensitive data and ensure that credit card information is securely stored and encrypted in the database.

Additionally, we should implement tokenization or encryption techniques to protect credit card data in transit. Regular reviews and updates of security configurations can prevent misconfigurations that could lead to data exposure. Regular security audits and penetration testing can help identify and fix vulnerabilities. Following industry best practices and security guidelines for handling sensitive data is also crucial.

Here is the fixed code:

package main

import (
"github.com/gin-gonic/gin"
)

type CreditCard struct {
CardNumber string `json:"-"`
CVV string `json:"-"`
ExpiryDate string `json:"-"`
}

func main() {
r := gin.Default()

r.GET("/get-card/:cardId", func(c *gin.Context) {
cardId := c.Param("cardId")

// This is just a placeholder. In a real-world application, you would fetch the card information from your database.
card := CreditCard{
CardNumber: "1234-5678-9012-3456",
CVV: "123",
ExpiryDate: "01/23",
}

c.JSON(200, gin.H{
"cardId": cardId,
})
})

r.Run()
}

In the fixed code, we have added json:"-" tags to the fields in the CreditCard struct. This tells the JSON encoder to ignore these fields, so they are not included in the API response.

References