-
Notifications
You must be signed in to change notification settings - Fork 408
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug: No placeholder icon when safe app's logo cannot be loaded #1516
Conversation
7fc3895
to
32b69c4
Compare
Branch preview✅ Deploy successful! https://bug_safe_apps_placeholder_cion--webcore.review-web-core.5afe.dev |
background: url('${src}') center center/contain no-repeat; | ||
} | ||
</style>` | ||
const APP_LOGO_FALLBACK_IMAGE = `/images/apps/app-placeholder.svg` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a new cross-theme icon by Lila
ESLint Summary View Full Report
Report generated by eslint-plus-action |
32b69c4
to
30e512f
Compare
const getIframeContent = (url: string, alt: string, width: number, height: number): string => { | ||
return ` | ||
<body style="margin: 0;"> | ||
<img src=${url} alt=${alt} width="${width}" height="${height}" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would add style="display: block"
to avoid a line underneath.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What line? I didn't see anything unwanted in all browsers I tested (chrome, safari desktop, firefox)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I remember you mentioned it in the slack convo but when working on it I didn't see a need for it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't really matter in this case tho, because the iframe itself is 40x40.
30e512f
to
cea8649
Compare
const getIframeContent = (url: string, alt: string, width: number, height: number): string => { | ||
return ` | ||
<body style="margin: 0;"> | ||
<img src=${url} alt=${alt} width="${width}" height="${height}" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would wrap url
and alt
in double quotes, and escape any double quotes in those strings. Otherwise, we have a classic XSS hole here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I would hardcode smth like "app logo" in the alt tag. The name of the app is already on the card anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good spot regarding xss. I've checked other platforms with lists to see how they implement alt attributes and seems like they don't lol (checked chrome web store, slack store)
c26343f
to
c890435
Compare
const getIframeContent = (url: string, width: number, height: number): string => { | ||
return ` | ||
<body style="margin: 0;"> | ||
<img src="${url}" alt="App logo" width="${width}" height="${height}" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like I said, you also might want to escape dangerous symbols here. encodeURI(url)
should do the trick.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The url is validated at the fetch time and also browsers seem to be smart nowadays: https://security.stackexchange.com/questions/124840/xss-vectors-in-img-src-and-background-image-url
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given we have all these safety things in place I think an additional check inside the component is redundant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not about fetching, you're inserting a string directly into HTML. It can close the tag and render a butt.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't seem like a big security threat to me given that we validate the URL before and the amount of sandboxing we enforce on the iframe. But to get the pr through i added it
Have you tried this btw? |
It seems to follow the CSP policy set in the app and doesn't allow loading from cross origin domains. If I understand correctly, an |
c890435
to
d14db7b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dunno if it's worth it just to show a placeholder for broken icons (it would be better to fix such icons quickly) but looks good. 👍
Muchas gracias gentlemen, todo bueno 👍 |
What it solves
Resolves safe-global/safe-react-apps#637 by rendering an img tag inside the sandboxed iframe for fetching safe apps icon (for more context see #1193)
thanks to @katspaugh for answering questions and suggesting script tag workaround
How this PR fixes it
It renders an img tag and attaches error event listener. It also allows scripts inside the iframe to define the error listener. Shouldn't be a security risk. Also it seems like scripts must be same-origin and cross origin ones have to be explicitly enabled
How to test it
Screenshots