
ABAP - Escape
In this article, let's take a closer look at different escape variants that you need for ABAP development and system security.
Table of contents
In this article, we'll look at the escape function and examine in detail why previous examples and classic functions should no longer be used.
Introduction
In web development, it's standard practice to check and process external input to ensure that no control characters end up in the database or, in the worst case, are used for SQL injection. In addition to input, URLs, for example, are also masked because certain characters are not allowed but may be required. For example, an ampersand (&) can be passed in a parameter, but since it is also an HTML control character, it must be replaced.
This is not a tutorial on how to improve the security of your code. We want to draw attention to the importance of the topic and introduce you to the ESCAPE command.
Classic
In classic ABAP development, the ESCAPE_URL method of the CL_HTTP_UTILITY class was used to convert the URL. However, if we perform a security check on an object today, we receive an error message for some objects and classes.
We used the following demo code to generate the message through the ABAP Test Cockpit. The check verifies the use of the ESCAPE methods from the CL_HTTP_UTILITY, CL_HTTP_SERVER, and CL_HTTP_CLIENT objects.
DATA(some_url) = `https://software-heroes.com/authors`.
DATA(escaped_url) = cl_http_utility=>escape_url( some_url ).
escaped_url = cl_web_http_utility=>escape_url( some_url ).
Hint: However, there is still a vagueness in the check here. With ABAP Cloud, the new released API class CL_WEB_HTTP_UTILITY was implemented. This calls the ESCAPE_URL method directly, but does not generate an error message during the security check.
Escape
In this chapter, let's look at the new ESCAPE function in ABAP, which has now been integrated directly into the language. You can find the documentation in the last part of this article if you want to view SAP Help directly.
Constants
To format the output, you need the constants from the CL_ABAP_FORMAT class. Here you can see all constants that begin with "E", like Escape.
This means that ESCAPE can currently cover the following scenarios:
- Markup and JavaScript
- URLs and URIs
- JSON
- REGEX
- String templates
- XSS (Cross Site Scripting)
URL
For example, if we wanted to replace the ESCAPE_URL method, we would have to use the constant E_URI_FULL_LC from the class as the format. This would produce the same result. The statement would then look like this:
DATA(escaped_function) = escape(
val = plain_url
format = cl_abap_format=>e_uri_full_lc ).
Currently, there are different variants for URLs and URIs, which also exchange different characters in the URL. To do this, we'll run all the variants and look at the differences.
String
What about string templates? There's not much that can go wrong with output to the frontend or to a file. Basically, yes, if control characters are used for the string templates, additional variables and content can be output that the user may not have access to. Therefore, there is also the option of escaping in this area.
DATA(template_string) = `This is a { Template } String in a |Box| `.
template_string &&= cl_abap_char_utilities=>cr_lf.
template_string &&= cl_abap_char_utilities=>horizontal_tab.
template_string &&= cl_abap_char_utilities=>newline.
template_string &&= ` End of text`.
DATA(escaped_string) = escape( val = template_string
format = cl_abap_format=>e_string_tpl ).
In the example above, we used different control characters in the string templates, as well as control characters to modify the output, such as a tab or a line break. After executing the escape, we output both strings to the console.
Demos
If you're still using an on-premises system, there are numerous demo reports you can run to see the results and examples. Unfortunately, these variants no longer work in the public cloud; SAP should provide another option for the demos.
Complete Example
Here you can find the complete example from today's article. Since we always make a comparison with the old SAP API, the example can only be used in its entirety in an on-premises system.
CLASS zcl_bs_demo_escape DEFINITION
PUBLIC FINAL
CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
PRIVATE SECTION.
CONSTANTS plain_url TYPE string VALUE `https://swh.com/c-r-v?repo='TIER3'&object=RFC_READ*`.
METHODS atc_check
IMPORTING !out TYPE REF TO if_oo_adt_classrun_out.
METHODS escape_url
IMPORTING !out TYPE REF TO if_oo_adt_classrun_out.
METHODS escape_url_compare
IMPORTING !out TYPE REF TO if_oo_adt_classrun_out.
METHODS escape_string
IMPORTING !out TYPE REF TO if_oo_adt_classrun_out.
ENDCLASS.
CLASS zcl_bs_demo_escape IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
atc_check( out ).
escape_url( out ).
escape_url_compare( out ).
escape_string( out ).
ENDMETHOD.
METHOD atc_check.
DATA(some_url) = `http://`.
DATA(escaped_url) = cl_http_utility=>escape_url( some_url ).
escaped_url = cl_web_http_utility=>escape_url( some_url ).
out->write( some_url ).
out->write( escaped_url ).
ENDMETHOD.
METHOD escape_url.
DATA(escaped_classic) = cl_http_utility=>escape_url( plain_url ).
DATA(escaped_function) = escape( val = plain_url
format = cl_abap_format=>e_uri_full_lc ).
out->write( escaped_classic ).
out->write( escaped_function ).
ENDMETHOD.
METHOD escape_url_compare.
out->write( |Original : { plain_url }| ).
out->write( |E_URL : { escape( val = plain_url
format = cl_abap_format=>e_url ) }| ).
out->write( |E_URL_FULL : { escape( val = plain_url
format = cl_abap_format=>e_url_full ) }| ).
out->write( |E_URI : { escape( val = plain_url
format = cl_abap_format=>e_uri ) }| ).
out->write( |E_URI_FULL : { escape( val = plain_url
format = cl_abap_format=>e_uri_full ) }| ).
out->write( |E_URI_1 : { escape( val = plain_url
format = cl_abap_format=>e_uri_1 ) }| ).
out->write( |E_URI_LC : { escape( val = plain_url
format = cl_abap_format=>e_uri_lc ) }| ).
out->write( |E_URI_FULL_LC: { escape( val = plain_url
format = cl_abap_format=>e_uri_full_lc ) }| ).
ENDMETHOD.
METHOD escape_string.
DATA(template_string) = `This is a { Template } String in a |Box| `.
template_string &&= cl_abap_char_utilities=>cr_lf.
template_string &&= cl_abap_char_utilities=>horizontal_tab.
template_string &&= cl_abap_char_utilities=>newline.
template_string &&= ` End of text`.
DATA(escaped_string) = escape( val = template_string
format = cl_abap_format=>e_string_tpl ).
out->write( template_string ).
out->write( escaped_string ).
ENDMETHOD.
ENDCLASS.
Conclusion
Important: For security reasons, you should always use the escape function and avoid helper classes and methods. Implementation is even simpler than with classes and should be easy to implement.
Source:
SAP Help - Escape



