Geek Culture
Published in

Geek Culture

Four Security Backlog Items That You Shouldn’t Reinvent the Wheel

Read this and count to 10 if you feel you have to…

It’s not infrequent across developers to posit a certain claim that may cause more harm than good. Upon a task that can be fulfilled by searching and finding quality solutions already existed, we most deservedly think that “I’m clever, I can write one”.

But, why is it a bad idea to device a new algorithm instead of using an already existing one?

Creating a new or customizing an existing security related technique may be costly.

After all, if it’s all about correctness, the existing ones could be fallacious as well. Because, the stakes are high for mistakes. In this post, we’ll try to look at not only reinventing but also re-utilizing existing algorithms from angles that reveal some evident disadvantages for security.

Here are the four main task groups for which designing your own algorithm or re-utilizing an already existing one might put you in security trouble; cryptography, input validation rules, authentication/authorization schemes and security bug mitigation techniques.

Cryptography

This is may be the most popular one, the usual suspect. It is extremely hard to design, implement and use a cryptographic algorithm. And please note that the word use in the previous sentence doesn’t have a lesser emphasis than the others.

In order to communicate this hardship to developers, I always use one specific drawing in Jeff Moser’s 4 act play guide about AES, maybe the most popular symmetric encryption algorithm;

http://www.moserware.com/2009/09/stick-figure-guide-to-advanced.html

Here the advice is that we shouldn’t implement the already designed AES algorithm without first understanding some of the attack techniques against encryption algorithms.

Over the course of several years I realized that even the difference between terms encryption and encoding is blurry for a quite many developers. They tend to use these words interchangeably, whereas, there are case where you should use encoding and cases where you should stick to encryption. Otherwise, there will be severe security consequences of wrong choices.

Learning a new cool technique immediately brings the urge to use it. However, it is not appropriate to use encoding where confidentiality of data is required. Encoding, too, like encryption is a two-way transformation. However, encoding doesn’t provide confidentiality. For example, one immediate thing to note in encryption is that you need keys that should be kept private but gets involved in the technique. An encoded string, when intercepted, can easily be decoded to its original plaintext. However, the same is not true for encrypted text. If, of course, the encryption is done properly.

Mismatch of encoding and encryption is just one simple example that without a proper knowledge it is dangerous to even use these techniques let alone devise your own cryptographic algorithm.

Input Validation Rules

Input validation is the heart of a secure application. I also implicitly include output validation into this claim but that’s another issue we covered in another post.

It is almost always wise to apply input validation to any of the untrusted data coming to your application. But there are various types of input validation and we, developers, don’t always choose the right one because the way our brain works.

Blacklisting is an input validation strategy where reject the incoming data which we categorize as bad input. The decision of what is bad and what is not is a shaky one. Any mistake there will result in malicious users bypassing our input validation.

Most of the application frameworks on the other hand provide built-in whitelisting input validation strategies. For example Java has the Validation API which you can use in multiple frameworks such as the popular Spring.

Here’s an example model class that incorporates Java Validation API. By using existing security APIs of a framework will prevent unwanted mistakes of using blacklisting and allow testing tools to statically show you the places that validation hasn’t been used or forgotten.

public class User {

@NotNull(message = "Cannot be null")
private String name;

@AssertTrue
private boolean working;
@Size(min=20, max=210, message="Must be bet. 20 and 210 chars")
@Pattern(pattern="[a-zA-Z\.0-9]+", message="Must be valid")
private String about;
@Min(value = 18, message = "Should not be less than 18")
@Max(value = 110, message = "Should not be greater than 110")
private int age;
@Email(message = "Should be valid")
private String email;
}

Authentication/Authorization Schemes

Both authentication and authorization are too complex to design and implement. You should virtually never create a new way of authentication or authorization unless… Well, there’s no unless.

Modern frameworks already contain built-in APIs and there are also reliable 3rd party components if they don’t support a scheme that you require such as OpenID, OAuth or JSON Web Token (JWT).

No existing solution is a security panacea, either. It is important here to note that if you use a framework or a 3rd party component, then you automatically acknowledge that periodic patch management is a necessity.

Let us given an example of a set of insecure implementation which when used as a library swing opens the entrance door of our application to hackers.

JWT is a standard for representing claims securely between two parties. It supports signing algorithms for sufficient integrity. However, there’s one more algorithm that standard supports and that is NONE. Directly from JWT’s RFC;

An Unsecured JWT is a JWS using the “alg” Header Parameter value “none” and with the empty string for its JWS Signature value, as defined in the JWA specification [JWA]; it is an Unsecured JWS with the JWT Claims Set as its JWS Payload.

When a malicious user sends a JWT including NONE as the algorithm, no validation is performed!

So, if a JSON Web Token instance is used with algorithm string ‘none’, the library will not verify it’s integrity but return true! Interestingly some of the the library implementations also supported this NONE algorithm, as it is without any further validation.

It’s easy to understand how complex an authentication scheme can be by just checking out one of RFCs of OpenID or OAuth. The authors put a lot of effort to minimize all the risks that design brings.

Security Bug Mitigation Techniques

Here’s a simple example which shows re-utilization of a certain cryptographic API could have disastrous security implications.

.NET has a built-in ValidateAntiForgeryToken attribute, which prevents Cross Site Request Forgery (CSRF) attacks when you decorate your actions and views with appropriate annotations and helper methods. The key idea is that when the user POSTs a request, both the request body and the cookie contains different pieces of a puzzle. When AntiForgery.Validate method is called with these two piece of information, it returns true. Otherwise it returns false throwing a security exception.

This is fine and built-in for classic, non-SPA applications. So, when you have a SPA application, such as Angular.IO, then you have to make some adjustments in order to adapt the same technology to your pages.

The below code triple shows this insecure enhancement which on the surface works. Here, we developed a custom attribute customizing the behaviour of the built-in technique.

We generate a pair by using AntifForgery.GetTokens method but instead of placing the returned pieces in a cookie and a page form separately, we place them concatenated in a hidden HTML input element. And when a request is triggered, the value of this hidden element is added to an HTTP request header called RequestVerificationToken.

Once the action decorated with our new customized attribute gets the request, it splits the header value and validates them.

An insecure SPA re-utilization of .NET’s CSRF protection

The security problem this customization has nothing to do with using weak encryption algorithms. The problem is that both of the pieces is sent using the same medium, a customized HTTP request header: RequestVerificationToken.

It’s easy to make the same application to produce a request verification token and use it in a CSRF attack; a web page when opened executes a cross domain request with a previously generated anti forgery token pair sent in a custom header.

Conclusion

At first sight, it may sound right to design, implement a new algorithm or customize an already existing one when we are faced with security related backlog items on our boards. Well, in fact this is a terrible idea and might be a recipe for disaster.

Inventing a “new algorithm” may feel great. Don’t miss the real danger that may come with or behind it.

Should we then exclusively use 3rd party libraries? How about Copy-Paste code?

Well, we already do, don’t we? And, sure, using 3rd party and copy-paste code both have their own security risks. But the thing is, we should already be aware of the attached responsibilities of using them; patch management and thorough analysis before usage.

We have to have a proper knowledge about the algorithm, technique, framework or API we are about to use. Otherwise, it’s still easy to incorporate security problems in our software. However, devising our own security related algorithms is highly prone to errors. It’s easy to mess up and it requires extensive knowledge and experience to securely design and implement most of the security related techniques no matter how clever we think we are.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store