Un API es un contrato entre un autor de llamada y un receptor de llamada. Las formas de abuso de API más comunes los produce el autor de llamada cuando no consigue atender su fin de este contrato. Por ejemplo, si un programa no consigue llamar chdir() después de llamar chroot(), se viola el contrato que especifica cómo cambiar el directorio de origen activo de una forma segura. Otro buen ejemplo de un abuso de manual es esperar que el receptor devuelva una información de DNS de confianza al autor de llamada. En este caso, el autor de llamada abusa el API del receptor haciendo determinadas suposiciones sobre su comportamiento (que el valor de retorno se puede usar con fines de autenticación). También se puede violar el contrato entre el autor de llamada y el receptor desde el otro lado. Por ejemplo, si un codificador envía SecureRandom y devuelve un valor no aleatorio, se viola el contrato.
IPAddress hostIPAddress = IPAddress.Parse(RemoteIpAddress);
IPHostEntry hostInfo = Dns.GetHostByAddress(hostIPAddress);
if (hostInfo.HostName.EndsWith("trustme.com")) {
trusted = true;
}
getlogin()
es fácil de reemplazar. Por eso, no confíe en el nombre que devuelva.getlogin()
devuelve una cadena que contiene el nombre del usuario registrado actualmente en el terminal. Sin embargo, un atacante podría hacer que getlogin()
devuelva el nombre de todos los usuarios registrado en el equipo. No confíe en el nombre devuelto por getlogin()
cuando tome decisiones relacionadas con la seguridad.getlogin()
para determinar si un usuario es de confianza o no. Es fácil de subvertir.
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()
se confunde a menudo con las llamadas a métodos Boolean.valueOf()
o Boolean.parseBoolean()
.Boolean.getBoolean()
se usa a menudo incorrectamente, ya que se presupone que devuelve el valor booleano representado por el argumento de cadena especificado. Sin embargo, como se indica en el método Boolean.getBoolean(String)
de Javadoc: "Devuelve el valor 'true' solo si existe la propiedad del sistema a la que el argumento ha asignado un nombre y esta es igual a la cadena 'true'".Boolean.valueOf(String)
o Boolean.parseBoolean(String)
.Boolean.getBoolean(String)
no convierte un primitivo de cadena, sino únicamente la propiedad del sistema.
...
String isValid = "true";
if ( Boolean.getBoolean(isValid) ) {
System.out.println("TRUE");
}
else {
System.out.println("FALSE");
}
...
GetChars
en las clases Decoder
y Encoding
, y el método GetBytes
en las clases Encoder
y Encoding
de .NET Framework llevan a cabo aritmética de puntero de forma interna en las matrices de caracteres y bytes para convertir un intervalo de caracteres en un intervalo de bytes y viceversa.
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()
puede lanzar una excepción de desbordamiento de pila, que podría ocasionar el bloqueo del programa._alloca()
asigna memoria en la pila. Si una solicitud de asignación es demasiado grande para el espacio de pila disponible, _alloca()
lanza una excepción. Si la excepción no se detecta, el programa se bloquea, con la posibilidad de que se habilite un ataque por denegación de servicio._alloca()
está en desuso desde Microsoft Visual Studio 2005(R). Se ha sustituido por _alloca_s()
, más seguro.MAX_PATH
bytes, aunque debe consultar la documentación de cada función individualmente. Si el búfer no tiene la longitud suficiente como para almacenar el resultado de la manipulación, podría producirse un desbordamiento de búfer.
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>
" en el directorio actual y devuelve una copia de su nombre asignada por montón. Para la mayoría de los valores del directorio actual y el parámetro de nombre, esta función funcionará correctamente. Sin embargo, si el parámetro name
es especialmente largo, entonces la segunda llamada a PathAppend()
podría provocar el buffer overflow outputDirectoryName
, que tiene menos de MAX_PATH
bytes.umask()
se confunde habitualmente con el argumento para chmod()
.umask()
comienza por la instrucción falsa:chmod()
, cuando el argumento proporcionado por el usuario especifica los bits para habilitar el archivo concreto, el comportamiento de umask()
es precisamente el contrario: umask()
establece umask en ~mask & 0777
.umask()
continúa para describir el uso correcto de umask()
:open()
utiliza umask para establecer los permisos de archivo iniciales de un archivo recién creado. De forma específica, los permisos de umask se desactivan desde el argumento de modo para open(2)
(de esta forma, por ejemplo, el valor predeterminado umask normal de 022 resultados en los archivos que se están creando con permisos 0666 & ~022 = 0644 = rw-r--r-- en el caso habitual donde se encuentra el modo se especifica como 0666)".
...
struct stat output;
int ret = stat(aFilePath, &output);
// error handling omitted for this example
struct timespec accessTime = output.st_atime;
...
umask()
se confunde habitualmente con el argumento para chmod()
.umask()
comienza por la instrucción falsa:chmod()
, cuando el argumento proporcionado por el usuario especifica los bits para habilitar el archivo concreto, el comportamiento de umask()
es precisamente el contrario: umask()
establece umask en ~mask & 0777
.umask()
continúa para describir el uso correcto de umask()
:transactionId
activo en un archivo temporal del directorio Documentos de la aplicación empleando un método vulnerable:
...
//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)
...
posted
. FileUpload
es del tipo System.Web.UI.HtmlControls.HtmlInputFile
.
HttpPostedFile posted = FileUpload.PostedFile;
@Controller
public class MyFormController {
...
@RequestMapping("/test")
public String uploadFile (org.springframework.web.multipart.MultipartFile file) {
...
} ...
}
<?php
$udir = 'upload/'; // Relative path under Web root
$ufile = $udir . basename($_FILES['userfile']['name']);
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $ufile)) {
echo "Valid upload received\n";
} else {
echo "Invalid upload rejected\n";
} ?>
from django.core.files.storage import default_storage
from django.core.files.base import File
...
def handle_upload(request):
files = request.FILES
for f in files.values():
path = default_storage.save('upload/', File(f))
...
<input>
del tipo file
indica que el programa acepta la carga de archivos.
<input type="file">
myModule.config(function($interpolateProvider){
$interpolateProvider.startSymbol("[[");
$interpolateProvider.endSymbol("]]");
});