Xss Cross Site Scripting in Adonisjs with Dynamodb
Xss Cross Site Scripting in Adonisjs with Dynamodb — how this specific combination creates or exposes the vulnerability
Cross-site scripting (XSS) in an AdonisJS application that uses DynamoDB as a persistence layer typically occurs when data is stored without adequate sanitization or escaping and later rendered in HTML, JSON responses, or streamed to a JavaScript context. Because DynamoDB is a NoSQL database, schema flexibility means user-supplied values can contain arbitrary strings, including script-like content, without being constrained by a relational schema. If an API endpoint returns these values directly into a browser context—such as embedding user input into JSON used by client-side templates or injecting values into HTML via unsafe templating—reflected or stored XSS can occur.
AdonisJS does not automatically escape values when you send them to the client; it is the developer’s responsibility to ensure that any data rendered in views or serialized to APIs is properly encoded. When DynamoDB records are fetched and passed to views or to REST/GraphQL resolvers without escaping, fields such as username, comment, or profile_bio can become injection vectors. For example, a stored value like <script>stealCookies()</script> will be persisted as-is in DynamoDB and, if injected into HTML without escaping, will execute in the victim’s browser. In API-driven workflows, unescaped data can also be returned in JSON and later used by a frontend framework to set innerHTML, again leading to XSS.
Because middleBrick tests unauthenticated attack surfaces and includes input validation and data exposure checks, it can surface endpoints where DynamoDB-sourced data reaches the client without sufficient encoding. The scanner does not fix the issue but provides findings with severity and remediation guidance to help you address XSS risks in this specific AdonisJS + DynamoDB flow.
Dynamodb-Specific Remediation in Adonisjs — concrete code fixes
Remediation focuses on context-aware escaping/sanitization before data is inserted into HTML, JSON, or JavaScript. Never rely on schema restrictions in DynamoDB alone to prevent XSS; treat all stored data as potentially malicious. Use AdonisJS helpers and escaping utilities consistently.
1. Server-side rendering (Edge or React SSR)
When rendering data in .edge templates, use built-in escaping. For example:
@each(user in users)
<div>{{ user.username }}</div>
@endeach
<div>{{{ userBio }}}</div> <!-- Only use triple braces if you trust the content --gt;
Double mustaches {{ }} escape HTML by default. Reserve triple mustaches for intentionally trusted HTML, and ensure that trusted content is sanitized with a library such as DOMPurify on the client if absolutely necessary.
2. JSON API responses
Ensure that serialized JSON does not cause XSS when consumed by a frontend framework. Escape or sanitize fields that may be assigned to DOM properties. For example, in a controller that returns DynamoDB items:
const { string } = require('@ioc:Adonis/Core/Helpers')
const User = use('App/Models/User')
class UserController {
async show({ params, response }) {
const user = await User.findOrFail(params.id)
// Safe: serialize only expected fields; escape any free-form text client-side
return response.json({
id: user.id,
username: string.escapeHtml(user.username),
email: string.escapeHtml(user.email)
})
}
}
On the client, avoid innerHTML when inserting data from DynamoDB; prefer textContent or framework bindings that escape by default.
3. DynamoDB data access example with validation
Use AdonisJS schema validation to constrain input before persisting to DynamoDB. This reduces the likelihood of storing garbage, but escaping on output remains essential.
const User = use('App/Models/User')
const { validate } = use('Validator')
async store({ request, response }) {
const rules = {
username: 'required|max:50|alphaNum',
comment: 'required|max:500|escapeHtml' // custom rule can pre-escape
}
const { username, comment } = await validate(request.all(), rules)
// Example using AWS SDK v3 with DynamoDB DocumentClient
const { DynamoDBClient, PutCommand } = require('@aws-sdk/client-dynamodb')
const { marshall } = require('@aws-sdk/util-dynamodb')
const client = new DynamoDBClient({ region: 'us-east-1' })
const params = {
TableName: 'users',
Item: marshall({
id: Date.now().toString(),
username: username,
comment: comment // already escaped by validator rule
})
}
await client.send(new PutCommand(params))
return response.created({ id: params.Item.id })
}
4. Input sanitization libraries
For content that intentionally allows limited HTML (e.g., comments), use a sanitizer on the server before storing or store raw data and sanitize on output depending on context. Example with a sanitizer:
const DOMPurify = require('dompurish')
const clean = DOMPurify.sanitize(dirtyComment)
// store clean in DynamoDB
On retrieval, if you must embed HTML, sanitize again on the client or re-sanitize server-side before rendering.
5. SSRF and data exposure considerations
Ensure that any metadata or attributes pulled from DynamoDB do not inadvertently expose internal paths or sensitive configuration that could assist SSRF or injection attacks. Validate and restrict what is returned in API responses (principle of least privilege).
Related CWEs: inputValidation
| CWE ID | Name | Severity |
|---|---|---|
| CWE-20 | Improper Input Validation | HIGH |
| CWE-22 | Path Traversal | HIGH |
| CWE-74 | Injection | CRITICAL |
| CWE-77 | Command Injection | CRITICAL |
| CWE-78 | OS Command Injection | CRITICAL |
| CWE-79 | Cross-site Scripting (XSS) | HIGH |
| CWE-89 | SQL Injection | CRITICAL |
| CWE-90 | LDAP Injection | HIGH |
| CWE-91 | XML Injection | HIGH |
| CWE-94 | Code Injection | CRITICAL |