Friday, September 29, 2006
AppSec Best Practice#2 - User Authentication using Passwords
In this post, I have described the accepted secure manner in which web applications must authenticate their users.
Using SSL in your applications - think again
We are used to the padded lock that appears at the bottom of the browser when visiting sites having the https:// prefix. That's a visual cue to indicate that SSL is active for that web session. SSL is used by web application architects as a security mechanism to protect data. However there are a few limitations to bear in mind when relying only on SSL for your application security needs.
1. SSL operates at the transport level not at the application level
This simply means that do not use SSL to protect persistent data on your PC. SSL protects data on when it is on the wire between the client and the server. The data is decrypted after it has reached its destination. Consider this example - You enter in your credit card number on a web page. Assuming SSL is active, the credit card number is encrypted before leaving your PC. The encrypted credit card number travels protected over the wire right upto the web server, at which point it is decrypted by SSL. Thereafter the data is in clear. It is the responsibility of the web application to protect it after that point.
2. SSL protects either all the data or none at all
As mentioned in the previous point, SSL operates at the transport level. This means that applications do not get to decide what they wish to encrypt and what they dont. This can have performance impacts in some cases as I have found that a site that uses SSL through out its pages turns out kind of slow. If SSL is active, all data is protected. Period.
3. SSL does not provide non-repudiation services
Non-repudiation means the ability to provide irrefutable evidence that a certain operation had been carried out. SSL does not, and cannot, provide that service.
4. SSL is not always effective for securing web services
Web services are not always front-ended by web servers. There often arises a scenario in which the application directly communicates with the web service (without intervention of the web server). In such cases, SSL does not help.
1. SSL operates at the transport level not at the application level
This simply means that do not use SSL to protect persistent data on your PC. SSL protects data on when it is on the wire between the client and the server. The data is decrypted after it has reached its destination. Consider this example - You enter in your credit card number on a web page. Assuming SSL is active, the credit card number is encrypted before leaving your PC. The encrypted credit card number travels protected over the wire right upto the web server, at which point it is decrypted by SSL. Thereafter the data is in clear. It is the responsibility of the web application to protect it after that point.
2. SSL protects either all the data or none at all
As mentioned in the previous point, SSL operates at the transport level. This means that applications do not get to decide what they wish to encrypt and what they dont. This can have performance impacts in some cases as I have found that a site that uses SSL through out its pages turns out kind of slow. If SSL is active, all data is protected. Period.
3. SSL does not provide non-repudiation services
Non-repudiation means the ability to provide irrefutable evidence that a certain operation had been carried out. SSL does not, and cannot, provide that service.
4. SSL is not always effective for securing web services
Web services are not always front-ended by web servers. There often arises a scenario in which the application directly communicates with the web service (without intervention of the web server). In such cases, SSL does not help.
Monday, September 04, 2006
C/C++ CodeSec QuickTip#1 Memory Management
Applies to
Whenever some memory is being allocated using new, for example.
What to Check For
Ensure that delete will be called properly. Ensure that all exceptions are being caught for code following the new. Consider the following code:
int * myint = new int;
//some work - with no exception handling
delete myint;
What will happen if an exception occurs in the second line of code? The delete will not be called and a memory leak will exist.
Why
Although you may take great pains to match new and delete, the delete may end up not being called due to very different reasons.
How to Check
1. Search for all locations in code where memory is being allocated.
2. Identify how the corresponding memory is being deallocated.
How to Fix
If ever you need to use new and delete, do ensure to new in the constructor and delete in the destructor. This is the only guarantee that the memory will be freed.
If you cannot always do a new in the constructor, then ensure that there arent any alternate code paths. For example, change of logic in code that prevents the deallocation code from executing. Another example (as described above) is when an unhandled exception occurs and the deallocation code is altogether skipped.
Problem Example
int * myint = new int;
//some work - with no exception handling
delete myint;
Solution Example
int * myint = new int; //FIX: Move this code to the constructor
//some work - with no exception handling
delete myint; //FIX: Move this code to the constructor
Whenever some memory is being allocated using new, for example.
What to Check For
Ensure that delete will be called properly. Ensure that all exceptions are being caught for code following the new. Consider the following code:
int * myint = new int;
//some work - with no exception handling
delete myint;
What will happen if an exception occurs in the second line of code? The delete will not be called and a memory leak will exist.
Why
Although you may take great pains to match new and delete, the delete may end up not being called due to very different reasons.
How to Check
1. Search for all locations in code where memory is being allocated.
2. Identify how the corresponding memory is being deallocated.
How to Fix
If ever you need to use new and delete, do ensure to new in the constructor and delete in the destructor. This is the only guarantee that the memory will be freed.
If you cannot always do a new in the constructor, then ensure that there arent any alternate code paths. For example, change of logic in code that prevents the deallocation code from executing. Another example (as described above) is when an unhandled exception occurs and the deallocation code is altogether skipped.
Problem Example
int * myint = new int;
//some work - with no exception handling
delete myint;
Solution Example
int * myint = new int; //FIX: Move this code to the constructor
//some work - with no exception handling
delete myint; //FIX: Move this code to the constructor
Subscribe to:
Posts (Atom)