T09 · Insecure Skill Coding Practices
- Location
references/scraper_example.py:140- Finding
JavaScript Injection Through an Unsafely Interpolated Data Key
- Content
View full analysis
str: """Extract content based on configured method""" if config.javascript_data_key: # Extract JavaScript global data return self.page.evaluate( f"() => JSON.stringify(window.{config.javascript_data_key} || null)" ) ``` ### Technical Analysis The `javascript_data_key` configuration value is interpolated directly into JavaScript source code passed to Playwright's `page.evaluate`. The implementation assumes that this value is a trusted JavaScript property name, but it performs no syntax or identifier validation. A caller able to control this configuration field can provide JavaScript syntax instead of a simple property name. The resulting expression is evaluated in the context of the loaded web page. Separating untrusted data from executable source is required even when the JavaScript runs inside a browser context. The vulnerable operation can expose any data available to page JavaScript, including DOM content, application state, non-HttpOnly tokens, and browser storage associated with the loaded origin. Injected code may also make authenticated same-origin requests or send data to an external endpoint, subject to browser security controls. ### Attack Path 1. An attacker controls or influences `ScrapeConfig.javascript_data_key`. 2. The attacker provides a value containing JavaScript syntax rather than a valid property key. 3. `_extract_content` embeds that value into the function source with an f-string. 4. Playwright executes the constructed source through `page.evaluate`. 5. The injected expression accesses page data, performs requests with the page's authenticated context, alters the DOM, or transmits accessible information. 6. The scr ...[truncated 842 chars]- Remediation
View remediation
JSON.stringify(window[key] ?? null)", config.javascript_data_key, ) ``` Apply the following additional controls: 1. If only top-level properties are supported, enforce a conservative identifier allowlist such as `^[A-Za-z_$][A-Za-z0-9_$]*$`. 2. If nested paths are required, split the input into components, validate every component, and traverse the object without constructing JavaScript source. 3. Reject keys containing parentheses, brackets, quotes, semicolons, whitespace, operators, or other executable syntax. 4. Treat extraction configuration as untrusted whenever it originates from users, remote jobs, or generated agent input. 5. Add tests using malicious syntax to confirm that configuration values cannot escape the data boundary. 6. Use a restricted browser context and avoid loading sensitive authenticated sessions unless they are necessary for the task. ]]>
