PBDR.COM

About   -   Contact   -   Purchase   -   Search   -   What's New

 
 
Middle Tier Object Security
Securing a Distributed Business Objects accessed by many client types such as Rich PowerBuilder Clients and HTML Clients is a bit more complex than securing a Client Server Business Object. Client Server Business Objects live in a very controlled world where the integrity of the objects user is known and the object does not have to worry about unauthorized access, or if it does it is normally only through business rules in the validation routine.

Some examples:

  • In an expense report application the user is presented with a list of their expense reports, from here they can select an expense report to view/edit. So you as a developer of the Business Object would never have to worry about the user opening a record that did not belong to them.
  • Client Server Business Objects use the already validated connection to the database, thus triggers can be used to show who updated the record last. Also you can be pretty sure the user is who the transaction object says they are.

In Distributed and Web application you cannot be sure of anything. You need to add two new layers of security to the basic security you have already in place.

Authentication

The first level of security is authentication. Authentication is the process of making sure you know who the person accessing and executing the object really is. The simplest approach in distributed PowerBuilder is to pass the user ID and password during the connectionbegin event of the application. Then you could validate the user ID and password against the database before allowing processing. While this is secure it is too slow for distributed processing where objects are created on demand.

Another restriction to this problem is if you want to expose your objects through something other than Distributed PowerBuilder such as COM or CORBA. You could add a method that passes the ID and password to the object when it is created, then validate the ID and password against the database, again even with the largest transaction pool in the world you will still run into speed problems with this approach. You could erase the speed problem by creating a table of ID's and passwords which you could check, but this is not very secure and would fail even the most basic security audits.

The best solution is to authenticate the user once right at the start of their session and create a token or cookie which is sent to the client. When the user wants to create an object they pass you this cookie to prove they are secure.

The cookie should contain some basic information about the user such as their ID, their IP address, the date and time the cookie was created and a check sum to make sure the cookie has not been altered. Then you should encrypt the cookie using an encryption algorithm. The users password should never be in the cookie.

Then when the client creates an object they can call a method passing the cookie, the object checks the cookie to make sure it is valid and extracts the user ID from the cookie. The User ID is then stored in the object. Whenever you perform any processing that requires the user ID you should always use the user ID from the cookie. Whenever possible do not create a method that passes the user ID, always make use of the ID from the cookie. This will help stop unauthorized transactions.

Inside the object create a Boolean flag ib_secure by default make this flag FALSE. Then when you have validated the cookie set the flag to TRUE. All public methods in your object should check the flag as the first thing they do, if the flag is FALSE then the functions should return a bad return code.

The UserID and Secure attributes should be private attributes of your ancestor business object. Provide a protected method to query the flag and a private method to set the flag. Your business entity should try to guard these attributes, even from the developers who will inherit from it.

After the cookie has been checked the setcookie function should call the setup routine for the object, why waste time setting up the object before we know who the user is? You can achieve this by creating a setup virtual method in the ancestor which your ancestor calls. The developer of the business object should override this to perform their setup work. This also gives you the chance to return a bad return code if something goes wrong and so is a much better way of setting the object up than using the constructor event. In fact as a rule of thumb Never place any code in the constructor event of a distributed object because you have no way of telling the client if something went wrong.

Unauthorized Access

In the client server world you did not have to validate that the user requesting the object your entity was being asked to retrieve has the rights to retrieve the object. In the Web and distributed objects world you have to make sure that the user requesting the record has the rights to view the record.

Imagine a web application where the HREFS in the list of objects contains the ID of the record to be opened. When the user clicks a HREF to view the record they could alter the HREF to point to a record that was not on the original list of objects! Even if you remove the location field from the browser window as we have done then you cannot stop them book marking the page, opening another browser window and going to the bookmark and then breaching security.

So your business object must check in any retrieve functions that the user who was identified to you in the cookie has the rights to view the record they are asking to see.

Other Issues

As well as the user problems, you have to think about securing the objects from fellow developers and Power Users. Think about people connecting the development objects to the production database, or some one logging into a development version of the application and using that cookie to access the production middle tier.

Another layer of security is to make the Business Object aware of the Environment it is running in (PROD, BETA, TEST, DEVL) and add the environment to the cookie, a PROD middle tier should only accept cookies from a PROD application.

The code to create the cookies and validate the cookies should not be written in PowerBuilder. This will help secure the cookies from other development staff, write the routines in C++ and create a DLL that the PowerBuilder code uses to perform cookie validation and information extract. Create two DLL's one that can only read cookies, and a second that can create cookies. Closely guard the cookie creation DLL.

Wrap Up

I hope this has opened your eye's to the potential security problems you will face as you move your business entities into a three tier model. Try to think of these issues while you are still in the design phase, its much easier to tackle the problems there than to patch the problem in testing!

 

Top of Page

Legal Notice

Ken Howe 2011