Dashy’s workspace view trusts the url query parameter and puts it straight into an iframe.
PoC:
https://demo.dashy.to/workspace?url=javascript%3Aalert%28origin%29
Root cause
In src/views/Workspace.vue, getInitialUrl() returns the query value directly:
if (route.query && route.query.url) {
return decodeURI(route.query.url);
}
That value is assigned on mount:
this.url = this.getInitialUrl();
Then src/components/Workspace/WebContent.vue uses it as the iframe source:
<iframe :src="url" allow="fullscreen; clipboard-write" />
Since there is no scheme validation before the value reaches the iframe.
Impact
If a logged-in user opens the crafted link, JavaScript runs on the Dashy origin. The payload can read same-origin browser data, interact with the Dashy DOM, and send requests as the victim.
Dashy’s workspace view trusts the
urlquery parameter and puts it straight into an iframe.PoC:
https://demo.dashy.to/workspace?url=javascript%3Aalert%28origin%29Root cause
In
src/views/Workspace.vue,getInitialUrl()returns the query value directly:That value is assigned on mount:
Then
src/components/Workspace/WebContent.vueuses it as the iframe source:Since there is no scheme validation before the value reaches the iframe.
Impact
If a logged-in user opens the crafted link, JavaScript runs on the Dashy origin. The payload can read same-origin browser data, interact with the Dashy DOM, and send requests as the victim.