English | Deutsch | Español

Ten golden rules for ABAP authorization checks

February 18, 2016 | From Virtual Forge GmbH

According to Virtual Forge's ongoing Business Application Benchmark and the BIZEC APP/11 standard, insufficient authorization checks are the most common security defect in custom ABAP code. This blog provides insights how to do it right.

BY ANDREAS WIEGENSTEIN, VIRTUAL FORGE

15_Ten_GoldenRules_Key-ea701a481.jpgApplication security is still a new (and too some mysterious) topic for most ABAP developers. Although Virtual Forge gave multiple SAP security talks at conferences (First SAP security talk given at SAP TechEd San Diego in 2004) and has written the reference book about secure ABAP programming ("Sichere ABAP Programmierung", SAP Press, 2009) most ABAP developers still don't know about common risks related to ABAP programming. This is no surprise since there has been virtually no useful documentation on security defects like SQL Injection, ABAP command Injection, Directory Traversal and Cross-Site Scripting available in the places SAP developers usually look. Assuming they can spare some time look, that is. Availability of documentation is improving somewhat. This year (2013), also SAP started writing blogs about the code security best practices we already described years ago in our book. Despite this slight delay, this is good for the general awareness of the topic in the SAP customer community.

Ten golden rules for ABAP authorization checks - SAP Security, Compliance and Quality

In the past, roles and authorizations were synonymous to SAP security. When talking with ABAP developers about ABAP security they usually concluded we mean authorizations. Because SAP is secure and magically protects all custom code. Fortunately today, most companies and developers know better. And we have to thank SAP security researchers for delivering talks on technical SAP security, gaining awareness in the general public.

But although most ABAP developers have been aware of the importance of authority checks already years ago, authorization-defects are still the most common security risk in ABAP code today. That's why it is important to focus on this topic.

Since there is still no comprehensive documentation about why, when and how to write AUTHORITY-CHECKS we are publishing a condensed version of our internal ABAP security guidelines in order to raise awareness and make the SAP world a little more secure.

Virtual Forge's Golden Rules for coding authorization checks in ABAP

I. Perform authority checks
As obvious as it may sound: the first step in enforcing authorizations is to actually code the authority check. Since SAP uses an explicit authorization model, all authority checks must be coded in order to be executed. If there is no authority check in the code, the SAP system will not check any authorizations (with very few exceptions). The numbers in our Business Application Benchmark are clear: Missing authority checks are still the most common security defect related to authorizations in custom code. And they are even quite common in the SAP standard (just look at the security notes of any of the SAP patch days in 2013).

General advice:

  • Check with your business department, if (and which) authorizations are required in order to execute the business logic you provide
  • As a fallback, analyze code that is similar to your business process for authorization checks.
  • If authority checks are required for your custom business logic, add them to your code.

Special advice:

  • Don't rely on S_RFC authorizations. They only determine, *if* a function module can be invoked remotely. They are by no means related to the specific business logic of your custom code. You don't want users with S_RFC * authorizations to be able to issue purchase orders or to raise someone's salary. Auditors don't like this either...
  • Don't rely on authorization groups assigned to reports. They are usually coarse grained, as the same authorization group is used for multiple programs. And they are not necessarily related to the specific business logic of your custom code.
  • Always check start authorizations (with function module AUTHORITY_CHECK_TCODE) when using CALL TRANSACTION, as no explicit start authorization check is performed by the kernel.

II. Perform authority checks according to SAP standard functionality

Make sure that you enforce authorizations only by using the ABAP command AUTHORITY-CHECK or by executing API's that use the ABAP command AUTHORITY-CHECK. Only checks based on AUTHORITY-CHECK appear in the authorization trace and are accepted by auditors. Ignoring this rule can cause a sudden change in your career.

A common bad practice is to base authorizations on usernames and/or table entries. We have even seen this happen in coding of the "Big 4" auditing companies.

General advice:

  • Always use functionality based on the ABAP command AUTHORITY-CHECK in order to perform authorization checks.

III. Check the result of an authority check
When the ABAP statement AUTHORITY-CHECK is executed, the SAP kernel checks if the currently logged on user has the required authorization. The kernel also writes an entry to the authorization trace (transaction ST01), if active. If the user has the required authorization, the global variable sy-subrc is set to zero. It is therefore important to check the status of sy-subrc right after the AUTHORITY-CHECK statement. Otherwise, an entry appears in the authorization trace that suggests a correct check, when actually the check is not enforced at all.

General advice:

  • Always check the result of sy-subrc after you perform an AUTHORITY-CHECK. sy-subrc with value zero means authorization sufficient.
  • Since other ABAP commands also change sy-subrc, make sure to perform the sy-subrc check *immediately* after the AUTHORITY-CHECK.
