Restrict script and css elements in user generated content

(Douglas (@finnatic at @waikato)) #1

Wondering if anyone has done anything like this before.

We have a large multi-site environment, and at times it would be useful to prevent users from including their own script and css via inline and … tags.

Has anyone got an elegant solution for paint layouts and designs that could be applied to restrict that insertion by “expert” users or to escape the content so they don’t function?

(John gill) #2

I’ve given this a (brief) bit of thought in the past, the best answer is probably “use Content Security Policy” . That should let you:

  • disallow inline CSS/JS (but then you can’t use it yourself either)
  • restrict CSS/JS files to being loaded from particular domains (to prevent your users just hosting the JS elsewhere or loading 10MB of junk from CDNs)

Unfortunately you can’t add CSP headers in the design, so you’d have to use triggers for now. There’s a SquizMap request about adding this ability to Design assets

Less good ideas …

In theory you could use a Paint Layout to consume %asset_contents% as an SSJS variable and then do some processing before you print it.

<script runat="server">
// Remove all references to Bart
var q = "%asset_contents^json_encode%";
q = q.replace('Bart','');

This probably isn’t a good idea because:

  • it intercepts asset_contents before %globals_ etc have been processed so anything incorporated with %globals_ will sneak past the filter
    • Subnote - you could try to filter out %globals_ to stop your publishers from doing any nesting?
  • It’ll probably break some complex Paint Layouts you provide for your publishers to use
  • you’ll probably end up needing multiple JS libraries to handle the HTML properly, it’s gonna get out of hand
  • probably super easy to accidentally break pages

Performance probably isn’t too bad as long as you’re using V8 for SSJS. On balance I strongly suspect this approach would cause you more pain than happiness in the fullness of time.

(Douglas (@finnatic at @waikato)) #3

Thanks John.

CSP is not likely to be an option right now, our CSS/JS build processes aren’t quite there to handle the situations where it’s just easiest to add some custom CSS/JS quickly.

My initial thoughts were to use a regular expression asset and pass the asset contents at the paint layout level - but not sure how efficient / server taxing that might be.

(Bart Banda) #4

You could maybe try and create a trigger that checks for content/HTML in the page and if it has <style or <script inside it, fire the action?

I guess it depends on where and how you want to “stop” them from doing it. As in, do you want to warn/stop them from doing it at the editing stage, or just stop the page from rendering it and still “allow” them to add it in?

(Douglas (@finnatic at @waikato)) #5

Thanks Bart - somewhere during the ‘save’ process would be ideal - so the Trigger Log option looks worth evaluating assuming it can work with Edit+ ?

Our use case is for staff profiles which staff are empowered to (a) create and (b) populate with no Matrix workflow at this time - but with an organisational security and risk focus alert to the risk of users (internal and external) uploading “hacked” web content. And being a University we have plenty of knowledgable IT and CS types who like to see what parts of the system they can poke.

(Bart Banda) #6

Good call, that I’m not 100% sure about, worth testing out. Maybe some form of Edit+ plugin could also work there.

Another, perhaps simpler, approach to start with would be to just use the ^striphtml keyword modifier on the PL that prints these profiles and then pass in the allowable tags only, such as p, li, ol, etc…
Something like: