Security in business-oriented languages: COBOL and RPG

Security in software written in business languages (like COBOL) follows a quite different path from software security in “modern” languages. Information flow issues are as much relevant than technical flaws. Knowledge and awareness in dev teams are not widespread. In this post we focus on the security flaws that happen in different business-oriented programming languages, how things could go wrong even with those “safe” languages, and how Kiuwan Software Analytics in the Cloud could help uncovering poorly-understood security flaws.


security photo

Security in business languages: are they “safe”or am I missing something?

When developing or maintaining business applications, typically located at the “back-end” of layered architectures, software security is an essential characteristic, not properly managed in many organizations.

Most development teams are aware of security issues in front-end layers (developed in Java, .Net and similar “modern” languages). There is a wealth of information on the matter and teams frequently follow “secure coding practices” and use early detection facilities (like reviews, security-focused testing, code audits, or static & dynamic analysis tools) to learn on software security and detect/prevent security flaws.

But when experts take a deeper look at the business layer, coded in COBOL, RPG, ABAP and similar “business-oriented” languages, they find overwhelming evidence that many security flaws plague critical software.

Reasons for this situation are multiple: most companies DO NOT have an official policy for “secure coding” in the back-end layer. Developers do not understand how a security flaw is injected in a particular technology, what are the security concerns for common programming constructs or what should be considered to ensure that no security flaws are deployed in production. Specific security-oriented test plans for applications under maintenance are uncommon. And software security specialists are nowadays web-and-mobile-focused; mainframes are unfamiliar beasts for them.

Within “legacy” systems, security exposures and weaknesses were always there, like influenza virus. The problem is that right now applications developed in the 80’s are probably facing (indirectly) the Internet, and the threat level is much higher. Sometimes the approach to security is indirect; think about compliance with PCI DSS in applications working with cardholder data.

Technical flaws, of which SQL injection is a glaring example, are often taken into consideration by organizations and development teams. Information flow issues, related to sensitive data leaking from the intended security domain and reaching unauthorized users, belong to a different story.

Characterizing sensitive information, as well as defining the boundaries between security domains, or determining when data access/modification escapes the proper domain, are rather difficult problems in static analysis. Information flow issues are more important for business-oriented languages than the technical flaws.

 

To recap, security flaws could be there, but their nature is quite different, when compared to the typical ones found in modern languages: information leakage is more important than buffer overflow.

Remember that static analysis systems (like Kiuwan) do not “understand” anything in source code. Static analysis blindly find stipulated patterns (data flows, forbidden calls or improper sequences of operations) provided by the analysis engine plus designed checks. Which is evident for us humans is not so evident for the tool. This is a concern with logical flaws, the meat for security in business-oriented languages.

 

COBOL: the most widespread business-oriented language

Let’s start our discussion with the venerable COBOL, born in 1959. Why COBOL remains on the field? Probably due to the so-called legacy lock-in: If you developed, time ago, a critical application in COBOL, you cannot afford rewriting it from scratch with a modern language.

Some new back-end systems are developed in COBOL; but pure corrective maintenance is rare (“it works”); most of the effort in COBOL apps is devoted to new functionality. New COBOL code is written every day. COBOL certainly will outlive all of us.

Don’t get confused by high-tech industry: you will not find COBOL at Google or Facebook, but you will find it in the back-end at most banks, financial institutions, inssurance companies… We could say that COBOL is the dark matter of programming languages.

Is COBOL a “safe” language? What is the “attack surface” for software written in COBOL? The language itself exposes few attack avenues: a few I/O statements (ACCEPT, DISPLAY), DB access (EXEC SQL and others), data file operations (typically considered trusted sources), and program calls. Dynamic code execution, attacks directed to XML parsing, remote file inclusion, HTTP protocols and that sort of facilities that make modern, web-and-mobile-oriented languages a hacker’s paradise, do not exist in the COBOL language. Support for pointers exist, but this feature is seldom used (so buffer issues common in C-like languages are not frequent).

Let’s start discussing some technical flaws in COBOL, with the well-known SQL Injection in front.

