WebApp Framework Access Restriction
by
, 2-May-2014 at 01:00 PM (36038 Views)
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.
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 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
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.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
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.