How serious are the XSS attack blocks in elm? - xss

I know that the elm compiler blocks you from putting <script> tags in HTML documents. Instead, it will switch them to <p>s:
node
"script"
[ id "MathJax-script"
, type_ "text/javascript"
, src "https://cdn.jsdelivr.net/npm/mathjax#3/es5/tex-chtml.js"
]
[]
I managed to find away around this. The compiled elm code (in my case stored in a js file), contains some special code:
// XSS ATTACK VECTOR CHECKS
function _VirtualDom_noScript(tag)
{
return tag == 'script' ? 'p' : tag;
}
The 'script' string could be replaced with 'scrip', and you can use <script> tags.
After a little research, I found out that this blocks XSS attacks. How serious is that concern? Should I use this trick to allow me to insert <script> tags?

One thing you should ask yourself is why would you want to do this? If you need to insert scripts, doing this from outside Elm is usually a more robust option anyway (for instance this allows the browser to start loading that resource before your Elm application has a chance to load/initialise).
That being said, the main reason you should worry about this is for code that you don't control. The nice thing is that Elm makes it quite difficult to execute supply chain attacks against your code. If you weaken these protections, you might make yourself vulnerable against these. However, it is fairly unlikely that someone will attempt this attack indiscriminately, as it generally won't work against anyone trying to do this.
(If you worry about being a target specifically, then you probably shouldn't be considering weakening any security feature).

Related

Is this enough to prevent xss?

I'm working on a website where there is going to be a lot of user generated content. As an WYSIWYG editor I'm using tinyMCE. As a template engine, I'm using ejs.
In order to prevent XSS I decided to use xss npm package.
I'm using these custom rulles:
const strict = {
whiteList: {},
}
const withTags = {
whiteList: {
div: [],
strong: [],
em: [],
br: [],
ul: [],
li: [],
ol: [],
blockquote: [],
},
}
Let's say a user uses text area and submits this code:
<script>alert("hi")</script>
In my DB it's saved this way:
<script>alert("hi")</script>
Now, when the content is rendered by ejs some content is rendered with escaped output (<%= %>). Rendered escaped output (html page) looks like this:
<script>console.log("test")</script>
However, some content is rendered with ejs unescaped raw output (<%- %>). Html will look this way:
<script>console.log("test")</script>
I have 2 questions:
Because < and > are escaped as < and > is it safe to render ejs unescaped output?
Is what I'm doing generally enough for XSS protection?
Thank you very much!
First of all your data probably isn't saved in database the way you presented. In all likelihood it's stored there without any encoding (as it should be).
EJS in itself, when used correctly, takes care of encoding output for you so that you can safely construct parameterized HTML. But in your case you want to disable this protection to render raw HTML, so yes, you must be careful. There are a couple of security controls at your disposal.
1. DOMPurify
I haven't used the xss library personally, it seems to have a lot of downloads and probably it's not a bad option. But DOMPurify is probably better. It also doesn't require configuration and has built-in support for trusted-types (I'll get to that in a minute).
You would use it twice. First on server-side when the HTML is submitted by the user, and second on client-side when the HTML is rendered by EJS.
If you are serious about security then you will connect anomaly alerts from the server-side purification to your SIEM/SOC etc. Then you will know when someone has attempted an XSS attack on your website.
2. Sandboxed Iframes
Another client-side control that you can implement is sandboxed iframes. Instead of just rendering the HTML on the page, you create an IFRAME, give it a properly configured sandbox attribute, and then set the purified HTML as the content. Now even if something goes wrong with the purification, the malicious HTML would be isolated in its own world.
3. Content Security Policy
The coolest and (when used properly) most effective defence against XSS is CSP. How it works is that you give your website restrictions such as "do not execute scripts", "do not load images", etc. And then you allow the scripts that you do want to execute, and nothing else. Now if an attacker manages to inject a script, link, form, etc. on the page, it will not work because it hasn't been specifically allowed.
I've written about CSP at length here, you will even find specific examples for your case (NodeJS and EJS) with CodeSandbox examples on that article. And in general about XSS protection you can read more here.
Hope this helps!

Vue: keep linebreaks and indentation intact

