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.
checkCallingOrSelfPermission()
or checkCallingOrSelfUriPermission()
determine whether the calling program has the required permission to access a certain service or a given URI. However, these functions should be used with care as they can grant access to malicious applications, lacking the appropriate permissions, by assuming your applications permissions.Assert()
with a specific permission it is a way to say that the current controlflow has the specified permission. This in turn leads to the .NET framework stopping any further permission checks as long as it satisfies the needed permissions, meaning that code that calls the code making the call to Assert()
may not have the required permission. The use of Assert()
is helpful in some cases, but can lead to vulnerabilities when this allows a malicious user to get control of a resource that they would not have permission to otherwise.
IPAddress hostIPAddress = IPAddress.Parse(RemoteIpAddress);
IPHostEntry hostInfo = Dns.GetHostByAddress(hostIPAddress);
if (hostInfo.HostName.EndsWith("trustme.com")) {
trusted = true;
}
getlogin()
function is easy to spoof. Do not rely on the name it returns.getlogin()
function is supposed to return a string containing the name of the user currently logged in at the terminal, but an attacker may cause getlogin()
to return the name of any user logged in to the machine. Do not rely on the name returned by getlogin()
when making security decisions.getlogin()
to determine whether or not a user is trusted. It is easily subverted.
pwd = getpwnam(getlogin());
if (isTrustedGroup(pwd->pw_gid)) {
allow();
} else {
deny();
}
String ip = request.getRemoteAddr();
InetAddress addr = InetAddress.getByName(ip);
if (addr.getCanonicalHostName().endsWith("trustme.com")) {
trusted = true;
}
Boolean.getBoolean()
is often confused with Boolean.valueOf()
or Boolean.parseBoolean()
method calls.Boolean.getBoolean()
is often misused as it is assumed to return the boolean value represented by the specified string argument. However, as stated in the Javadoc Boolean.getBoolean(String)
method "Returns true if and only if the system property named by the argument exists and is equal to the string 'true'."Boolean.valueOf(String)
or Boolean.parseBoolean(String)
method.Boolean.getBoolean(String)
does not translate a String primitive. It only translates system property.
...
String isValid = "true";
if ( Boolean.getBoolean(isValid) ) {
System.out.println("TRUE");
}
else {
System.out.println("FALSE");
}
...
GetChars
method in Decoder
& Encoding
classes and the GetBytes
method in Encoder
& Encoding
classes in the .NET Framework internally performs pointer arithmetic on the char & byte arrays to convert range of character into range of bytes and vice versa.
out.println("x = " + encoder.encodeForJavaScript(input) + ";");
...
unichar ellipsis = 0x2026;
NSString *myString = [NSString stringWithFormat:@"My Test String%C", ellipsis];
NSData *asciiData = [myString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *asciiString = [[NSString alloc] initWithData:asciiData encoding:NSASCIIStringEncoding];
NSLog(@"Original: %@ (length %d)", myString, [myString length]);
NSLog(@"Best-fit-mapped: %@ (length %d)", asciiString, [asciiString length]);
// output:
// Original: My Test String... (length 15)
// Best-fit-mapped: My Test String... (length 17)
...
...
let ellipsis = 0x2026;
let myString = NSString(format:"My Test String %C", ellipsis)
let asciiData = myString.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion:true)
let asciiString = NSString(data:asciiData!, encoding:NSASCIIStringEncoding)
NSLog("Original: %@ (length %d)", myString, myString.length)
NSLog("Best-fit-mapped: %@ (length %d)", asciiString!, asciiString!.length)
// output:
// Original: My Test String ... (length 16)
// Best-fit-mapped: My Test String ... (length 18)
...
_alloca()
function can throw a stack overflow exception, potentially causing the program to crash._alloca()
function allocates memory on the stack. If an allocation request is too large for the available stack space, _alloca()
throws an exception. If the exception is not caught, the program will crash, potentially enabling a denial of service attack._alloca()
has been deprecated as of Microsoft Visual Studio 2005(R). It has been replaced with the more secure _alloca_s()
.MAX_PATH
bytes in length, but you should check the documentation for each function individually. If the buffer is not large enough to store the result of the manipulation, a buffer overflow can occur.
char *createOutputDirectory(char *name) {
char outputDirectoryName[128];
if (getCurrentDirectory(128, outputDirectoryName) == 0) {
return null;
}
if (!PathAppend(outputDirectoryName, "output")) {
return null;
}
if (!PathAppend(outputDirectoryName, name)) {
return null;
}
if (SHCreateDirectoryEx(NULL, outputDirectoryName, NULL)
!= ERROR_SUCCESS) {
return null;
}
return StrDup(outputDirectoryName);
}
output\<name>
" in the current directory and returns a heap-allocated copy of its name. For most values of the current directory and the name parameter, this function will work properly. However, if the name
parameter is particularly long, then the second call to PathAppend()
could overflow the outputDirectoryName
buffer, which is smaller than MAX_PATH
bytes.umask()
is often confused with the argument to chmod()
.umask()
man page begins with the false statement:chmod()
, where the user provided argument specifies the bits to enable on the specified file, the behavior of umask()
is in fact opposite: umask()
sets the umask to ~mask & 0777
.umask()
man page goes on to describe the correct usage of umask()
:open()
to set initial file permissions on a newly-created file. Specifically, permissions in the umask are turned off from the mode argument to open(2)
(so, for example, the common umask default value of 022 results in new files being created with permissions 0666 & ~022 = 0644 = rw-r--r-- in the usual case where the mode is specified as 0666)."
...
struct stat output;
int ret = stat(aFilePath, &output);
// error handling omitted for this example
struct timespec accessTime = output.st_atime;
...
umask()
is often confused with the argument to chmod()
.umask()
man page begins with the false statement:chmod()
, where the user provided argument specifies the bits to enable on the specified file, the behavior of umask()
is in fact opposite: umask()
sets the umask to ~mask & 0777
.umask()
man page goes on to describe the correct usage of umask()
:transactionId
to a temporary file in the application Documents directory using a vulnerable method:
...
//get the documents directory:
let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
//make a file name to write the data to using the documents directory:
let fileName = NSString(format:"%@/tmp_activeTrans.txt", documentsPath)
// write data to the file
let transactionId = "TransactionId=12341234"
transactionId.writeToFile(fileName, atomically:true)
...