IV. Perform authority checks for the user that is actually logged on
The command AUTHORITY-CHECK can technically also be used in order to check if any given user (other than the one currently logged on) has any given authorization. This is done with the optional addition FOR USER. However, such practice is rarely useful in custom programs and should be avoided.

General advice:

  • Only check the authorization of the currently logged on user (by avoiding the optional parameter FOR USER).

V. Always use APIs instead of AUTHORITY-CHECK, if they exist
There are multiple SAP APIs for authorization checks. Whenever you discover that SAP provides an API (which is released to customers), use this API instead of the authority check. These API usually perform important additional checks and are maintained by SAP in case the requirements for this kind of authority check change.

General advice:

  • Always use specialized API functions for authorization checks instead of AUTHORITY-CHECK.

Specific advice:

  • Use AUTHORITY_CHECK_TCODE instead of S_TCODE
  • Use AUTHORITY_CHECK_DATASET instead of S_DATASET and S_PATH

VI. Declare all fields of the authorization object
Unfortunately it's technically possible to omit (important) fields when making authority checks. In such a case the authority check is still performed, but with a limited scope. When you initially code authority checks, make use of SAP's pattern button. The pattern automatically includes all fields of the authorization object. However, sometimes developers need to omit certain fields in an authorization check. In such a case, declare that field, but mark it as DUMMY. Why is this better? It makes you intention clear, in case someone else reads your code. If a field is missing, they may think you forgot to declare it. If you use DUMMY they know you intentionally don't consider the field.

General advice:

  • Always make sure to specify all fields of the authorization object you check.
  • If there are fields you don't want to check, mark them as DUMMY in order to make your intentions explicit.

VII. Don't use DUMMY values in important fields
There are several fields in authorization objects that should not be DUMMY'd out (i.e. ignored) in checks. ACTVT is such an example. The activity determines what action (e.g. read, change, delete, ...) is to be performed. If this field is DUMMY'd out, users with read permission may find themselves in the situation where they can change or delete objects, depending on what the custom business code actually does.

General advice:

  • Do not use DUMMY values in important authorization fields like 'ACTVT'

VIII. Don't program privileging authorization checks
Sometimes developers are confused with the "*" in authorization fields, because its usage is not exactly intuitive. To some, the following code appears to check if the user is authorized to read to report specified in the variable lv_prog, no matter in which package it resides.

AUTHORITY-CHECK OBJECT 'S_DEVELOP'

  ID 'DEVCLASS' FIELD '*'
ID 'OBJTYPE' FIELD 'PROG'
ID 'OBJNAME' FIELD lv_prog
ID 'P_GROUP' DUMMY " Field not required in this context
ID 'ACTVT' FIELD '03'.

IF sy-subrc = 0.
READ REPORT lv_prog INTO lt_code.
ENDIF.

However, the "*" value does not mean "authorization is granted in case the user has some package assigned to the DEVCLASS field in his role". It means "authorization is granted in case the user has "*" assigned to the DEVCLASS field in his role", i.e. the user needs the privilege to access all packages.

What is the problem with this? Simple: Such coding forces (role) administrators to assign all users running this program a "*" privilege for S_DEVELOP (read) authorizations. This leads to unnecessary privileges. Therefore always carefully consider which values you use in authorization fields.

General advice:

  • Avoid "*" values in authorization fields, as they force administrators to grant unnecessarily high privileges to users

IX. Make authorization checks early in your business logic
This practice is not necessarily a security best practice. But it helps to provide better usability and to avoid unnecessary computations. If there is an authorization required to execute any given business logic, this should be check immediately. If users to through several steps of a process only to find out that they actually are not authorized to push the final button, they will not donate sweets to your team at Christmas.

General advice:

  • If an authorization check is required for a given business logic, it should be checked as early as possible

X. Perform authorization checks in order to avoid dumps
Some ABAP commands come with an implicit authorization check made by the kernel when they are executed. Examples are OPEN DATASET and CALL 'SYSTEM'. While this is good from a security perspective, it is bad from a robustness perspective. Because the kernel dumps, in case the user does not have the proper authorization.

Specific advice:

  • Always make sure to test for S_DATASET and S_PATH authorizations before you open a server-side file.

Why don't we recommend S_C_FUNC checks before CALL 'SYSTEM'? Because usage of CALL 'SYSTEM' leads to the dark side. And we don't want to encourage developers to follow this path...

Summary
Follow Virtual Forge's Golden Rules for coding authorization checks in ABAP. Proper authorization checks are an important part of your company's security strategy, since they are in scope for all audit activities that are based on the BIZEC APP/11 security standard.

No more excuses for missing, broken or incomplete AUTHORITY CHECKS.
Become an ABAP Jedi, not an ABAP Sith!