Sending Ruby to the jail: an attemp on a Haml Safemode

posted: February 17th, 2008 · by: Sven

in: Programming · tagged as: , , , , ·  20 comments »

For my intial speculations about the feasibility of a Haml safemode as an alternative for Liquid I got a bold 'No!'.sub(/o/){|c| c * 46} by Ryan Davis. Ouch! Also, Peter Cooper initially commented rather sceptically …

You guys were right that my first thoughts didn’t go far enough with just looking for certain syntax node types. But hey! There’s still hope. :)

In the meantime I’ve implemented an experimental attemp on a safemode plugin for Haml which takes a bit different approach and certainly does more to get its job done better.

Find the code here: http://svn.artweb-design.de/stuff/rails/haml_safemode.

So how does this work?

Basically I’ve switched to an approach where the “precompiled” Ruby code from a Haml template gets parsed (using ParseTree and Ruby2Ruby) and all method calls get “jailed” with only whitelisted methods allowed (think: Rails blankslate plus methods access control).

For example the code:

@article.title.upcase

in a Haml template would be converted to this:

@article.to_jail.title.to_jail.upcase

The method to_jail wraps the returned objects into Jail instances which are proxy objects with almost all methods removed. These proxies allow access only to whitelisted methods and raise an exception if someone tries to access something else. To instantiate this object it looks for a class Jail within the object’s class’ namespace (e.g. Article::Jail).

So, to actually allow to do something useful in Haml templates these Jail subclasses have to be implemented for an application’s models. (I.e. this is basically Liquid’s concept of so called drops.) For most of Ruby’s native classes like String, Fixnum, Array, Hash etc. the plugin will do that for us (see this file for a list of methods that will be allowed for certain native Ruby classes).

Also, the resulting Ruby code will be evaluated with a ScopeObject’s binding which shares the same blankslate-like base class with the jails. This object forbids access to almost everything but additionally passes calls to Rails helper methods back to the ActionView instance. So we can use helpers, too.

Compared to Liquid jails play the role of drops (I chose a different name to avoid any name clashes). Liquid’s filters actually become obsolete as they essentially play the role of calling methods on objects (e.g. formatting a date) which we can do in native Ruby here.

Because Haml uses Rails’ “compiled templates” architecture all the ParseTree parsing and Ruby2Ruby re-assembling only takes place once when the template is “compiled”. The result will be cached in memory and reused for subsequent requests.

Thus I wouldn’t be surprised when this Haml Safemode actually proves faster compared to Liquid which (unless I’m totally mistaken) does it’s RegExp work each and every time when the template gets rendered.

Now what?

So, this approach should be rather restrictive than permissive. All attack vectors I could think of pass the tests (i.e. they raise an exception). But of course I’m not sure whether it’s already waterproof.

I am by no means a security expert and definitely lack some “black creativity”. So I need your help with this!

Like I said, this code is highly experimental. Do not rely on it or use it for any serious purpose beyond playing with it, yet!

That said, this code is experimental :)

Please do experiment with it!

Check it out, hammer it with all your evil creativity and try to find any working attack vectors. I totally lack this kind of skill, so I’m sure there’s something to improve.

Many thanks to Peter Cooper who was so kind to already (briefly) review the code to catch any obvious bugs and check out the test cases.

Leave a comment

