When a finding reappears, preserve both the old closure evidence and the new signal. Bind the old patch, the new alert and the running artifact to exact revisions. Then decide whether this is the same unsafe path restored, a second path to the same effect, an older deployment, or a mistaken detection. Reopen or link work based on that evidence; do not assume the previous reviewer was wrong or that the latest scanner is right. If sensitive data may already have been exposed, involve the incident owner while root-cause review proceeds.
The fix is only durable when it covers the right trust boundary and later changes preserve that rule. A recurrence review should therefore answer two questions: “What can happen now?” and “Why did the earlier fix fail to prevent this path?” The second answer shapes the preventive change, but it does not delay urgent containment.
An illustrative recurrence through a new logger
Illustrative case, not a customer incident: Elm Support's API originally logged full HTTP request headers during authentication errors. A reviewed finding at A_SHA identified that this could place access tokens in application logs. The team patched the authentication handler at B_SHA to omit the Authorization header. An authorized staging check paired the absent synthetic marker with a present ordinary correlation event at the intended sink. That supported closure for this handler and artifact, without claiming all logging paths were safe.
Three weeks later, a new alert at C_SHA points to a shared request logger added by another team. It serializes all headers before the authentication handler runs. The old handler remains safe. The problem is a new path to the same harmful effect, not necessarily a revert of the original patch. OWASP's Logging Cheat Sheet lists access tokens and session identifiers among values that usually should not be recorded directly. MITRE's CWE-532 describes insertion of sensitive information into log files; neither reference tells us that Elm's actual logs contain real tokens. That fact requires separate, authorized evidence.
The chronology should be explicit:
| Point | Code or observation | What it supports |
|---|---|---|
A_SHA |
Authentication handler logs request headers. | Original source-supported path. |
B_SHA |
Handler excludes authorization material; synthetic staging marker absent on that path. | Original handler fix supported in stated scope. |
C_SHA |
New shared logger serializes headers before handler. | Plausible new path; inspect configuration and sinks. |
| Current deployment | Artifact identity not yet supplied. | Production exposure remains unknown. |
The new issue may be serious even though the original closure was valid. The practical next move is to examine the current logging path and, if real secrets may have reached retained logs, start the organization's incident and credential-handling process. Do not paste token values into a ticket to prove the point.
Step 1: Triage the new signal without overwriting history
Save the alert's tool, rule, run time, revision, selected scope and exact source citation. Retrieve the old finding, patch and closure note. Ask whether the new signal refers to the same actor, entry, data, sink and effect. A similarity of title is not enough. “Access token in logs” can describe different middleware, libraries and environments.
For Elm, trace the new shared logger from request entry to log serialization and destination. Check which routes call it, whether token-bearing headers arrive there, whether redaction happens before serialization, and which log levels/configurations enable it. A source path that could log a token is not proof that production emitted one. Conversely, a missing search hit in a log index is not proof that no copy exists; the index may be sampled, delayed, filtered or out of scope.
Output: a new actor/data-to-sink path with confirmed facts and unknowns. Owner: a security reviewer and the service owner together, because the security impact and operational logging configuration may live in different teams.
Step 2: Classify the recurrence
| Pattern | Evidence to look for | Work item |
|---|---|---|
| Same path restored | A later commit removes or bypasses the guard at the original entry. | Reopen the original issue with the new revision and a regression timeline. |
| Alternate path added | Original guard still works; a new route, helper, middleware or sink reaches the same effect. | Link a new finding to the old one and review the shared root cause. |
| Old artifact still deployed | Source is fixed, but the affected environment runs a pre-fix build or stale configuration. | Assign deployment/rollback investigation; keep production status open. |
| New detector is wrong or stale | Its cited line is absent at the bound revision or a verified control defeats the precise claim. | Reject the new alert with counterevidence while preserving its record. |
| Insufficient evidence | Rule ran on partial scope, configuration is unknown, or the destination cannot be inspected. | Keep investigation open and name the missing artifact. |
Compare revisions rather than relying on a commit message. Git diff helps identify the actual changes between the old patch and current code. But a clean diff in the original file can coexist with a new unsafe caller elsewhere, as it does in Elm. Look for both the original control and other paths that handle the same sensitive material.
Step 3: Protect current users while diagnosing the cause
If there is credible evidence that sensitive values may be flowing to a log sink, use the service's response procedure to take proportionate containment and notify the incident owner: disabling the unsafe logger, changing collection rules, restricting log access and considering credential rotation under the organization's procedure. Choose actions according to the observed data and system dependencies. Rotating every credential without checking which values and time window were involved can create avoidable disruption; doing nothing because the scanner has not proved exfiltration can leave a real exposure active.
Preserve relevant evidence through approved channels with restricted access and retention. Do not move raw logs into a broadly accessible developer ticket. A synthetic canary in an authorized test environment can demonstrate the current code path without exposing a real token. The remediation and incident tracks can proceed in parallel: one fixes future logging, the other determines whether past sensitive values need response.
For Elm, a service owner first identifies whether the shared logger runs in the deployed environment and which sink receives its output. An authorized reviewer then searches for the synthetic marker from a controlled request, using access to the staging log sink. If it appears, the source-supported path has a runtime observation. If it does not, check configuration, sampling, collection and artifact identity before declaring the path absent. Do not use a production customer's token as a test value.
Step 4: Resolve the sink evidence, then repair the boundary
Continue Elm's constructed case with staging artifact C-STAGE bound to C_SHA. The supplied exercise observations are:
| Sink/path | Synthetic secret marker | Ordinary correlation event | Meaning |
|---|---|---|---|
| Original authentication-handler sink | Absent | Present | Supports the original handler correction within this checked path. |
| New shared request-log sink | Present | Present | Supports the new logger's token-bearing path in this staging artifact. |
| Archive sink | Absent | Absent | Inconclusive: collection or visibility may be missing. Absence of the marker proves nothing here. |
These are teaching records, not checks executed for this article. The ordinary correlation event is essential: it demonstrates that the intended request reached the observable sink. It still does not establish that every retained copy was searched or that production has the same configuration.
The local repair proposal removes only Authorization from a copied header map. That may address this instance but leaves cookies, future token-bearing headers and raw-request logging elsewhere dependent on an expanding blacklist. A reviewed event interface can instead admit the diagnostic fields operations needs:
request_event:
event_type = authentication_failure
request_id = server_generated_correlation_id
route = matched_route_template
status = 401
duration_bucket = short
The route is a matched template, not a raw URL carrying query values. The request ID is server-generated, not an arbitrary header copied into logs. Operations retains correlation, route and outcome without receiving the request's credential fields. This is a proposed schema to review, not a guarantee that any existing logger uses it.
The selected correction is to route the new logger and old handler through the checked event serializer and remove raw-header serialization in the assessed callers. Inventory the remaining emitters: an allowlisted interface offers no protection to a caller that bypasses it. OWASP's logging guidance supports excluding tokens while retaining useful event data.
Choose prevention that matches the recurrence
The recurrence category should determine the follow-up improvement. If a later commit removed the original redaction, strengthen the review of that boundary and the check that would detect its removal. If a new logger bypassed the safe serializer, the useful prevention is a clearer logging interface and an inventory of emitters. If an old artifact remained active, the problem belongs in release reconciliation. These are different failures even when their alerts share a title.
For Elm, the new logger shows that protecting one authentication handler was insufficient as a long-term design boundary. The earlier closure can remain valid for that handler while the team improves the common event interface. Record which callers adopted the interface and which remain outside its reviewed scope. An interface that exists but is optional does not protect bypassing callers.
The incident inquiry also has its own stopping conditions. It needs the potentially affected time window, sinks, readers and credential validity decisions. The code developer should not mark those questions answered because D_SHA no longer serializes headers. Conversely, an unresolved historical sink should not prevent the developer from accurately reporting that the new source path has been corrected.
A useful recurrence review ends with one cause statement and one prevention action: “The new request logger serialized raw headers outside the corrected handler; route assessed emitters through the reviewed event interface and review additions to that emitter set.” This is more actionable than “developers must be more careful.”
At the next similar change, inspect whether the chosen prevention actually applies. Does a new emitter pass through the interface, preserve useful correlation and exclude sensitive fields at the serialization boundary? That bounded check evaluates the team's response to the recurrence without claiming that all future logging defects are impossible.
Close the new path without rewriting the old closure
The new linked finding is “shared request logger serializes token-bearing headers at C_SHA.” The B_SHA handler closure remains valid. At D_SHA, source review must show both emitters use the safe event interface; controlled validation must show the ordinary event at each relevant sink and no marker in its recorded fields. The archive sink needs its collection gap resolved before its result can contribute to closure. Production status waits for artifact and configuration mapping.
The resulting work record separates three outcomes: new source path corrected, runtime/deployment verification pending, and historical credential response owned by the incident/identity team. Removing future logging does not revoke credentials or erase retained logs. This lets the developer finish the right code task while the incident owner addresses a different time window and evidence set.
For the next recurring alert, fill in that relationship field before changing the old ticket. It prevents a new path from being hidden under an old closure and makes the preventive work visible. Use the new-commit verification method for the follow-up patch, and fixed versus no longer detected when the latest scanner becomes quiet.