In SAP ABAP development, database access is fundamental to retrieving and manipulating business data. However, improperly handling database queries can expose SAP systems to critical security risks, especially SQL Injection attacks—one of the most common and dangerous vulnerabilities exploited by cybercriminals.
This article explores the concept of prepared statements in SAP ABAP, their importance in secure database access, and how they help prevent injection attacks and maintain data integrity.
SQL Injection occurs when malicious users insert or "inject" unauthorized SQL code through user inputs into database queries. If these inputs are not properly validated or escaped, the injected SQL can manipulate or damage the database, expose sensitive data, or even compromise entire SAP systems.
Example of vulnerable code:
DATA lv_sql TYPE string.
lv_sql = |SELECT * FROM users WHERE username = '{p_username}'|.
EXEC SQL.
EXECUTE IMMEDIATE :lv_sql
ENDEXEC.
If p_username contains malicious SQL, it can alter the intended query.
Prepared statements are a database programming technique where SQL queries are pre-compiled with placeholders for parameters. These placeholders are later bound to user-supplied values safely, ensuring that input data is treated strictly as data—not executable code.
This prevents attackers from injecting malicious SQL because the database treats parameters separately from SQL commands.
While classic ABAP Open SQL doesn’t natively support prepared statements in the way some other languages do, ABAP provides mechanisms to safely pass parameters and avoid dynamic SQL vulnerabilities.
Instead of concatenating strings dynamically, use Open SQL with host variables and parameters.
DATA: lv_username TYPE string VALUE 'john_doe',
lt_users TYPE TABLE OF users,
ls_user LIKE LINE OF lt_users.
SELECT * FROM users INTO TABLE lt_users WHERE username = @lv_username.
LOOP AT lt_users INTO ls_user.
WRITE: / ls_user-username, ls_user-email.
ENDLOOP.
Here, @lv_username safely binds the variable, preventing injection.
If dynamic SQL is required, never concatenate user inputs directly. Use parameter placeholders and proper binding.
DATA: lv_sql TYPE string,
lv_username TYPE string VALUE 'john_doe'.
lv_sql = |SELECT * FROM users WHERE username = ?|.
EXEC SQL.
PREPARE stmt FROM :lv_sql
ENDEXEC.
EXEC SQL.
EXECUTE stmt USING :lv_username
ENDEXEC.
Note: This example is conceptual; native ABAP Open SQL is preferred.
In SAP NetWeaver AS ABAP 7.40 and later, you can use the CL_SQL_PREPARED_STATEMENT class for true prepared statements.
DATA: lo_con TYPE REF TO cl_sql_connection,
lo_stmt TYPE REF TO cl_sql_prepared_statement,
lo_result TYPE REF TO cl_sql_result_set,
lv_username TYPE string VALUE 'john_doe'.
lo_con = cl_sql_connection=>get_connection( ).
lo_stmt = lo_con->prepare_statement( 'SELECT * FROM users WHERE username = ?' ).
lo_stmt->set_string( 1, lv_username ).
lo_result = lo_stmt->execute_query( ).
WHILE lo_result->next( ) = abap_true.
WRITE: / lo_result->get_string( 'username' ), lo_result->get_string( 'email' ).
ENDWHILE.
This method provides full prepared statement support and parameter binding, ensuring maximum security.
Using prepared statements or parameterized queries in SAP ABAP is a critical defense mechanism against SQL Injection attacks and other database-related security threats. By binding user inputs as parameters rather than embedding them directly into SQL strings, developers ensure that inputs are treated as data only, preserving the integrity and confidentiality of SAP databases.
Embracing these secure coding practices not only protects your SAP environment from cybercrimes but also improves application performance and maintainability, aligning with SAP’s best practice security standards.