Showing posts with label cktricky. Show all posts
Showing posts with label cktricky. Show all posts

Friday, April 12, 2013

Rails - Guard, Brakeman, and Bundler-Audit

Thanks to the efforts of Justin Collins (@presidentbeef - Brakeman)  and Hal Brodigan (@postmodern_mod3 - Bundler-Audit), Rails developers (and Sinatra) can use these two tools in tandem with Guard to protect their applications while under development. For those who aren't familiar, Guard was designed to run while you are developing, when you save a file it triggers Guard to run whatever tests you've specified in your Guardfile.

The following video depicts this.

Wednesday, April 10, 2013

Bundler-Audit -> Auditing your RubyGems

Ruby applications that utilize a Gemfile/Gemfile.lock, file(s) that contain the list of ruby gems an application should use along with their respective version number, can now be audited to determine if those libraries are vulnerable.

Credit to postmodern for developing the auditing gem and also to RubySec for creating the ruby-advisory-db, a community maintained database of Ruby gem vulnerabilities for which bundler-audit is built on top of. 

So to install this - 

gem install bundler-audit

to run it, navigate to the directory where the Gemfile.lock is stored:

bundle-audit check

If the application is using a vulnerable version of a gem, the output will look like...
















Thanks,

Ken (@cktricky)











Tuesday, April 9, 2013

Quick way to view ruby gems


This post is a very short and very simple tip for easily opening a ruby gem up for closer inspection.

When reviewing a Rails or Sinatra application (code review), it sometimes becomes necessary to view the libraries (ruby gems) that an application is including and using. Instead of navigating to the ~/.rvm/gems/<version>@<gemset name>  directory (or wherever else the gems are stored) and opening them with your text editor of choice, you can instead leverage the power of bundler.

For your *nix based systems that leverage a bashrc, bash_profile, etc.

open your ~/.bash_profile file (or whatever the appropriate bash file is)

add this line export BUNDLER_EDITOR=mate

I chose "mate" because I use TextMate. Otherwise, just link to the appropriate editor executable.

(exit and save bash_profile)

type: source ~/.bash_profile

Then, navigate to an app that contains the Gemfile, and switch to the gemset or ruby version where these gems are contained, and choose a gem that you want to open...

bundle open <gem name>

That's all there is to it.

Ken (@cktricky)

Monday, December 31, 2012

Basics of Rails Part 5

If you'd like to skip coding this up or are having issues, you can find the application source code here.

To start at the code which represents the completion of Parts 1-5, do the following:

$ git clone git://github.com/cktricky/attackresearch.git

$ cd attackresearch/

$ git reset --hard 3c3003d0b087d64f60446f74bcb2deedca60691f

$ bundle install

$ rake db:create db:migrate unicorn:start[4444]

=========== Part 5 Code and Walkthrough ==============

The first thing we need to do in this post is correct a mistake in the last post.

Type the following to change the model "Users" to it's singular form "User". If you don't, it will cause problems with Rails routing.

$ rails d model Users

$ rails g model User first_name:string last_name:string email:string password_hash:string password_salt:string admin:boolean

$ rake db:drop

$ rake db:create

$ rvmsudo rake db:migrate


Also, a small but important detail, please ensure within your Gemfile you change:

gem 'bcrypt-ruby', '~> 3.0.0' 

to

gem 'bcrypt-ruby', '~> 3.0.0', :require => 'bcrypt'


Now........back to the series. So, we last left off where a login page was visible when browsing to your site but it didn't really do anything.  Time to rectify that.

Within the Sessions controller, a create method was defined and in it we called the User model's method, "authenticate". We have yet to define this "authenticate" method so let's do that now.

Located at /app/models/user.rb

Also, we are going to add an encrypt method and call it using the "before_save" Rails method. Basically, we are going to instruct the User model to call encrypt_password when the "save" method is called. For example:

me = User.new
me.email = "test@ar.com"
me.password = "test"
me.password_confirmation = "test"
me.save <~ at this point, any "before_save" methods get called

So when you see something like user = User.new and user.save you know that the encrypt_password method will be called by Rails prior to saving the user data because of the "before_save" definition on line 4.


Now we have to add a few more things:

attr_accessor :password

