Re: Xss library

89 views
Skip to first unread message

James Reeves

unread,
Apr 24, 2013, 5:52:48 PM4/24/13
to ring-c...@googlegroups.com
What do you mean by "call functions only when the data is being output"?

Could you provide some sort of an example to illustrate what you mean?

I'm also uncertain why you'd expect XSS attacks to come from data in the session store. That seems somewhat unusual.

- James


On 24 April 2013 22:03, code dreamer <mikem...@gmail.com> wrote:
I'm trying to create a library to help with XSS (escaping input) in ring based projects.

I've looked at some solutions so far and I haven't seen anything where you set it and forget it, or don't have to worry about it at all.  Most solutions require manually escaping.

I want to create something like rails where escaping is done for you.  I feel like doing it manually can lead to problems that I would rather avoid.  

The approach I have so far, is just a function that allows you to escape through a map using whatever function you want to escape with.  Each value can have a specific escaping function (aside from default).

This approach can be used in situations where you would apply it when you call session map, right before you start using it's values.

My question is, using middleware is there a way that I can call functions only when the data is being output?  

Basically, I don't want to affect the values before they are stored in whatever session store.

Are there any better XSS (escaping) options available, or does anyone have any suggestions for this library?

Thanks.

--
You received this message because you are subscribed to the Google Groups "Ring" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ring-clojure...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

code dreamer

unread,
Apr 24, 2013, 11:49:53 PM4/24/13
to ring-c...@googlegroups.com, ja...@booleanknot.com
I apologize for the confusion. I'm just starting to learn ring development.

As I understand, sessions in ring can use different store options such as the database.  Xss should be: validate on the way into the database, escape on the way out.

I wan't to use my escape function on the way out, and not affect the data on the way into the session store (database).  

Normally, your template library will accomplish this, but currently there's nothing that does it automatically.

Is there a way using middleware that allows me to escape the data, and not affect the data before it goes into the database (only after)?

James Reeves

unread,
Apr 25, 2013, 6:43:00 AM4/25/13
to ring-c...@googlegroups.com
You can use different session stores to save session data in a variety of places, but where session data is stored has no effect on whether or not it's vulnerable to a XSS.

A XSS occurs when you insert data from a user onto a HTML page without escaping it first. Usually the session store just contains some reference to the logged in user, such as their ID, and this is only ever accessed internally.

Storing user data in the session that you'll later insert into a HTML page is unusual, and I'm not sure why you'd want to do it...

In any case, XSS protection should be orthogonal to the session.

- James

code dreamer

unread,
Apr 25, 2013, 10:38:09 AM4/25/13
to ring-c...@googlegroups.com, ja...@booleanknot.com

I just used session as an example, because I figured it to be the best place for the middleware.
When I used mongostore as my session store, everything I put into the ring session was put into the database. 

Is it not suppose to work like that?

I used session as an example because of the interaction with the database.

If it is suppose to work like that, in the session you can enter different types of information.  If you have a cookie store, you will probably only enter a ID, not personal information.  However, if I use a database session store I can store any information about that user, because it's not available to the client.

Some information may be copied from the user's (table/document) into the session (table/document), and used from there to reference the user from then on.

Knowing that information is coming from the database, I'm now at a point where I'm about to insert that data into some page to display to the user.  Right before I put it on the page I want to escape it.

In any case, I only used session as an example.  

I'm just trying to see if there's some automated way to perform escaping because I don't think manual escaping is the best way.  Without control over template libraries, I just though maybe some way in middleware.

What do you think the best approach is? 

Thanks 

James Reeves

unread,
Apr 25, 2013, 11:16:20 AM4/25/13
to code dreamer, ring-c...@googlegroups.com
On 25 April 2013 15:38, code dreamer <mikem...@gmail.com> wrote:

If it is suppose to work like that, in the session you can enter different types of information.  If you have a cookie store, you will probably only enter a ID, not personal information.  However, if I use a database session store I can store any information about that user, because it's not available to the client.

Sessions only hold temporary information, no matter whether they are stored in a database or encoded directly in an encrypted cookie. When a user logs out or switches browser, any information in the session is lost.

Typically you store data about a user in a database, and use sessions just to keep track of the user's ID.
 
I'm just trying to see if there's some automated way to perform escaping because I don't think manual escaping is the best way.  Without control over template libraries, I just though maybe some way in middleware.

What do you think the best approach is? 

I don't think middleware is the best approach, because by the time you've generated the response it's usually to late. XSS protection is typically down to your template layer.

One option is to create a wrapper around your template function that automatically encodes any parameters you pass into it. For example:

    (defn template [func & args]
      (apply func (map escape-html args)))

Another possibility is to use some sort of custom container around user data so you always need to explicitly escape it.

- James

Nelson Morris

unread,
Apr 25, 2013, 11:31:56 AM4/25/13
to ring-c...@googlegroups.com
There are a number of templating libraries for clojure, some of which do escaping automatically.

Non-escape by default:

hiccup

Escape by default:

laser
enlive (through net.cgrand.enlive-html/content)
stencil (or any other spec compliant mustache template lib)
clabango


I have a mokeypatching-esque hack on hiccup that turns it into escape by default at https://github.com/ato/clojars-web/blob/master/src/clojars/web/safe_hiccup.clj. I have plans to properly package and release something similar as a fork, but its been low priority since I've been using laser recently. Note: using it by copying that file might require rewriting some hiccup macros to use (raw ...), similar to `html5` there.  Also, I've not tested the performance implications of this beyond saying it was good enough for the purposes needed.


Only a subset of user input comes from places a middleware could escape before getting to the route functions. I suppose you could attempt to have a middleware do the rendering and escape then. Assuming you are using hiccup, it might be possible to write your routes in a way that they return hiccup vectors in a ring response key. Then have a middleware that walks the hiccup vector tree and does escaping on any strings and renders to :body.  I've only given this a quick thought, so there might be something problematic about the hiccup structure, such as the `html5` macro, though perhaps that portion is best done by the middleware after escaping.

I've done something similar in a project with laser for layouts. The routes return a response with a partial template and a middleware lookups a layout, inserts the partial template, and finishes rendering.

-
Nelson Morris

code dreamer

unread,
Apr 25, 2013, 11:49:36 AM4/25/13
to ring-c...@googlegroups.com, code dreamer, ja...@booleanknot.com
Thanks for your help.

I will look to implement your template wrapper suggestion.

Here what I have so far 


The html-escape function can just take a user-map from the database and escape the values. 
However, I would still have to put it into each db call.

I will look more into the template wrapper idea.

code dreamer

unread,
Apr 25, 2013, 11:58:03 AM4/25/13
to ring-c...@googlegroups.com
I do use hiccup, so I guess that's why I'm looking for a solution.

Nelson Morris, thanks for the different options.  I'm tempted to just use a html5 hiccup macro similar to yours.
I will look into some more options but they will probably remain in the template layer, because that's where I think it should be.

Thanks for the help.
Reply all
Reply to author
Forward
0 new messages