Pii Leakage in Chi with Dynamodb
Pii Leakage in Chi with Dynamodb — how this specific combination creates or exposes the vulnerability
PII leakage in a Chi application using Amazon DynamoDB typically occurs when sensitive data is stored without adequate protection and the API surface that interacts with DynamoDB exposes that data to unauthorized access. Chi is a functional, composable web framework for Clojure that encourages explicit routing and handler composition. When handlers perform DynamoDB operations such as GetItem or Query and return raw items to clients, any PII fields (for example, email, phone, or national ID) can be unintentionally included in responses.
DynamoDB itself does not inherently redact fields; it returns whatever attributes exist in the item. If the data model includes PII and access controls are enforced at a coarse level (for example, only at the table level), a compromised endpoint or misconfigured IAM policy can lead to wide data exposure. In Chi, a typical route might call a service function that performs a dynamodb/get-item and then serialize the result to JSON. Without explicit filtering, nested attributes such as :user/ssn or :user/password-hash can be included in the JSON response.
Another vector is logging and error reporting. Chi applications often log requests and responses for debugging. If DynamoDB items containing PII are logged in full, those logs can become an unintended data store. Additionally, DynamoDB streams or backups that contain PII can be exposed if access policies are not tightly scoped. The scan types supported by tools like middleBrick help detect such issues by checking for missing authentication on endpoints and data exposure patterns, including PII in outputs such as LLM responses or API payloads.
Using DynamoDB with Chi also requires attention to serialization formats. When attributes are stored as nested maps or lists, it is easy to miss a PII field during development. For example, a user item might store address details as a nested map, and if the handler returns the entire item, the nested address becomes part of the response. middleBrick’s checks for Data Exposure and Property Authorization are designed to highlight these risks by correlating OpenAPI specifications with runtime behavior, ensuring that defined schemas and actual responses are aligned.
Developers should treat PII in DynamoDB as sensitive by design and apply defense-in-depth: encrypt sensitive attributes at rest, use field-level access patterns, and ensure API responses are shaped to exclude unnecessary data. In Chi, this means designing handlers to project only required fields and using middleware to enforce authorization before data is serialized. Continuous monitoring through the middleBrick Dashboard can track changes in risk scores over time, while the Pro plan’s continuous monitoring and GitHub Action integrations help catch regressions before deployment.
Dynamodb-Specific Remediation in Chi — concrete code fixes
Remediation for PII leakage when using DynamoDB in Chi focuses on data minimization, strict access patterns, and secure serialization. Instead of returning entire DynamoDB items, define explicit projection functions that strip sensitive attributes. Use DynamoDB’s expression attribute names to safely reference nested fields, and apply conditional checks in Chi handlers to ensure the requester is authorized for the specific attributes they are allowed to view.
Below is a concrete example of a Chi handler that retrieves a user item from DynamoDB and returns only safe, non-PII fields. This approach reduces the attack surface by explicitly selecting attributes and avoiding raw item propagation.
(ns myapp.handler
(:require [cheshire.core :as json]
[myapp.dynamo :as ddb]
[myapp.schema :as schema]
[ring.util.response :refer [response]]))
(defn safe-user-handler [request]
(let [user-id (get-in request [:params :id])
item (ddb/get-user-item user-id)]
(if item
(let [safe-keys #{:user/id :user/name :user/role}
safe-item (select-keys item safe-keys)]
(response safe-item))
{:status 404 :body "Not found"})))
On the DynamoDB side, use a helper that constructs the GetItem request with expression attribute names to avoid injection risks and to make field referencing robust. This also makes it easier to audit which fields are accessed.
(ns myapp.dynamo
(:require [taoensso.timbre :as log]
[aws.sdk.dynamodb :as ddb]))
(defn get-user-item [user-id]
(try
(let [resp (ddb/get-item {:table-name "users"
:key {"id" {:s user-id}}
:expression-attribute-names {"#data" :user/data}
:projection-expression "id, #data.name, #data.role"})]
(get resp :item))
(catch Exception e
(log/error e "Failed to fetch user item"))))
For responses that must include nested data, apply a transformation that removes or hashes PII. For example, before sending an item that contains an email address, replace the email with a null placeholder or a salted hash if the client needs a non-PII reference. Also enforce encryption at rest and in transit via DynamoDB server-side encryption and HTTPS, which are prerequisites for any secure integration.
In Chi middleware, you can add a wrapping handler that scrubs outgoing JSON. This complements DynamoDB-side controls and ensures that even if a developer accidentally includes a PII attribute, it is removed before reaching the client. Combine this with the middleBrick CLI to scan endpoints regularly and verify that no PII appears in API outputs, leveraging checks such as Output scanning for PII and Encryption validation.
Related CWEs: dataExposure
| CWE ID | Name | Severity |
|---|---|---|
| CWE-200 | Exposure of Sensitive Information | HIGH |
| CWE-209 | Error Information Disclosure | MEDIUM |
| CWE-213 | Exposure of Sensitive Information Due to Incompatible Policies | HIGH |
| CWE-215 | Insertion of Sensitive Information Into Debugging Code | MEDIUM |
| CWE-312 | Cleartext Storage of Sensitive Information | HIGH |
| CWE-359 | Exposure of Private Personal Information (PII) | HIGH |
| CWE-522 | Insufficiently Protected Credentials | CRITICAL |
| CWE-532 | Insertion of Sensitive Information into Log File | MEDIUM |
| CWE-538 | Insertion of Sensitive Information into Externally-Accessible File | HIGH |
| CWE-540 | Inclusion of Sensitive Information in Source Code | HIGH |