Embedded SQL (via EXEC SQL) is considered safe when static SQL statements with interpolated host variables are used. A precompiler (for example, with DB2 databases) produces modified source code and a database request module, which is bound to a database package/application plan. In short, host variables are considered data, not part of the SQL code (aka “parameterized statement”), which is safe against SQL injection attacks. But do not forget that dynamic SQL (PREPARE or EXECUTE IMMEDIATE) is allowed, and binding does not prevent that the following code could be SQL-injected if host variables X, Y or Z come from untrusted inputs:

In COBOL, data files are typically trusted, but injection attacks, like path traversal, are possible. For example, MicroFocus COBOL allows a SELECT logical-file ASSIGN TO DYNAMIC data-entry , which could allow path manipulation if data-entry is partially controlled by untrusted input. CICS file commands, system functions like CLB_CREATE_DIR, and other routines are vulnerable to path manipulation attacks.

If, for any reason, system commands should be executed in a COBOL program, developers should be aware of command injection flaws, like in the following:

Of course, calling unsafe C library functions from COBOL is a security problem. Never do this:

COBOL does not walk alone —like Liverpool FC supporters ;-)—. COBOL programs are called from batch jobs and online middlewares. Often system calls and execution of CICS commands (via EXEC CICS) are seen in COBOL code. Cryptographic libraries, like IBM ICSF or iSeries Cryptographic Services API, could be misused. Calling C library from COBOL may inherit the known issues with C and its libraries, like buffer overflow. Fortunately, this is unusual.

COBOL is regarded as a “safe” language. Certainly most statements (“verbs”) are relatively safe, as the COBOL compiler adds runtime controls that check validity for operations. For example, table subscripting or ranges in string-like character arrays are checked either by the compiler, or at least may produce an out-of-range runtime error, but unintended memory areas cannot be overwritten (note: such checks could be disabled at compile time, anyway).

But there are ways to evade such runtime checks and pre-processor safe compilation. For example, recent COBOL versions allow dynamic (“heap”) memory allocation and pointer arithmetic. Pointer arithmetic opens the same buffer-overflow issues found in C language. Dynamic memory could be misused (the CEEFTST/CEEFRST routines under IBM System p/iSeries, CBL_ALLOC_MEM/CBL_FREE_MEM under MicroFocus Cobol, or CICS GETMAIN/FREEMAIN commands), like in the following example:

In COBOL, information flows leaking sensitive or private information could be more relevant than technical issues. A violation of a privacy regulation could have a large impact. The following example shows how sensitive information may be exposed to unintended users; the problem is how to discriminate which is sensitive information and unintended access:

A final word about information availability. If you google about “COBOL secure coding”, you will see yourself in an unsettled village. Not all business languages share this situation: information on ABAP secure coding is somewhat more abundant.

Reporting in the old way: RPG

RPG is another “legacy” programming language, also born in the sixties, evolved later by IBM to its modern incarnation (RPG IV). RPG language is used today in IBM platforms, on mainframe and mid-range systems (iSeries, AS/400 or whatever brand IBM currently uses). “Attack surface” is similar to COBOL, with security concerns in RPG code not well-known, as with COBOL.

Regarding technical flaws, RPG uses EXEC SQL for embedded code, that is safe unless dynamic SQL is used, like in the following code:

Developers may code execution of a program whose name comes from an external, untrusted input, leading to a Process Control flaw (CWE 114):

Of course, improper access to system facilities from RPG programs may lead to security flaws. In the following example, the QCMDEXC system routine is the target for a potential Command-Injection flaw (CWE 78):

RPG allows pointer arithmetic, with the built-in “address-of” functions %ADDR / %PADDR. The following RPG code shows a potential buffer over-read flaw due to pointer arithmetic:

As you may guess, similar technical/information flow issues, as with COBOL, may arise if the developer does not follow proper security policy for preventing them. RPG and COBOL are similar with regard to how defects are injected; the language itself is only a vehicle that need due care when driving over business data and system facilities.

 

In the next post, we will see how security flaws may affect code written in another business-oriented language: ABAP, and how Kiuwan can help you to detect and prevent this kind of problems.

Stay tuned!