20 Comments

  1. Tiago Bastos said February 18th, 2008 at 01:11 PM  

    Nice work!

  2. rewt said February 19th, 2008 at 04:29 AM  

    wrwf

  3. Eric Hodel said February 21st, 2008 at 10:41 AM  

    What is ruby2rubypatch.rb about? Why isn’t processcall overridden in Haml::Safemode::Parser?

  4. Sven said February 21st, 2008 at 12:30 PM  

    Hi Eric,

    ruby2ruby_patch.rb splits up process_call into several more fine-grained methods (to avoid the need of overwriting the whole, pretty long method). One of these (process_call_receiver) is then overridden in Haml::Safemode::Parser. So, in effect, process_call actually is modified in the parser (it prepends the call to to_jail to the call receiver).

    Does that answer your question?

  5. Eric Hodel said February 21st, 2008 at 07:44 PM  

    You haven’t avoided overwriting Ruby2Ruby#process_call, you’ve explicitly overwritten it, just in a different file and class.

    It would be better to pull the whole thing down into your subclass so you don’t pollute the namespace of other users of Ruby2Ruby.

  6. Sven said February 21st, 2008 at 10:12 PM  

    Hi Eric,

    depends how you look at it. If this change would go into Ruby2Ruby I wouldn’t. ;)

    You’re right that things didn’t make a lot of sense the way they’ve been. I’ve moved that stuff to the parser class.

    Thanks for the suggestion.

  7. Peter Cooper said February 23rd, 2008 at 04:36 PM  

    You need to comment out:

    require ‘ruby2ruby_patch’

    in the test initializer, since it isn’t in the repository anymore.

  8. Sven said March 3rd, 2008 at 08:20 PM  

    Hi Peter,

    thanks for the catch. I’ve just done that. Also, I’ve added a MIT license.

  9. Flurin said March 11th, 2008 at 08:24 AM  

    Hi Sven,

    How is the progress on haml_safemode? I’m very interesting in doing a similar thing with the precombiled ruby code ERB generates.

    Did your approach hold against the various “attacks”?

    Flurin

  10. Sven said March 12th, 2008 at 02:07 AM  

    Hi Flurin!

    Actually there hasn’t been too much process. Neither attacks I would have learned of. Maybe that’s a good sign as this article has received quite some attention. But maybe it just means that nobody cared enough to really check things out.

    I’ve had some conversation with Peter though regarding using it for ERB (and pretty much any Ruby eval). This most probably will raise some more attention and … hopefully … testing.

    If you’re interested in getting involved into this, please drop me a note by email.

  11. refinance said May 9th, 2009 at 01:53 AM  

    what is loans? :)

  12. money said May 9th, 2009 at 03:11 PM  

    what is finance? :)

  13. Andrew Townley said November 27th, 2009 at 07:42 PM  

    Hi Sven,

    This is really interesting as I’m looking at doing some dynamic templating in a web application as well. However, it doesn’t use precompiled templates. Basically, in order to make it work the way it needs to, it does instance_eval because these are really like macros as far as the application goes. Since the possibility of certain users to edit them is a requirement, your solution seems quite intriguing.

    Did you and Peter take this further? If not, what would it take to move your conversation forward? I’m going to need this in the near future, and I’d like to avoid reinventing the wheel. I’ll send you an email as well.

    I’ll grab the code and see if I can figure out how to integrate it into what I have. I’m not using Haml or anything else. I just need this kind of functionality applied to arbitrary strings of ruby code.

    It would be very interesting to know the limits of an approach like this.

    Thanks for the post! :)

    Cheers,

    ast

  14. Tyler Rick said January 1st, 2010 at 01:35 AM  

    This looks very interesting indeed. I wish there were more exposure for this and more people out there using and talking about it.

    I’m looking at options for making parts of a site editable… Since I’m already using HAML for my templates, I’d hate to have to install Liquid in addition to HAML just for this purpose, especially given HAML’s superior syntax (although I have to wonder if non-programmers will appreciate/understand HAML’s syntax?).

    Anyway, hopefully I’ll get a chance to take a closer look at this soon…

  15. jack said January 23rd, 2011 at 10:44 AM  

    Like many others, I’ve set up Nginx to serve cached pages. Those requests never reach my Mongrels. What then? cheap vps

  16. ddsgd said March 21st, 2011 at 06:27 AM  

    How to Convert AVCHD films to AVI

    URL?http://www.wondershare.com/avchd/convert-avchd-to-avi.html Troubles we may possibly have encountered to take satisfaction in and reveal AVCHD films with friends:

    1. You have shot lots of films utilizing AVCHD camcorder, and you also need to upload these films to internet that consist of Youtube to reveal with friends, but you can’t determine the right way to create it.
    2. you could possibly also uncover which you would not possess the ability to available your AVCHD camcorder films on house windows film maker or advertising player.

    That’s true, the AVCHD structure is not accepted by lots of players, and also this kind of structure cannot be uploaded to internet which prevents film sharing. I’ve searched near to some great offer and uncover an simplest alternative finally. The simplest way can be to convert avchd to avi or other standard formats.

    The alternative we are able to consider to solve them: An AVCHD to AVI Converter is needed. Please click to obtain avchd to avi converter, set up and run it. Step one Get AVCHD films from AVCHD Camcorder to PC

    Connect the AVCHD Camcorder for the PC using a USB cable. when attached and powered on, the camcorder should seek out the desktop like a brand brand new disk. It is desirable which you duplicate the films for the PC’s hard-drive earlier to converting avchd to avi or editing it. Step 2. fill AVCHD camcorder videos

    Click “Add Video” or just drag & squirrel away your AVCHD camcorder films using the document checklist directly, you can very easily include AVCHD camcorder videos.

    Load AVCHD camcorder videos Step 3. find AVI as output format

    Select AVI as output structure away from your categorized output formats checklist in “Profile” drop-down checklist and specify the output list to preserve your converted records in “Output” drop-down list.

    Select Convert AVCHD films to AVI output format Step 4. start to convert avchd to avi

    After every little thing is done, strike “Start” key to convert avchd to avi. And all the things can be achieved at quickly demand and higher quality. The conversion demand often is dependent for the genuine film sizing as well as your PC configuration. as well as the output best quality is great.

    After converting avchd to avi, now you can upload these AVI films to internet or view them with house windows advertising Player/Movie Maker to reveal them jointly with your friends. The complete method is easy, and you also can possess a try of the AVCHD to AVI Converter to how to convert avchd to avi and reveal your delighted instant easily.

    Tips: Why we choose AVI format? As we realize that AVI structure is among the probably the most standard formats, that is broadly accepted by the majority of players. as well as the best quality of AVI film is great. using the sake of reputation and compatibility, AVI is regarded as probably the most advantageous choice. Therefore, you only should convert AVCHD to AVI, after which you can very easily reveal your AVCHD camcorder videos.

  17. Okey oyunu said May 12th, 2011 at 03:40 PM  

    Tüm dünya artik okey oyunu oynuyor. Yillardir bir çok oyun programi olmasina ragmen, içlerinden en güzeli olarak nitelendirebilecegimiz tek bir site göze çarpmaktadir. Diger tüm okey oyunu programlarinin aksine ücretsiz olmasi ve 3 boyutlu olarak hizmet vermesi mükemmel bir gelismedir. Sizlerde www.okey-oyunu.com adresinden bu essiz okey oyununu indirebilirsiniz. Kullanimi çok basit ve Türkçe dil seçenegi ile kolaylikla oyuna baslayabilirsiniz. Ister kendi ülkenizden, isterseniz dünyanin tüm farkli bölgelerinden dilediginiz oyun odalarini seçerek, oyuna hemen baslayabilirsiniz. Okey oyunu oynamak için artik arkadas bile aramaniza gerek kalmadan, bilgisayarinizdan 100 binlerce üye ile online olarak okey oyununu oynamanin zevkine varabilirsiniz.

  18. Hanns said May 13th, 2011 at 01:28 PM  

    As always thanks for the great article and I hope Im allowed to quote or use certain sections of this on my own website. Hanns at spill pallets

  19. porno said May 22nd, 2011 at 01:37 PM  

    I do agree with all of the ideas you have presented in your post. They’re really convincing and will definitely work. Still, the posts are too short for newbies. Could you please extend them a bit from next time? Thanks for the post.

  20. porno said May 23rd, 2011 at 10:44 AM  

    good comment. thanks you friends.

    I’ve surfed the net more than three hours today, however, I haven’t found such useful information. Thanks a lot, it is really useful to me

Sorry, comments are closed for this article.

artweb design
Sven Fuchs
Grünberger Str. 65
10245 Berlin, Germany


http://www.artweb-design.de

Fon +49 (30) 47 98 69 96
Fax +49 (30) 47 98 69 97