The Open Web Application Security Project (OWASP) is an online community that produces freely-available articles, methodologies, documentation, tools, and technologies in the field of web application security. In particular they have published the
OWASP Top 10, which describes in detail the major threats against web applications.
In this article we will confront the document with duties of ABAP developer in programming safe user interfaces. There are few simple rules that every ABAP programmer should be aware.
The following sections describe examples for different vulnerabilities in Web application's user interface and explain how to prevent them with secure programming. The trouble with Web applications is that you want users to come to your site and interact with the application. If the user makes unexpected entries an attacker could cause the server or the client/browser to perform unintended actions. Therefore, the first guideline for developing a secure Web application is:
Never trust any information coming from the outside and never assume anything about it.
Input validation
Whenever software processes input, it should be validated. It ensures high data quality and prevents from unexpected input. Proper input validation should consists of 6 steps:
Step 1: Existence and length check
Step 2: Canonicalization
The input variable's content is transformed into its simplest and shortest representation.
Step 3: Type check
Step 4: Range check
Step 5: Whitelist filter
Whitelist is the table that consist items that are allowed.
TYPES whitelist TYPE HASHED TABLE OF string
WITH UNIQUE KEY table_line.
DATA(whitelist_name) = VALUE whitelist( ( `APPLE` ) ( `ORANGE` ) ( `PEACH` ) ).
PARAMETERS p_input TYPE string.
IF NOT line_exists( whitelist_name[ table_line = p_input ] ).
cl_demo_output=>write( `Only the following items are allowed:` ).
cl_demo_output=>display( whitelist_name[] ).
ENDIF.
Step 6: Blacklist filter
Blacklist is the opposite of a whitelist and consist items that are not allowed.
TYPES blacklist TYPE HASHED TABLE OF string
WITH UNIQUE KEY table_line.
DATA(blacklist_name) = VALUE blacklist( ( `APPLE` ) ( `ORANGE` ) ( `PEACH` ) ).
PARAMETERS p_input TYPE string.
IF line_exists( blacklist_name[ table_line = p_input ] ).
cl_demo_output=>write( `The following items are not allowed:` ).
cl_demo_output=>display( blacklist_name[] ).
ENDIF.
Above you can see simple implementation of whitelist and blacklist. Of course its final shape will differ depending on a situation you want to use but you can see a general idea here.
A1 - Injections
Currently, SQL injection is one of the most common injection vulnerabilities in general and in ABAP as well. It consists of the insertion of malicious SQL query by an attacker. Via SQL injection, an attacker can affect database in different ways: read sensitive data, modify content or even shutdown the database.
In case of SAP normal SELECT statements are well secured and it is impossible to perform SQL injection attack. However dynamic SELECT statement where you build your own SQL condition based on user's input are vulnerable for SQL injection.
PARAMETERS: pa_input TYPE string.
*Type " ' OR '1' = '1 " to perform SQL injection attack
DATA(sql_cond) = |carrid = '{ pa_input }'|.
SELECT *
FROM spfli
WHERE (sql_cond)
INTO TABLE @DATA(lt_spfli).
cl_demo_output=>display( lt_spfli ).
Thanks to syntax check an attacker can only gain all the records from the table. Syntax check will raise an error if it finds statement such as: „DROP”, „UNION ALL” etc.
Generally try to use only normal SELECT statement. Do not use native SQL or dynamic SELECT unless it is the only way. If do so, be sure to validate data correctly. You can use whitelist, blacklist, range check etc.
ABAP code itself can be directly injected. It can be done via “INSERT REPORT” and “GENERATE SUBROUTINE POOL” statements.
DATA: lt_prog(200) OCCURS 0 WITH HEADER LINE.
PARAMETERS: lv_comnd(200),
lv_rep(50).
* Type command to be inserted and name of program. Execute code and check out program.
* It contains the inserted code and is active.
READ REPORT lv_rep INTO lt_prog.
INSERT lv_comnd INTO TABLE lt_prog.
INSERT REPORT lv_rep FROM lt_prog.
Generally avoid using a dynamic program generation using user’s input. Instead, create static programs with parameters. If dynamic programs are the only solutions perform proper input validation.
OS command injections are much more dangerous than other injections. They may give an attacker access to OS of a victim. There are possible via statements: "CALL 'SYSTEM' ID 'COMMAND' FIELD command" and "OPEN DATASET ... FILTER".
DATA dbserver TYPE c LENGTH 255.
CALL 'C_SAPGPARAM' ID 'NAME' FIELD 'SAPDBHOST'
ID 'VALUE' FIELD dbserver.
DATA(command) = |ping -c1 { dbserver }|.
DATA(fname) = 'result.dat'.
OPEN DATASET fname FOR OUTPUT IN BINARY MODE FILTER command.
CLOSE DATASET fname.
OPEN DATASET fname FOR INPUT IN BINARY MODE.
DATA result TYPE xstring.
READ DATASET fname INTO result.
CLOSE DATASET fname.
cl_demo_output=>display( cl_abap_codepage=>convert_from( result ) ).
In this example you can see that we can create own command and perform it on the server. In this case it’s only PING command but for sure you can imagine something much more dangerous.
How to do it in the safest way?
If possible, the SXPG framework should be used instead of these two options. Use SM69 translation create a commands whitelist and later use FM SXPG_COMMAND_EXECUTE to call it.
A3 - Sensitive Data Exposure
- Directory traversal attack
In a directory traversal an attacker manipulates a URL in such a way that the Web server executes or reveals the contents of a file anywhere on the server. Path traversal attacks take advantage of special character sequences in URL input parameters, cookies, and HTTP request headers.
A common path traversal attack uses the "../" character sequence to alter the document or resource location requested in a URL. Although most Web servers prevent this method, encoding of the "../" sequence can bypass basic security filters. Result of the successful attack can cause access to redundant information or configuration files.
To prevent path traversal attacks in ABAP programs:
- Do not implement file access functionality that is based on user input, unless there is no other alternative.
- While accessing the file system use FM:
- FILE_GET_NAME - you give logical file name and receive physical path to it,
- FILE_VALIDATE_NAME - checks whether a given filename is within a directory specified.
A7 - Cross-Site Scripting (XSS)
- JavaScript, HTML and CSS injections
Cross-site Scripting (XSS) is an attack of Web application's front-end client by injection of HTML or JS. XSS can occur whenever the application dynamically creates its HTML, JavaScript, or CSS content. This source is then rendered by the victim's Web browser and, thus, interpreted in the victim's current authentication context.
In the example, we see that user input is passed in the HTTP request to the server, processed and returned. In this way the user interface was attacked.
XXS attacks can lead to:
- Leak of confidential information
- Manipulate the application’s front-end client (as a result of user’s actions)
- Hijack the application
- Impersonating the user
Two techniques to prevent XSS attacks are:
- Input validation - we check if input consists potentially dangerous things. We can use blacklist and whitelist.
- Input transformation - encoding special symbols into non special characters that correspond to each special symbol. This helps the browser to determine the difference between actual code and potential XSS attack.
The implementation of the encoding is available as an API in two variants:
- For SAP_BASIS >= 731 there are built-in functions ESCAPE from cl_abap_fromat class
- In all versions of SAP you can use methods from class cl_abap_dyn_prg.
It is possible to encode: JavaScript, HTML, URL and CSS.
A9 - Using Components with Known Vulnerabilities
You can be surprised but OWASP described Using Components with Known Vulnerabilities in it’s TOP TEN. It shows that even if it sounds obviously not all developers follow this rule and it still causes problems. How to prevent that? Solution is easy: don’t use components which you know that they have vulnerabilities.
Conclusions
This article was designed to draw your attention to issues in the field of secure programming of user interfaces. Although examples shown in the article are extremely rare you should be aware that such situations may occur. I hope you see the sense of performing proper user's input validation and you have learned examples of how you can do this.
It's just a cursory review of the subject, so you should deepen this knowledge yourself if interested. You can start with link provided below.
Sources:
Secure Programming – ABAP -
https://help.sap.com/viewer/1a93b7a44ac146b5ad9b6fd95c1223cc/7.5.13/en-US/584d767ed850443c891ad27208...
Secure ABAP development Guide -
https://erpscan.io/tag/secure-abap-development-guide/
SAP documentation, Security Notes -
https://help.sap.com/doc/abapdocu_751_index_htm/7.51/en-US/abendynamic_programming_scrty.htm