Use of an insecure channel - HTTP
Need
Secure transmission of client information
Context
- Usage of Go 1.16 for building high-performance and scalable applications
- Usage of gin-gonic/gin for building web applications in Go
Description
Non compliant code
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
router.GET("/login", func(c *gin.Context) {
username := c.Query("username")
password := c.Query("password")
// ... authentication process ...
})
router.Run(":80")
}
This Go code uses the Gin framework to create a simple HTTP server that listens on port 80. It includes a route, /login
, that accepts GET requests. The server retrieves the username
and password
from the query parameters of the request.
The vulnerability lies in the fact that the server is using HTTP, not HTTPS. HTTP is a plaintext protocol, meaning that all data sent between the client and server is unencrypted. This includes the username
and password
query parameters in the /login
route.
If an attacker can intercept the network traffic between the client and server (for example, if the client is using an unsecured Wi-Fi network), they can easily read the username
and password
in plain text. This is known as a "man-in-the-middle" attack.
Furthermore, it's a bad practice to send sensitive data like passwords as query parameters, even over HTTPS, because they can be stored in server logs or browser history.
The server should instead be configured to use HTTPS, which encrypts all data sent between the client and server. In addition, sensitive data should be sent in the body of a POST request, not as query parameters.
Steps
- Step 1: Switch from using HTTP to HTTPS for secure communication.
- Step 2: Obtain an SSL/TLS certificate for your domain to enable HTTPS.
- Step 3: Configure your Go backend application to use HTTPS instead of HTTP.
- Step 4: Update the router.Run() function to listen on the appropriate HTTPS port (e.g., :443).
- Step 5: Implement proper authentication mechanisms to protect sensitive information.
- Step 6: Use secure protocols and encryption algorithms for transmitting sensitive data.
- Step 7: Regularly update and patch your server and dependencies to ensure security.
- Step 8: Implement secure coding practices to prevent other vulnerabilities.
Compliant code
package main
import (
"github.com/gin-gonic/gin"
"net/http"
"log"
"crypto/tls"
)
func main() {
router := gin.Default()
router.GET("/login", func(c *gin.Context) {
username := c.Query("username")
password := c.Query("password")
// ... authentication process ...
})
// Configure HTTPS with the SSL/TLS certificate and key
server := &http.Server{
Addr: ":443",
Handler: router,
TLSConfig: &tls.Config{
// Use modern TLS configurations
MinVersion: tls.VersionTLS13,
},
}
log.Fatal(server.ListenAndServeTLS("server.crt", "server.key"))
}
The updated code now uses HTTPS for secure communication. The router.Run(":80")
function has been replaced with a http.Server
struct that is configured to use HTTPS on port 443. The ListenAndServeTLS
function is used to start the server with the provided SSL/TLS certificate and key.
The TLSConfig
struct is used to specify the minimum version of TLS to use. In this case, it is set to tls.VersionTLS13
, which is the latest version of TLS and offers improved security over previous versions.
The ListenAndServeTLS
function requires the paths to the SSL/TLS certificate and key as arguments. These files should be obtained from a trusted Certificate Authority and stored securely on the server.
The log.Fatal
function is used to log any errors that occur when starting the server. If the server fails to start, the application will exit with a non-zero status code.
Remember to replace "server.crt"
and "server.key"
with the actual paths to your SSL/TLS certificate and key.
The username and password are still being retrieved from the query parameters in the /login
route. This is not a secure way to transmit sensitive information, even over HTTPS. Consider implementing a secure authentication mechanism, such as JWT or OAuth.
Regularly update and patch your server and dependencies to ensure security. Implement secure coding practices to prevent other vulnerabilities.