I'm working on a Vue app that (obviously ;)) loads Vue templates, lets the user fill in content and then export the markup of those templates/components. However, all linebreaks and indentation are lost in the process.
Is there any way to make Vue keep that information? So far at least I achieved to keep (conditional) comments via the
comments: true
option. There are several other options like expectHTML or shouldDecodeNewlines, but they don't seem to be documented and none of them seem to help me accomplish what I want.
The problem is that we're in part handling email templates (meh...) and it's a client requirement that "input === output" (well, markup-wise), because indeed a space or linebreak here or there can indeed make a difference in fussy mail clients. So simply running the markup through a beautifier is not an option.
I know, I know... That's not really what Vue is made for, and markup !== DOM... But the tool itself is written in Vue and I love to currently be able to use all the magic of Vue syntax inside the templates being processed as well.
If all else fails, I might have to resort to using mustache (or any other template system - recommendations welcome) - but I would really like to keep the templating as it is right now, for the aforementioned reasons.

Is Mustache XSS-proof?

I was thinking about my app's XSS vulnerability. On the server side I don't sanitize either input or output, so
<script>alert(document.cookies)</script>
is stored in database exactly so. To view this value on the client side I use Mustache. If this script was executed by an admin, it is of course easy to hijack his session. However I've noticed that Mustache by default escapes these values & \ " < > when you use the {{}} syntax. Do I need to worry about XSS, when the value from the database would be inserted into
<p>{{value}}</p>
or even
<p data-id='{{value}}'>something</p>
? Should I perhaps review my Mustache templates to look for any vulnerable code, or unless I'd use
<script>{{value}}</script>
I am safe?
Well, you should always worry :) But yes, Mustache accomplishes the goal you are talking about here, protecting your examples from XSS (except where you're outputting the value directly into a <script> tag).
Note: check that the Mustache implementation you're using escapes single quotes. It's apparently not in the spec to do so (https://github.com/mustache/spec/issues/69) but the major implementations thankfully escape it anyway.

How do you decide what to use: UDF or Custom Tag?

WACK says:
If you feel you need to have lots of arguments, consider creating a CT instead.
...
CT are significantly more powerful and
flexible than custom functions. Try to
use UDFs for simple matters... Use CT
and Components for more involved
processes, especially those you can
think of as discrete actions rather
than simple "massaging"
Okay, but how are you usually making decisions? Interesting to know real-life practice and examples.
For me it happens when a function has many not-required arguments, so I have to call them myFunc(arg1="foo", arg2="bar"). Sometimes <cfmodule> syntax simply becomes more readable, but not always.
Other reason is that I don't like long (say, more than 2 screens of code) UDFs.
But all these thoughts are very subjective, that's why I'm interested in reading other people opinions. Maybe there's better rules for that?
Thanks in advance.
There a probably plenty of people in the community that would disagree with me, but here is how I generally think about it. If what you need to do involves output to the screen, and if it makes sense to "wrap" this around some other code or text, then a custom tag might be in order. In all other cases a UDF works fine and generally better. That being said, in close to 8 years of CF development, I really haven't ever came across a very good reason for a custom tag. I'm not saying the reasons don't exist, but I would say that they are rare.
If you have a very long UDF, is it safe to assume that this is something where you are outputting to the screen by calling this UDF (not really returning a value I mean)? I would consider breaking that UDF into smaller more manageable parts if that could make sense, but like you are alluding to, what matters in the end is what is the most readable, to you, your team and those who may come after you.
Update: Out of curiosity, which CFWACK book are you referring to (version and volume) and which page?
As I remember things, custom tags can be called at any time, where as UDFs have to be defined before you can use them. This makes custom tags easier generally. If you had huge libraries of UDFs it would be burdensome to make sure they are all included and potentially hard work for the server to parse them all (in olden days at least).
However UDFs can be used in a more compact way
<cfif myUdf(myVariable)>
The advantage of custom tags is that they can sit nicely with your markup.
<h1>Order Page</h1>
<cf_basket_nav>
<ul>
<cfloop ...>
<li>
<cf_basket_item item="#items[i]#">
</li>
</cfloop>
</ul>
</cf_basket_nav>
Generally nowadays I would have a 'utils' CFC with methods for what were your UDFs.
one consideration on the use of custom tags over udfs or cfc methods is when you find that a subroutine needs to be passed an array of child items, you can use nested custom tags to associate a child custom tag and its elements to a parent custom tag. this allows you to do very nice clean coding thats easy to read:
<cfmenubar ... >
<cfloop array="menuitems" ...>
<cfmenubaritem url="#i.url#">
#i.label#
</cfmenubaritem>
</cfloop>
</cfmenubar>
yes,yes i know we have nicer dhtml stuff like menus and tabs, this is simply to point out an example. you can use cfassociate in the custom tag to "pass" the attributes to the parent custom tag and then in the executionmode="end" access all the dynamically generated child items in the array of associated attributes. this is where you would loop and output the menu to the screen in this example.
also, as another commented, allows you to do some clever things... one thing in particular i use is that i set prefix="" and then i can essentially force simple html tags (like the <a> tag) to get kicked through a custom tag handler at runtime - so an html tag becomes intelligent at runtime... i do this so i can analize the href and the target attributes and decide if i want to display a pdf icon (or other mime type icon) next to the link... its pretty slick! this is especially helpful in a content management system or when 7you have html developers using dreamweaver or contribute and you want to have their tags fire smart coldfusion tags without them doing anything outside of standard html - the editor doesnt know any difference and they dont need to go into "code" view to make some fairly powerful functionality.
finally, in a custom tag you can choose to suppress output (or use a cache), so this can be very useful to wrap around chunck of dynamically generated html... access the thistag.generatedcontent variable in the executionmode EQ "end" mode
dont throw out the baby with the bathwater on this one ... i agree their usage is much less frequent since we have cfcs, however there is still some powerful functionality in custom tags... i usually have one or 2 in every application (and at least dozens of cfcs)
hth
jon
cfmodule has no advantage over functions; cfinvoke works just the same.
Of course, with cfimport you can enable a nice tidy namespaced CT syntax - and this is when custom tags are good: when working with clear open/close construct, or if nested logic is important.
For everything else, especially when returning results, functions are easier to handle.
Jeremy pointed to useful option: wrapping HTML by CT. But this feature seems to be so rarely used. Any way, it's a plus for CT.
Also I thought that I prefer function because I love cfscript coding. Few times I had to wrap legacy CT into UDF only to be able to use it at totally cfscript-ed page. It's a plus for UDF.
Simple reusable code can go into a UDF. This might include things like string formatting, data structure manipulation, etc etc.
For anything more complex than that, I would consider using CFCs instead of a custom tag. You'll be able to write much cleaner code in an OO model. You can always wrap the logic in your CFCs with a custom tag if you want to provide ease of use for someone who is more used to working with tags.
Not sure why I fell into this pattern, but in general I use Custom Tags (always with cfmodule) for anything that outputs HTML and UDFs for anything that merely returns simple data/objects. I realize that UDFs can do output as well, but I don't like my functions to have any side effects and this feels like one. For similar reasons, I now use Custom Tags anywhere where previously I would have used a cfinclude, since they provide encapsulation of data.

How do you allow the usage of an <img> while preventing XSS?

I'm using ASP.NET Web Forms for blog style comments.
Edit 1: This looks way more complicated then I first thought. How do you filter the src?
I would prefer to still use real html tags but if things get too complicated that way, I might go a custom route. I haven't done any XML yet, so do I need to learn more about that?
If IMG is the only thing you'd allow, I'd suggest you use a simple square-bracket syntax to allow it. This would eliminate the need for a parser and reduce a load of other dangerous edge cases with the parser as well. Say, something like:
Look at this! [http://a.b.c/m.jpg]
Which would get converted to
Look at this! <img src="http://a.b.c/m.jpg" />
You should filter the SRC address so that no malicious things get passed in the SRC part too. Like maybe
Look at this! [javascript:alert('pwned!')]
Use an XML parser to validate your input, and drop or encode all elements, and attributes, that you do not want to allow. In this case, delete or encode all tags except the <img> tag, and all attributes from that except src, alt and title.
If you end up going with a non-HTML format (which makes things easier b/c you can literally escape all HTML), use a standard syntax like markdown. The markdown image syntax is ![alt text](/path/to/image.jpg)
There are others also, like Textile. Its syntax for images is !imageurl!
#chakrit suggested using a custom syntax, e.g. bracketed URLs - This might very well be the best solution. You DEFINITELY dont want to start messing with parsing etc.
Just make sure you properly encode the entire comment (according to the context - see my answer on this here Will HTML Encoding prevent all kinds of XSS attacks?)
(btw I just discovered a good example of custom syntax right there... ;-) )
As also mentioned, restrict the file extension to jpg/gif/etc - even though this can be bypassed, and also restrict the protocol (e.g. http://).
Another issue to be considered besides XSS - is CSRF (http://www.owasp.org/index.php/Cross-Site_Request_Forgery). If you're not familiar with this security issue, it basically allows the attacker to force my browser to submit a valid authenticated request to your application, for instance to transfer money or to change my password. If this is hosted on your site, he can anonymously attack any vulnerable application - including yours. (Note that even if other applications are vulnerable, its not your fault they get attacked, but you still dont want to be the exploit host or the source of the attack...). As far as your own site goes, it's that much easier for the attacker to change the users password on your site, for instance.