<story><title>How I Learned Enough Ruby On Rails In 12 Weeks To Launch Freelancify</title><url>http://www.webstartup.me/learned-ruby-rails-12-weeks-launch-freelancify</url><text></text></story><parent_chain><item><author>tptacek</author><text>Congrats on the launch. I think I speak for everyone on HN when I say, you&apos;re going about this the right way: learn enough to build applications for yourself, whether or not you&apos;re going to be a code committer over the long term.&lt;p&gt;Can I give you some quick advice? Don&apos;t take this the wrong way: Rails makes it easy to learn enough to be dangerous in 12 weeks. Some quick hits on obvious things you should look over in your application to ensure it isn&apos;t overtly insecure:&lt;p&gt;* Every model class should have an &quot;attr_accessible&quot; statement, and the attributes you expose through it should be minimal. A very common misconception: &quot;the things in attr_accessible are the only attributes users can set&quot;. Not so! The things in attr_accessible are the only attributes users can set &lt;i&gt;automatically, through mass assignment&lt;/i&gt;. You can expose things that aren&apos;t in attr_accessible by manually settings them with assignment statements. Assume anything that&apos;s in an &quot;attr_accessible&quot; list, and &lt;i&gt;every&lt;/i&gt; attribute of a model without attr_accessible, can and will be set to the most hostile possible value, like &quot;role=admin&quot;.&lt;p&gt;* Rails programming intros have a bad habit of introducing ActiveRecord finders in the context of the model class object --- in other words, &quot;Post.find(params[:id])&quot;. This is exactly the wrong way to do it; it&apos;s so bad that you can literally generate a list of vulnerabilities on Rails projects by grepping app/controllers for &quot;[A-Z][a-z]+]\.find&quot;. Instead, make sure all your finders work via associations, like &quot;@current_user.posts.find(params[:id])&quot;.&lt;p&gt;* Use a popular plugin for file uploads. Rails doesn&apos;t do much of anything to defend against file upload/download vulnerabilities. If I was building a public-facing Rails application, I&apos;d do whatever I could to keep the filesystem namespace out of my requests --- storing all files on Amazon S3 without explicitly storing them in temp files is a good way to do this.&lt;p&gt;* Don&apos;t enable the old-style wildcard route (&quot;/:controller/:action/:id) or any of its variants (&quot;/posts/:action/:id :controller =&amp;#62; :posts); whether you declare methods &quot;public&quot; or &quot;private&quot; in a controller should have nothing to do with whether they&apos;re exposed to attackers.&lt;p&gt;* Have a &quot;PreauthController&quot; that inherits from &quot;ApplicationController&quot; and &lt;i&gt;disables&lt;/i&gt; the is-logged-in check; in other words, every controller, particularly every controller generated by &quot;rails generate&quot;, should be post-authentication &lt;i&gt;by default&lt;/i&gt;. Set up the before_filter that checks for a valid user session right there in ApplicationController, then &quot;turn it off&quot; for the LoginController by having it inherit from PreauthController. 
Similarly: if you can get away with not having an AdminController at all --- run a totally separate Rails app for admin that requires a VPN to get to --- do that; otherwise, have an abstract AdminOnlyController class with no methods in it that does nothing but set up a before_filter to check for admin privileges, and have every admin-only controller inherit from it.&lt;p&gt;* Pretend the backtic operator (the one that executes Unix commands) doesn&apos;t exist.&lt;p&gt;You may do all of these things already (in which case, good for you! you learned more in 12 weeks than a lot of Rails developers do in years). I just called them out because (a) not doing them will be tremendously painful down the road (individual XSS slipups are annoying but unlikely to kill you, but vulnerabilities that allow people to dump your whole database are something else) and (b) they are so easy to fix.&lt;p&gt;Good luck!</text></item></parent_chain><comment><author>mhartl</author><text>Teaching good security practices was one goal of the &lt;i&gt;Ruby on Rails Tutorial&lt;/i&gt; (a resource mentioned in the OP). It uses attr_accessible for &lt;i&gt;every&lt;/i&gt; model and uses find-through-association (emphasizing the security implications of both), and it most assuredly does &lt;i&gt;not&lt;/i&gt; use the /:controller/:action/:id pattern or backticks. It punts image upload over to Gravatar, and recommends Paperclip for those who need custom uploads.&lt;p&gt;Having a PreauthController definitely sounds like a good idea, but it might be a bit obscure for beginning developers. I&apos;ll consider it for inclusion as an exercise in one of the chapters covering authorization, or maybe I&apos;ll include it in more advanced &lt;i&gt;Rails Tutorial&lt;/i&gt; material down the road. Thanks for the tip.</text></comment>
<story><title>How I Learned Enough Ruby On Rails In 12 Weeks To Launch Freelancify</title><url>http://www.webstartup.me/learned-ruby-rails-12-weeks-launch-freelancify</url><text></text></story><parent_chain><item><author>tptacek</author><text>Congrats on the launch. I think I speak for everyone on HN when I say, you&apos;re going about this the right way: learn enough to build applications for yourself, whether or not you&apos;re going to be a code committer over the long term.&lt;p&gt;Can I give you some quick advice? Don&apos;t take this the wrong way: Rails makes it easy to learn enough to be dangerous in 12 weeks. Some quick hits on obvious things you should look over in your application to ensure it isn&apos;t overtly insecure:&lt;p&gt;* Every model class should have an &quot;attr_accessible&quot; statement, and the attributes you expose through it should be minimal. A very common misconception: &quot;the things in attr_accessible are the only attributes users can set&quot;. Not so! The things in attr_accessible are the only attributes users can set &lt;i&gt;automatically, through mass assignment&lt;/i&gt;. You can expose things that aren&apos;t in attr_accessible by manually settings them with assignment statements. Assume anything that&apos;s in an &quot;attr_accessible&quot; list, and &lt;i&gt;every&lt;/i&gt; attribute of a model without attr_accessible, can and will be set to the most hostile possible value, like &quot;role=admin&quot;.&lt;p&gt;* Rails programming intros have a bad habit of introducing ActiveRecord finders in the context of the model class object --- in other words, &quot;Post.find(params[:id])&quot;. This is exactly the wrong way to do it; it&apos;s so bad that you can literally generate a list of vulnerabilities on Rails projects by grepping app/controllers for &quot;[A-Z][a-z]+]\.find&quot;. Instead, make sure all your finders work via associations, like &quot;@current_user.posts.find(params[:id])&quot;.&lt;p&gt;* Use a popular plugin for file uploads. Rails doesn&apos;t do much of anything to defend against file upload/download vulnerabilities. If I was building a public-facing Rails application, I&apos;d do whatever I could to keep the filesystem namespace out of my requests --- storing all files on Amazon S3 without explicitly storing them in temp files is a good way to do this.&lt;p&gt;* Don&apos;t enable the old-style wildcard route (&quot;/:controller/:action/:id) or any of its variants (&quot;/posts/:action/:id :controller =&amp;#62; :posts); whether you declare methods &quot;public&quot; or &quot;private&quot; in a controller should have nothing to do with whether they&apos;re exposed to attackers.&lt;p&gt;* Have a &quot;PreauthController&quot; that inherits from &quot;ApplicationController&quot; and &lt;i&gt;disables&lt;/i&gt; the is-logged-in check; in other words, every controller, particularly every controller generated by &quot;rails generate&quot;, should be post-authentication &lt;i&gt;by default&lt;/i&gt;. Set up the before_filter that checks for a valid user session right there in ApplicationController, then &quot;turn it off&quot; for the LoginController by having it inherit from PreauthController. 
Similarly: if you can get away with not having an AdminController at all --- run a totally separate Rails app for admin that requires a VPN to get to --- do that; otherwise, have an abstract AdminOnlyController class with no methods in it that does nothing but set up a before_filter to check for admin privileges, and have every admin-only controller inherit from it.&lt;p&gt;* Pretend the backtic operator (the one that executes Unix commands) doesn&apos;t exist.&lt;p&gt;You may do all of these things already (in which case, good for you! you learned more in 12 weeks than a lot of Rails developers do in years). I just called them out because (a) not doing them will be tremendously painful down the road (individual XSS slipups are annoying but unlikely to kill you, but vulnerabilities that allow people to dump your whole database are something else) and (b) they are so easy to fix.&lt;p&gt;Good luck!</text></item></parent_chain><comment><author>joeag</author><text>Those are awesome pointers - there should be a tool that you could upload all your applications files to, the tool would scan all the files for these errors and return a report on vulnerabilities found and instructions on correcting. Maybe this already exists? I am a beginner programmer as well, making my way through Rails Tutorial (chapter 10) and Learn Ruby the Hard Way (exercise 35) and Codecademy Code year.</text></comment>