An API is a contract between a caller and a callee. The most common forms of API abuse are caused by the caller failing to honor its end of this contract. For example, if a program fails to call chdir() after calling chroot(), it violates the contract that specifies how to change the active root directory in a secure fashion. Another good example of library abuse is expecting the callee to return trustworthy DNS information to the caller. In this case, the caller abuses the callee API by making certain assumptions about its behavior (that the return value can be used for authentication purposes). One can also violate the caller-callee contract from the other side. For example, if a coder subclasses SecureRandom and returns a non-random value, the contract is violated.
DBMS_UTILITY.EXEC_DDL_STATEMENT
will only execute statements classified as part of the Data Definition Language. Other statements not supported by embedded SQL will be silently ignored. This behavior makes it difficult to detect errors when using the procedure.http://www.example.com/index.php?param=...
, the following snippet of php within index.php
will print the value of the URL parameter param
(passed in-place of the "...") to the screen if it matches the POSIX regular expression '^[[:alnum:]]*$'
representing "zero or more alphanumeric characters":
<?php
$pattern = '^[[:alnum:]]*$';
$string = $_GET['param'];
if (ereg($pattern, $string)) {
echo($string);
}
?>
Example 1
operates as expected with alphanumeric input, because the unsafe ereg()
function is used to validate tainted input, it is possible to carry out a cross-site scripting (XSS) attack via null
byte injection. By passing a value for param
containing a valid alphanumeric string followed by a null
byte and then a <script>
tag (e.g. "Hello123%00<script>alert("XSS")</script>"
), ereg($pattern, $string)
will still return true
, as the ereg()
function ignores everything following a null
byte character when reading the input string (left-to-right). In this example, this means that the injected <script>
tag following the null
byte will be displayed to the user and evaluated.xp_cmdshell
cannot be used safely. It should not be used.xp_cmdshell
launches a Windows command shell to execute the provided command string. The command executes either in the default system or a provided proxy context. However, there is no way to limit a user to prespecified set of privileged operations and any privilege grant opens up the user to execute any command string.chroot()
system call could allow attackers to escape a chroot jail.chroot()
system call allows a process to change its perception of the root directory of the file system. After properly invoking chroot()
, a process cannot access any files outside the directory tree defined by the new root directory. Such an environment is called a chroot jail and is commonly used to prevent the possibility that a processes could be subverted and used to access unauthorized files. For instance, many FTP servers run in chroot jails to prevent an attacker who discovers a new vulnerability in the server from being able to download the password file or other sensitive files on the system.chroot()
may allow attackers to escape from the chroot jail. The chroot()
function call does not change the process's current working directory, so relative paths may still refer to file system resources outside of the chroot jail after chroot()
has been called.
chroot("/var/ftproot");
...
fgets(filename, sizeof(filename), network);
localfile = fopen(filename, "r");
while ((len = fread(buf, 1, sizeof(buf), localfile)) != EOF) {
fwrite(buf, 1, sizeof(buf), network);
}
fclose(localfile);
GET
command. The FTP server calls chroot()
in its initialization routines in an attempt to prevent access to files outside of /var/ftproot
. But because the server fails to change the current working directory by calling chdir("/")
, an attacker could request the file "../../../../../etc/passwd
" and obtain a copy of the system password file.java.io
package.FileResponse
instance with user input could allow an attacker to download application binaries or view arbitrary files within protected directories.
from django.http import FileResponse
...
def file_disclosure(request):
path = request.GET['returnURL']
return FileResponse(open(path, 'rb'))
...
Example 2: The following code takes untrusted data and uses it to build a path which is used in a server side forward.
...
String returnURL = request.getParameter("returnURL");
RequestDispatcher rd = request.getRequestDispatcher(returnURL);
rd.forward();
...
...
<% String returnURL = request.getParameter("returnURL"); %>
<jsp:include page="<%=returnURL%>" />
...
...
String returnURL = request.getParameter("returnURL");
return new ModelAndView(returnURL);
...
<webflow:end-state id="finalStep" view="${requestParameters.url}"/>
<webflow:view-state id="showView" view="${requestParameters.test}">
<bean class="org.springframework.web.servlet.view.
InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
InternalResourceViewResolver
will take the prefix it is configured with then concatenate the value passed in the view attribute and finally add the suffix.
...
String returnURL = request.getParameter("returnURL");
return new ActionForward(returnURL);
...
realloc()
to resize buffers that store sensitive information. The function might leave a copy of the sensitive information stranded in memory where it cannot be overwritten.realloc()
function is commonly used to increase the size of a block of allocated memory. This operation often requires copying the contents of the old memory block into a new and larger block. This operation leaves the contents of the original block intact but inaccessible to the program, preventing the program from being able to scrub sensitive data from memory. If an attacker can later examine the contents of a memory dump, the sensitive data could be exposed.realloc()
on a buffer containing sensitive data:
plaintext_buffer = get_secret();
...
plaintext_buffer = realloc(plaintext_buffer, 1024);
...
scrub_memory(plaintext_buffer, 1024);
realloc()
is used, so a copy of the data can still be exposed in the memory originally allocated for plaintext_buffer
.