Author Archive
Multipage validator
If you need a quick overview whether the internal links of your website are working and the markup is valid, checkout the Multipage Validator tool.
Popularity: 1% [?]
New version of CI output formatter available
With Cucumber 0.4 the API for the output formatters has been changed. We updated our output formatter according to these changes. It is now compatible with Cucumber versions 0.4.x to 0.6.x.
The the updated code can be found here: imedo_ci_formatter.rb
Popularity: 1% [?]
Parameter pollution with JSON
Nice approach for circumventing input validation for JSON: Parameter Pollution with JSON.
Be sure to have your input validation handle this kind of injection attacks.
Popularity: 1% [?]
Choosing a good web password
Most web applications depend on user name password combinations in order to authorize user access. Hence one of the biggest security problems in the world wide web are weak passwords. Users choose easy to guess password because they are easy to remember. In this article some hints are given which should help choosing a good password and remembering it, because good user passwords increase the overall security of a web application.
In 2006 Bruce Schneier, a well known security expert, analyzed 34,000 MySpace passwords which were collected by a pishing attack. The most common of these passwords were password1, abc123, myspace1, password, blink182, qwerty1, fuckyou, 123abc, baseball1, football1, 123456, soccer, monkey1, liverpool1, princess1, jordan23, slipknot1, superman1, iloveyou1, and monkey.
Recently Microsoft published the results of a one year study in which Microsoft monitored automated attacks against user accounts with a fake FTP server. From the collected data they generated statistics of the most common used user names and passwords for this kind of attack. In case of passwords the top 10 consists of password, 123456, #!comment:, changeme, Fuckyou, abc123, peter, Michael, andrew, and matthew.
Both analysis underline the basic thesis of this article. Users tend to choose simple passwords which would not resist a dictionary attack and the bad guys are aware of this vulnerability and try to exploit it.
From their analysis Microsoft derived three basic hints which should be remembered when choosing a password. These hints should be presented to users of web applications during signup.
- Use a combination of letters, numbers and special characters. Also, remember that some dictionaries used in attacks have a “l33t” mode, which allows common letter/number-to-special character substitutions (like changing a-@, i-1 ,o-0 and s=$, for example, password = p@$$w0rd). Therefore, mix them in different ways so that they are not predictable.
- Use a combination of upper and lower case letters.
- Make it lengthy. A longer password does not necessarily mean it is strong but it can help in some cases.
Bruce Schneier recommends to write passwords down and keep them with your valuable things in e.g. your wallet, since passwords which are not based on a dictionary are hard to remember. But remember to change them like you cancel your credit card in case you lose your wallet.
Popularity: 1% [?]
Is your web server up-to-date?
Here is an interesting article about the search engine Shodan which is supposed to find web servers instead of web pages. This means that one can e.g. search for a particular web server version in one country.
Finding vulnerable web servers with Shodan is as easy as using Google. Hence in combination with the Metasploit exploit framework now almost everybody is able to easily run attacks against unpatched web servers.
So, have you installed the latest security updates for your web server?
Popularity: 1% [?]
Secure coding with Ruby on Rails 7: Cross-site request forgery (CSRF)
Although discovered already in 1988 by Norm Hardy, cross-site request forgery (CSRF) has been the shooting star of web attacks in 2008. As a result it has become one of the 2009 CWE/SANS Top 25 Most Dangerous Programming Errors.
The idea behind CSRF is that an attacker sends a malicious request to the target application using a trusted connection which he expects to have been established by an innocent user. In case of web applications this could be done by hiding the request in a web page with harmless content. If the user visits the malicious web page while he is logged in to the target application in another browser tab, the dangerous request is send to the target over the trusted connection between browser and web application. Two basic scenarios are possible. In the first scenario the attacker forges a request to a commonly used web application so that it doesn’t matter who opens the malicious web page. The other scenario is to trick somebody who is known to have special privileges for one web application to open the prepared web page.
In both scenarios the malicious web page of the attacker is crafted so that it sends a hidden request to the target application. For example a HTTP GET request could be executed by using the src attribute of an img tag like in the following line of code. In this case it would delete one user account.
<img src="http://victim.example.com/user/destroy/1" />
Another possibility to hide a request in a web page is displayed in the next example. It’s a hidden HTTP POST request which changes the name and email address of the logged in user. It sends the request automatically on page load. With the changed email address the attacker can use the “forgot password?” function in order to receive a newly generated password and capture the account.
<SCRIPT>
function SendAttack() {
var form = document.createElement("form");
form.style.display = "none";
this.parentNode.appendChild(form);
form.method = "POST";
form.action = "http://victim.example.com/profile.php";
form.first_name = "Bad";
form.last_name = "Guy";
form.email = "attacker@example.com";
form.submit();
}
</SCRIPT>
<BODY onload="javascript:SendAttack();"></BODY>
These two examples demonstrate that HTTP GET as well as HTTP POST are vulnerable by CSRF. Hence it is not enough to allow only POST requests to alter data. Other measure need to be applied, too. An obvious client-side countermeasures is to use separate browsers for surfing and administration, but Rails provides a server-side measure as well. The method protect_from_forgery() automatically inserts a security token in all forms and Ajax request generated by Rails. The token is calculated from the current session and the server-side secret. If the session storage is not CookieStorage the secret needs to be passed as option to the method. If an attacker is trying to send a request without the valid token to the application an ActionController::InvalidAuthenticityToken error is raised.
In Rails versions newer than 2.0 protect_from_forgery() is called for all HTTP POST requests by default. Hence it only has to be taken care of that HTTP GET and HTTP POST requests are used appropriately (see W3C checklist) and that this is enforced. For assuring that actions are only called by HTTP POST requests Rails provides the verify() method which can be added to a controller as demonstrated in the following example. It is also shown how to define actions which should be callable by other HTTP methods than POST with the except option.
class MyController < ApplicationController verify :method => "post", :except => :index end
In older Rails versions the protect_from_forgery() method can be used like shown in the following lines of code. In this example CSRF protection is disabled for the index action.
class MyController < ApplicationController protect_from_forgery :except => :index end
For further information on cross-side request forgery see www.cgisecurity.com/csrf-faq.html.
Popularity: 1% [?]
Matching elements on complex web pages with Webrat 2
In the first part of this article it was shown how to use CSS selectors for matching elements on complex web pages. But selectors are not the only way of matching HTML elements, Webrat also supports matching via XPath.
XPath matchers can be combined with CSS-selector matchers. This is really useful if not, for example, the content of an element should be matched but the element itself like in the following example. Here a form is used to display data as default value in its input elements. This can be the case in web applications in which data should be edited easily without additional clicks.
<div id="content">
<form>
Label 1: <input id="entry_1" name="entry[1]" value="Entry 1"/>
Label 2: <input id="entry_2" name="entry[2]" value="Entry 2"/>
<input type="submit">
</form>
</div>
Matching the default values of input elements with Webrat can look like the following lines of code. It is a nested combination of CSS-selector and XPath matching in order to have a readable error message if the actual output differs from the expected.
response.body.should have_selector("#content") do |content|
content.should have_tag("form") do |form|
form.should have_selector("#entry_1") do |input|
input.should have_xpath("@value") do |value|
value.should contain("Entry 1")
end
end
end
end
XPath matchers are currently not support by Webrat’s within() method and therefore cannot be used to limit the area on a web page where an action should take place, e.g. clicking of a link. They can only be used for evaluating the response of an action.
Popularity: 1% [?]
Secure coding with Ruby on Rails 6: TLS
The transmission of sensitive information in cleartext is the number six of the 2009 CWE/SANS Top 25 Most Dangerous Programming Errors. Sending data without encryption becomes a security issue when nobody but the receiver is supposed to be able to read the included information and the data is send over an open network like the Internet. Login information for closed areas on websites is a typical example for this kind of data.
How easy it is to sniff for sensitive information on the Internet has been demonstrated with the Tor-pishing attack not long time ago. As a result it is highly recommended to encrypt the whole communication between login and logout on access controlled web pages.
One way to secure communication over the Internet is to activate the transport layer security (TLS), formerly known as secure socket layer (SSL), for web applications. TLS encrypts the transmitted data between web browser and web server which denies unauthorized access to the sensitive data. Recently a vulnerability in TLS has been discovered and exploited. But common implementations like OpenSSL have already been fixed.
With the help of the SSL requirement plugin (github fork of Ian Warshak) secure communication can be easily added to Rails applications. It can be used opt-in or opt-out. The plugin is added to an application with the following lines of code.
class ApplicationController < ActiveRecord::Base include SslRequirement end
In order to implement encryption opt-in, the plugin should be used like in the following example. In this example the actions signup and login are set to require TLS which means that non-TLS requests are forwarded to TLS. The index action can be accessed with or without TLS.
class AccountController < ApplicationController ssl_required :signup, :login ssl_allowed :index end
For applications which are supposed to have encryption enabled by default and only some actions should be accessable without TLS, the plugin provides opt-out for TLS as well. In the following example all actions but index require TLS. Calling ssl_exceptions() with no action enables TLS for all actions.
class AccountController < ApplicationController ssl_exceptions :index end
The SSL requirement plugin provides TLS support in Ruby on Rails by checking whether the HTTP header X_FORWARDED_PROTO of the request is set to ‘https’. This is done with the method request.ssl? of Rails. The plugin does not implement TLS. Hence further configuration of the used web server is needed. How to configure a web server with TLS is beyond the focus of this article, but be sure to consider the case that an attacker might set X_FORWARDED_PROTO to ‘https’ in an ordinary HTTP request. Rails depends on the underlying web server to create and handle the actual TLS connection.
UPDATE: Further information about TLS is provided on OWASP’s TLS cheat sheet.
Popularity: 1% [?]
Matching elements on complex web pages with Webrat
Writing feature, integration, or acceptance tests with Webrat is a lot easier with simple web pages than it is with huge pages which provide much content. It can get really annoying to find the correct links or buttons to click. The same applies for matching content elements on complex pages in order to evaluate whether a test case was successful or not, since the same content can appear on different areas of one web page. Both issues can escalate if the position of layout elements is variable like in A/B usability tests or if a front-end layout manager is used. CSS selectors can help to find a layout element on a web page independent of its position. In this article is demonstrated how CSS selectors can be used with Webrat.
Given
In order to present the usage of CSS selectors with Webrat the following example is used. It shows a layout element called “content” which contains a table with two rows and each row provides the same options for its entry: Edit and delete.
<div id="content">
<table>
<thead>
<tr><th>Name</th><th>Options</th></tr>
</thead>
<tbody>
<tr id="entry_1" class="odd">
<td>Entry 1</td>
<td><a href="">Edit</a> <a href="">Delete</a></td>
</tr>
<tr id="entry_2" class="even">
<td>Entry 2</td>
<td><a href="">Edit</a> <a href="">Delete</a></td>
</tr>
</tbody>
</table>
</div>
When
In order to find the corresponding delete link for one particular entry in the example, it is necessary to define a scope in which the link can be found. With Webrat this can be achieved with the within() method.
within "#entry_2" do |scope| scope.click_link "Delete" end
Within() does only support the following selectors which have been defined in W3C CSS level 1.
- Type selectors, e.g. “table”
- Class selectors, e.g. “tr.odd”
- ID selectors, e.g. “#content”
The nesting of within() calls is currently not supported which means that well chosen IDs in the HTML code are necessary for good tests.
Then
In order to evaluate the response of the example after clicking the delete link of the second entry, the following statement would be sufficient, but in case the test did not work as expected it would return an error message which includes the content of the whole web page.
response.body.should_not contain("Entry 2")
Narrowing the part of the HTML code to the CSS selector which should be evaluated helps to get a more readable error message, since it only includes the selected part. In opposite to the the within() method have_selector() and have_tag() can be used nested, too. If a selector, e.g. in case of an error, is not available on a web page, an error message for the current scope is generated. This could be the whole page if the selector was the first one. Therefore it is recommended to start with a selector which is available even if an error occurs.
response.body.should have_selector("#content") do |content|
content.should have_tag("tbody") do |table|
table.should_not contain("Entry 2")
end
end
Using selectors in order to match elements on a web page has the disadvantage of a bigger dependency to the HTML code. Changing the name of a CSS selector can break test case. But this disadvantage should be insignificant compared to the achievement of error messages in which the actual problem is easily identifiable.
UPDATE: Due to a bug in Webrat should_not() does currently not work in a have_selector() block. The bug ticket contains a workaround for this issue.
Popularity: 1% [?]
Writing good stories
One of the biggest problems in software development has nothing to do with coding. It is about communication, the “code monkey versus software artist problem”.
Business people tend to specify as much as possible, but often lack the necessary knowledge of the technical details. From their point of view software developers are code monkeys who are supposed to implement specifications. On the other side programmers often see themselves as software artists who need total freedom since they are the ones who know the code.
The truth lies – like in most cases – somewhere in between. Feature requests are a result of business decisions which are made in the e.g. marketing or sales departments and usually need to be realized as soon as possible. But only software developers can estimate the needed resources to implement these features. They know which particular tasks have to be done, since they know the code.
One process which currently seems to be the solution for bringing business and software development together is agile software development with Scrum. It uses the rules of extreme programming (XP) and is therefore lightweight with low specification overhead and short release cycles. But still some specification needs to be done. Although the user stories of XP are really short they can contain quite a bit on information if they follow certain rules. Here are six rules which can help to get more information from one story. These rules do not conflict with the advices for writing stories in XP, but can be seen as a more practical approach which is based on them.
1 One use case per story
The first rule is to limit one story to one use case, i.e. only one use case for one feature is added or altered. For example if a new feature called “simple web forum” with the following use cases needs to be implemented.
- Guest views forum entry
- User writes forum entry
- User edits forum entry
- Moderator deletes forum entry
Each of these use case should be developed as one single story.
2 Consistent story format
Rule number two is to use a consistent format for the stories. The feature description part of the language Gherkin used by Cucumber is a good way of keeping stories short, but readable. In the following example is shown how it can be used to describe a use case.
Use Case: User writes forum entry
In order to produce user-generated content for one topic
As a logged in user
I want to write a new forum entry
One use case description consists of four lines. The first line is a short summary of the use case. Line number two, the “in order to” line, is reserved for a brief business value explanation. And the last two lines are supposed to describe the uses case itself: Who needs to do what.
3 Cover all wanted scenarios with a story
Rule number three is about the used semantic. A story should always be formulated as generic as possible so that it covers all wanted scenarios. This is because giving only a specific scenario like in the following bad example means that only this scenario should be implemented.
Bad example:
Use Case: Little Red Riding Hood searches for "Wolf"
In order to see how the Big Bad Wolf looks like
As Little Red Riding Hood
I want to search for "Wolf"
Good example:
Use Case: Guest searches for keyword
In order to get information about a keyword
As a guest
I want to search for a keyword
4 Use of scenarios to describe use case
Sometimes the expected behavior for a scenario of a use case is different than for others, e.g. if access control is an issue. In this case the possible scenarios should be described in the story as well. Here, the scenario syntax of Gherkin can be used.
Use Case: User searches for content
In order to get information about a keyword
As a user
I want to search for a keyword
Scenario: User searches for private content
Given a user Big Bad Wolf
And a user named Little Red Riding Hood
And Big Bad Wolf's private document with information about the Big Bad Wolf
When Little Red Riding Hood searches for "Wolf"
Then Little Red Riding Hood should not see the document about the Big Bad Wolf
5 Roles need to be known to the system
The fifth rule is that a role in a use case description of a story should always be known to the system, otherwise it is supposed to be added to the system. Like in the examples of rule 3 and 4 the Little Red Riding Hood might be a user name, but is probably no defined role. But e.g. the role “guest” stands for an unregistered visitor.
6 Use acceptance criteria for additional specification
In order to define additional things for one story it should be possible to give acceptance criteria for the QA team. This is rule number six. Acceptance criteria should be short and in list form. For the example with the keyword search one could be the following.
- A search form should be on every page
Popularity: 1% [?]