validates_confirmation_of :password
validates_presence_of :password, :on => :create
validates_presence_of :email
validates_uniqueness_of :email

These are basically Rails validation functions that get called when attempting to save the state of an object that represents a User. The exception being "attr_accessor", which is a standard Ruby call that allows an object to be both a getter & setter.

Okay, now let's see what it looks like.


Alright, so now we have a login page that does something but we need to create users. For this application's purpose, we are going to allow user's to signup. Let's provide a link for this purpose on the login page and even further, let's create a navigation bar at the top. We want this navigation bar visible on every page visited by the user. Easiest way to do that is to make it systemic and place it within the application.html.erb file under the layouts folder. Unless overridden, all views will inherit the properties specified in this file (navigation bar, for example).


Located at /app/views/layouts/application.html.erb

Without explaining all of Twitter-Bootstrap, one important thing to note is the class names of the HTML tags (ex: <div class="nav">) are how we associate an HTML element with a Twitter-Bootstrap defined style.

The logic portion, the portion that belongs to Ruby and Rails, are Lines 13 -18. Effectively we are asking if the user (current_user) visiting the page is authenticated (exists), if they are (do exist), show a link to the logout path. Otherwise, render a login and signup path link.

You are probably wondering where link_to and current_user come from. Rails provides built-in methods and you'll notice, in the views, they are typically placed between <%= and %>. So, link_to is a built in method. However, current_user is defined by us within the application controller and is NOT a built-in method.

Located at /app/controllers/application_controller.rb
Notice on line 8 we define a method called current_user. This pulls a user_id value from the Rails session. In order to make the current_user method accessible outside of just this controller and extend it to the view, we have annotated it as a helper_method on line 4.

The next thing we need to do now is actually make the signup page. First, let's modify the attributes that are mass assignable via attr_accessilbe in the user model file.



Next, review the users_controller.rb file and add the methods new & create. When new is called, instantiate a new blank User object (@user). Under the create method, we can modify a new user element leveraging the parameters submitted by the user (email, password, password_confirmation) to create the user. 



Explanation of the Intended Flow - 

  • User clicks "signup" and is sent to /signup (GET request). 
  • User is routed to the "new" action within the "user" controller and then the HTML content is rendered from - /app/views/users/new.html.erb. 
  • Upon filling in the form data presented via new.html.erb, the user clicks "submit" and this data is sent off, this time in a POST request, to /users. 
  • The POST request to /users translates to the "create" action within the "user" controller. 


Now, obviously we are missing something.....we need a signup page! Let's code that up under new.html.erb.


/app/views/users/new.html.erb

The internals of Rails and how we are able to treat @user as an enumerable object and create label tags and text field tags might be a little too complicated for this post. That being said, basically, the @user object (defined in the User controller under the new action - ex: @user = User.new) has properties associated with it such as email, password, and password confirmation. When Rails renders the view, it generates the parameter names based off the code in this file. In the end, the parameters will look like something like user[email] and user[password_confirmation], for example. Here is what the actual request looks like in Burp...


Signup form generated by the code within /app/views/users/new.html.erb

Raw request of signup form submission captured.

Okay, so, now we have registered a user. The last piece here is to have a home page to view after successful authentication and also code the logout link logic so that it actually does something.

In order to do this, let's make a quick change in the sessions controller. Under the create method, we change home_path to home_index_path as well as create a destroy method which calls the Rails method "reset_session" and redirects the user back to the root_url. Also, remove the content within the index action under the home controller.

Okay, here is what I mean...

Session Controller - Note changes on Lines 9 and additions on Lines 16-19.

Home Controller - Note that the code contained within the index action has been removed.
You should be able to complete the authentication flow now! Stayed tuned for Part 6.

Note: If you see any security holes in some of the code shown in this series please remember that's kind of the point and refrain from commenting until later.

Tuesday, October 30, 2012

Basics of Rails Part 4

In this portion of the series, we will create the foundation for a login page and deal a little bit more with the Model portion of MVC.

We need to be able to assign the following information to a user.
  • First Name
  • Last Name
  • Email Address
  • Password
  • Admin (true/false)
This is where the Model comes in. Before we jump into that, let's create a Users controller similar to the way we create a Home controller in the last post.

Note that the "new" following Users simply states that a "new" action (method) will be automatically defined in the controller for you. 
Also, we should briefly cover how you connect to a database with Rails. In this tutorial, we will stick with the default configuration/database, SQLite. Navigate to config/database.yml:


If you remember Part 2 of the series, we covered the 3 default modes of Rails. This is the reason there are 3 different database configurations in this file. It is useful as your local development environment database will differ from Production (ex: database username, password, and host would/should be different).

When we are running in development mode, the database we will be using will be db/development.sqlite3 as specified on line 8. The naming convention refers to it's location and filename.

So nothing really to change there, let's go ahead and create the model.


Command(s) Breakdown:
  • rails - Invoking a Rails command
  • g - Short for generate, used to generate Rails items
  • model - specifies that we are generating a model
  • Users - the name of the model which, actually refers to both the model (app/models/users.rb) and a table in the database
  • first_name:string (etc.) - The first portion is the name of the column in the table and the second part (string) identifies the variable type to be stored in the database.
Now, upon generation, the model is created but the db table/columns do not yet exist. To make this happen, let's run rake db:migrate.


To give you a visual of what was just created...

Note the table "users" has been created along with the columns we identified during model creation.
This is great and later if you'd like to add an additional column to your local db, you can. What if you'd like to add a column so that the next person to download your code and run rake db:migrate also has the new column? Navigate to db/migrate/ and you'll see a file that ends in _create_users.rb. This is where you would make that change. Do NOT edit the db/schema.rb file for that purpose (this is overwritten by the migrate files).

Next, create a sessions controller:



Time to add code to the session controller (app/controllers/sessions_controller.rb).



Notice the new and create actions. The gist of this, AFAIK, is that Rails uses new to instantiate a new instance of the Model object and create will actually save data and perform some of the more permanent actions. For our purposes, the "GET" request to the sessions#new and the new.html.erb file will show a login form. Once 'POST'-ing from that login form, the create method will receive the email and password parameters.

Code Breakdown:

Line 6 - Calls a method in the User model (authenticate).
Line 8 - Extract a user ID from the user's session
Line 9 - redirects to a home path once authenticated
Line 11 - A user did not authenticate correctly and we want to send them back to the login page.

The next thing we need to discuss are the changes to your routes.rb file:


Lines 3 - The first portion (ex: logout) identifies a request for that resources, goes to sessions#destroy.
Line 8 - Our root has changed to the login page (app/views/sessions/new.html.erb)
Line 10-12 - We've identified resources (controllers) and instantiated some default routes. 7 to be exact:

You can run `rake routes` to see these.

7 routes automatically created for the actions: index, create, new, edit, show, update, destroy
Note that 7 routes were not manually defined by you, in your routes file but rather, Rails created them for you. This is because you specified `resources :<controller name>` in your routes.rb file. You can create views and controller actions whose names match the names of those 7 defined routes (index, create, etc.). They automagically have routes!


Code breakdown:

Line 5 - form_tag is a Rails method, notice how we encapsulate it in <%= %>. This is how we separate Rails code from regular HTML. You may also see <% %>.
Line 7, 8, 11, 12 - Rails methods that are converted by Rails to define labels and input fields.
Line 14 - submit_tag, again, a Rails method. Note the {:class => "btn btn-primary"}. This is a Twitter-Boostrap definition you can find here.

Now fire up your instance, you should see the following:

Note: You can't necessarily use this yet but it looks nice :-)
This was a lot of information (read: lengthy post) and while the login does not yet work, we will wrap all of this up in Part 5 of the series. While part 5 of this series will walk you through the details of the code, you can always skip ahead and grab it from this Railscast (if you'd like to finish up).

Thanks!




Tuesday, October 16, 2012

Basics of Rails Part 3

If you've been following along in this series you've already created a Rails application called "attackresearch, configured your Ruby/gem environment with RVM, and created a Rake task to start the application with Unicorn.

In this portion, we will create our first Rails page and configure the appropriate routes.

Now, first thing first, remove the index.html file located under the public directory:

Removing this file removes the new Rails application landing page as it is unecessary.
Fire up the server using the rake task created earlier in this series and browse to the site.

Uh-oh:

Why did this occur? Rails requires some direction from you, the developer. Where does the default or "root" page live and how do I get there?

Like any good map, you need to show a route. That being said, open config/routes.rb and take a look at what I mean:


Notice the comment? Each comment block provides instructions on mapping routes in various ways. You can delete them :-). Leave the first and last line (actual code) but remove the comments.

