-
Notifications
You must be signed in to change notification settings - Fork 25
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
Images aren't displaying in TinyMCE #2348
Comments
Summary: A request for images attached to an APD yields a 401 response. This is because the |
Suggested fix: Allow requests for files/images to pass-through. If a client is requesting images attached to an APD, this means they can access the APD. S3 does a decent job of obfuscating filenames. For example: It would be possible for an authorized user to share an image URL with an unauthorized user. The authorized user could just as easily download the file and email it to an unauthorized user. An alternative solution would be to hijack requests on the front-end using a service worker, and add the |
I think it would be better to try to intercept it like we do for axios. If that proves to be too hard we can lower the requirements on retrieving an image. |
Not sure if this would be related, but at some point states will need to be able to attach other documents (contracts/amendments/RFPs) and those need to be secured. Just something to consider as you are thinking through solutions on file storage. |
FWIW, I don't think we'll be uploading any documents through the RTE if that has any bearing on this. |
I will approach this bug in two-parts: One PR allowing requests for attached files to pass-through, and another that hijacks requests on the front-end and adds the necessary header. Note that an S3 |
There are two things happening with the images. One I haven't fully investigated yet and one I have and could be problematic to fix. Either way, it's a bug and is probably already affecting production.
The URL that TinyMCE is inserting into the image href attribute is incorrect. For preview deployments it should be /api/apds/.../, but instead it's https://api//apds/.... I assume it's an issue with the URL being relative and TinyMCE is "helping" by adding a protocol and interpreting it as a full path. This only affects preview. The image URL is built on the client side by combining the relative image URL returned from the API with the full API URL. In staging and production, the API URL is absolute, so combining the two creates a new absolute URL. In preview deployments, the API URL is also relative, so the combined URL remains relative. Not clear to me offhand if there is a fix, but if it only affects preview deployments, it seems like a relatively low priority.
The API protects images with authorization just like everything else. A user can only view an image if it is associated with an APD that they have access to. The issue is that we now require authentication to happen via the Authorization header, but there's no (immediate) way to set that header on tags, which is what the TinyMCE editor is using. This worked previously because we were using cookies for authentication, and those got passed automatically by the browser – no need to set anything. There aren't a lot of good options here, but some options do exist:
My current strong lean would be towards something like a Service Worker to intercept all calls to the API. That service worker could then inject the authorization header (see this StackOverflow answer for an example of exactly how to do it without losing anything else that may have been set on the request) on the fly. We would also remove the code that Richard added to the API wrapper since it'd be incorporated by the service worker. The downside? Service workers don't exist in IE, full stop. They work in all the modern browsers, but not IE. So if we went the service worker route, images could be uploaded from IE, but they couldn't be viewed from IE.
Alternatively, we can make images publicly accessible. My instinct is that, while the images are probably mostly safe for public exposure, some won't be. Even among those that are safe, I can imagine that states (and likely CMS security folks) would be squeamish about making everything wide open like that. That said, this is an easy, universal solution. It'd just take commenting out a couple of lines of code in the API.
Rewrite the contents of the RichText field on-the-fly to append the user's token to any image hrefs found in the content. This would also require tweaking the API to look for authentication tokens in the query string along with the headers. It's also not my favorite approach because it seems fragile. It might have cacheing implications, too, since caches sometimes ignore query strings, so a malicious actor could potentially retrieve an image from an intermediate cache even though the associated token had expired.
Hopefully there's another method that's also universal, but in my brief dive, I couldn't find anything. In any case, there should probably be a bug issue related to these images. This PR didn't introduce the problem, though. The bug came about when we migrated to the Authorization header, and we just plain didn't catch it. I did not even think about tags when Richard did all that work, and I imagine he didn't either. (It was 100% the right work to do, though.) What an unexpected edge case...
Because we're switching to OKTA for authentication, this may all change again once that is done, so this is a placeholder task that we probably want to wait to deal with until then
This task is done when...
*Add a LABEL (design, dev, compliance, BUG, etc) before submitting.
*If the issue is needed to complete prioritized work for the CURRENT SPRINT, add it to the "This Sprint" pipeline. Otherwise, all other issues will be automatically added to the unprioritized pipeline for PRODUCT to prioritize.
The text was updated successfully, but these errors were encountered: