CSC/ECE 517 Fall 2009/wiki1b 8 rubysecurity

From Expertiza_Wiki
Revision as of 23:06, 28 September 2009 by Hunter (talk | contribs) (Fixing reference 1 and some minor prose changes)
Jump to navigation Jump to search

This article explores how the Ruby on Rails framework handles common dangerous programming errors committed in the development of a web application and how it compares with other web application frameworks in terms of handling these common errors.

Introduction

Almost all real world data and transactions are now available as web services which are created in some web application framework. As the number of such services increase, so do the possibility that attackers might try to exploit new loopholes in the application that is developed. The consequences of such attacks are far reaching and destructive in terms of business and security perspective. The danger is so grave that during January this year that experts from more than 30 US and international cyber security organizations jointly released the consensus list of the 25 most dangerous programming errors that lead to security bugs and that enable cyber espionage and cyber crime. Ruby on Rails [1], a MVC based application framework architecture, is used for designing web applications using Ruby language, comes with some features which can handle some of the common programming errors cited. In the next section we will see how each of these errors are handled according to their classification and in the third section we will see how Rails compares with other application framework in handling these errors.

Ruby on rails security measures against common programming errors

Synchronous to the classification of programming errors as cited in [2], this section has three divisions or categories.

CATEGORY: Insecure communication between components


This section contains the programming errors such as Improper Input validation, improper encoding of output,SQL injection etc., and five more error types which we will see now.

Improper Input Validation


Authorization is the process of checking whether a user has access to do what he wants to do. This automatically brings the issue of handling roles in the web application. If roles are not properly defined and implemented, an attacker can login as a genuine user by registering with your application and can perform unwanted reads / write which can lead to loss of sensitive information.

Validation in Rails is very simple and short. We have to use the function validates. Validation can be done with ActiveRecord [3] which is the ORM layer supplied with rails that relieves the programmer of dealing with the underlying database and is the solid model foundation of Rails MVC architecture. ActiveRecord comes with a number of helper classes for validation. Using these helper classes, to check that a variable in the model is not null, we use validates_presence_of: followed by the field names that need to be validated. To check the length of a variable we use validates.lengthof: function. The below code uses the validation helper methods of ActiveRecords which checks if the name of the student is not null or no symbols are present. It also checks whether the user with the same name already exists in the database as a new user is being created. The rest of the code is self-explanatory. sample code for Input validation [4].

 class Student < ActiveRecord::Base
   validates_presence_of :name, :sex, :age, :weight
   validates_format_of :name,
                       :with => /^\w+$/,
                       :message => "is missing or invalid"
   validates_uniqueness_of :name,
                           :on => :create,
                           :message => "is already present"
   validates_inclusion_of :sex, :in => %w(M F), :message => 'must be M or F'
   validates_inclusion_of :age, :within => 18..40
   validates_length_of :name, :allow_blank => false, :allow_nil => false, :maximum => 30
 end

Without the validates helper method, the check for the format of the name can be done as

  class Student < ActiveRecord:Base
      def validate
         unless name && name=~/^\w+$/
            errors.add(:name, "is missing or invalid")
         end
      end
  end

Failure to Preserve SQL Query Structure (aka 'SQL Injection')


If not much attention is paid as to how SQL queries are handled in the application code, attackers can modify / supply appropriate parameters so that they can gain access to sensitive information in the database such as Account database, which is not good from the security viewpoint. For example in Ruby, the following function poses a serious security threat if the value for the conditions method comes from an external source. The attacker can pass a SQL meta-character as the input to breach his/her privilege.[5]

  Users.find(:all, 
             :conditions => "name like '%#{session[:user].name}'")

Rails recommends that in order to avoid SQL injections, never to substitute anything into an SQL statement using the ruby's #mechanism. Rails comes with a facility called blind variable for using in place of #. It is nothing but having a placeholder in place of #. If more than one placeholder is present in the query, ActiveRecord uses the corresponding input from the input array to substitute in the placeholder. The function from the above example can be replaced by [5]

  Users.find(:all, 
             :conditions => "name like '%?%'")

Failure to Preserve Web Page Structure (aka 'Cross-site Scripting')


Attackers are known to write simple javascript code in to an application's page using session cookies so that whenever a cookie destined for another legitimate user of the application is sent to that user, the attacker can redirect the cookie to be sent his/her computer. In this way an attacker can steal a legitimate users' identity. To prevent this Rails recommends that the application we create never blindly display any data coming from an external source to be blindly displayed on the application's page. It recommends the application to convert such HTML codes into plain texts before displaying.[5] Rails also comes with a helper method h(string) which is an alias for HTML escape, which performs the above mentioned escaping in Rails views. Rails also recommends using this helper method for any variable that is rendered in the view. The below code snippet shows how to render a user comment on to the application's view.[5]

     <%= h(user.comment)%> #user is the model for the current user

Failure to Preserve OS Command Structure (aka 'OS Command Injection')


An attacker will try and execute execute malicious code when an application uses data from the user as a parameter to execute system level commands resulting in breach of security. This is because an attacker can execute another command through the input to a first command by appending a semicolon(;) or a vertical bar (|). Ruby's exec(command), syscall(command), system(command) and \command are all vulnerable to such attacks. In order to avoid this Rails recommends programmers to use the system(command, parameters) method which passes command line parameters safely. For example, [7]

       system("/bin/echo","hello; rm *") # prints "hello; rm *" and does not delete files

Cleartext Transmission of Sensitive Information


If our software sends sensitive information across a network, attackers can sniff this data right off the wire. Trying to obfuscate traffic using schemes like Base64[19] and URL encoding doesn't offer any protection, either since those encodings are for normalizing communications, not scrambling data to make it unreadable. This can be overcome in Rails by using Secure Socket Layer (SSL)[6] for entire session. Assuming the SSL keys and certificates are setup and the Web server has been configured to use SSL. Rails provides the ssl_requirement plug-in to use SSL in a rails application. Include it at the top of application.rb file present in the directory app/controllers, which effectively includes it in every controller [6]:

       include SslRequirement

Now all that is needed to be specified is, at the top of each controller, which controller actions require SSL. For example :

       ssl_required  :login, :account, :payment, :cart

Any access to an action that requires SSL will automatically redirect to https://. If anyone tries to access a page that is supposed to be secure with an http:// link, they’ll be redirected.

Cross-Site Request Forgery (CSRF)


This attack method works by including malicious code or a link in a page that accesses a web application that the user is believed to have authenticated. If the session for that web application has not timed out, an attacker may execute unauthorized commands. Most Rails applications use cookie-based sessions. Either they store the session id in the cookie and have a server-side session hash, or the entire session hash is on the client-side. In either case the browser will automatically send along the cookie on every request to a domain, if it can find a cookie for that domain. The controversial point is, that it will also send the cookie, if the request comes from a site of a different domain. Rails uses a hidden _method field to handle this barrier [7]. The verify method in a controller can make sure that specific actions may not be used over GET. Here is an example to verify the use of the transfer action over POST. If the action comes in using any other verb, it redirects to the list action.

      verify :method => :post, :only 
      => [:transfer], :redirect_to => {:action => :list}

With this precaution, the attack from above will not work, because the browser sends a GET request for images, which will not be accepted by the web application. But this was only the first step, because POST requests can be sent automatically too. The solution to this is including a security token in non-GET requests which check on the server-side. In Rails 2 or higher, this is a one-liner in the application controller:

      protect_from_forgery :secret => 
      "123456789012345678901234567890..."

Race Condition


Race condition is the scenario where multiple processes attempt to use the exact same shared resource at exactly the same time. Rails framework follows the Shared nothing architecture (SN) [27 ], which describes a Distributed Computing-architecture, where each node independently and autonomously to carry out its task with its own processor and associated storage components such as hard disk and memory and not a specific, individual node to connect to a database is necessary. Hence this avoids the possibility of processes having to access a shared resource.Moreover the default ruby interpreter is also thread safe(correct functioning during simultaneous execution)

Error Message Information Leak


Improper error messages may leak out secrets to an attacker. The secrets could cover a wide range of valuable data, including personally identifiable information (PII), authentication credentials, and server configuration. Sometimes, they might seem like harmless secrets that are convenient for users and admins, such as the full installation path of the software. Rails offer complete customization of default validation error messages it provides. change the entire contents of any validation error message. Make the application secure by reducing error message information leaks by writing customized error_messages_for helper.

CATEGORY: Risky Resource Management


This category contains errors such as Code Injection, Improper Resource Shutdown or Release , Failure to Constrain Operations within the Bounds of a Memory Buffer etc., and six other errors which will be covered in this section.

Failure to Constrain Operations within the Bounds of a Memory Buffer


If the memory accessible by the attacker can be effectively controlled, it may be possible to execute arbitrary code, as with a standard buffer overflow. Out of bounds memory access will very likely result in the corruption of relevant memory, and perhaps instructions, possibly leading to a crash. Other attacks leading to lack of availability are possible, including putting the program into an infinite loop. Buffer overflow attacks generally rely upon two techniques (and usually the combination). One is writing data to particular memory addresses and the other is having the operating system mishandle data types . Rails automatically eliminates buffer overflow attacks since it is a strongly-typed programming language, meaning that it will disallow direct memory access and thereby usually prevent buffer overflows from happening [8].

External Control of Critical State Data


If you store that data in a place where an attacker can modify it, this also reduces the overhead for a successful compromise. For example, the data could be stored in configuration files, profiles, cookies, hidden form fields, environment variables, registry keys, or other locations, all of which can be modified by an attacker. In stateless protocols such as HTTP, some form of user state information must be captured in each request, so it is exposed to an attacker out of necessity. Rails suggests that all model requests are properly scoped, and for internal security, we need to make sure that confidential information isn’t leaking out in our logs, exception reports, and backups. The sessions which maintain the state for HTTP is maintained by the rails framework and provides several storage mechanisms for the session hashes. The most important are ActiveRecordStore [9] and CookieStore [10]. ActiveRecordStore keeps the session id and hash in a database table and saves and retrieves the hash on every request. Thus keeping it in a safe storage from the attacker. CookieStore saves the session hash directly in a cookie on the client-side. The server retrieves the session hash from the cookie and eliminates the need for a session id. Hence in this case the client can see everything you store in a session. To prevent session hash tampering, a digest is calculated from the session with a server-side secret and inserted into the end of the cookie. That means the security of this storage depends on this secret (and on the digest algorithm, which defaults to SHA512, which has not been compromised, yet). So don’t use a trivial secret, i.e. a word from a dictionary, or one which is shorter than 30 characters. Put the secret in your environment.rb [11]:

     config.action_controller.session = { 
     :key => '_app_session', :secret => '0x0dkfj3927dkc7djdh36rkckdfzsg...' } 

Rails also provides secure logging to protect log files. We can filter certain request parameters from your log files by the filter_parameter_logging method in a controller. These parameters will be marked [FILTERED] in the log.

     filter_parameter_logging :password

External Control of File Name or Path


When you use an outsider's input while constructing a filename, the resulting path could point outside of the intended directory. An attacker could combine multiple ".." or similar sequences to cause the operating system to navigate out of the restricted directory. Other file-related attacks are simplified by external control of a filename, such as symbolic link following, which causes your application to read or modify files that the attacker can't access directly. This vulnerability can be overcome by using $SAFE, which is a global security parameter that Ruby provides. $SAFE controls a number of security features in the Ruby programming language. The higher you raise $SAFE, the more restrictions the Ruby interpreter puts on your program. The $SAFE level [12] can only be raised, not lowered; malicious code cannot lower the $SAFE level [12]to escalate privileges. There are 5 $SAFE levels [12], represented by the integers 0 through 4. To set a $SAFE level, assign an integer to $SAFE. By default, $SAFE is set to 0. At this level, no extra checks will be performed by the Ruby interpreter. If, when you try to assign an integer to $SAFE that is less than the current value of $SAFE, a SecurityError exception will be raised. In addition, you can run Ruby scripts with a higher $SAFE level by supplying the -T switch to the Ruby interpreter. $SAFE level 1 [12] introduces the concept of tainted objects. Objects that accept input from external sources (files, sockets, environment variables, etc) will have the tainted flag set. This flag will follow all copies of the object, no matter how many times you filter or copy this object, it will always remain tainted. There are two methods that will help you manage tainted objects; Object#tainted? returns true if an object has the tainted flag set, and Object#untaint untaints the object.

Ruby will refuse to accept tainted objects as arguments to some "dangerous" methods. For example, you can't pass a tainted object to require or load, or open a file whose filename is a tainted object. This forces you to properly sanitize all input and explicitly untaint it before you can use it. It's also easy to add a tainted check to your methods; if any arguments you'd like to be untainted fail the tainted? check, raise a SecurityError exception.

   begin
       # Raise the security level
       $SAFE = 1
       # Read from $stdin, then try to open a file with a tainted object
       path = gets.strip
       puts "path is tainted" if path.tainted?
       f = File.open( path )
       rescue SecurityError => e
       puts "Caught security exception: #{e}"
   end


   % ./taint2.rb
   path is tainted
   Caught security exception: Insecure operation - initialize

One cannot open files whose names are tainted strings.$SAFE level [12] one alone can make your Ruby programs much more secure. It forces you to be vigilant with input validation.

Untrusted Search Path


If a search path is under attacker control, then the attacker can modify it to point to resources of the attacker's choosing. The same risk exists if a single search path element could be under attacker control, such as the current working directory. Ruby’s $SAFE security parameter can be used to avoid this. Refer to the section External Control of File Name or Path for information on $SAFE.

Download of Code Without Integrity Check


Attackers can hack the download site, impersonate it with DNS spoofing [13] or cache poisoning, convince the system to redirect to a different site, or even modify the code in transit as it crosses the network. This scenario even applies to cases in which your own product downloads and installs its own updates. This can be prevented by encrypting the code with a reliable encryption scheme before transmitting or using proper forward and reverse DNS look-up to detect against DNS spoofing. Rails provides a simple way to confirm with file names before they are downloaded on to the client. For example, The send_file() method sends files from the server to the client. If you use a file name, that the user entered, without filtering, any file can be downloaded:

      send_file('/var/www/uploads/' + 
      params[:filename]) 

Simply pass a file name like “../../../etc/passwd” to download the server’s login information. A simple solution against this, is to check that the requested file is in the expected directory:

      basename = 
      File.expand_path(File.join(File.dirname(__FILE__), '../../files')) filename = 
      File.expand_path(File.join(basename, @file.public_filename)) raise if basename 
      =! File.expand_path(File.join(File.dirname(filename), '../../../')) send_file 
      filename, :disposition => 'inline'

Improper Resource Shutdown or Release


System resources that have reached their end-of-life need to be dispose off correctly. Otherwise, your environment will become heavily congested or contaminated. This applies to memory, files, cookies, data structures, sessions, communication pipes, and so on. Attackers can exploit improper shutdown to maintain control over those resources well after you thought you got rid of them. Ruby uses automatic garbage collectors [14] which overcomes this problem.

Improper Initialization


If you don't properly initialize your data and variables, an attacker might be able to do the initialization for you, or extract sensitive information that remains from previous sessions. When those variables are used in security-critical operations, such as making an authentication decision, then they could be modified to bypass your security. Incorrect initialization can occur anywhere. In ruby uninitialized instance variables have a default value of nil, the sole-instance of the NilClass class which, expresses nothing. Hence unlike some other languages like C they donot contain any garbage value or previous runtime values [15]. Moreover, referencing an undefined global or instance variable returns nil. Referencing an undefined local variable throws a NameError exception, which could be appropriately handled using the raise construct.

Incorrect Calculation


There are instances when the numerical operations lead to exceptions like Integer overflow [16] and divide by zero errors. When attackers have some control over the inputs that are used in numeric calculations, this weakness can actually have security consequences. Integer overflow exceptions also occur in ruby and they can be handled with the raise construct. Integers overflow behavior of Ruby is as follows, the interpreter converts a Fixnums (30 bits) into a Bignums (unlimited precision integers). Ruby has an integer overflow vulnerability in the rb_ary_fill() function(as on Dec. 2008)[17] . For more details about the vulnerability refer [17].

CATEGORY: Porous Defenses


This category contains errors such as improper access control, Use of a Broken or Risky Cryptographic Algorithm , Hard-Coded Password, Use of Insufficiently Random Values and three more errors which will be covered in this section.

Use of a Broken or Risky Cryptographic Algorithm


Programmers who try to invent their own cryptographic environment for securing transfer of sensitive information mostly end up writing a broken or risky cryptographic algorithms. Brilliant mathematicians and scientists worldwide have broken their minds trying to perfect an algorithm which will be difficult to break. So a programmer is not expected to come up with a brand new algorithm. The programmer may be just re inventing the wheel and it results in an unnecessary risk that may lead to the disclosure or modification of sensitive information. Ruby allows easy implementation of advanced 128 and 256 bit algorithms such as AES [18]. Ruby allows using Active record hooks to perform AES encryption and decryption. Ezcrypto and Sentry are two such hooks. EzCrypto is optimized for simple encryption and decryption of strings. There are encrypt/decrypt pairs for normal binary use as well as for Base64 [19] encoded use. It also provides a key class to generate keys as random or initialized with binary / Base 64 encoded data. An example piece of code for generating a random key and encrypting data using the generated key [20]

            @key=EzCrypto::Key.generate #to generate a random key
            @encrypted=@key.encrypt("clear text")  # encrypting using previous gen key
            @decrypted=@key.decrypt(@encrypted)

Hard-Coded Password


Passwords are generally used in both inbound and outbound authentications.Having hard coded passwords in an application sounds naive and we do not expect any programmer to do it. But when the constraints in terms of cost become tight, programmers do hard code passwords, even for sensitive accounts, within their application as it will reduce testing and support budget. If hard-coded passwords are used, it is almost certain that malicious users will gain access through the account in question. The likelihood of the vulnerability being exploited is very high as mentioned in [21]. Rails recommends handling passwords by generating a random but unique salt value for each password and hashing them using 160-bit SHA [22] hashing algorithm and then storing the hash in the database. The salt is created by concatenating a random number and the object id of the user object. The salt’s value is then stored in the model object’s salt attribute[5].

              def create_new_salt
                 self.salt=self.object_id.to_s + rand.to_s
              end

Then the SHA is computed with following piece of code [5]

              private
                 def self.encrypted_password(password, salt)

string_to_hash = password + “wibble” + salt

 	          Digest::SHA1.hexdigest(string_to_hash)
              End

When an incoming authentication request arrives, the entered password is appended with a salt and hashed using SHA1 [22] and it is stored in the password attribute of the user object. This is then compared to the stored password for that user in the database to check whether it is correct or not.

Use of Insufficiently Random Values


Good randomness is necessary for the security features implemented in our web application using cryptographic algorithms to be effective and useful. If our application is using a normal Pseudo Random Number Generator [23] then it is easy for the attacker to guess the next random number after some number of trials. Randomness is needed to produce session IDs and for generating nonces to prevent replay attacks. Rails make sure that the random number generated is random enough so that the attacker has very less probability of guessing the random number. For example, for generating session IDs in Rails, first a random number is generated where the random string is the current time, a random number between 0 and 1, the process id number of the Ruby interpreter (also basically a random number) and a constant string. This random string is then hashed using MD5 [24] and the resulting value is stored as session ID. The method to produce a random string is rand. If you needed a random integer to simulate a roll of a six-sided die, you'd use: 1 + rand(6). A roll in craps could be simulated with 2 + rand (6) + rand(6) [25]. Finally, if you just need a random float, just call rand with no arguments.

Client-Side Enforcement of Server-Side Security


Trusting clients to perform security checks on behalf of the server is not a good idea because the attackers can reverse engineer the client and can write their own custom clients to bypass authentication and authorization. To avoid this situation, Rails recommends that the authorization mechanism and input validation mechanism (refer to Improper Input validation from the section 2.1.1) be implemented properly.

Improper Access Control (Authorization)


If proper authorization mechanism is not implemented in the web application then we are not making sure that the users do what they can do. Attackers exploit this loophole to gain access to protected and sensitive files which they modify or delete. Rails provides filters to make sure that only administrators have access to admin files and no user of the application can modify these files. beforefilter is used to intercept all calls to the actions in the admin controller. Here this function acts as an interceptor and checks the user id stored in the session to check if it is really the administrator who has requested the action. If yes, the action is allowed to go through. Else, it is blocked. This method is included as a part of ApplicationController, the parent class of all the controllers in our Ruby application. Also the beforefilter method is restricted as a private method so that it is not visible to the end user or else the attacker can modify this method also. An example beforefilter method which checks for admin login for continuing the action and if not prompts the user to log in as an admin [5]

     class ApplicationController < ActionController::Base
         private
         def authorize
            unless User.find_by_id(session[:user_id])
               flash[:notice]="log in as admin to proceed"
               redirect_to(:controller => "login", :action => "login") 
            end
         end
     end 

This method can be invoked before performing any actions in the administration controller by adding the line

      before_filter :authorize

Execution with Unnecessary Privileges


This error falls under the category of providing Role Based Access Control[26 ]. Therefore we need to provide proper authorization mechanisms for avoiding this error. Refer to Improper Access Control (Authorization) to see how this can be achieved.

Insecure Permission Assignment for Critical Resource


This error too is as a result of improper handling of authorization. Refer to the section Improper Access Control (Authorization) to see how this can be achieved.


Security Features Comparison of Rails with other Application Frameworks

Security Feature Rails (Ruby) Spring (Java) Struts (Java)
Authorization a beforefilter is used to intercept all calls to the actions to check the user and his/her role before the action is processed a security manager level exists between the caller and service which intercepts the request and checks for access rights of the caller. implemented in the RequestProcessor portion of the "Controller" via the RequestProcessor.processRoles method
Input Validation uses the helper class validates of ActiveRecord Spring uses a validator interface to validate objects. A validation class is written implementing this interface so that its features can be used in the validation class. There is a validator plug-in and after it is loaded into the application, have to extend org.apache.struts.validator.action.ValidatorForm instead of org.apache.struts.action.ActionForm.Then when the validate method is called, the action's name attribute from the struts-config.xml is used to load the validations for the current form.


Race Condition Uses no shared architecture to avoid race condition, hence easy and elegant design to implement thread safe code. Uses Data access abstraction to prevent race condition. designing thread safe methods not as elegant as rails Methods accessing shard objects have to explicitly take care of cached values of objects(values cannot be stored in field but rather always passed as parameters) in order to make it thread safe.So not an elegant solution
SQL injection attack: could be still be performed if vulnerable sql statements are constructed by the programmer manually. Cannot be performed Cannot be performed
Storage of session data: On disk or database, inherently less secure since person with access to server can view private files on the server stores session data in memory, hence more secure for against this particular vulnerability stores session data in memory, hence more secure for against this particular vulnerability
CSRF attacks: provides good defense against CSRF by inclusion of tokens. Rails MVC has enough official clear documentations to prevent it Spring MVC documentation doesnt provide clear guidance in defending against these attacks Struts has enough documentation. Provides the tokenSessionInterpreter to prevent CSRF attacks
Validation Integration with Model Object A fundamental idea in object programming is to unite data with related actions. In rails, the Model Object should typically encapsulate both data and validations. Spring MVC takes validation out of your Model Objects (its proper home), and moves it into a separate class having a single method In Struts 1, data validation is completely separated from the Model Object.

Conclusion

Security in web applications is a very sensitive issue but they can be easily ignored by programmers. It is highly imperative that they go through all the possible attack methods which can be made on an application. It is also important that they understand the security features of the framework using which they develop the web application. As such, there is no framework which provides web security features as a plug and play tool. All frameworks come with some features which help attain the security levels needed. In the end it is the job of the programmer to implement them in the correct manner. Ruby on Rails also is one such framework. It comes with features which are easy to understand and implement by the programmer. Threats to web applications are always evolving and attackers are finding new ways to exploit the vulnerabilities in an application’s implementation. It may be said that it is not possible to prevent such attacks but with strong security features, programmers can be in a better position to reduce its effects on their application. In this article we have discussed ways in which Rails implements its security features in order to assist the programmer in repeating such mistakes.

References

1. Ruby on Rails

2. CWE/SANS TOP 25 Most Dangerous Programming Errors

3. Active Record — Object-relation mapping put on rails

4. Introduction to validations and validation error handling in Rails

5. Dave Thomas; David Heinemeier Hansson(2006). Agile Web Development with Rails. ISBN: 978-0-9776-1663-3

6. Using SSL in Rails applications

7. Ruby on Rails Security Guide

8. Buffer Overflows

9. RecordActiveStore

10. Ruby On Rails Secuirty Project- Rails 2.0 Cookies

11. Guide: Environments in Rails 1.1

12. NewOrder - Secure Programming With Ruby (Part 1)

13. DNS Spoofing techniques

14. Meshplex-Ruby/Ruby on Rails programming tutorials2

15. RosettaCode-Variables

16. RubyForum-Ruby Overflow behavior

17. Ruby: integer overflow

18. Wikipedia AES

19. Wikipedia Base64

20. EzCrypto - Easy to use Crypto for Ruby

21. Common Weakness Enumeration -259: Hard-Coded Password

22. Wikipedia SHA

23. Wikipedia Pseudo Random Number Generator

24. Wikipedia MD5

25. Ruby random numbers

26. Wikipedia Role Based Access Control

27. Wikipedia Shared Nothing Architecture