<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3417536245318356746</id><updated>2011-07-30T11:42:03.232-07:00</updated><category term='Unicode'/><category term='ruby regex'/><category term='session fixation'/><category term='model security'/><category term='UTF-8'/><category term='rails'/><category term='validations'/><title type='text'>New-school Security Ruminations</title><subtitle type='html'>Security, Ruby on Rails</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://new-school-sec.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3417536245318356746/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://new-school-sec.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Dominique Brezinski</name><uri>http://www.blogger.com/profile/16830317606929397263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://3.bp.blogspot.com/_YJP47ub49Lo/SW0Qaq6JkAI/AAAAAAAAAAM/z9ZcAhhDyMQ/S220/head.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>8</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3417536245318356746.post-112600150434148226</id><published>2008-06-24T14:56:00.000-07:00</published><updated>2008-06-24T15:20:35.530-07:00</updated><title type='text'>An older presentation on a 'new' topic</title><content type='html'>Back in 2005 I gave this presentation at Black Hat Japan:&lt;br /&gt;&lt;br /&gt;http://www.blackhat.com/presentations/bh-jp-05/bh-jp-05-brezinski.pdf&lt;br /&gt;&lt;br /&gt;This year a number of security researchers have done work on the topic and are making the rounds with their presentations.&lt;br /&gt;&lt;br /&gt;Just a few days ago there was a big to do about security vulnerabilities in ruby. The primary vulnerabilities were integer overflows affecting memory allocations in Array and String. However, it was pointed out to ruby-core in early 2006 that integer overflow issues existed in Array and that the memory allocation macros used through out the interpreter code were subject to integer overflows:&lt;br /&gt;&lt;br /&gt;http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/7818&lt;br /&gt;&lt;br /&gt;Great to see the communities getting ahead of the curve :/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3417536245318356746-112600150434148226?l=new-school-sec.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://new-school-sec.blogspot.com/feeds/112600150434148226/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3417536245318356746&amp;postID=112600150434148226' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3417536245318356746/posts/default/112600150434148226'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3417536245318356746/posts/default/112600150434148226'/><link rel='alternate' type='text/html' href='http://new-school-sec.blogspot.com/2008/06/older-presentation-on-new-topic.html' title='An older presentation on a &apos;new&apos; topic'/><author><name>Dominique Brezinski</name><uri>http://www.blogger.com/profile/16830317606929397263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://3.bp.blogspot.com/_YJP47ub49Lo/SW0Qaq6JkAI/AAAAAAAAAAM/z9ZcAhhDyMQ/S220/head.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3417536245318356746.post-2489389900440951669</id><published>2007-05-04T16:39:00.000-07:00</published><updated>2007-05-09T15:11:25.774-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='validations'/><title type='text'>Dynamic attribute validation for forms</title><content type='html'>Developing usable web application is a lot more difficult than many people think. Forms are an obvious point of friction for users, so anything you can do to help get the user through the form successfully is a good thing. One of my applications has a fair amount of restrictions on data that the models will accept (though validation restrictions). Users were frustrated after submitting a form and having it rejected due to failed validations. This presented a couple of challenges.&lt;br/&gt;&lt;br /&gt;-There are a couple of AR models that are updated or created from the form&lt;br/&gt;&lt;br /&gt;-The validation and feedback to the user should occur as each field is entered, and any error messages should be presented close to the offending field&lt;br/&gt;&lt;br /&gt;-The validations on the models are somewhat complex&lt;br/&gt;&lt;br /&gt;Here is a flexible, but somewhat expensive, solution I came up with and plopped in a controller. Substitute the AR models in your application for Model1, Model2, Model3 in the following code:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;private&lt;br /&gt;&lt;br /&gt;  def validate_input_by_model&lt;br /&gt;    error_msgs = Hash::new&lt;br /&gt;    [Model1, Model2, Model3].each do |klass|&lt;br /&gt;      classname = klass.to_s.downcase&lt;br /&gt;      error_msgs[classname] = Hash::new&lt;br /&gt;      if params.has_key?(classname)&lt;br /&gt;        obj = klass::new(params[classname])&lt;br /&gt;        unless obj.valid?&lt;br /&gt;          obj.attributes.each do |k,v|&lt;br /&gt;            if params[classname].has_key?(k)&lt;br /&gt;              error_msgs[classname][k] = obj.errors.on(k)&lt;br /&gt;            end&lt;br /&gt;          end&lt;br /&gt;        end&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;    error_msgs&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;public&lt;br /&gt;&lt;br /&gt;  def validate_field&lt;br /&gt;    if request.xml_http_request?&lt;br /&gt;      error_msgs = validate_input_by_model&lt;br /&gt;      render :update do |page|&lt;br /&gt;        error_msgs.each_key do |classname|&lt;br /&gt;          error_msgs[classname].each do |k,v|&lt;br /&gt;            page.inject_error_msg_if_condition "#{classname}_#{k}", v, v&lt;br /&gt;          end&lt;br /&gt;        end&lt;br /&gt;      end&lt;br /&gt;    else&lt;br /&gt;      render :nothing =&amp;gt; true, :status =&amp;gt; 401&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;An example of the view code:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;% css_form_for :model1, @model1obj, :url =&amp;gt; { :controller =&amp;gt; 'controller1', :action =&amp;gt; 'confirm' } do |@f| %&amp;gt;&lt;br /&gt;  &amp;lt;%= @f.text_field :attribute1, :extra =&amp;gt; 'Required' %&amp;gt;&lt;br /&gt;  &amp;lt;%= validate_remote_by_model 'model1_attribute1' %&amp;gt;&lt;br /&gt;  &amp;lt;% css_fields_for :model2, @model2obj do |@model2_f| %&amp;gt;&lt;br /&gt;    &amp;lt;%= @model2_f.text_field :attribute1 %&amp;gt;&lt;br /&gt;    &amp;lt;%= validate_remote_by_model 'model2_attribute1' %&amp;gt;&lt;br /&gt;  &amp;lt;% end %&amp;gt;&lt;br /&gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The Helper (for the controller associated views) code:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  def validate_remote_by_model(id)&lt;br /&gt;    validate_local_by_regex(id, /^[^&amp;]*$/, '&amp;amp;amp; characters are not allowed. ') + observe_field(id, :with =&amp;gt; ("%s[%s]" % id.split(/_/)), :url =&amp;gt; { :action =&amp;gt; 'validate_field' })&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def validate_local_by_regex(id, regex = nil, error_msg = nil)&lt;br /&gt;    default_regex, default_error_msg = *@@validations[@@validation_mapping[id]]&lt;br /&gt;    regex ||= default_regex&lt;br /&gt;    error_msg ||= default_error_msg&lt;br /&gt;    function = &amp;lt;&amp;lt;-SCRIPT&lt;br /&gt;    if (value.match(#{regex.inspect}))&lt;br /&gt;      { Element.remove('l_#{id}_error'); } &lt;br /&gt;    else &lt;br /&gt;      { var prev_error = document.getElementById('l_#{id}_error');&lt;br /&gt;        if (prev_error != null) {&lt;br /&gt;          Element.update('l_#{id}_error', '#{error_msg}');&lt;br /&gt;        } else {&lt;br /&gt;          new Insertion.Before('#{id}', '&amp;lt;div class=\"field_error\" id=\"l_#{id}_error\"&amp;gt;#{error_msg}&amp;lt;/div&amp;gt;');&lt;br /&gt;        }&lt;br /&gt;      }&lt;br /&gt;    SCRIPT&lt;br /&gt;    observe_field(id, :function =&amp;gt; function)&lt;br /&gt;  end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This code is dense, but the object is to make the view code as simple and clear as possible and still be able to use the pleasant form_for (or css_form_for with plugin) helpers.&lt;br/&gt;&lt;br /&gt;The helper code is knarly, since it is generating javascript, but its functionality is pretty simple. The field text is first check in the browser using a regular expression to screen for ampersands (see post about RoR/prototype issue), and then an AJAX call is made to validate_field sending the field and its value formatted in the standard ROR form syntax. The RoR form parameter syntax is model[attribute]=value. The controller code takes over from there and does its magic to see if the field value will pass validation when applied to the corresponding model. If validation fails and error messages are generated, the errors are passed back to the AJAX code. The javascript then inserts a new element in the DOM that is adjacent to the form field and contains the error message. The new element is updated or cleared based on the response to subsequent calls.&lt;br/&gt;&lt;br /&gt;You can disregard that *@@validations[@@validation_mapping[id]] reference in validate_local_by_regex. It is simply a dictionary of regular expressions and error messages used for other in-browser validations. It is not used in this case.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3417536245318356746-2489389900440951669?l=new-school-sec.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://new-school-sec.blogspot.com/feeds/2489389900440951669/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3417536245318356746&amp;postID=2489389900440951669' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3417536245318356746/posts/default/2489389900440951669'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3417536245318356746/posts/default/2489389900440951669'/><link rel='alternate' type='text/html' href='http://new-school-sec.blogspot.com/2007/05/dynamic-attribute-validation-for-forms.html' title='Dynamic attribute validation for forms'/><author><name>Dominique Brezinski</name><uri>http://www.blogger.com/profile/16830317606929397263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://3.bp.blogspot.com/_YJP47ub49Lo/SW0Qaq6JkAI/AAAAAAAAAAM/z9ZcAhhDyMQ/S220/head.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3417536245318356746.post-305495342868601090</id><published>2007-05-04T13:40:00.000-07:00</published><updated>2008-10-02T11:52:38.618-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='model security'/><title type='text'>Safe model attribute updates using AJAX</title><content type='html'>Sometimes it is nice to have little AJAX click to edit controls that update specific attributes in a model. There are many ways to implement this functionality, some more DRY than others. The code below references an example application that contains users with a corresponding User model. Once authenticated, the user object is stashed in the session. In the following code, current_user references the instance of User for the currently authenticated user. One might be tempted to do the following in the corresponding controller:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  def method_missing(name)&lt;br /&gt;    match = /\Aupdate_([a-z]{1,20})\Z/.match(name.id2name)&lt;br /&gt;    if match &amp;amp;&amp;amp; current_user &amp;amp;&amp;amp; current_user.attributes.keys.include?(match[1])&lt;br /&gt;        if params[:value]&lt;br /&gt;            current_user.update_attribute(match[1],params[:value])&lt;br /&gt;            current_user.reload&lt;br /&gt;            render :text =&amp;gt; current_user.send(match[1])&lt;br /&gt;        else&lt;br /&gt;            render :nothing =&amp;gt; true, :status =&gt; 500&lt;br /&gt;        end&lt;br /&gt;    else&lt;br /&gt;        raise NoMethodError, "undefined method '#{name}'"&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is a good time to point out that care must be taken with the choice of attributes=, update_attribute or update_attributes. attributes= is a good choice, because it pays attention to protect attributes that have been excluded from mass-assignment. Using attr_protected or attr_accessible gives one a consistent mechanism to protect sensitive attributes, which one might assume a user object has. attributes= requires an explicit save call on the object afterwards. update_attribute is probably never a good choice, since it bypasses validations. update_attributes actually just calls attributes= and does the save in one call, so it conforms to the protections provided by attr_protected and attr_accessible. update_attributes is probably the best choice here.&lt;br/&gt;&lt;br /&gt;The best solution is to use the attr_protected or attr_accessible mechanisms in your model to restrict sensitive attributes from mass assignment. Since the following reference code uses update_attributes, your attribute restrictions will apply to this update mechanism:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  def method_missing(name)&lt;br /&gt;    match = /\Aupdate_([a-z]{1,20})\Z/.match(name.id2name)&lt;br /&gt;    if match &amp;amp;&amp;amp; current_user &amp;amp;&amp;amp; current_user.attributes.keys.include?(match[1])&lt;br /&gt;        if params[:value]&lt;br /&gt;            current_user.update_attributes(match[1] =&amp;gt; params[:value])&lt;br /&gt;            current_user.reload&lt;br /&gt;            render :text =&amp;gt; current_user.send(match[1])&lt;br /&gt;        else&lt;br /&gt;            render :nothing =&amp;gt; true, :status =&gt; 500&lt;br /&gt;        end&lt;br /&gt;    else&lt;br /&gt;        raise NoMethodError, "undefined method '#{name}'"&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This code is simplified, since the object we need to reference is readily available in the session hash. If you need to pass an object id, you would need to extend the AJAX call (using the :with option for the JavaScriptMacrosHelpers) to include the id as an additional parameter and retrieve the object in the normal way.&lt;br/&gt;&lt;br /&gt;Notice this code uses update_attributes and constructs a hash of the attribute name and the value.&lt;br/&gt;&lt;br /&gt;In the view, you would have erb such as:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Name: &amp;lt;p id="user_name"&amp;gt;&amp;lt;%= h @current_user.name %&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;%= in_place_editor 'user_name', {:url =&gt; '/user/update_name' } %&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If you feel you need to deviate from the normal attribute protection scheme (you should not as a general principle), then you can do something like this in your model:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  def self.protected_attributes&lt;br /&gt;    ['id','type','salt','hashed_password','verify_code']&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def safe_attribute?(attr_name)&lt;br /&gt;    (self.attributes.keys - User.protected_attributes).include? attr_name&lt;br /&gt;  end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and then add it to your method_missing hook like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  def method_missing(name)&lt;br /&gt;    match = /\Aupdate_([a-z]{1,20})\Z/.match(name.id2name)&lt;br /&gt;    if match&amp;amp;&amp;amp; current_user &amp;amp;&amp;amp; current_user.safe_attribute?(match[1])&lt;br /&gt;        if params[:value]&lt;br /&gt;            current_user.update_attributes(match[1] =&amp;gt; params[:value])&lt;br /&gt;            current_user.reload&lt;br /&gt;            render :text =&amp;gt; current_user.send(match[1])&lt;br /&gt;        else&lt;br /&gt;            render :nothing =&amp;gt; true, :status =&amp;gt; 500&lt;br /&gt;        end&lt;br /&gt;    else&lt;br /&gt;        raise NoMethodError, "undefined method '#{name}'"&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Hooking method_missing is a little dirty. You might actually need to hook method_missing for other (better) reasons. Here is a solution that is dirty in a different way. In the controller:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;private&lt;br /&gt; &lt;br /&gt;  def called_as&lt;br /&gt;    /`([^']*)'/.match(caller[0])[1]&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;public&lt;br /&gt;&lt;br /&gt;  def update_attr_generic&lt;br /&gt;    match = /\Aupdate_([a-z]{1,20})\Z/.match(called_as)&lt;br /&gt;    if match &amp;amp;&amp;amp; current_user &amp;amp;&amp;amp; current_user.attributes.keys.include?(match[1])&lt;br /&gt;        if params[:value]&lt;br /&gt;            current_user.update_attributes(match[1] =&amp;gt; params[:value])&lt;br /&gt;            current_user.reload&lt;br /&gt;            render :text =&amp;gt; current_user.send(match[1])&lt;br /&gt;        else&lt;br /&gt;            render :nothing =&amp;gt; true, :status =&amp;gt; 500&lt;br /&gt;        end&lt;br /&gt;    else&lt;br /&gt;        render :nothing =&amp;gt; true, :status =&amp;gt; 500&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  alias_method(update_name, update_attr_generic)&lt;br /&gt;  alias_method(update_phone, update_attr_generic)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The obvious down side being that you have to create an aliased method name for each attribute you want the ability to update (code generation?). I am jumping through this naming hoop because, by default, the AJAX stuff included in rails likes to post a single parameter (:value) to a named action (commonly :controller/:action). If you modify the AJAX call to send the attribute name and value, or have a more complicated route map and URI, then you can ditch the method name introspection, regular expression and alias_method foolishness and have a single update_attr method. For example (replace ObjModelClass with the model name):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  def update_attr&lt;br /&gt;    obj = ObjModelClass.find(params[:id])&lt;br /&gt;    if obj &amp;amp;&amp;amp; obj.attributes.keys.include?(params[:attrname])&lt;br /&gt;        if params[:value]&lt;br /&gt;            obj.update_attributes(params[:attrname] =&amp;gt; params[:value])&lt;br /&gt;            render :text =&amp;gt; obj.send(params[:attrname])&lt;br /&gt;        else&lt;br /&gt;            render :nothing =&amp;gt; true, :status =&amp;gt; 500&lt;br /&gt;        end&lt;br /&gt;    else&lt;br /&gt;        render :nothing =&amp;gt; true, :status =&amp;gt; 500&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;There you go! A generic attribute updater for a given AR model that adheres to attribute protections placed with attr_protected or attr_accessible. However, you will have to do a little more work in your views to make the AJAX methods pass :id, :attrname and :value parameters to the action. I like to simplify my views, so I often use the dirty, lazy method_missing implementation previously described.&lt;br/&gt;&lt;br /&gt;BTW, these methods respond with the value of the attribute after the update, successful or not. If no value is passed in the parameters, the response is an HTTP error code, which most Javascript AJAX libraries handle OK.&lt;br/&gt;&lt;br /&gt;Another quick point is that this is pretty generic functionality. All the attribute validation and restrictions should be in your models. Models are the object-oriented part of the RoR MVC implementation. Controllers are the procedural part of your application. Keep your controller code simple. If you find yourself duplicating code in controller actions, it probably can be put into a model (one place to fix and DRY). By using update_attributes or attributes=, you leave the security and enforcement in the model where it belongs.&lt;br/&gt;&lt;br /&gt;Go ahead, pick your poison.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3417536245318356746-305495342868601090?l=new-school-sec.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://new-school-sec.blogspot.com/feeds/305495342868601090/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3417536245318356746&amp;postID=305495342868601090' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3417536245318356746/posts/default/305495342868601090'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3417536245318356746/posts/default/305495342868601090'/><link rel='alternate' type='text/html' href='http://new-school-sec.blogspot.com/2007/05/safe-model-attribute-updates-using-ajax.html' title='Safe model attribute updates using AJAX'/><author><name>Dominique Brezinski</name><uri>http://www.blogger.com/profile/16830317606929397263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://3.bp.blogspot.com/_YJP47ub49Lo/SW0Qaq6JkAI/AAAAAAAAAAM/z9ZcAhhDyMQ/S220/head.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3417536245318356746.post-6324203228851171510</id><published>2007-01-31T23:28:00.000-08:00</published><updated>2007-01-31T23:32:52.714-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby regex'/><title type='text'>Speaking of regex and ruby...</title><content type='html'>I came across this link: http://macromates.com/textmate/manual/regular_expressions&lt;br /&gt;&lt;br /&gt;This is a nice summary (with link to original source document) of the regex library used in ruby. Related the UTF-8 regex issues I commented on, the document describes what subset \w actually matches with u extension. It may be out of date (not sure), but it is the most thorough documentation of the ruby regex I have stumbled across.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3417536245318356746-6324203228851171510?l=new-school-sec.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://new-school-sec.blogspot.com/feeds/6324203228851171510/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3417536245318356746&amp;postID=6324203228851171510' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3417536245318356746/posts/default/6324203228851171510'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3417536245318356746/posts/default/6324203228851171510'/><link rel='alternate' type='text/html' href='http://new-school-sec.blogspot.com/2007/01/speaking-of-regex-and-ruby.html' title='Speaking of regex and ruby...'/><author><name>Dominique Brezinski</name><uri>http://www.blogger.com/profile/16830317606929397263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://3.bp.blogspot.com/_YJP47ub49Lo/SW0Qaq6JkAI/AAAAAAAAAAM/z9ZcAhhDyMQ/S220/head.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3417536245318356746.post-3272635972087622002</id><published>2007-01-31T17:38:00.000-08:00</published><updated>2007-05-08T12:03:39.914-07:00</updated><title type='text'>Ugly bug in prototype/rails</title><content type='html'>While testing an app, I just noticed that the observe_field (Form.Element.EventObserver), defined this way:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;new Form.Element.EventObserver('customer_Name', function(element, value) {new Ajax.Request('/foo/validate_field', {asynchronous:true, evalScripts:true, parameters:'customer[Name]=' + value})})&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;passed the value through without any munging, which is then parsed by rails into the params hash. Rails param parsing simply splits on &amp; and seems to take the last assignment, so input something like '&amp;amp;amp;' into an input tag with the name 'customer[Name]' will generate:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Processing FooController#validate_field (for 127.0.0.1 at 2007-01-31 17:58:39) [POST]&lt;br /&gt;  Session ID: 02685db5b8bfde88f7b858eeec0b3a9d&lt;br /&gt;  Parameters: {"action"=&gt;"validate_field", "amp;"=&gt;"", "controller"=&gt;"foo", "customer"=&gt;{"Name"=&gt;""}}&lt;br /&gt;  Customer Columns (0.001306)   SHOW FIELDS FROM customers&lt;br /&gt;Completed in 0.13547 (7 reqs/sec) | Rendering: 0.02115 (15%) | DB: 0.00131 (0%) | 200 OK [http://127.0.0.1/foo/validate_field] &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And input  '&amp;customer[Name]=bar' will generate a request like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Processing FooController#validate_field (for 127.0.0.1 at 2007-01-31 18:16:20) [POST]&lt;br /&gt;  Session ID: 02685db5b8bfde88f7b858eeec0b3a9d&lt;br /&gt;  Parameters: {"action"=&gt;"validate_field", "controller"=&gt;"foo", "customer"=&gt;{"Name"=&gt;"bar"}}&lt;br /&gt;  Customer Columns (0.001054)   SHOW FIELDS FROM customers&lt;br /&gt;Completed in 0.13539 (7 reqs/sec) | Rendering: 0.02108 (15%) | DB: 0.00105 (0%) | 200 OK [http://127.0.0.1/foo/validate_field]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Oops. That is not good. Considering the parameters you hope for would include '"customer"=&gt;{"Name"=&gt;"&amp;customer[Name]=bar"}, but instead you get "customer"=&gt;{"Name"=&gt;"bar"}. The value from the field, when parsed by rails, over-wrote the previously generated customer hash. This has a number of implications:&lt;br /&gt;&lt;br /&gt;- if you are using an AJAX (prototype) methods to validate form field data, input that includes ampersand(s) will have some or all of the string hidden from the receiver. This assumes that the controller method is trying to receive the data to validate from a specific key(s) in the params hash.&lt;br /&gt;&lt;br /&gt;- if you are using AJAX (prototype) methods to receive model-mapped input to update an object, it is possible for someone to piggyback additional attributes (assuming bulk attribute assignment) straight from input fields. No mucking around and hand-crafting a request. Just &amp;amp;model[current_attribute]=data&amp;amp;model[other_attribute]=data_you_did_not_expect. Of course it is still subject to validation and accessible restrictions (you do use those right?). This is not the default BTW. Most of the helpers like observe_field simply send the data from the field as the post body. It will get parsed, and ampersands will cause separate entries in params. It really depends on your expectations and whether you use the :with option to place the data where you expect to find it (or mapped for attribute assignment to an AR object).&lt;br /&gt;&lt;br /&gt;- worse I assume. It really depends on a lot of factors. If your models have all attributes accessible to bulk assignment, you use one or more attributes to store information that is state sensitive and you update attributes on that model using AJAX, you may find yourself in trouble.&lt;br /&gt;&lt;br /&gt;There are a couple ways to code around this issue, but the right one for you depends greatly on your implementation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3417536245318356746-3272635972087622002?l=new-school-sec.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://new-school-sec.blogspot.com/feeds/3272635972087622002/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3417536245318356746&amp;postID=3272635972087622002' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3417536245318356746/posts/default/3272635972087622002'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3417536245318356746/posts/default/3272635972087622002'/><link rel='alternate' type='text/html' href='http://new-school-sec.blogspot.com/2007/01/ugly-bug-in-prototyperails.html' title='Ugly bug in prototype/rails'/><author><name>Dominique Brezinski</name><uri>http://www.blogger.com/profile/16830317606929397263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://3.bp.blogspot.com/_YJP47ub49Lo/SW0Qaq6JkAI/AAAAAAAAAAM/z9ZcAhhDyMQ/S220/head.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3417536245318356746.post-647633661896159622</id><published>2006-12-15T16:38:00.000-08:00</published><updated>2007-05-08T12:04:44.987-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='UTF-8'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='validations'/><category scheme='http://www.blogger.com/atom/ns#' term='Unicode'/><title type='text'>UTF-8, rails vaildations and all that jazz</title><content type='html'>To be honest, it never occurred to me that Ruby did not natively support Unicode given its roots. Alas, Ruby really has no clue about multi-byte character encodings, except Regexp that can handle UTF-8 if the 'u' specifier is used. But wait, given that UTF-8 is the default encoding for XHTML etc., what affect does this have in Rails applications? A lot and not much at all at the same time. Let me explain the little I know about this.&lt;br /&gt;&lt;br /&gt;I ran into this issue on the first rails app I deployed. Even though I had pretty tight validation regexs on my models, every once in a while user provided content would clearly contain Unicode and not display correctly. Damn, that is scary. My validations where not stopping this data from making it into the model. The app served out XHTML 1.0 Strict pages with charaset set to UTF-8. By default browsers POST form data in the same encoding as the page containing the form; In this case UTF-8. All it takes is one cut&amp;paste from MS Office into a form field (think bullet points etc.) to end up with Unicode in the form parameter values. The reason I was ending up with multi-byte values that were not displaying correctly it two-part.&lt;br /&gt;&lt;br /&gt;The more trivial side of the issue is that it turns out Safari has a bug when handling response data from XmlHttpRequest that contains multi-byte encoded characters. This issue is resolved by explicitly setting the encoding on AJAX responses. The more troublesome issue is how the multi-byte characters made it past the validations on the ActiveRecord models. After a little experimentation I came up with this: &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;irb(main):036:0&gt; utf8 = "\342\200\271script\342\200\272"&lt;br /&gt;=&gt; "\342\200\271script\342\200\272"&lt;br /&gt;irb(main):037:0&gt; test_regex = /^[\w]+$/u&lt;br /&gt;=&gt; /^[\w]+$/u&lt;br /&gt;irb(main):038:0&gt; m = test_regex.match utf8&lt;br /&gt;=&gt; #&lt;MatchData:0x348f78&gt;&lt;br /&gt;irb(main):039:0&gt; m[0]&lt;br /&gt;=&gt; "\342\200\271script\342\200\272"&lt;br /&gt;irb(main):040:0&gt; test_regex = /^[-a-zA-Z0-9_.]+$/u&lt;br /&gt;=&gt; /^[-a-zA-Z0-9_.]+$/u&lt;br /&gt;irb(main):041:0&gt; m = test_regex.match utf8&lt;br /&gt;=&gt; nil&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Argh, \w in UTF-8 enabled Regexp matches most, if not all, of the UTF-8 character set above the single-byte encodable ASCII subset. Fortunately, it appears that Ruby's Regexp UTF-8 string handling does not honor overlong-encoded characters, so it appears if you are doing validations that exclude many of the characters generally needed to inject HTML or Javascript, it is unlikely that they can simply be avoided by using overlong UTF-8 encodings. That is good news. However, if multi-byte encoded characters make it into your models and you use methods like sanitize() or h() to do some safety filtering on presentation, don't expect them to do their jobs well.&lt;br /&gt;&lt;br /&gt;In summary, there is potential for some security issues to arise out of acceptance of multi-byte encoded data, but the most straight-forward issues like direct tag and script injection will generally not escape past your input validations. As I research this more, I will keep you posted.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3417536245318356746-647633661896159622?l=new-school-sec.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://new-school-sec.blogspot.com/feeds/647633661896159622/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3417536245318356746&amp;postID=647633661896159622' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3417536245318356746/posts/default/647633661896159622'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3417536245318356746/posts/default/647633661896159622'/><link rel='alternate' type='text/html' href='http://new-school-sec.blogspot.com/2006/12/utf-8-rails-vaildations-and-all-that.html' title='UTF-8, rails vaildations and all that jazz'/><author><name>Dominique Brezinski</name><uri>http://www.blogger.com/profile/16830317606929397263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://3.bp.blogspot.com/_YJP47ub49Lo/SW0Qaq6JkAI/AAAAAAAAAAM/z9ZcAhhDyMQ/S220/head.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3417536245318356746.post-2545778795487803691</id><published>2006-12-14T22:03:00.000-08:00</published><updated>2006-12-14T23:36:46.375-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='session fixation'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Session fixation in Rails</title><content type='html'>If you are not familar with session fixation vulnerabilities, just google it or hit up wikipedia. &lt;br /&gt;&lt;br /&gt;By default Rails supports sessions and uses CGI::Session to handle session management. CGI::Session defaults to setting the session id in a cookie, but it has a backup:&lt;br /&gt;&lt;br /&gt;"If the client has cookies disabled, the session id must be included as a parameter of all requests sent by the client to the server. The CGI::Session class in conjunction with the CGI class will transparently add the session id as a hidden input field to all forms generated using the CGI.form HTML generation method. No built-in support is provided for other mechanisms, such as URL re-writing."&lt;br /&gt;&lt;br /&gt;OK, so there is an avenue to exploit session fixation without having to be able to manipulate cookies (through a client-side vulnerability) in Rails. Hack a little on CGI.form to figure out the parameter name that will make it accept a session id from a form parameter (so the attack would be to modify the form served via an XSS vulnerability or rehost the form in a phish variation). Sessions are on by default in Rails, so we need a to remediate this issue. Here are a couple of options:&lt;br /&gt;&lt;br /&gt;1. Disable session support in your application if you can. It may be a little more of a design challenge, but in some cases you can safely avoid having to maintain state between client and server. Edit app/controllers/application.rb and add "session :off" to it. There you go, sessions are disabled.&lt;br /&gt;&lt;br /&gt;2. OK, you need sessions. Fine. In an app I wrote, there are a few views that are unauthenticated, a bunch of views that are authenticated, a login mechanism and sessions are used to store error/response messages in the unauthenticated views and to hold the user object in the authenticated views. The risk of session fixation in the unauthenticated views in very minimal, but it does give an attacker a very easy mechanism to obtain a valid session id. Once the user is authenticated, knowing the session id provides access as the user, but that is a different issue (session hijacking) assuming we fix session fixation. We really just need to protect the transition for unauthenticated to authenticated by changing the session id on the transition, which is controlled by the login mechanism. The application is largely RESTful, so a GET to /user/login yields the XHTML login form and a POST to /user/login attempts to authenticate the user with the parameter values. In the user controller, I added "session :new_session =&gt; true, :session_expires =&gt; (Time::new + (60 * 60 * 24)), :only =&gt; :login, :if =&gt; Proc::new {|req| req.post? }" The :if parameter provides an anonymous function that checks whether the current request is a POST to be consistent with the REST semantics of user controller actions. The other parameters are self-explanatory. Even if an attacker steers the user to the login view with a know session id, when the user authenticates the session id will change. There you go, authentication yields a different session id.&lt;br /&gt;&lt;br /&gt;For the auditors out there, you should be looking for "session :off" or "session :new_session =&gt; true" that covers the unauthenticated/authenticated transition in those rails apps growing like weeds in your front yard.&lt;br /&gt;&lt;br /&gt;Oh, and I am sure there is a more elegant solution, and with the beauty of rails, I am sure someone will figure out how to package it in a plugin. I also use one-time, time-limited nonces to validate forms were served from the server, but that only hinders the form rehosting (phish) version of the attack (forces the attacker to proxy, a different threat altogether, or periodically re-GET the form, which is generally easy to spot in logs). Dealing with the session fixation issue is still necessary.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3417536245318356746-2545778795487803691?l=new-school-sec.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://new-school-sec.blogspot.com/feeds/2545778795487803691/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3417536245318356746&amp;postID=2545778795487803691' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3417536245318356746/posts/default/2545778795487803691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3417536245318356746/posts/default/2545778795487803691'/><link rel='alternate' type='text/html' href='http://new-school-sec.blogspot.com/2006/12/session-fixation-in-rails.html' title='Session fixation in Rails'/><author><name>Dominique Brezinski</name><uri>http://www.blogger.com/profile/16830317606929397263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://3.bp.blogspot.com/_YJP47ub49Lo/SW0Qaq6JkAI/AAAAAAAAAAM/z9ZcAhhDyMQ/S220/head.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3417536245318356746.post-4074536925763357639</id><published>2006-12-14T22:02:00.001-08:00</published><updated>2006-12-17T14:32:42.832-08:00</updated><title type='text'>Welcome to the New-school</title><content type='html'>I finally decided to contribute something to the global knowledge-base. Whether this something is of interest to you is yet to be determined. You may ask what is the deal with the blog name, so let's start there.&lt;br /&gt;&lt;br /&gt;In the underground, hackers were often referred to as either old-school or new-school, with the latter term being somewhat derogatory. I always considered myself on the cusp. The old-school was long in the tooth when I started hacking freebsd, linux and Windows NT 3.1. Shell accounts on Netcom did not compare to X.25. But I had the old-school ethic and interest, and many of my friends are straight-up old-school: the NWA of globally connected networks. WTF you say? I am getting there--just explaining my relationship with the new-school term.&lt;br /&gt;&lt;br /&gt;The role of a security engineer is rapidly changing. Five to ten years ago, security engineers handled a lot of firewall configuration; IDS deployment; anti-virus; pentesting and in enlightened environments, code review/programmer training. Now, security engineering is moving towards an aspect of, or integral part of, the software development process. I think the following factors are contributing to this change:&lt;br /&gt;&lt;br /&gt;1. For a number of very pragmatic reasons (simplifying operations and responsibility, improved product knowledge, easier to configure products with better defaults, device-ifying of many things), much of the network side of security engineering has moved into network engineering. Any product company building a networking device with security functionality should be expecting it to be managed by network engineers. Network engineers are, in the end, responsible for the network infrastructure, and if packets flow through it, it is part of the network infrastructure. Having split-responsibility for networking devices complicates trouble-shooting and increases MTTR.&lt;br /&gt;&lt;br /&gt;2. In-house software development is rapidly increasing as many business leverage the internet for some or all of their revenue stream. I worked at Amazon.com for a total of three years, and it may come as a shock to hear that Amazon largely considers itself a software platform development company. Simply put, Amazon's software platform enables its revenue stream, and Amazon's ability to be agile with regard to features and platform direction is critical to its success. Amazon is an internet company, but not only internet companies are highly dependent on software agility. The financial industry stands on the cutting edge of computing and software development. And software product companies have taken notice; look at Microsoft. What does this have to do with security engineering? If you have been paying any attention to the security space, you have witnessed the rise of the application-level vulnerability. Core OS network-connected services where once the focus of vulnerability research. If one thing was learned about security, it was that only the necessary services should be exposed externally. Indeed, the average company has a radically improved external security posture with regard to exposed services. What is left? Web applications springing up like weeds and the SOA offerings coming online. Of course there is also the core software these applications depend on, going all the way down to the OS (and beyond).&lt;br /&gt;&lt;br /&gt;Where should the focus of security expertise be applied? It does not take a genius to figure that it is better to build security in than try to bolt it on, hence the re-focus of security engineering towards the software development process. This brings us to the new new-school.&lt;br /&gt;&lt;br /&gt;Some of the old-school are not all that prepared for the new new-school, while others are deeply thankful to finally start working on the real security problem: design and implementation of software, hardware and everything inbetween. Design and implementation baby. Yeah, now we are talking. Well, sort of. I also have another little bias that is a love of dynamic programming languages. To some of the old-school, dynamic programming languages are considered toy-like, suitable for scripting at best, near sacrilegious, dangerous and should be exercised from real programs. Not in this new new-school; we are all over this dynamic programming language sh*t and intend to use it for everything we can get away with.&lt;br /&gt;&lt;br /&gt;There you go. This blog is about security as part of software design and implementation with a bent on dynamic programming languages. It actually just might be a place that I jot down little things I notice and learn while hacking Ruby on Rails apps, but I don't know if that is enough for a BLOG, so I will pretend the scope is big and worthy of notice. Time for me to shut up and add some real content.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3417536245318356746-4074536925763357639?l=new-school-sec.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://new-school-sec.blogspot.com/feeds/4074536925763357639/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3417536245318356746&amp;postID=4074536925763357639' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3417536245318356746/posts/default/4074536925763357639'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3417536245318356746/posts/default/4074536925763357639'/><link rel='alternate' type='text/html' href='http://new-school-sec.blogspot.com/2006/12/welcome-to-new-school.html' title='Welcome to the New-school'/><author><name>Dominique Brezinski</name><uri>http://www.blogger.com/profile/16830317606929397263</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='27' src='http://3.bp.blogspot.com/_YJP47ub49Lo/SW0Qaq6JkAI/AAAAAAAAAAM/z9ZcAhhDyMQ/S220/head.jpg'/></author><thr:total>0</thr:total></entry></feed>