Now that we know where to map out the route to our destination, let's create a destination. The first thing we want to do is go to our terminal and enter the following (this only has to be done once):


Remember the twitter-bootstrap-rails gem we added in the first part of this series? We just installed it. This allows us to forego some CSS and HTML work and piggyback off those of the Twitter designers (thanks gals/guys).

Next, we will generate our first controller and view. As of right now, we don't necessarily require a model. First, here is a quick break down of MVC:

  • Model - Used for handling data resources (databases, usually).
  • View - Renders HTML content to users.
  • Controller - Code that handles the bulk of the logic and decision making.

Generating a "Home" controller:

We used --skip-stylesheets as they are unnecessary when using twitter-bootstrap
Note that a new *View* folder was created app/views/home and a controller file "app/controllers/home_controller.rb".

One thing to be aware of. The name of your controller will have `_controller.rb` appended to it. This is the standard convention.

Time to make an entry in routes.rb. The first thing we need to define is a landing page so that if you request our URL, you have a starting page. We will call it "welcome". There are a few things that have to happen:
  • Make an action inside the home controller called "welcome". 
  • Create a view page under the /app/views/home folder called "welcome.html.erb".
  • Configure the route but since this is our first, we will simply use `root :to => "<controller>#<action>"

Note: Rails does not require code within the action (method), only that it exists.

Note: Only one root route can exist.



Time to edit the welcome.html.erb...

Note that the h1 tag is has a look and feel defined by the h1 definition in Twitter's CSS.
Welcome Page
..And with that we have a website, sort of. To recap we covered generating a controller and making a view page as well as adding the action with the home_controller called "welcome".

That last thing I'll cover before the next tutorial is the flow of a request. So when you request http://localhost/ this is what is happening.


  1. The config/routes.rb file is checked to see where this request should go.
  2. Since the request is for the root page '/', it is rerouted to the Home controller and Welcome action.
  3. Immediately following any code executing in the Welcome action (none right now), the request finally lands on the view page or the last part in it's journey, welcome.html.erb.


Again, the flow is route -> controller -> view.

If you want to see what I mean, we can stop the flow from reaching the view stage by (welcome.html.erb) by rendering content at the controller. Observe:

Added the directive render :text => <some text> which stops the flow from reaching the view page and renders content itself.

The outcome of this change.


Thanks for following along, more to come in the next post as we dig a bit deeper with routes and the MVC.


~cktricky





Saturday, October 13, 2012

Basics of Rails Part 2

In the last post, Basics of Rails Part 1, we created and ran the Rails application "attackresearch". Next,  we will change the Web Server to Unicorn as well as introduce the concept of Rake.

Something to note, Rails typically is run in three modes:
  • Test - Mode typically used for Unit Tests.
  • Development - Development environment, includes verbose errors and stack traces.
  • Production - Settings are as if you were running in this application in a production environment.
The default mode of running Rails locally on your machine is, development mode. Also, any command you enter will be run in the context of the development mode. This means both Rake tasks and Rails commands alike and also holds true for the Rails console which, can be your best friend.

Now obviously, if you've done something custom like `export RAILS_ENV=production` this would be different. Additionally, explicitly casting the mode in which something like the Rails console runs (example: rails console production) will change the default behavior or mode, rather.

What does all this mean? Well, really it means that you want to develop in development mode and run a production application in production mode. Pretty simple huh?

Time to configure for Unicorn versus the default Webrick web server. If you are asking yourself "why", the answer is fairly straightforward. Unicorn is meant for production and handles a large amount of requests better and overall,  is more configurable. For the purposes of this tutorial, we will use Unicorn for both development and production.

I want to demonstrate two ways of doing this. The first is by using a startup shell script. The other, for the purposes of an introduction to Rake tasks, will be to actually create a Rake task to start the application in lieu of a shell script.

Startup shell file:



Modify your Gemfile by uncommenting the line with the Unicorn gem. Also, while we are at it, let's uncomment the Bcrypt gem as well:



Run `bundle install`:



Make the startup script executable and fire it up:



The line `rvmsudo bundle exec unicorn $*` means...

  • rvmsudo  - Allows you to run sudo commands while maintaining your RVM environment. 
  • bundle exec = Directs bundler to execute the program which, automatically 'require'(s) all the gems in your Gemfile.
  • unicorn - Unicorn service.
  • $* - Any arguments passed to the script will be executed as part of the command inside of the script. Example: ./start.sh -p 4444 translates to - `rvmsudo bundle exec unicorn -p 4444` and would start the server on port 4444.
Alternatively, we can just easily package this up as a Rake task. A Rake task is a repeatable task that can be executed using the `rake` command.  Nothing magical, it just harnesses Ruby goodness to convert your task definitions into an executable command.

There is an excellent tutorial on Rake available via the Railscasts site. For our purposes, let's create a Unicorn rake file. Do this under /lib/tasks and use the `.rake` extension.


Presumably, you may wish to have multiple tasks available to the Unicorn namespace. For instance, if you'd like to both start and stop the Unicorn service it would be beneficial to create a namespace titled "unicorn" with multiple tasks inside it. For the purposes of this tutorial, I will only cover building a start task as you can easily expand upon this. Also, since we are running the Unicorn service in an interactive mode, you can hit ctrl+c to stop it. 

I would like to note that having a start and stop task is very beneficial if you are running Unicorn detached (non-interactive), where the service runs in the background.

Moving along, here is the task...


Lines 1 & 9 - Begin and end the unicorn namespace definition.

Line 3 - Describe the task (useful at the console).

Line 4 - Define the task with the first argument "task" and any additional definitions (comma separated) are arguments. In this example, we except a port argument. 

Line 5 - We code some logic that says, port_command will equal either an empty string or "-p <port number>" and  if a port number is not provided (nil) it will equal an empty string.

Line 6 - This is a shell command that appends the result of port_command to `rvmsudo bundle exe unicorn`.

Let's list our tasks and see if it is available:


Success! Notice how the description and command format are auto-magically taken care of for you.'

You can run this in one of two ways.

`rake unicorn:start[4444]` (starts the Unicorn service on port 444) OR....

`rake unicorn:start` (starts it on the default port, 8080)



To recap, we've shifted off of Webrick and over to Unicorn. Also, we've introduced the concept of a Rake task.

Stay tuned for more parts in this series...

~cktricky
















Thursday, October 11, 2012

Basics of Rails Part 1

In this series, I would like to demonstrate some of the basics of building a Ruby on Rails application and how MVC (Model-View-Controller) works. We will discuss some of the security pitfalls as well. Firstly, we need to make sure the tech is understood.

That being said, in this first part of the series, let's discuss some general Ruby "stuff" that makes life a little bit easier when dealing with day to day Ruby tasks.

RVM, RVM Gemsets, and an RVM resource file.

On the surface, Ruby Version Manager (RVM) allows you to host multiple versions of Ruby on your system and easily switch between them. If you go a little deeper, you'll see that RVM also provides the ability to host multiple "Gemsets" within each version of Ruby.  This means you can create a Gemset per application and never worry about conflicting dependency versions.

One last thing to mention, you can do all of this seamlessly leveraging an .rvmrc file. When you change into the application's folder that holds an .rvmrc file, you will automatically switch Ruby versions and gemset based off the values specified in the rvm resource file (.rvmrc).

Firstly, lets choose our Ruby version as well as the name of our Gemset. I'm going to choose Ruby Enterprise Edition (already installed via $ rvm install ree) and name my Gemset after the application, "attackresearch". Shown later.



Now let's install Rails and it's required gems



Let's create the Rails application!


Now let's get the Gemfile and .rvmrc in order. I'm going to add the 'twitter-bootstrap-rails' gem and then perform a "bundle install". Whenever a change is made to your Gems, run 'bundle install' again to update the Gemfile.lock file.

The reason for twitter bootstrap will become clear later in these tutorials. Essentially, it allows us to easily create the visual aspects of the application.




Now for the .rvmrc file



Just to test that the .rvmrc file works, let's leave the directory then navigate back into it. Lastly, perform a 'gem list' to ensure our gems are available.



Now let's start it up!





Okay, that's enough for now. More to come in the next post :-)

~cktricky