---
title: Output Encoding For Dynamic JS/JSON
impact: HIGH
impactDescription: prevents code injection when transferring data from backend to frontend scripts
tags: xss, javascript, json, encoding, security, kotlin
---

## Output Encoding For Dynamic JS/JSON

When Kotlin backends generate HTML that includes inline JavaScript or JSON data blocks, user-controlled data must be properly encoded to prevent attackers from injecting malicious scripts.

**Incorrect (unescaped data in inline JS):**

```kotlin
// VULNERABLE: Direct string interpolation in JS
val username = request.getParameter("name") // Input: admin"; alert('xss'); "
val html = """
    <script>
        var currentUser = "$username"; 
    </script>
"""
call.respondText(html, ContentType.Text.Html)
```

**Correct (proper JSON or JS encoding):**

```kotlin
import com.fasterxml.jackson.databind.ObjectMapper
import org.owasp.encoder.Encode

// 1. Using Jackson for safe JSON serialization (Best for objects)
val mapper = ObjectMapper()
val userData = mapOf("name" to username, "id" to userId)
val safeJson = mapper.writeValueAsString(userData)

val html = """
    <script>
        var userData = $safeJson; // safeJson is wrapped in quotes if it's a string, or is an object
    </script>
"""

// 2. Using OWASP Encoder for specific JS literal strings
val safeJsString = Encode.forJavaScript(username)
val htmlLiteral = "<script>var name = '$safeJsString';</script>"

// 3. Recommended: Use HTML Data Attributes instead of inline JS
val htmlDataAttr = """
    <div id="user-context" data-user-info='${Encode.forHtmlAttribute(safeJson)}'></div>
"""
```

**Key Strategies:**
- **Prefer Data Attributes:** Instead of inline `<script>`, put your data in `data-*` attributes of HTML elements and read them from your external JS file.
- **Use JSON Parsers:** Use `Jackson` or `Kotlinx.Serialization` to convert objects to JSON. They handle most escaping issues, but you still need to be careful about the `</script>` tag inside strings.
- **Escape `</script>`:** Even inside a quoted JS string, the browser might interpret `</script>` as the end of the script block. Secure encoders will escape the `/` or use unicode sequences.

**Tools:** Jackson, Kotlinx.Serialization, OWASP Java Encoder, Manual Review
