Drupal 6: embedding just about any content securely
Introduction: the requirements
A customer of ours wanted a website which could manage the integration of just about any external content (meaning video, audio, images, but also Google docs, slides from Slideshare and books from Scribd) in a ‘Resource’ content type. There are multiple ways to do this in Drupal, however there are lots of possible pitfalls.
The possible solutions
I investigated and looked at the following solutions:
- The Embedded Media Field module: the module creates CCK field types that allow you to add EITHER video, audio or image from different content providers. The module has the following problems however:
- It creates 3 CCK field types: Embedded Audio Field, Embedded Video Field and Embedded Image Field. There is a patch here that creates an Embedded generic field which supports all media types, however the patch didn’t work in my case.
- You can “only” embed audio, video and images, so if you want to embed more (like Slideshare or Google Docs content), you will have to find another solution.
- Each time you want to add a new provider, if it’s not already provided as a Drupal module, you have to write a small module.
- The Media module will be THE media embedding solution in the future, however, at the time of writing this article, it is still unstable and under heavy development.
- Finally, the last solution that came to my mind was to allow users to simply embed some HTML code within a Resource. They would simply go to their YouTube video or Slideshare slides or whatever and copy and paste the embed code provided by the website, and all done.
Security pitfall: what NOT to do
It would be very tempting for someone who doesn’t know about Cross site scripting to simply allow his users to use “Full HTML” within their posts. That would allow your users to embed about anything however they want to embed it, without further configuration needed. However, for obvious reasons if you know about cross site scripting issues, you do not want to allow that, and you want to find a more secure way of doing it.
In order to do it securely, you will basically need one single module: Embed filter. This module filters various embed tags (embed, object and script) based on a hostname, so for example you can say that you allow your users to embed anything that comes from youtube.com, but you won’t allow them to embed from any other website. This solves the cross site scripting issues while still allowing your users to embed just about anything.
If you want to configure it in the same way that I’m going to show you in the following lines, you will also need the Better Formats module.
How to configure it ?
First, you obviously need to create a ‘Resource’ content type. Allow your resource to have a Title and a Description.
Then, in your resource content type, create a text field labeled Embed HTML for example.
Then, you will need to create a new Input format. Site configuration > Input formats > Add input format. I called mine Filtered HTML with embed. When you configure it, make sure you activate the Object and embed tag filter which should be present if you have the Embed filter module activated. Also, when you configure it, make sure you allow the <object>, <script>, <embed> and <param> tags in the configuration of the HTML filter.
Then, you will need to allow your users to use this new format. Once you have done this, you will see that your users will be prompted to choose between the Filtered HTML format or the Filtered HTML with embed format. What you probably want is to remove this prompt, and allow the Filtered HTML with embed for the Embed HTML CCK field you created, but only allow the Filtered HTML format for the other fields (like the Description of the resource for example). This is where the Better Formats module kicks in.
Go to Input Formats and in Settings, check “Control formats per node type”. Then, you will need to apply this patch to the Better Formats module. Then go to your Modules list and activate the “Better Formats additional CCK text widgets” module. Go back to your resource content type and edit the ‘Embed HTML’ field you created. Click on ‘Change basic information’ and choose ‘Text field using Better Formats module’ as the Widget type. In the configuration of the field, you should now see an ‘Input format settings’ collapsible box. Only allow the ‘Filtered HTML with embed’ in the list of allowed formats.
Finally, in order to remove those collapsible boxes that allow users to choose their input format, go to the User permissions list and, in the ‘better_formats module’, uncheck the permission to ‘collapsible format selection’.
Configuring the embed filter module
Finally, you will need to configure the embed filter module. Go to Site configuration > Embed filter and add whatever allowed hosts you want to allow in the list. Be careful as, sometimes, some providers do not host their content at the same address as their site. For example, if you want to allow Slideshare, you need to add slidesharecdn.com in your allowed hosts instead of slideshare.com.
Also note that if you want to allow img tags or iframe tags (Google uses iframes to embed their presentations and google docs), you will need to apply this patch to the embed filter module.
Conclusion: or help Media…
You can either do what’s explained in this article, or help the development of the Media module, because everything I wrote in this article will become obsolete when the Media module becomes stable. So waiting and helping the development of the Media module can also be a good option…