T09 · Insecure Skill Coding Practices
- Location
scripts/export_slack_threads.py:14- Finding
JavaScript Injection in Authenticated Slack Browser Context
- Content
View full analysis
{ const channel = '__CHANNEL__'; const page = __PAGE__; const teamId = '__TEAM_ID__'; const userId = '__USER_ID__'; const after = '__AFTER__'; const before = '__BEFORE__'; ``` ```python def run_eval(target_id: str, channel: str, page: int, user_id: str, team_id: str, after: str | None, before: str | None) -> dict: fn = (JS_TEMPLATE .replace('__CHANNEL__', channel) .replace('__PAGE__', str(page)) .replace('__TEAM_ID__', team_id) .replace('__USER_ID__', user_id) .replace('__AFTER__', after or '') .replace('__BEFORE__', before or '')) cmd = [ 'openclaw', 'browser', '--browser-profile', 'chrome', '--timeout', '120000', 'evaluate', '--target-id', target_id, '--fn', fn, '--json' ] ``` ### Technical Analysis The channel name, Slack team ID, Slack user ID, and date arguments are inserted directly into JavaScript source code using string replacement. These values are placed inside single-quoted JavaScript literals without escaping quotes, backslashes, line terminators, or other JavaScript syntax. An input containing a single quote followed by JavaScript statements can terminate the intended literal and alter the function evaluated by Browser Relay. This is not shell injection—the subprocess command is correctly passed as an argument array—but it is code injection into the JavaScript evaluation layer. The injection is especially sensitive because the generated function executes inside an authenticated Slack browser tab. The page context can read Slack-origin local storage, including the `localConfig_v2` data used by the exporter, and can make requests using the active browser session. The retry workflow does not r ...[truncated 1880 chars]- Remediation
View remediation
