Swift is a new language developed by Apple for iOS and OS X development. Introduced at Apple’s developer conference WWDC 2014, the language is designed to eventually replace Objective-C and provide several important benefits, one of which is greater resilience against erroneous code. This research, published originally on Dr.Dobb’s, covers how Swift compares with Objective-C from the security perspective.
The Checkmarx researchers based the comparison on Apple’s Secure Coding Guide, examining the various vulnerabilities stated in the document and checking if they can be exploited in Swift. It’s important to mention that only loopholes that exist in Objective-C were explored and not new ones that may exist in Swift. In each case, typical classifications including the category, the severity and also the likelihood of exploitation were used.
Severity: High; Likelihood of Exploit: Medium
The Integer Overflow vulnerability can be exploited when user-supplied input is used in calculating the amount of memory that is to be allocated. When the user input is not validated, there is the potential for a malicious user to enter a number that is too large for the integer data type, which can cause program crashes among other problems. In two’s-complement arithmetic, a negative number is represented by inverting all the bits of the binary number and adding 1. When the digit in the most-significant bit is 1, it indicates a negative number. Therefore, in Objective-C:
Swift shows across-the-board improvement and is immune to the Integer Overflow vulnerability, unlike the older Objective-C.
Severity: Very High; Likelihood of Exploit: High to Very High
A buffer overflow occurs when an application attempts to write data past the end of a buffer. These overflows can cause applications to crash, compromise data, and provide an attack vector for further privilege escalation. Books on software security invariably mention buffer overflows as a major source of vulnerabilities. Approximately 26 percent of the exploits published by United States Computer Emergency Readiness Team (US-CERT) for 2012 involved buffer overflows. In Objective-C, a buffer overflow may be caused by incorrect pointer manipulations, by incorrectly allocating heap memory, or by incorrect C-string manipulation. For example:
The surprising fact is that the same kind of heap overflow can be reproduced in Swift. Although Swift does not have pointers, which are the cause of buffer overflow bugs, it has a capability to call C functions. To make this C function calling possible, Swift provides some pointer-like constructs, such as Unsafe Pointer. By using these constructs, it is eventually possible to reproduce the exact same heap overflow:
Stack overflow is also possible through this C-compatibility mechanism. Here we demonstrate changing the value of a local constant via pointer manipulation:
In sum, the risk of buffer overflows in Swift is lower than in Objective-C due to the lack of pointers, although it is still possible to mistakenly create a loophole. Fortunately, Swift’s term, Unsafe Pointer, is a reminder of the dangers of this feature.
Format String Attack
Severity: High; Likelihood of Exploit: Very High
If an input from an untrusted source is being displayed, the developer needs to be careful not to use the received string for format processing. For example, the code below shows how the syslog standard C library function is used to write a received HTTP request to the system log. Because the syslog function processes format strings, it will process any format strings included in the input packet:
Many format strings can cause problems for applications. For example, suppose an attacker passes the following string in the input packet:
This string retrieves eight items from the stack, assuming that the format string itself is stored on the stack. This might effectively move the stack pointer back to the beginning of the format string. Then the %n token would cause the print function to take the number of bytes written so far and write that value to the memory address stored in the next parameter, which happens to be the format string. Thus, assuming a 32-bit architecture, the AAAA in the format string itself would be treated as the pointer value 0x41414141, and the value at that address would be overwritten with the number 76. This situation can enable the attacker to write arbitrary data into any location. To prevent format string attacks, input data should never be used as a format string. For example, the following code is vulnerable:
But when written like this, it is safe:
The remedy is to use string literals for format strings and route all inputs to substitution parameters. Swift has a new language feature called string interpolation. This is a way of constructing a new String value from a mix of constants, variables, literals, and expressions by including their values inside a string literal. Each item that you insert into the string literal is wrapped in a pair of parentheses, prefixed by a backslash:
Because interpolation is only available for string literals, there is no risk of untrusted input being processed for interpolation. In sum,Swift inherits the format string vulnerability from Objective-C. However, Swift introduces the new string interpolation feature, which is safe from format string attacks.
We have found that Swift behaves no differently than Objective-C regarding the rest of the vulnerabilities described in the Apple Secure Coding Guide. These include:
- Invalidated Input
- Race Conditions
- Interprocess Communication
- Insecure File Operations
- Access Control Problems
- Secure Storage and Encryption
- Social Engineering
- Cross-Site Scripting (XSS) and Injection Attacks
This is due to the fact that these vulnerabilities are not related to language, but originate from the library that Swift inherits from the older Objective-C.
Taking the aforementioned parameters into consideration, we can see that the security standards in Swift are only somewhat better than those found in Objective-C. This is due to the fact that numerous vulnerabilities were located in the Swift classes that enabled calling the Objective-C interfaces. This means that even Swift development needs to be done with security in mind. Following safe coding practices and employing the use of security solutions is mandatory for both Objective-C and Swift. A Static Application Security Testing solution, such as Checkmarx’s Source Code Analysis (SCA) or Sonar, are good ways to identify and eliminate the vulnerabilities mentioned in this article. Penetration (Pen) Testing is also an effective means of testing the robustness of the software.
The vulnerability ratings mentioned in this article were taken from the OWASP portal.