Technical information leak - SourceMap - Go

Technical information leak - SourceMap - Go

Need

Protection of sensitive technical information

Context

  • Usage of Go 1.16 for developing high-performance and efficient applications
  • Usage of gin-gonic/gin for building web applications in Go
  • Usage of net/http for handling HTTP requests and building web servers

Description

Non compliant code

        package main

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

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

	r.Static("/assets", "./assets")

	r.GET("/", func(c *gin.Context) {
		c.String(http.StatusOK, "Hello World!")
	})

	r.Run(":8080") // listen and serve on 0.0.0.0:8080
}
        
        

The above code is a simple Go application using the Gin framework. It serves static files from the ./assets directory on the /assets route. This means that any file within the ./assets directory is publicly accessible, including any .map files that might be present.

The vulnerability lies in the r.Static("/assets", "./assets") line. This line of code exposes all files in the ./assets directory to the public. If there are any .map files in this directory, they will be accessible to anyone who knows the URL.

Source map files ( .map) are typically used in JavaScript applications for debugging purposes. They map the minified version of the code back to the original source code, making it easier to debug in production. However, if these files are exposed to the public, they can provide a malicious actor with detailed information about the application's source code, potentially revealing sensitive information or making it easier for them to find and exploit vulnerabilities.

To exploit this vulnerability, an attacker would simply need to navigate to http:///assets/.map in their web browser or another HTTP client. If a .map file exists at that location, they would be able to view its contents.

Steps

  • Disable source map generation in the build process.
  • Remove or restrict access to the .map files in the server configuration.
  • Ensure that the server does not serve any sensitive information or debug information.
  • Regularly update and patch the server and its dependencies to prevent any potential vulnerabilities.

Compliant code

        package main

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

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

	r.StaticFS("/assets", http.Dir("./assets"))
	r.NoRoute(func(c *gin.Context) {
		if path := c.Request.URL.Path; len(path) > 4 && path[len(path)-4:] == ".map" {
			c.String(http.StatusNotFound, "Not found")
			return
		}
		c.File("./assets/index.html")
	})

	r.GET("/", func(c *gin.Context) {
		c.String(http.StatusOK, "Hello World!")
	})

	r.Run(":8080") // listen and serve on 0.0.0.0:8080
}
        
        

The updated code includes a middleware function that checks if the requested URL path ends with ".map". If it does, the server responds with a 404 Not Found status, effectively preventing access to any .map files. This is a simple way to prevent the exposure of source map files, which could potentially be used by a malicious actor to analyze the application.

The r.StaticFS("/assets", http.Dir("./assets")) line serves static files from the "./assets" directory at the "/assets" endpoint. The r.NoRoute function is a catch-all handler that will be invoked when no other route matches the request. Inside this function, we check if the request is for a .map file and, if so, return a 404 Not Found response.

Please note that this is a basic solution and might not cover all edge cases. For a more robust solution, consider using a dedicated static file server that can be configured to ignore or deny requests for certain file types. Also, ensure to regularly update and patch the server and its dependencies to prevent any potential vulnerabilities.

References