Security: Redact secret names from production logs & bind port to localhost (#1)
* security: redact secret names from logs, bind port to localhost - handlers: replace secret names in Warn/Error logs with client IP (prevents information disclosure via log access/injection) - client: downgrade secret name logs from Info to Debug level (Debug is discarded in production via io.Discard) - docker-compose: bind port to 127.0.0.1:8080 instead of 0.0.0.0:8080 (prevents direct access bypassing reverse proxy) Found during security pen test of vault.turboot.com * Enhance logging for secret retrieval and cache access
This commit is contained in:
1 parent
9f41e1a1f7
commit
e320f95d9f
3 files changed
+5
-5
No files matched your search
+1
-1
@@ -8,7 +8,7 @@ services:
|
|||||||
container_name: vaultwarden-api
|
container_name: vaultwarden-api
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
- "8080:8080"
|
- "127.0.0.1:8080:8080"
|
||||||
environment:
|
environment:
|
||||||
# Server configuration
|
# Server configuration
|
||||||
- API_PORT=8080
|
- API_PORT=8080
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ func (h *Handler) GetSecret(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !validators.IsValidSecretName(secretName) {
|
if !validators.IsValidSecretName(secretName) {
|
||||||
logger.Warn.Printf("Invalid secret name attempted: %s", secretName)
|
logger.Warn.Printf("Invalid secret name format attempted from IP: %s", c.IP())
|
||||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
|
||||||
"error": "invalid secret name format",
|
"error": "invalid secret name format",
|
||||||
})
|
})
|
||||||
@@ -48,7 +48,7 @@ func (h *Handler) GetSecret(c *fiber.Ctx) error {
|
|||||||
|
|
||||||
value, err := h.vaultClient.GetSecret(secretName)
|
value, err := h.vaultClient.GetSecret(secretName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error.Printf("Failed to fetch secret '%s': %v", secretName, err)
|
logger.Error.Printf("Failed to fetch secret (requested by IP: %s): %v", c.IP(), err)
|
||||||
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{
|
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{
|
||||||
"error": "secret not found",
|
"error": "secret not found",
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -59,13 +59,13 @@ func (c *Client) GetSecret(name string) (string, error) {
|
|||||||
// Check cache first
|
// Check cache first
|
||||||
if c.cache.enabled {
|
if c.cache.enabled {
|
||||||
if value, found := c.cache.get(name); found {
|
if value, found := c.cache.get(name); found {
|
||||||
logger.Info.Printf("Cache hit for secret: %s", name)
|
logger.Debug.Printf("Cache hit for secret")
|
||||||
return value, nil
|
return value, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache miss - fetch from API
|
// Cache miss - fetch from API
|
||||||
logger.Info.Printf("Fetching secret from Vaultwarden: %s", name)
|
logger.Debug.Printf("Fetching secret from Vaultwarden (cache miss)")
|
||||||
value, err := c.fetchSecret(name)
|
value, err := c.fetchSecret(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
|||||||
Reference in new issue
Block a user