Data Leak Prevention Examples
This guide provides examples of common scenarios where Censor can be used to prevent data leaks.
Logging Sensitive Data
Problem
// BAD: Logging sensitive data directly
logger.Info("user login", zap.String("email", user.Email), zap.String("password", user.Password))
Solution
// GOOD: Using Censor to mask sensitive data
logger := zap.New(censorlog.NewHandler(...))
logger.Info("user login", zap.Any("user", user))
// Output: {"level":"info","msg":"user login","user":{"Email":"[CENSORED]","Password":"[CENSORED]"}}
API Responses
Problem
// BAD: Returning sensitive data in API responses
func (h *Handler) GetUser(w http.ResponseWriter, r *http.Request) {
user := h.getUserFromDB()
json.NewEncoder(w).Encode(user) // Might expose sensitive fields
}
Solution
// GOOD: Using Censor to sanitize API responses
func (h *Handler) GetUser(w http.ResponseWriter, r *http.Request) {
user := h.getUserFromDB()
c := censor.New()
sanitized := c.Process(user)
json.NewEncoder(w).Encode(sanitized)
}
Error Messages
Problem
// BAD: Including sensitive data in error messages
if err != nil {
return fmt.Errorf("failed to process payment for card %s: %v", card.Number, err)
}
Solution
// GOOD: Using Censor for error messages
if err != nil {
c := censor.New()
maskedCard := c.Process(card)
return fmt.Errorf("failed to process payment: %v", err)
}
Debug Information
Problem
// BAD: Including sensitive data in debug logs
debug.Printf("Processing request: %+v", request)
Solution
// GOOD: Using Censor for debug information
c := censor.New()
debug.Printf("Processing request: %v", c.Process(request))
Database Queries
Problem
// BAD: Logging raw SQL queries with sensitive data
logger.Debug("executing query", zap.String("query", query), zap.Any("params", params))
Solution
// GOOD: Using Censor for query parameters
c := censor.New()
logger.Debug("executing query",
zap.String("query", query),
zap.Any("params", c.Process(params)))
Complete Example
Here's a complete example showing how to use Censor in a web application:
package main
import (
"encoding/json"
"net/http"
"github.com/vpakhuchyi/censor"
"github.com/vpakhuchyi/censor/logger/zap"
"go.uber.org/zap"
)
type User struct {
ID string `json:"id" censor:"display"`
Email string `json:"email"`
Password string `json:"password"`
APIKey string `json:"api_key"`
}
type Handler struct {
logger *zap.Logger
censor *censor.Censor
}
func NewHandler() *Handler {
// Create a Censor instance
c := censor.New()
// Create a logger with Censor handler
logger := zap.New(censorlog.NewHandler(...))
return &Handler{
logger: logger,
censor: c,
}
}
func (h *Handler) GetUser(w http.ResponseWriter, r *http.Request) {
user := h.getUserFromDB()
// Log the request (safely)
h.logger.Info("processing user request",
zap.Any("user", user),
zap.String("path", r.URL.Path))
// Return sanitized response
sanitized := h.censor.Process(user)
json.NewEncoder(w).Encode(sanitized)
}
func (h *Handler) UpdateUser(w http.ResponseWriter, r *http.Request) {
var user User
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
h.logger.Error("failed to decode request", zap.Error(err))
http.Error(w, "Invalid request", http.StatusBadRequest)
return
}
// Log the update (safely)
h.logger.Info("updating user",
zap.Any("user", user))
// Process the update
if err := h.updateUserInDB(user); err != nil {
h.logger.Error("failed to update user",
zap.Error(err),
zap.Any("user", user))
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}
// Return sanitized response
sanitized := h.censor.Process(user)
json.NewEncoder(w).Encode(sanitized)
}
Next Steps
- Review your Configuration settings
- Learn about Type Support
- Check out Logger Integration