**Parent:** #2
## Description
In `node.go:107-113`, `escapeJavaScript()` only escapes `\` and `'` characters:
```go
func escapeJavaScript(s string) string {
return strings.Replace(strings.Replace(s, "\\", "\\\\", -1), "'", "\\'", -1)
}
func (n node) SetAttribute(name, value string) error {
_, err := n.locator.Evaluate(
fmt.Sprintf(`(element) => element.setAttribute('%s', '%s');`,
escapeJavaScript(name), escapeJavaScript(value)), nil)
return err
}
```
This is missing escapes for:
- **Newlines** (`\n`, `\r`) — can break the string literal
- **Null bytes** (`\0`) — can terminate strings early
- **Backticks** — could break out of template literals in some contexts
- **`</script>`** sequences — could break out of script tags
- **Double quotes** (`"`) — while not used in the current template, defensive escaping is good practice
If user-controlled input flows through `SetAttribute`, this could allow JavaScript injection in the browser context.
## Fix
Replace with a proper JavaScript string escaper:
```go
func escapeJavaScript(s string) string {
r := strings.NewReplacer(
"\\", "\\\\",
"'", "\\'",
"\"", "\\\"",
"\n", "\\n",
"\r", "\\r",
"\t", "\\t",
"\x00", "\\x00",
"</", "<\\/",
)
return r.Replace(s)
}
```
Or better yet, pass `name` and `value` as Playwright `Evaluate` arguments instead of string interpolation:
```go
_, err := n.locator.Evaluate(
`([name, value]) => element.setAttribute(name, value)`,
[]string{name, value})
```
Starting work on this. Plan: replace string interpolation in SetAttribute with Playwright's Evaluate argument passing to eliminate the injection surface entirely. Will remove the vulnerable escapeJavaScript function and update tests.
Starting work on this. Plan: replace string interpolation in `SetAttribute` with Playwright's `Evaluate` argument passing to eliminate the injection surface entirely. Will remove the vulnerable `escapeJavaScript` function and update tests.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Parent: #2
Description
In
node.go:107-113,escapeJavaScript()only escapes\and'characters:This is missing escapes for:
\n,\r) — can break the string literal\0) — can terminate strings early</script>sequences — could break out of script tags") — while not used in the current template, defensive escaping is good practiceIf user-controlled input flows through
SetAttribute, this could allow JavaScript injection in the browser context.Fix
Replace with a proper JavaScript string escaper:
Or better yet, pass
nameandvalueas PlaywrightEvaluatearguments instead of string interpolation:Starting work on this. Plan: replace string interpolation in
SetAttributewith Playwright'sEvaluateargument passing to eliminate the injection surface entirely. Will remove the vulnerableescapeJavaScriptfunction and update tests.Work finished. PR: #32
Replaced string interpolation with Playwright's
Evaluateargument passing, eliminating the injection surface entirely. Removed the vulnerableescapeJavaScripthelper.