The Risks of SAP RFC Callbacks and How to Avoid Them
In our recent blog on how to protect your SAP system with the Unified Connectivity Framework (UCON), we talked about minimizing the risk of malicious Remote Function Calls (RFC) into an SAP Production system initiated from other, less protected SAP systems or from other, external clients (Inbound Calls). The UCON framework provides powerful options to get and to stay protected against such RFC calls.
These attacks can be launched by bad actors, however they must first obtain the credentials of a valid user in the production system.The user must have the appropriate authorizations to execute the malicious function module (S_RFC authorization) as well as to successfully pass every authorization check implemented explicitly in the function module.
However, user credentials to execute this attack are not needed if an RFC callback is used to get into the production system.
What is an RFC Callback?
If an RFC call is initiated on a production system that connects to a less protected SAP system (outbound call), the called function module can be manipulated by an attacker. The attacker can compromise the target system and enable it to start an RFC call back to the production system. The attacker can use the predefined RFC destination BACK in order to start the malicious callback. A callback is then executed on the production system in the user context of the production user who started the original outbound call, so there is no need for user credentials.
Example: An attacker has access to a poorly protected system and manipulates the source code of SAP function module RFC_PING so that it will call function module BAPI_USER_CREATE with destination BACK. He or she asks the system administrator of the production system for a connection test from production to the compromised system. The administrator starts transaction SM59 to initiate the test.
Due to the manipulated RFC_PING module in the target system, a new user will be created unnoticed on the production system, in the user context of the SAP admin user. Fortunately, RFC function calls via callback require the appropriate S_RFC authorizations for the user who initiated the initial RFC call on the production system. This highlights an important reason not to assign authorizations on authorization object S_RFC too generously – even to SAP admins.
System Protection Against RFC Callbacks
As of SAP NetWeaver 740 (downported to SAP NW 731 with Kernel 7.21 SP 321), SAP has introduced the concept of callback allowlists. This concept is very granular and enables the definition of a separate allowlist for each RFC destination via transaction SM59. An allowlist includes pairs of calling function modules and allowed callback functions.
Example: To allow function module RFC_READ_TABLE as a callback inside function module ZTF_OUTBOUND, the following allowlist entry is required:
Note: On some screens SAP uses the term “Positive List” on others “Allowlist”.
Allowlists can be active or inactive. The impact of an allowlist’s activation status depends on SAP profile parameter rfc/callback_security_method. Possible values for this parameter are:
Permitted callback, that would be rejected in case the existing inactive allowlist would be activated:
The parameter rfc/callback_security_method can be changed dynamically via transaction RZ11. However, this should only be an option for temporary tests and it is strongly recommended to set the parameter value in the default profile of the SAP system. The current parameter value can also be seen in transaction SM59(Refer to table column SM59 Indicator) .
Generation of Initial Allowlists
Similar to the activation of UCON, the biggest challenge of the callback protection concept is the initial feed of the allowlists. Fortunately, SAP provides technical support here, too. An important prerequisite is the activation of the Security Audit Log events:
- DUI: RFC callback executed (destination &A, called &B, callback &C)
- DUJ: RFC callback rejected (destination &A, called &B, callback &C)
- DUK: RFC callback in simulation mode (destination &A, called &B, callback &C)
The typical approach is to set rfc/callback_security_method to the value 2 (Simulation Mode) for some months. The SAP Security Audit Log(SAL) reports any permitted and any rejected callback attempt during this phase. At the end of the phase, transaction SM59 can be used to automatically generate allowlists based on the logged callback information. After calling the menu option:
RFC -> Generate RFC Callback Allowlist
or using the corresponding button,
you can restrict the time interval that is analyzed in the SAL. The resulting list includes all Called Function Module/Callback Function Module pairs that have been processed during the analysis interval and the number of processing for each defined RFC destination. You can select all records or exclude some of them before generating (and optionally activating) the allowlists. Afterwards you can switch parameter rfc/callback_security_method to the value 3.
Note: According to SAP’s Secure by default initiative the default value for rfc/callback_security_method has been changed from 1 to 3 as of SAP S/4HANA 1909.
Source Code Protection Against RFC Callbacks
A callback protection can also be achieved in the source code object containing synchronous calls to RFC function modules. Calling the function module RFC_CALLBACK_REJECTED before the first RFC function call disables the possibility to use callbacks on the target system:
CALL FUNCTION ‘RFC_CALLBACK_REJECTED’
REJECT_OPTION = ‘S’
SET_REJECT_STATE = ‘X’
INVALID_REJECT_OPTION = 1
INVALID_REJECT_STATE = 2
FUNCTION_NOT_SUPPORTED = 3
INTERNAL_ERROR = 4
OTHERS = 5.
This protection is the most secure one as it is always active, independent of the profile parameter rfc/callback_security_method. Thus, the outbound call is protected even if the profile parameter is set to an insecure value, by accident or on purpose. In the first months after introducing callback allowlists, there were also some SAP notes recommending to not set rfc/callback_security_method to 3 as some SAP standard functions did not work any longer due to the restrictive callback protection.
Dependency Between UCON and RFC Callback Protection
There is a dependency between UCON and RFC callback protection that undermines the granularity provided by the allowlist concept for callbacks. When UCON is activated, it is not sufficient to put the required Called Function Module/Callback Function Module pair onto the active allowlist of the affected RFC destination. You also have to add the Callback Function Module to the default communication assembly(CA) in UCON. That means that if you want to use a function module in a very specific, local RFC callback scenario, between your production system and one other system, you have to expose it in general! A separate UCON CA exposing its members only for callback scenarios would help a lot here, see the example below.
In order to allow the RFC scenario above, it needs an RFC callback allowlist entry on system A, for the destination used, to connect to system B:
“Function Module A/ Function Module B”
If UCON is activated on system A, but function module B is not included in the default CA, the callback will fail:
When function module B is added to the default CA on system A, it can be called in general from outside the system:
The risks of RFC callbacks can be minimized by activating the allowlist concept for RFC destinations. Both UCON and callback protection should be used as additional security layers on top of the authorization concept. Customers using The Onapsis Platform are also provided additional protection. Onapsis provides several checks against RFC callbacks. These checks include protection measures on a system level, on a source code level, and on a transport level.The checks performed are if:
- SAP profile parameter rfc/callback_security_method is set to 3
- SAP profile parameter auth/rfc_authority_check is set to 6
- An RFC enabled function module contains an explicit authorization check
- Function module RFC_CALLBACK_REJECTED is called before starting an RFC call
- A transport request doesn’t contain callback allowlist entries
- A transport request doesn’t contain activation status information of a callback allowlist