T09 · Insecure Skill Coding Practices
Error
- Location
- rules/server-after-nonblocking.md:41
- Finding
- Raw Session Credential Passed to Logging Infrastructure<![CDATA[ ## Vulnerability Details **File Location**: `rules/server-after-nonblocking.md:41-49` and duplicated in `AGENTS.md:998-1006` **Vulnerability Type**: Sensitive credential exposure through logging **Risk Level**: High ### Vulnerable Code ```tsx // Log after response is sent after(async () => { const userAgent = (await headers()).get('user-agent') || 'unknown' const sessionCookie = (await cookies()).get('session-id')?.value || 'anonymous' logUserAction({ sessionCookie, userAgent }) }) ``` ### Technical Analysis The recommended implementation reads the complete value of the `session-id` cookie and passes it to `logUserAction`. A session cookie is normally a bearer credential: possession of a valid value may be sufficient to impersonate the associated user. Logging systems frequently have broader access controls and longer retention periods than authentication systems. They may also forward records to external analytics, observability, archival, or support platforms. Passing the raw session credential into an unspecified logging function therefore creates an unnecessary credential-disclosure path. The behavior is not required to demonstrate the documented use of Next.js `after()`. A non-secret event identifier, authenticated user identifier, or redacted correlation value would provide adequate logging context without exposing the session token. ### Attack Path 1. An application developer adopts the documented “correct” example. 2. The application reads the raw `session-id` cookie during a request. 3. `logUserAction` stores or forwards the session value to a log or analytics system. 4. An attacker obtains access to those records through a compromised logging account, overly broad employee permissions, an exported support bundle, a log injection flaw, or a breached downstream provider. 5. The attacker extracts a session value that has not expired or been revoked. 6. The attacker replays the cookie against the application and impersonates the vi ...[truncated 705 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Remove the session cookie from all logging and analytics payloads. - Replace it with a non-secret identifier, such as: - An internally generated event or request ID. - A stable user ID that is safe under the application’s privacy policy. - A keyed HMAC-derived pseudonymous identifier when cross-event correlation is necessary. - Do not use an ordinary unkeyed hash of the token as a replacement, because predictable or leaked token values may still be correlated. - Configure centralized log redaction for cookie names, `Authorization` headers, access tokens, refresh tokens, API keys, and session identifiers. - Apply least-privilege access controls and short retention periods to logs. - Document whether logging data is forwarded to third parties and prohibit credentials from entering those systems. - Add automated tests or static-analysis checks that reject sensitive fields in logging calls. A safer example is: ```tsx after(async () => { const userAgent = (await headers()).get('user-agent') || 'unknown' const requestId = crypto.randomUUID() await logUserAction({ requestId, userAgent }) }) ``` ]]>
