How to put proper authority-checks to your custom programs
My daily job is a combination of security and ABAP development. I have blogged about both the topics a lot, but not about the intersection of both the disciplines. I only realized this now. Funny.
Let’s concentrate more on this intersection today and what that very often (from my experience) means for the customers. Not exclusively of course, but way too often customers put an equal mark between the term “application security” and the AUTHORITY-CHECK statement in ABAP. So let’s concentrate on the AUTHORITY-CHECK statement for a moment. I will make the today’s blog more of a checklist with some pointers than a book type story, but that should also work for you I hope.
The basic things (MUST-HAVE)
First of all if you’re not an everyday user of the AUTHORITY-CHECKs in your code, always do the following things (they worked for me in the early days VERY WELL!!). Don’t question these, just do it! The advanced tips and tricks come later.
- Realize that security does not “just happen”. You must code your AUTHORITY-CHECK to protect your data and business logic. There are exceptions to the rule though, checks that are performed by the SAP kernel, but that is so rare that you should always think about security as if that is a hard work you must do, not some magic that “just happens”. Something like with the change documents. You must code the thing so that it runs.
- Read the help for God’s sake! This one sounds very obvious right? Unfortunately people don’t do obvious things. Go to transaction SU21, find your object and read the documentation. Hint: Documentation IS NOT for the slow. It is for those that want to do the job well.
- c) When you’re in SU21 reading the definition of the object (fields etc.), note that there is a WHERE-USED list button at the bottom of the popup. Use it often! It will become your new best friend for AUTHORITY-CHECKS. SAP knows what they’re doing and they do it (reasonably) well. What I am trying to say is that if you do it the way SAP is doing it you will probably code an above-average check. I have seen lots of custom code and if everyone went for this “above average option”, the quality and security of the checks would explode through the roof. And that would make the world a better place (…and more secure at the same time).
- When you actually code the authority-check (so you’re in the development workbench right now), use the pattern button, hmm? Way too often there is a typo or the developer forgot a field or something like this and the AUTHORITY-CHECK is there, but not doing anything.
- Handle the return code. I have mentioned that already and will be mentioning that a lot in this blog and all those coming in the future – security does not just happen. That includes the belief that when you code the AUTHORITY-CHECK, your code is secure. It is not. You MUST REACT to the return code of the check and do something about it. If the AUTHORITY-CHECK says the user is not authorized, you must kick the user out of the transaction (read: “inform the user nicely, return the transaction to a consistent state, but decline the access”). Handling of the return code does not “just happen”. When you use the pattern button in the development workbench, the pattern logic will add the return code (SY-SUBRC) check for you. Complete it and sleep better in the night.
The intermediate things (also MUST-HAVE)
- Get yourself familiar with the concept of a DUMMY check. Help.sap.com will help you with this one the best I guess. Just briefly: you use special keyword DUMMY when coding an AUTHORITY-CHECK without being interested in values of all the fields. Example: you want to see if a user is authorized for ACTIVITY 03 for object XYZ and the object has 4 fields. Then you check ACTVT field value 03 and for all the other fields you use DUMMY. Example of a DUMMY check follows (it illustrates the DUMMY and has nothing to do with the 03 ACTVT example above).
- Why is it important to use DUMMY? One of the things where it helps a lot is with the developers that think they’re smart and they can build something fancy around this AUHTORITY-CHECK. Instead of using DUMMY (typically because they don’t even know about it), they start inventing DUMMY values. They invent values which then don’t exist in the domains behind fields, values that one cannot authorize for in PFCG roles etc. Don’t be inventive, ok? Use existing values for checks. Sometimes Creativity is bad.
- Let me emphasize this one more time: use field values that make sense (that exist in domains, in data etc.). Do not invent “your own little authorization concept just for this application”. Understand that what you hardcode in your programs must then go to the PFCG roles so the users can use your programs and transactions. That means two things: If your security administrator does not call you, he/she gave the access you’re checking in the code. If the admin calls you to say this check can’t stay in this form, it is probably because the check is too strong and forces the admin to give that access to users which in turn means that the users can then use the same access in the standard tools. And that is something the admin does not want. That should help you understand why you need to change the coded checks afterwards.
- The former can lead to various problems like you start creating custom authorization concepts for standard applications (not that you go and start modifying your system, but you use custom objects in custom development to protect standard things differently). Just to be clear: I am not saying you must not invent things, but create the authorization concepts using custom objects for custom development only. Don’t force the administrator to try understand the two concepts. In 99% of the cases SAP’s standard concept is much better, more stable, better documented and understood by more developers (in case the “proud author” of this sidetrack concept leaves the company or a project). If your “new concept” works the same as the “old” concept, it doubles the work and effort and all those things without any benefit. If the new concept works differently would you put your hand on a fire that the development department informs the security administrators well enough to ensure the maximum security and understanding?
- e) The formed situation can also lead to something even more evil. Instead of authorization objects you are tempted to use evil things like check tables (if a user is there with some setting, it means he/she can do something more or less with the application). This information does not go into any trace and is nearly impossible to trace and debug if you’re not aware of the booby-trap.
- Trace your applications (using ST01, SU53 etc.) and compile a list of the AUTHORITY-CHECKs for your security administrator. It will spare you the ping-pong, meetings and certainly one or two tough moments. You should do it regardless of whether you like it or not, it is your job. Information you provide your security administrator with goes to the PFCG roles and also into the transaction SU24 (authorization defaults). It will make you a better person if you familiarize yourself with the transaction, why and how it is used and what is your part of the job in the process.
The “ultimate question” (with answers)
The ultimate question is: “Where do I put the AUTHORITY-CHECK and what type of check do I perform?”
There is no silver bullet answer to the question, but there are some hints and pointers you can follow:
- a) “Where do I put the AUTHORITY-CHECK” part of the question has one shortcut you can and should use. Use release APIs (they perform the correct checks). There is no reason to copy SAP standard code and try to invent and hack at the same time. Just go for BAPIs and that’s it. BAPIs normally perform the correct checks and that is what you need – you need to perform the same checks for the same things standard would perform and the checks will be semantically correct, provided by SAP, tested, documented and also “accepted” by all the other customers. In case the BAPI does not perform the correct checks, you should have a pretty good chance to get it fix on OSS. Of course BAPIs are not always available. In that case read further.
- b) If you invent something completely new, divorced from SAP standard, the way you build an authorization concept of the application is way beyond the scope of this blog. Which leaves us with custom code that uses SAP standard in a new way (after seeing some hundreds of systems let me assure you very little code is actually something “new”). That means that your code is “doing something like transaction or program XYZ”. Well, that means that your code should perform the same checks. That should answer the “what type of check” part of the “ultimate question”. That’s not that difficult, right? Just run the ST01 trace while testing the application that you’re building on top of (or around) and that will tell you two things: which checks you want to perform and HOW you want to perform them. Note that the ST01 trace is capable of taking you to the part of the code where the check happened. That means that you can double-click the ST01 trace line, jump to the standard code and ideally call that code from your application. If not possible, you have a template you can copy into your application at least.
- c) Often you will see that that the code locations you find using the idea from the previous point are central function modules for AUTHORITY-CHECKs on a particular object (or a combination of objects). Use these central functions for checks as much as possible. Often the semantic logic and meaning of the checks and their combinations (and their link to OSS notes and system enhancement options and configuration etc.) are far from being trivial but the interface of these modules is much easier to understand at the same time. You’re welcome to use WHERE-USED list to see how the function is called and mimic that.
- d) I have performed my own research on the point c) – how many AUTHORITY-CHECKs are wrapped in the function modules you can easily reuse. Here is the result: I stopped counting when I reached 100 functions in two hours research. Lesson learnt: Some of these checks are MUST-HAVE (-CALL) because the logic is complex and/or allows BADis and customer functions and customizing and enhancement points etc. In many cases the check (or a group of checks) is relatively simple and it would be possible to copy the thing (don’t do it, believe me!). In these cases there are still the two advantages that should win you to call the function instead of copying the check: when SAP changes/ enhances these functions, your code will require no additional maintenance + these functions return translated messages what went wrong (either as a direct exporting parameter or by setting the system variables and an exception). This is very very cool for international environment and even if you don’t care about translations you should go this way to make the end-user experience consistent – same message is returned by a standard transaction as well as you custom code.
I have worked for many customers, performed code reviews and various additional ABAP code + security checks (including organizational problems!!) and if everyone stick to thesimple rules I listed above, world would really become a better place. Try it. Should work for you, worked for me. Don’t forget the most important thing about SCN and blogs -> please provide feedback, add comments, share your stories. I am looking forward to learning something from you as well.
Best regards, sleep well (and be safe and secure), Otto