MEDIUM log injectionchifirestore

Log Injection in Chi with Firestore

Log Injection in Chi with Firestore — how this specific combination creates or exposes the vulnerability

Log injection occurs when untrusted input is written directly into log entries, allowing an attacker to forge log lines, obscure true events, or trigger log-based attacks such as log forging or log poisoning. In a Chi application that uses Firestore as a backend, this risk arises when request data—such as user IDs, query parameters, or custom identifiers—are interpolated into log messages without sanitization before being written to Firestore documents or queried as log entries.

Chi is a lightweight, composable router for Clojure web applications. When you log request context (e.g., for debugging or audit trails) and store those logs in Firestore, each log entry may include user-controlled fields. If these fields contain newline characters or structured payload markers, an attacker can inject additional log lines or metadata. For example, a crafted query parameter containing a newline and fabricated key-value pairs can result in multiple log entries when the Firestore document is later read, breaking log integrity and complicating incident response.

Because Firestore stores documents as JSON, newline characters in string fields are preserved. When log consumers parse these documents line-by-line or assume one document equals one log event, injected newlines cause misalignment. This can lead to misinterpretation by monitoring tools or SIEMs that rely on deterministic log structure. Additionally, if log entries include Firestore document IDs or paths that reflect user input, an attacker may manipulate these values to reference sensitive documents or trigger path traversal in log viewers that render links to documents.

Consider a Chi handler that logs a map containing user input before writing to Firestore:

(defn log-and-store [db request-params]
  (let [doc-id (str "audit-" (:user-id request-params))
        entry {:timestamp (java.time.Instant/now)
               :user-id (:user-id request-params)
               :action (:action request-params)
               :details (:details request-params)}]
    ;; Potential log injection if :details contains newlines or structured text
    (println "AUDIT" entry)
    (-> db
        (firestore/collection "audit_logs")
        (firestore/document doc-id)
        (firestore/create! entry))
    {:status 200}))

If :details contains a newline followed by JSON-like text, the printed log line may appear as a single entry while the Firestore document preserves the raw string. Downstream log parsers that split on newlines will treat the injected text as a separate event. Moreover, if :user-id or the generated document ID is used in log paths without validation, an attacker can influence document references, potentially aiding in reconnaissance or malicious linking.

In summary, the combination of Chi for request routing, Firestore for log persistence, and insufficient input validation or encoding creates conditions where log injection can undermine log reliability and observability. Mitigations focus on sanitizing and encoding user-controlled data before it reaches structured logging and Firestore writes.

Firestore-Specific Remediation in Chi — concrete code fixes

To prevent log injection when using Chi and Firestore, treat all user-controlled data as untrusted. Apply canonicalization and encoding before logging and before storing in Firestore. Below are concrete, idiomatic examples that demonstrate safe practices.

1. Sanitize and structure log data explicitly

Instead of interpolating raw maps into log strings, construct a deterministic log object and encode potentially dangerous characters. For Firestore, store separate fields rather than embedding newlines in a single string field.

(defn sanitize-input [s]
  ;; Remove or replace control characters that can break log parsing
  (if (string? s)
    (-> s
        (str/replace #"\r\n" " ")
        (str/replace #"\n" " ")
        (str/replace #"\r" " "))
    s))

(defn safe-log-and-store [db request-params]
  (let [user-id (sanitize-input (:user-id request-params))
        action (sanitize-input (:action request-params))
        details (sanitize-input (:details request-params))
        entry {:timestamp (java.time.Instant/now)
               :user-id user-id
               :action action
               :details details}]
    ;; Safe: structured Firestore document; no injected newlines in single fields
    (-> db
        (firestore/collection "audit_logs")
        (firestore/document (str "audit-" user-id))
        (firestore/create! entry))
    ;; Safe: single-line log output
    (println (pr-str entry))
    {:status 200}))

2. Use Firestore transaction or batched writes with normalized data

When logging multiple related events, use batched writes and ensure each field is normalized. This prevents partial writes and keeps logs atomic from the perspective of log consumers.

(defn batch-audit-logs [db entries]
  (let [batch (.batch db)]
    (doseq [entry entries]
      (let [doc-ref (-> db
                        (firestore/collection "audit_logs")
                        (firestore/document (str "audit-" (:user-id entry))))]
        (.set batch doc-ref entry)))
    (.commit batch)))

;; Example usage with sanitized entries
(let [entries [(safe-make-entry params1)
               (safe-make-entry params2)]]
  (batch-audit-logs db entries))

3. Encode newlines when you must store multiline details

If you need to preserve multiline details, store them in a structured format (e.g., base64 or JSON string) and decode only when necessary. Avoid raw newlines in string fields that may be read line-by-line by log processors.

(defn encode-details [details]
  (when details
    (Base64/getEncoder (encodeToString (str/utf8-bytes details)))))

(defn stored-entry [request-params]
  {:timestamp (java.time.Instant/now)
   :user-id (sanitize-input (:user-id request-params))
   :action (sanitize-input (:action request-params))
   :details (encode-details (:details request-params))})

By normalizing inputs, structuring log data, and avoiding raw newlines in string fields, you reduce the risk of log injection while maintaining compatibility with Firestore and Chi-based services.

Frequently Asked Questions

Can log injection in Chi with Firestore affect authentication or authorization checks?
Yes. If log entries are used to reconstruct session or permission context, injected newlines or fabricated fields can mislead log-based authorization checks. Always validate and sanitize before logging and storing.
Does middleBrick detect log injection risks in API scans?
middleBrick runs 12 security checks including Input Validation and Data Exposure. While it does not test application logging directly, findings related to input handling and data exposure can highlight conditions that enable log injection. Use the CLI to scan endpoints and review prioritized remediation guidance.