Skip to main content

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

  1. Review your Configuration settings
  2. Learn about Type Support
  3. Check out Logger Integration