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.
_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("]]");
});
root
han provocado innumerables desastres de seguridad de Unix. Es imprescindible que revise atentamente los programas con privilegios en relación con todos los tipos de problemas de seguridad, pero es igual de importante restablecer los programas con privilegios a un estado sin ellos tan rápido como sea posible a fin de limitar la cantidad de daños que puede provocar una vulnerabilidad que se pasó por alto.root
a otro. root
cuando se desencadena una señal o se ejecuta un subproceso, el controlador de señales funcionará con privilegios raíz. Es posible que un usuario malintencionado aproveche estos privilegios elevados para realizar aún más daño.root
han causado innumerables desastres de seguridad Unix. Es absolutamente necesario que revise cuidadosamente los programas privilegiados para descubrir cualquier tipo de problema de seguridad, pero es igualmente importante que los programas privilegiados vuelvan a un estado no privilegiado tan pronto como sea posible para limitar el daño total que una vulnerabilidad no detectada pueda causar.root
a otro.root
cuando una señal salta o se ejecuta un subproceso, el tratamiento de señales o el subproceso operará con privilegios de origen. Un atacante puede ser capaz de aprovechar estos privilegios avanzados para hacer más daño.root
han provocado innumerables desastres de seguridad de Unix. Es imprescindible que revise atentamente los programas con privilegios en relación con todos los tipos de problemas de seguridad, pero es igual de importante restablecer los programas con privilegios a un estado sin ellos tan rápido como sea posible a fin de limitar la cantidad de daños que puede provocar una vulnerabilidad que se pasó por alto.root
a otro.root
cuando se desencadena una señal o se ejecuta un subproceso, el controlador de señales funcionará con privilegios raíz. Es posible que un atacante aproveche estos privilegios elevados para realizar aún más daño.root
han provocado innumerables desastres de seguridad de Unix. Es imprescindible que revise atentamente los programas con privilegios en relación con todos los tipos de problemas de seguridad, pero es igual de importante restablecer los programas con privilegios a un estado sin ellos tan rápido como sea posible a fin de limitar la cantidad de daños que puede provocar una vulnerabilidad que se pasó por alto.root
a otro.root
cuando se desencadena una señal o se ejecuta un subproceso, el controlador de señales funcionará con privilegios raíz. Es posible que un usuario malintencionado aproveche estos privilegios elevados para realizar aún más daño....
Device.OpenUri("sms:+12345678910");
...
...
[[CTMessageCenter sharedMessageCenter] sendSMSWithText:@"Hello world!" serviceCenter:nil toAddress:@"+12345678910"];
...
// or
...
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms:+12345678910"]];
...
// or
...
MFMessageComposeViewController *messageComposerVC = [[MFMessageComposeViewController alloc] init];
[messageComposerVC setMessageComposeDelegate:self];
[messageComposerVC setBody:@"Hello World!"];
[messageComposerVC setRecipients:[NSArray arrayWithObject:@"+12345678910"]];
[self presentViewController:messageComposerVC animated:YES completion:nil];
...
...
UIApplication.sharedApplication().openURL(NSURL(string: "sms:+12345678910"))
...
...
let messageComposeVC = MFMessageComposeViewController()
messageComposeVC.messageComposeDelegate = self
messageComposeVC.body = "Hello World!"
messageComposeVC.recipients = ["+12345678910"]
presentViewController(messageComposeVC, animated: true, completion: nil)
...
MultiByteToWideChar()
, WideCharToMultiByte()
, UnicodeToBytes()
y BytesToUnicode()
para convertir cadenas de caracteres multibyte (normalmente ANSI) arbitrarias a cadenas Unicode (carácter ancho) y viceversa. Los argumentos de tamaño para estas funciones están especificados en diferentes unidades (una en bytes y la otra en caracteres) y su uso suele llevar a errores. En una cadena de caracteres multibyte, cada carácter ocupa una cantidad variable de bytes; por lo tanto, el tamaño de dichas cadenas se especifica más fácilmente como un número total de bytes. Sin embargo, en Unicode los caracteres siempre tienen un tamaño fijo y la longitud de las cadenas está definida por el número de caracteres que contienen. La especificación incorrecta de las unidades erróneas en un argumento de tamaño podría provocar un buffer overflow.
void getUserInfo(char *username, struct _USER_INFO_2 info){
WCHAR unicodeUser[UNLEN+1];
MultiByteToWideChar(CP_ACP, 0, username, -1,
unicodeUser, sizeof(unicodeUser));
NetUserGetInfo(NULL, unicodeUser, 2, (LPBYTE *)&info);
}
unicodeUser
en bytes en lugar de hacerlo en caracteres. Así pues, la llamada a MultiByteToWideChar()
puede escribir hasta (UNLEN+1)*sizeof(WCHAR
) caracteres anchos o (UNLEN+1)*sizeof(WCHAR)*sizeof(WCHAR)
bytes, en la matriz unicodeUser
, que solo tiene (UNLEN+1)*sizeof(WCHAR)
bytes asignados. Si la cadena username
contiene más de UNLEN
caracteres, la llamada a MultiByteToWideChar()
desbordará el búfer unicodeUser
.sun.misc.Unsafe
. Las funcionalidades de esta clase son intrínsecamente inseguras y solo se puede acceder a ellas previa reflexión.sun.misc.Unsafe
se utiliza para realizar operaciones inseguras de bajo nivel y no está diseñada para que la usen los desarrolladores.Unsafe
solo se puede obtener mediante un código de confianza y normalmente se obtiene a través de la reflexión, ya que se puede usar para corromper el sistema o asignar manualmente memoria en masa que, si no se maneja adecuadamente, podría tener efectos perjudiciales en el sistema. Es absolutamente necesario que toda la funcionalidad alrededor de sun.misc.Unsafe
se revise y pruebe cuidadosamente para que no tenga fallos.
String password=request.getParameter("password");
...
DefaultUser user = (DefaultUser) ESAPI.authenticator().createUser(username, password, password);
finalize()
solo debe ser llamado por el JVM después de que el objeto haya sido recolectado.finalize()
de objeto sea llamado desde fuera del finalizador, se trata de una mala idea. Por ejemplo, llamar finalize()
explícitamente indica que finalize()
se llamará más de una vez: la primera vez será la llamada explícita y la última vez será la llamada que se hace después de que el objeto sea recolectado.finalize()
explícitamente:
// time to clean up
widget.finalize();
dangerouslySetInnerHTML
El atributo se establece como HTML desde el código innecesariamente.dangerouslySetInnerHTML
en React reemplaza el uso de innerHTML en el DOM del navegador, pero se ha cambiado el nombre de la API para transmitir los peligros potenciales de su uso. En general, configurar HTML desde el código es arriesgado porque es fácil exponer inadvertidamente a los usuarios a un ataque de Cross-Site Scripting (XSS).dangerouslySetInnerHTML
:
function MyComponent(data) {
return (
<div
dangerouslySetInnerHTML={{__html: data.innerHTML}}
/>
);
}
AUTHID CURRENT_USER
, los identificadores se solucionan en primer lugar según el esquema del usuario actual. Esto puede provocar un comportamiento inesperado si el definidor del código no expresa explícitamente a qué esquema pertenece un identificador.SYS.PERMISSIONS
y no podrá modificar los permisos definidos.
CREATE or REPLACE FUNCTION check_permissions(
p_name IN VARCHAR2, p_action IN VARCHAR2)
RETURN BOOLEAN
AUTHID CURRENT_USER
IS
r_count NUMBER;
perm BOOLEAN := FALSE;
BEGIN
SELECT count(*) INTO r_count FROM PERMISSIONS
WHERE name = p_name AND action = p_action;
IF r_count > 0 THEN
perm := TRUE;
END IF;
RETURN perm;
END check_permissions
check_permissions
define una tabla PERMISSIONS
en su esquema, la base de datos decidirá que el identificador haga referencia a la tabla local. El usuario podría tener acceso de escritura a la nueva tabla y podría modificarla para obtener los permisos que de otro modo no tendría.org.apache.struts2.interceptor.ApplicationtAware
, org.apache.struts2.interceptor.SessionAware
y org.apache.struts2.interceptor.RequestAware
. Con el fin de incorporar cualquiera de estos mapas de datos en el código de Actions, los desarrolladores deben implementar el marco que se especifica en la interfaz (por ejemplo: setSession
para la interfaz SessionAware
):
public class VulnerableAction extends ActionSupport implements SessionAware {
protected Map<String, Object> session;
@Override
public void setSession(Map<String, Object> session) {
this.session = session;
}
SessionAware
, RequestAware
, ApplicationAware
.
http://server/VulnerableAction?session.roles=admin
execute()
de la acción.execute()
. El carácter !
(bang) o el prefijo method:
se pueden utilizar en la URL de la acción para invocar a cualquier método público de la acción si se ha habilitado la "invocación de método dinámico". Los desarrolladores que no conocen la existencia de esta función pueden exponer a los atacantes la lógica empresarial interna de forma involuntaria.http://server/app/recoverpassword!getPassword.action
org.apache.struts2.interceptor.ApplicationtAware
, org.apache.struts2.interceptor.SessionAware
y org.apache.struts2.interceptor.RequestAware
. Con el fin de incorporar cualquiera de estos mapas de datos en el código de Actions, los desarrolladores deben implementar el marco que se especifica en la interfaz (por ejemplo: setSession
para la interfaz SessionAware
):
public class VulnerableAction extends ActionSupport implements SessionAware {
protected Map<String, Object> session;
@Override
public void setSession(Map<String, Object> session) {
this.session = session;
}
SessionAware
, RequestAware
, ApplicationAware
.
http://server/VulnerableAction?session.roles=admin
org.apache.struts2.interceptor.ApplicationtAware
, org.apache.struts2.interceptor.SessionAware
y org.apache.struts2.interceptor.RequestAware
. Con el fin de incorporar cualquiera de estos mapas de datos en el código de Actions, los desarrolladores deben implementar el marco que se especifica en la interfaz (por ejemplo: setSession
para la interfaz SessionAware
):
public class VulnerableAction extends ActionSupport implements SessionAware {
protected Map<String, Object> session;
@Override
public void setSession(Map<String, Object> session) {
this.session = session;
}
SessionAware
, RequestAware
, ApplicationAware
.
http://server/VulnerableAction?session.roles=admin