---
title: Do Not Pass Sensitive Data In Query String
impact: HIGH
impactDescription: prevents sensitive credential leakage in browser history, logs, and referrer headers
tags: url, query-string, sensitive-data, leakage, security, kotlin
---

## Do Not Pass Sensitive Data In Query String

URL query strings are stored in browser history, server access logs, and transmitted in `Referer` headers. Sensitive data like tokens, passwords, or PII (Personally Identifiable Information) must never be part of a URL.

**Incorrect (sensitive data in URL):**

```kotlin
// Token in URL
httpClient.get("https://api.sun-asterisk.vn/data?apiKey=$mySecretKey")

// Sending sensitive PII in URL
httpClient.get("https://api.sun-asterisk.vn/profile?email=$userEmail&phone=$phone")

// Password-based login via GET
@GetMapping("/login")
fun login(@RequestParam pass: String) { ... }
```

**Correct (sensitive data in body or headers):**

```kotlin
// Token in Authorization Header (Stateless)
httpClient.get("https://api.sun-asterisk.vn/data") {
    headers {
        append(HttpHeaders.Authorization, "Bearer $accessToken")
    }
}

// Credentials in POST Body
@PostMapping("/login")
fun login(@RequestBody credentials: LoginRequest) { ... }

// Sensitive search via POST session-based
@PostMapping("/api/secure-search")
fun secureSearch(@RequestBody query: SecureSearchRequest) { ... }
```

**Where Query Strings Leak:**
1.  **Server Logs:** Almost all web servers (NGINX, Apache) log the full requested URL.
2.  **Browser History:** Browser "Back" button or history allows anyone with local access to see the sensitive URL.
3.  **Referer Headers:** If the page redirects or the user clicks a link, the URL (with tokens) is sent to the next site.
4.  **Forward Proxies/CDNs:** Any intermediate network device may log the full URL.

**Tools:** Semgrep, SonarQube (S2245), Manual Review, OWASP Secure Headers
