Technical information leak - Logs
Need
Protection of sensitive technical information from unauthorized access
Context
- Usage of Go 1.16 for developing high-performance and efficient applications
- Usage of gin-gonic/gin for building web applications and APIs in Go
- Usage of io/ioutil for reading and writing files in Node.js
Description
Non compliant code
package main
import (
"github.com/gin-gonic/gin"
"io/ioutil"
)
func main() {
r := gin.Default()
r.GET("/logs", func(c *gin.Context) {
data, err := ioutil.ReadFile("system.log")
if err != nil {
c.JSON(500, gin.H{
"message": "Error reading log file",
})
} else {
c.String(200, string(data))
}
})
r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}
The above code is a simple Go application using the Gin framework. It has a single route /logs
that reads a system log file and returns its content as a response.
This is a security vulnerability because it exposes sensitive system information to the users. Anyone who accesses the /logs
endpoint can read the system logs, which may contain confidential and sensitive information about the system. This kind of information leakage can be leveraged by an attacker to gain more knowledge about the system and exploit other vulnerabilities.
Specifically, the vulnerability lies in the route handler function for /logs
. The function reads the content of system.log
file and directly sends it as a response. This means that any user can send a GET request to http://<your-app-address>:8080/logs
and see the system logs.
Steps
- Restrict access to the /logs endpoint to authorized users only.
- Implement authentication and authorization mechanisms to ensure that only authenticated users can access the logs.
- Use proper access control mechanisms to restrict access to the log file on the server.
- Avoid displaying the raw contents of the log file to users. Instead, consider implementing a secure log viewer that provides controlled access to the log data.
- Regularly review and rotate log files to minimize the exposure of sensitive information.
- Implement proper error handling to avoid exposing sensitive error messages or stack traces to users.
Compliant code
package main
import (
"github.com/gin-gonic/gin"
"io/ioutil"
"net/http"
)
func main() {
r := gin.Default()
// Middleware for authentication
r.Use(AuthMiddleware())
r.GET("/logs", func(c *gin.Context) {
data, err := ioutil.ReadFile("system.log")
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"message": "Error reading log file",
})
return
}
// Implement a secure log viewer instead of sending raw data
c.JSON(http.StatusOK, SecureLogViewer(data))
})
r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}
// Dummy function for AuthMiddleware
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// Implement your authentication logic here
// If authentication fails, call c.Abort() to stop the request
}
}
// Dummy function for SecureLogViewer
func SecureLogViewer(data []byte) interface{} {
// Implement your log viewing logic here
// Return a data structure that is safe to send to the client
}
The updated code includes an authentication middleware that is used to authenticate users before they can access the /logs
endpoint. This middleware should contain the logic for authenticating users based on your application's specific requirements.
The GET /logs
handler has been updated to use a SecureLogViewer
function instead of directly sending the raw log data to the client. This function should be implemented to provide a controlled view of the log data that is safe to send to the client.
The error handling in the GET /logs
handler has been updated to return a 500 Internal Server Error
status code when there is an error reading the log file. This avoids exposing sensitive error messages or stack traces to the client.
The AuthMiddleware
and SecureLogViewer
functions are placeholders and should be replaced with actual implementations based on your application's specific requirements.