View RSS Feed

Development Team Blog

WebApp Framework Access Restriction

Rate this Entry
The WebApp Framework comes with a prepared system for building proper secure Web Applications. By default there is the session manager that generates a unique key for each session and remembers the login state of this session and there are several hooks that allow the developer to easily implement access rules on view level. Now having this all in place it is just a matter of implementing the right hooks to restrict access to parts of the application based on the login state and user rights. But it turns out that not only our customers but also we ourselves sometimes forget to do this!

Our WebOrder sample is unfortunately a great example of a case where we forgot to actually enforce the security rules in the right spots. If we open the sample we are presented with a login screen and to be able to get further access we need to login. This looks pretty secure right? Unfortunately it is not, as everything on the client is interpreted (including JavaScript) it means that one can easily tamper with it. Especially since modern browsers all come with great debugging tools we can easily execute lines of JavaScript code and change the user interface by messing with the browser DOM. Using these tools it would be easy to hide the login dialog and work with the application that is already partially loaded on the background.

Having done this one can basically access the entire WebOrder application except for one view. In the Demo menu there is an item called "Panels + Allow Access". The reason why this view is not accessible at all is because we have implemented a function in it called AllowAccess. This function is the main security hook on view level that allows you to control access to this particular view. It will be called every time something happens to this view. In case of the "DemoPanels.wo" view this function is implemented to check if a user is an administrator and it uses the piUserRights property of the cWebStandardSessionManager. This property is kept up-to-date by the ValidateSession and CreateSession procedures based on the WebAppUser.Rights column.

Code:
//
//  Only administrators should be able to access this view.
//
Function AllowAccess Returns Boolean
    Boolean bAccess
    Integer iUserRights
    
    Forward Get AllowAccess to bAccess
    
    If (bAccess) Begin
        Get piUserRights of ghoWebSessionManager to iUserRights
        
        If (iUserRights < 1) Begin
            Move False to bAccess
        End
    End
    Function_Return bAccess
End_Function
So why can you access all the other views? This is because the WebApp Framework doesn't know that a user needs to be logged in to access this view. The system is designed for this to be enforced by AllowAccess but by default it doesn't check anything. So to make the WebOrder more secure we would have to implement AllowAccess in all the views and check if the user is logged in. The code for doing this is pretty straight forward:
Code:
//
//  Only logged in users should be able to access this view.
//
Function AllowAccess Returns Boolean
    Boolean bRetVal
    Forward Get AllowAccess to bRetVal
    
    If (bRetVal) Begin
        Get IsLoggedIn of ghoWebSessionManager to bRetVal
    End
    
    Function_Return bRetVal
End_Function
Why doesn't the WebApp Framework perform this check by default? To answer that question we'd have to take into consideration the cWebModalDialogs are basically views (they are actually a subclass of cWebView). This means that the same system applies for the login dialog. But the login dialog needs to be accessed before the user logged in right? So the code above shouldn't be placed inside the login dialog. Next thing would probably be a signup view. Or maybe you want to show a "dashboard" style view without having to login first. We thought that this was something that needed to be decided for every view independently and figured that the easiest default would be to allow access.

That wasn't the right choice and the WebOrder sample is the perfect example of this. So in the next build of DataFlex 18.0 we are going to turn this around and make the default to check if the user is logged in. Of course this will be controllable by properties on the view level and on the webapp level. The advice for existing 17.1 users would be to add the method shown above to every view & dialog that should be accessible after login only.

Comments

  1. Sture's Avatar
    It makes really good sense for cWebView's. But will this change also affect the cWebModalDialogs then, or have you filtered that out in the sub-class?

    -Sture
  2. Sture's Avatar
    -
    Updated 5-May-2014 at 05:34 PM by Sture (once is enough)
  3. Harm Wibier's Avatar
    Hi Sture,

    This change will affect modal dialogs as well as these are subclass views. That is actually a good thing as the same security risks applied to modal dialogs as well.

    Regards,