T09 · Insecure Skill Coding Practices
- Location
SKILL.md:205- Finding
Unvalidated Table Field Passed to window.open()
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md:205-208
Vulnerability Type: Unvalidated external navigation
Risk Level: Mediumtypescript // 链接字段点击 s2Instance.on(S2Event.GLOBAL_LINK_FIELD_JUMP, (data) => { window.open(data.fieldValue) })Technical Analysis
The example passes
data.fieldValuedirectly towindow.open()without parsing the value, restricting permitted URL schemes, or validating the destination against an origin allowlist.If the table data can be influenced by an attacker, a malicious value could cause the application to open an attacker-controlled website when a user activates the corresponding link field. This creates a phishing or unsafe-redirection risk. The call also does not explicitly request
noopener,noreferrer; depending on browser behavior, the opened document may receive an opener reference and attempt reverse-tabnabbing or manipulation of the originating page.Exploitation requires an attacker to control or influence a link-field value and persuade a user to click that field. This is documentation example code rather than an executable component bundled in the audited package, but applications adopting the example unchanged would inherit the weakness.
Attack Path
- An application implements the documented event handler without additional validation.
- An attacker inserts or influences a table record whose link field points to an attacker-controlled destination.
- The application renders the malicious field as an interactive link.
- A user clicks the field, triggering
GLOBAL_LINK_FIELD_JUMP. - The handler forwards the untrusted value directly to
window.open(). - The browser opens the attacker-controlled page, which can present phishing content and, where an opener reference remains available, attempt to manipulate the original page.
Impact Assessment
Successful exploitation can redirect a user to an untrusted site and facilitate phishi ...[truncated 431 chars]
- Remediation
View remediation
Remediation Suggestions
Treat all link-field values as untrusted input:
- Parse the value with
new URL()inside atry/catchblock. - Permit only required schemes, preferably
https:. - Restrict destinations to an explicit hostname or origin allowlist where business requirements permit.
- Reject malformed URLs and dangerous or unnecessary schemes.
- Open approved links with
_blankandnoopener,noreferrer. - Consider showing the validated destination to the user before leaving the application.
Example hardened implementation:
typescript const allowedOrigins = new Set([ 'https://reports.example.com', ]) s2Instance.on(S2Event.GLOBAL_LINK_FIELD_JUMP, (data) => { try { const url = new URL(String(data.fieldValue)) if (url.protocol !== 'https:' || !allowedOrigins.has(url.origin)) { return } window.open(url.href, '_blank', 'noopener,noreferrer') } catch { // Reject malformed URLs. } })- Parse the value with
