var params:Object = LoaderInfo(this.root.loaderInfo).parameters;
var ctl:String = String(params["ctl"]);
var ao:Worker;
if (ctl == "Add) {
ao = new AddCommand();
} else if (ctl == "Modify") {
ao = new ModifyCommand();
} else {
throw new UnknownActionError();
}
ao.doAction(params);
var params:Object = LoaderInfo(this.root.loaderInfo).parameters;
var ctl:String = String(params["ctl"]);
var ao:Worker;
var cmdClass:Class = getDefinitionByName(ctl + "Command") as Class;
ao = new cmdClass();
ao.doAction(params);
if/else
se han eliminado por completo y ahora es posible agregar nuevos tipos de comando sin modificar el distribuidor de comandos.Worker
. Si el distribuidor de comandos sigue siendo responsable del control de acceso, entonces cada vez que los programadores creen una nueva clase que implemente la interfaz Worker
, no deben olvidar modificar el código de control de acceso del distribuidor. Si no pueden modificar el código de control de acceso, algunas clases Worker
no tendrán ningún control de acceso.Worker
sea responsable de realizar la comprobación de control de acceso. A continuación se muestra un ejemplo del código refactorizado:
var params:Object = LoaderInfo(this.root.loaderInfo).parameters;
var ctl:String = String(params["ctl"]);
var ao:Worker;
var cmdClass:Class = getDefinitionByName(ctl + "Command") as Class;
ao = new cmdClass();
ao.checkAccessControl(params);
ao.doAction(params);
Continuation
podría permitir a los atacantes crear rutas de flujo de control inesperadas a través de la aplicación, lo que podría eludir los controles de seguridad.continuationMethod
, que determina el nombre del método al que se llamará al recibir una respuesta.
public Object startRequest() {
Continuation con = new Continuation(40);
Map<String,String> params = ApexPages.currentPage().getParameters();
if (params.containsKey('contMethod')) {
con.continuationMethod = params.get('contMethod');
} else {
con.continuationMethod = 'processResponse';
}
HttpRequest req = new HttpRequest();
req.setMethod('GET');
req.setEndpoint(LONG_RUNNING_SERVICE_URL);
this.requestLabel = con.addHttpRequest(req);
return con;
}
continuationMethod
se establezca mediante parámetros de solicitud de tiempo de ejecución, lo que permite a los atacantes llamar a cualquier función que coincida con el nombre.
...
Dim ctl As String
Dim ao As New Worker()
ctl = Request.Form("ctl")
If (String.Compare(ctl,"Add") = 0) Then
ao.DoAddCommand(Request)
Else If (String.Compare(ctl,"Modify") = 0) Then
ao.DoModifyCommand(Request)
Else
App.EventLog("No Action Found", 4)
End If
...
...
Dim ctl As String
Dim ao As New Worker()
ctl = Request.Form("ctl")
CallByName(ao, ctl, vbMethod, Request)
...
if/else
se han eliminado por completo y ahora es posible agregar nuevos tipos de comando sin modificar el distribuidor de comandos.Worker
. Si el distribuidor de comandos se encarga del control de acceso, cada vez que los programadores creen un número método en la clase Worker
, deben acordarse de modificar la lógica de control de acceso del distribuidor. Si esta lógica de control de acceso se queda obsoleta, algunos métodos Worker
no tendrán ningún control de acceso.Worker
sea responsable de realizar la comprobación de control de acceso. A continuación se muestra un ejemplo del código refactorizado:
...
Dim ctl As String
Dim ao As New Worker()
ctl = Request.Form("ctl")
If (ao.checkAccessControl(ctl,Request) = True) Then
CallByName(ao, "Do" & ctl & "Command", vbMethod, Request)
End If
...
clazz
.
char* ctl = getenv("ctl");
...
jmethodID mid = GetMethodID(clazz, ctl, sig);
status = CallIntMethod(env, clazz, mid, JAVA_ARGS);
...
Ejemplo 2: Similar al ejemplo anterior, la aplicación utiliza el paquete
...
func beforeExampleCallback(scope *Scope){
input := os.Args[1]
if input{
scope.CallMethod(input)
}
}
...
reflect
para recuperar el nombre de una función a la que se va a llamar desde un argumento de la línea de comandos.
...
input := os.Args[1]
var worker WokerType
reflect.ValueOf(&worker).MethodByName(input).Call([]reflect.Value{})
...
String ctl = request.getParameter("ctl");
Worker ao = null;
if (ctl.equals("Add")) {
ao = new AddCommand();
} else if (ctl.equals("Modify")) {
ao = new ModifyCommand();
} else {
throw new UnknownActionError();
}
ao.doAction(request);
String ctl = request.getParameter("ctl");
Class cmdClass = Class.forName(ctl + "Command");
Worker ao = (Worker) cmdClass.newInstance();
ao.doAction(request);
if/else
se han eliminado por completo y ahora es posible agregar nuevos tipos de comando sin modificar el distribuidor de comandos.Worker
. Si el distribuidor de comandos sigue siendo responsable del control de acceso, entonces cada vez que los programadores creen una nueva clase que implemente la interfaz Worker
, no deben olvidar modificar el código de control de acceso del distribuidor. Si no pueden modificar el código de control de acceso, algunas clases Worker
no tendrán ningún control de acceso.Worker
sea responsable de realizar la comprobación de control de acceso. A continuación se muestra un ejemplo del código refactorizado:
String ctl = request.getParameter("ctl");
Class cmdClass = Class.forName(ctl + "Command");
Worker ao = (Worker) cmdClass.newInstance();
ao.checkAccessControl(request);
ao.doAction(request);
Worker
; se puede llamar al constructor predeterminado de cualquier objeto del sistema. Si el objeto no implementa la interfaz de Worker
, se generará una ClassCastException
antes de la asignación a ao
. Sin embargo, si el constructor realiza operaciones que trabajan a favor del usuario malintencionado, el daño ya estará hecho. Aunque este escenario es relativamente benigno en aplicaciones sencillas, en las aplicaciones de mayor tamaño en las que la complejidad crece exponencialmente, es razonable creer que un usuario malintencionado podría encontrar un constructor para aprovecharlo como parte de un ataque.performSelector
, lo que podría permitirles crear rutas de flujo de control inesperadas a través de la aplicación, omitiendo potencialmente las comprobaciones de seguridad.UIApplicationDelegate
.
...
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
NSString *query = [url query];
NSString *pathExt = [url pathExtension];
[self performSelector:NSSelectorFromString(pathExt) withObject:query];
...
$ctl = $_GET["ctl"];
$ao = null;
if (ctl->equals("Add")) {
$ao = new AddCommand();
} else if ($ctl.equals("Modify")) {
$ao = new ModifyCommand();
} else {
throw new UnknownActionError();
}
$ao->doAction(request);
$ctl = $_GET["ctl"];
$args = $_GET["args"];
$cmdClass = new ReflectionClass(ctl . "Command");
$ao = $cmdClass->newInstance($args);
$ao->doAction(request);
if/else
se han eliminado por completo y ahora es posible agregar nuevos tipos de comando sin modificar el distribuidor de comandos.Worker
. Si el distribuidor de comandos sigue siendo responsable del control de acceso, entonces cada vez que los programadores creen una nueva clase que implemente la interfaz Worker
, no deben olvidar modificar el código de control de acceso del distribuidor. Si no pueden modificar el código de control de acceso, algunas clases Worker
no tendrán ningún control de acceso.Worker
sea responsable de realizar la comprobación de control de acceso. A continuación se muestra un ejemplo del código refactorizado:
$ctl = $_GET["ctl"];
$args = $_GET["args"];
$cmdClass = new ReflectionClass(ctl . "Command");
$ao = $cmdClass->newInstance($args);
$ao->checkAccessControl(request);
ao->doAction(request);
Worker
; se puede llamar al constructor predeterminado de cualquier objeto del sistema. Si el objeto no implementa la interfaz de Worker
, se generará una ClassCastException
antes de la asignación a $ao
. Sin embargo, si el constructor realiza operaciones que trabajan a favor del usuario malintencionado, el daño ya estará hecho. Aunque este escenario es relativamente benigno en aplicaciones sencillas, en las aplicaciones de mayor tamaño en las que la complejidad crece exponencialmente, es razonable creer que un usuario malintencionado podría encontrar un constructor para aprovecharlo como parte de un ataque.
ctl = req['ctl']
if ctl=='add'
addCommand(req)
elsif ctl=='modify'
modifyCommand(req)
else
raise UnknownCommandError.new
end
ctl = req['ctl']
ctl << "Command"
send(ctl)
if/else
se han eliminado por completo y ahora es posible agregar nuevos tipos de comando sin modificar el distribuidor de comandos.define_method()
o llamarlos mediante el reemplazo de missing_method()
. Auditar y realizar un seguimiento de estos métodos y de cómo se utiliza el código de control de acceso con ellos resulta muy difícil, y si consideramos que también depende de qué código de biblioteca se cargue, realizar esta tarea correctamente puede convertirse en una misión imposible.
def exec(ctl: String) = Action { request =>
val cmdClass = Platform.getClassForName(ctl + "Command")
Worker ao = (Worker) cmdClass.newInstance()
ao.doAction(request)
...
}
if/else
se han eliminado por completo y ahora es posible agregar nuevos tipos de comando sin modificar el distribuidor de comandos.Worker
. Si el distribuidor de comandos sigue siendo responsable del control de acceso, entonces cada vez que los programadores creen una nueva clase que implemente la interfaz Worker
, no deben olvidar modificar el código de control de acceso del distribuidor. Si no pueden modificar el código de control de acceso, algunas clases Worker
no tendrán ningún control de acceso.Worker
sea responsable de realizar la comprobación de control de acceso. A continuación se muestra un ejemplo del código refactorizado:
def exec(ctl: String) = Action { request =>
val cmdClass = Platform.getClassForName(ctl + "Command")
Worker ao = (Worker) cmdClass.newInstance()
ao.checkAccessControl(request);
ao.doAction(request)
...
}
Worker
; se puede llamar al constructor predeterminado de cualquier objeto del sistema. Si el objeto no implementa la interfaz de Worker
, se generará una ClassCastException
antes de la asignación a ao
. Sin embargo, si el constructor realiza operaciones que trabajan a favor del usuario malintencionado, el daño ya estará hecho. Aunque este escenario es relativamente benigno en aplicaciones sencillas, en las aplicaciones de mayor tamaño en las que la complejidad crece exponencialmente, es razonable creer que un usuario malintencionado podría encontrar un constructor para aprovecharlo como parte de un ataque.performSelector
, lo que podría permitirles crear rutas de flujo de control inesperadas a través de la aplicación, omitiendo potencialmente las comprobaciones de seguridad.UIApplicationDelegate
.
func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
...
let query = url.query
let pathExt = url.pathExtension
let selector = NSSelectorFromString(pathExt!)
performSelector(selector, withObject:query)
...
}
...
Dim ctl As String
Dim ao As new Worker
ctl = Request.Form("ctl")
If String.Compare(ctl,"Add") = 0 Then
ao.DoAddCommand Request
Else If String.Compare(ctl,"Modify") = 0 Then
ao.DoModifyCommand Request
Else
App.EventLog "No Action Found", 4
End If
...
...
Dim ctl As String
Dim ao As Worker
ctl = Request.Form("ctl")
CallByName ao, ctl, vbMethod, Request
...
if/else
se han eliminado por completo y ahora es posible agregar nuevos tipos de comando sin modificar el distribuidor de comandos.Worker
. Si el distribuidor de comandos sigue siendo responsable del control de acceso, siempre que los programadores creen un nuevo método dentro de la clase Worker
, deberán acordarse de modificar el código de control de acceso del distribuidor. Si no pueden modificar el código de control de acceso, algunos métodos de Worker
no tendrán ningún control de acceso.Worker
sea responsable de realizar la comprobación de control de acceso. A continuación se muestra un ejemplo del código refactorizado:
...
Dim ctl As String
Dim ao As Worker
ctl = Request.Form("ctl")
If ao.checkAccessControl(ctl,Request) = True Then
CallByName ao, "Do" & ctl & "Command", vbMethod, Request
End If
...
NSData *imageData = [NSData dataWithContentsOfFile:file];
CC_MD5(imageData, [imageData length], result);
let encodedText = text.cStringUsingEncoding(NSUTF8StringEncoding)
let textLength = CC_LONG(text.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))
let digestLength = Int(CC_MD5_DIGEST_LENGTH)
let result = UnsafeMutablePointer<CUnsignedChar>.alloc(digestLength)
CC_MD5(encodedText, textLength, result)
...
private static final String salt = "";
...
PBEKeySpec pbeSpec=new PBEKeySpec(password);
SecretKeyFactory keyFact=SecretKeyFactory.getInstance(CIPHER_ALG);
PBEParameterSpec defParams=new PBEParameterSpec(salt,100000);
Cipher cipher=Cipher.getInstance(CIPHER_ALG);
cipher.init(cipherMode,keyFact.generateSecret(pbeSpec),defParams);
...
...
const salt = "";
crypto.pbkdf2(
password,
salt,
iterations,
keyLength,
"sha256",
function (err, derivedKey) { ... }
);
...
CCKeyDerivationPBKDF(kCCPBKDF2,
password,
passwordLen,
"",
0,
kCCPRFHmacAlgSHA256,
100000,
derivedKey,
derivedKeyLen);
...
...
$hash = hash_pbkdf2('sha256', $password, '', 100000);
...
from hashlib import pbkdf2_hmac
...
dk = pbkdf2_hmac('sha256', password, '', 100000)
...
...
dk = OpenSSL::PKCS5.pbkdf2_hmac(password, "", 100000, 256, digest)
...
...
let ITERATION = UInt32(100000)
...
CCKeyDerivationPBKDF(CCPBKDFAlgorithm(kCCPBKDF2),
password,
passwordLength,
"",
0,
CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA256),
ITERATION,
derivedKey,
derivedKeyLength)
...
PKCS5_PBKDF2_HMAC(pass, strlen(pass), "2!@$(5#@532@%#$253l5#@$", 2, ITERATION, EVP_sha512(), outputBytes, digest);
...
...
private static final String salt = "2!@$(5#@532@%#$253l5#@$";
...
PBEKeySpec pbeSpec=new PBEKeySpec(password);
SecretKeyFactory keyFact=SecretKeyFactory.getInstance(CIPHER_ALG);
PBEParameterSpec defParams=new PBEParameterSpec(salt,100000);
Cipher cipher=Cipher.getInstance(CIPHER_ALG);
cipher.init(cipherMode,keyFact.generateSecret(pbeSpec),defParams);
...
...
const salt = "some constant value";
crypto.pbkdf2(
password,
salt,
iterations,
keyLength,
"sha256",
function (err, derivedKey) { ... }
);
...
CCKeyDerivationPBKDF(kCCPBKDF2,
password,
passwordLen,
"2!@$(5#@532@%#$253l5#@$",
2,
kCCPRFHmacAlgSHA256,
100000,
derivedKey,
derivedKeyLen);
...
...
$hash = hash_pbkdf2('sha256', $password, '2!@$(5#@532@%#$253l5#@$', 100000)
...
...
from hashlib import pbkdf2_hmac
dk = pbkdf2_hmac('sha256', password, '2!@$(5#@532@%#$253l5#@$', 100000)
...
...
dk = OpenSSL::PKCS5.pbkdf2_hmac(password, '2!@$(5#@532@%#$253l5#@$', 100000, 256, digest)
...
...
let ITERATION = UInt32(100000)
let salt = "2!@$(5#@532@%#$253l5#@$"
...
CCKeyDerivationPBKDF(CCPBKDFAlgorithm(kCCPBKDF2),
password,
passwordLength,
salt,
salt.lengthOfBytesUsingEncoding(NSUTF8StringEncoding),
CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA256),
ITERATION,
derivedKey,
derivedKeyLength)
...
...
crypt(password, "2!@$(5#@532@%#$253l5#@$");
...
...
salt := "2!@$(5#@532@%#$253l5#@$"
password := get_password()
sha256.Sum256([]byte(salt + password)
...
...
Encryptor instance = ESAPI.encryptor();
String hash1 = instance.hash(input, "2!@$(5#@532@%#$253l5#@$");
...
javap -c
para acceder al código desensamblado, que contiene los valores de la sal usada.
...
crypt($password, '2!@$(5#@532@%#$253l5#@$');
...
...
from django.contrib.auth.hashers import make_password
make_password(password, salt="2!@$(5#@532@%#$253l5#@$")
...
require 'openssl'
...
password = get_password()
salt = '2!@$(5#@532@%#$253l5#@$'
hash = OpenSSL::Digest::SHA256.digest(salt + password)
...
...
Rfc2898DeriveBytes rdb8 = new Rfc2898DeriveBytes(password, salt,50);
...
...
#define ITERATION 50
...
PKCS5_PBKDF2_HMAC(pass, sizeof(pass), salt, sizeof(salt), ITERATION, EVP_sha512(), outputBytes, digest);
...
...
final int iterationCount=50;
PBEParameterSpec pbeps=new PBEParameterSpec(salt,iterationCount);
...
...
const iterations = 50;
crypto.pbkdf2(
password,
salt,
iterations,
keyLength,
"sha256",
function (err, derivedKey) { ... }
);
...
#define ITERATION 50
...
CCKeyDerivationPBKDF(kCCPBKDF2,
password,
passwordLen,
salt,
saltLen
kCCPRFHmacAlgSHA256,
ITERATION,
derivedKey,
derivedKeyLen);
...
...
$hash = hash_pbkdf2('sha256', $password, $salt, 50);
...
...
from hashlib import pbkdf2_hmac
dk = pbkdf2_hmac('sha256', password, salt, 50)
...
bcrypt_hash = bcrypt(b64pwd, 11)
bcrypt
en Pycryptodome, es crucial tener en cuenta que el parámetro de costo juega un papel importante en la determinación de la complejidad computacional del proceso de hash subyacente. Se recomienda encarecidamente establecer el parámetro de costo en un valor de al menos 12 para garantizar un nivel de seguridad suficiente. Este valor influye directamente en el tiempo necesario para calcular el hash, lo que hace que sea más costoso computacionalmente para los atacantes potenciales llevar a cabo ataques de fuerza bruta o de diccionario.
require 'openssl'
...
key = OpenSSL::PKCS5::pbkdf2_hmac(pass, salt, 50, 256, 'SHA256')
...
let ITERATION = UInt32(50)
...
CCKeyDerivationPBKDF(CCPBKDFAlgorithm(kCCPBKDF2),
password,
passwordLength,
saltBytes,
saltLength,
CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA256),
ITERATION,
derivedKey,
derivedKeyLength)
...
...
<param name="keyObtentionIterations" value="50"/>
...
CL_ABAP_HMAC->UPDATE
, lo que dará como resultado la creación de un hash basado en ningún dato:
...
DATA: obj TYPE REF TO cl_abap_hmac.
CALL METHOD cl_abap_hmac=>get_instance
EXPORTING
if_key = 'ABCDEFG123456789'
RECEIVING
ro_object = obj.
obj->final( ).
....
CryptCreateHash
, lo que producirá la creación de un hash basado en ningún dato:
...
if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0)) {
break;
}
if(!CryptHashData(hHash, (BYTE*)hashData, strlen(hashData), 0)) {
break;
}
...
MessageDigest.update()
, lo que dará como resultado la creación de un hash basado en ningún dato:
...
MessageDigest messageDigest = MessageDigest.getInstance("SHA-512");
io.writeLine(MyUtilClass.bytesToHex(messageDigest.digest()));
....
...
string hashname = ConfigurationManager.AppSettings["hash"];
...
HashAlgorithm ha = HashAlgorithm.Create(hashname);
...
Example 1
se ejecutará correctamente, pero cualquier persona con acceso a esta función podrá manipular el algoritmo de hash modificando la propiedad hash
. Una vez lanzado el programa, puede resultar muy difícil deshacer un problema relacionado con algoritmos controlados por el usuario, dado que probablemente no habría forma de saber si un usuario malintencionado ha determinado el parámetro del algoritmo de un hash criptográfico específico.
...
Properties prop = new Properties();
prop.load(new FileInputStream("config.properties"));
String algorithm = prop.getProperty("hash");
...
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
messageDigest.update(hashInput.getBytes("UTF-8"));
...
Example 1
se ejecutará correctamente, pero cualquier persona con acceso a esta función podrá manipular el algoritmo de hash modificando la propiedad hash
. Una vez lanzado el programa, puede resultar muy difícil deshacer un problema relacionado con algoritmos controlados por el usuario, dado que probablemente no habría forma de saber si un usuario malintencionado ha determinado el parámetro del algoritmo de un hash criptográfico específico.
require 'openssl'
require 'csv'
...
CSV.read(my_file).each do |row|
...
hash = row[4]
...
digest = OpenSSL::Digest.new(hash, data)
...
end
Example 1
se ejecutará correctamente, pero cualquier persona con acceso a esta función podrá manipular el algoritmo de hash modificando el parámetro hash
del archivo CSV. Una vez lanzado el programa, puede resultar muy difícil deshacer un problema relacionado con algoritmos controlados por el usuario, dado que probablemente no habría forma de saber si un usuario malintencionado ha determinado el parámetro del algoritmo de un hash criptográfico específico.
...
String minimumBits = prop.getProperty("minimumbits");
Hashing.goodFastHash(minimumBits).hashString("foo", StandardCharsets.UTF_8);
...
Example 1
se ejecuta correctamente, pero cualquier persona con acceso a esta funcionalidad puede manipular los bits mínimos utilizados para aplicar hash a la contraseña modificando la propiedad minimumBits
. Una vez que se haya distribuido el programa, puede resultar difícil deshacer un problema relacionado con bits mínimos controlados por el usuario, dado que no puede saber si un usuario malintencionado ha configurado los bits mínimos del hash de la contraseña.
string salt = ConfigurationManager.AppSettings["salt"];
...
Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes("password", Encoding.ASCII.GetBytes(salt));
...
Example 1
se ejecutará correctamente, pero cualquier persona con acceso a esta funcionalidad podrá manipular la sal utilizada para derivar la clave o la contraseña modificando la propiedad salt
. Una vez que se haya distribuido el programa, puede resultar muy difícil deshacer un problema relacionado con sal controlada por el usuario, dado que probablemente no habría forma de saber si un usuario malintencionado ha determinado la sal de un hash de contraseña.
...
salt = getenv("SALT");
PKCS5_PBKDF2_HMAC(pass, sizeof(pass), salt, sizeof(salt), ITERATION, EVP_sha512(), outputBytes, digest);
...
Example 1
se ejecutará correctamente, pero cualquier persona con acceso a esta funcionalidad podrá manipular la sal utilizada para derivar la clave o la contraseña modificando la variable de entorno SALT
. Una vez que se haya distribuido el programa, puede resultar muy difícil deshacer un problema relacionado con sal controlada por el usuario, dado que probablemente no habría forma de saber si un usuario malintencionado ha determinado la sal de un hash de contraseña.
...
Properties prop = new Properties();
prop.load(new FileInputStream("local.properties"));
String salt = prop.getProperty("salt");
...
PBEKeySpec pbeSpec=new PBEKeySpec(password);
SecretKeyFactory keyFact=SecretKeyFactory.getInstance(CIPHER_ALG);
PBEParameterSpec defParams=new PBEParameterSpec(salt,100000);
Cipher cipher=Cipher.getInstance(CIPHER_ALG);
cipher.init(cipherMode,keyFact.generateSecret(pbeSpec),defParams);
...
Example 1
se ejecutará correctamente, pero cualquier persona con acceso a esta funcionalidad podrá manipular la sal utilizada para derivar la clave o la contraseña modificando la propiedad salt
. Una vez que se haya distribuido el programa, puede resultar muy difícil deshacer un problema relacionado con sal controlada por el usuario, dado que probablemente no habría forma de saber si un usuario malintencionado ha determinado la sal de un hash de contraseña.
app.get('/pbkdf2', function(req, res) {
...
let salt = req.params['salt'];
crypto.pbkdf2(
password,
salt,
iterations,
keyLength,
"sha256",
function (err, derivedKey) { ... }
);
}
Example 1
se ejecutará correctamente, pero cualquier persona con acceso a esta funcionalidad podrá manipular la sal utilizada para derivar la clave o la contraseña modificando la propiedad salt
. Una vez que se haya distribuido el programa, puede resultar muy difícil deshacer un problema relacionado con sal controlada por el usuario, dado que probablemente no habría forma de saber si un usuario malintencionado ha determinado la sal de un hash de contraseña.
...
@property (strong, nonatomic) IBOutlet UITextField *inputTextField;
...
NSString *salt = _inputTextField.text;
const char *salt_cstr = [salt cStringUsingEncoding:NSUTF8StringEncoding];
...
CCKeyDerivationPBKDF(kCCPBKDF2,
password,
passwordLen,
salt_cstr,
salt.length,
kCCPRFHmacAlgSHA256,
100000,
derivedKey,
derivedKeyLen);
...
Example 1
se ejecutará correctamente, pero cualquier persona con acceso a esta funcionalidad podrá manipular la sal utilizada para derivar la clave o la contraseña modificando el texto de UITextField inputTextField
. Una vez que se haya distribuido el programa, puede resultar muy difícil deshacer un problema relacionado con sal controlada por el usuario, dado que probablemente no habría forma de saber si un usuario malintencionado ha determinado la sal de un hash de contraseña.
function register(){
$password = $_GET['password'];
$username = $_GET['username'];
$salt = getenv('SALT');
$hash = hash_pbkdf2('sha256', $password, $salt, 100000);
...
Example 1
se ejecutará correctamente, pero cualquier persona con acceso a esta funcionalidad podrá manipular la sal utilizada para derivar la clave o la contraseña modificando la variable de entorno SALT
. Una vez que se haya distribuido el programa, puede resultar muy difícil deshacer un problema relacionado con sal controlada por el usuario, dado que probablemente no habría forma de saber si un usuario malintencionado ha determinado la sal de un hash de contraseña.
import hashlib, binascii
def register(request):
password = request.GET['password']
username = request.GET['username']
salt = os.environ['SALT']
dk = hashlib.pbkdf2_hmac('sha256', password, salt, 100000)
hash = binascii.hexlify(dk)
store(username, hash)
...
Example 1
se ejecutará correctamente, pero cualquier persona con acceso a esta funcionalidad podrá manipular la sal utilizada para derivar la clave o la contraseña modificando la variable de entorno SALT
. Una vez que se haya distribuido el programa, puede resultar muy difícil deshacer un problema relacionado con sal controlada por el usuario, dado que probablemente no habría forma de saber si un usuario malintencionado ha determinado la sal de un hash de contraseña.
...
salt=io.read
key = OpenSSL::PKCS5::pbkdf2_hmac(pass, salt, iter_count, 256, 'SHA256')
...
Example 1
se ejecutará correctamente, pero cualquier persona con acceso a esta funcionalidad podrá manipular la sal utilizada para derivar la clave o la contraseña modificando el texto de salt
. Una vez que se haya distribuido el programa, puede resultar muy difícil deshacer un problema relacionado con sal controlada por el usuario, dado que probablemente no habría forma de saber si un usuario malintencionado ha determinado la sal de un hash de contraseña.
...
@IBOutlet weak var inputTextField : UITextField!
...
let salt = (inputTextField.text as NSString).dataUsingEncoding(NSUTF8StringEncoding)
let saltPointer = UnsafePointer<UInt8>(salt.bytes)
let saltLength = size_t(salt.length)
...
let algorithm : CCPBKDFAlgorithm = CCPBKDFAlgorithm(kCCPBKDF2)
let prf : CCPseudoRandomAlgorithm = CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA256)
CCKeyDerivationPBKDF(algorithm,
passwordPointer,
passwordLength,
saltPointer,
saltLength,
prf,
100000,
derivedKeyPointer,
derivedKeyLength)
...
Example 1
se ejecutará correctamente, pero cualquier persona con acceso a esta funcionalidad podrá manipular la sal utilizada para derivar la clave o la contraseña modificando el texto de UITextField inputTextField
. Una vez que se haya distribuido el programa, puede resultar muy difícil deshacer un problema relacionado con sal controlada por el usuario, dado que probablemente no habría forma de saber si un usuario malintencionado ha determinado la sal de un hash de contraseña.
...
salt = getenv("SALT");
password = crypt(getpass("Password:"), salt);
...
Example 1
se ejecutará correctamente, pero cualquier persona con acceso a esta función podrá manipular la sal utilizada para aplicar hash a la contraseña modificando la variable de entorno SALT
. Además, este código utiliza la función crypt()
, que no debería emplearse para el hash criptográfico de las contraseñas. Una vez que se haya distribuido el programa, puede resultar muy difícil deshacer un problema relacionado con sal controlada por el usuario, dado que probablemente no habría forma de saber si un usuario malintencionado ha determinado la sal de un hash de contraseña.
func someHandler(w http.ResponseWriter, r *http.Request){
r.parseForm()
salt := r.FormValue("salt")
password := r.FormValue("password")
...
sha256.Sum256([]byte(salt + password))
}
Example 1
se ejecutará correctamente, pero cualquier persona con acceso a esta funcionalidad puede manipular sal utilizada para aplicar hash a la contraseña modificando la variable de entorno salt
. Además, este código utiliza la función hash criptográfico Sum256
, que no debería emplearse para hashes criptográficos de contraseñas. Una vez distribuido el programa, resulta muy difícil deshacer un problema relacionado con sal controlada por el usuario, dado que probablemente no habría forma de saber si un usuario malintencionado determinó sal de un hash de contraseña.
...
Properties prop = new Properties();
prop.load(new FileInputStream("local.properties"));
String salt = prop.getProperty("salt");
...
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.reset();
digest.update(salt);
return digest.digest(password.getBytes("UTF-8"));
...
Example 1
se ejecutará correctamente, pero cualquier persona con acceso a esta función podrá manipular la sal utilizada para aplicar hash a la contraseña modificando la propiedad salt
. Una vez que se haya distribuido el programa, puede resultar muy difícil deshacer un problema relacionado con sal controlada por el usuario, dado que probablemente no habría forma de saber si un usuario malintencionado ha determinado o no sal del hash de la contraseña.
import hashlib, binascii
def register(request):
password = request.GET['password']
username = request.GET['username']
salt = os.environ['SALT']
hash = hashlib.md5("%s:%s" % (salt, password,)).hexdigest()
store(username, hash)
...
Example 1
se ejecutará correctamente, pero cualquier persona con acceso a esta función podrá manipular la sal utilizada para aplicar hash a la contraseña modificando la variable SALT
. Además, este código utiliza la función hash criptográfico md5()
, que no debería emplearse para hashes criptográficos de contraseñas. Una vez que se haya distribuido el programa, puede resultar muy difícil deshacer un problema relacionado con sal controlada por el usuario, dado que probablemente no habría forma de saber si un usuario malintencionado ha determinado la sal de un hash de contraseña.
...
salt = req.params['salt']
hash = @userPassword.crypt(salt)
...
Example 1
se ejecutará correctamente, pero cualquier persona con acceso a esta función podrá manipular la sal utilizada para aplicar hash a la contraseña modificando el parámetro salt
. Además, este código utiliza la función String#crypt()
, que no debería emplearse para el hash criptográfico de las contraseñas. Una vez que se haya distribuido el programa, puede resultar muy difícil deshacer un problema relacionado con sal controlada por el usuario, dado que probablemente no habría forma de saber si un usuario malintencionado ha determinado la sal de un hash de contraseña.
let saltData = userInput.data(using: .utf8)
sharedSecret.hkdfDerivedSymmetricKey(
using: SHA256.self,
salt: saltData,
sharedInfo: info,
outputByteCount: 1000
)
Ejemplo 1
se ejecutará correctamente, pero cualquier persona con acceso a esta funcionalidad puede manipular sal utilizada para derivar la clave de cifrado modificando el valor userInput
. Una vez distribuido el programa, resulta muy difícil deshacer un problema relacionado con sal controlada por el usuario, dado que probablemente no habría forma de saber si un usuario malintencionado determinó sal de un hash de contraseña.
...
String seed = prop.getProperty("seed");
Hashing.murmur3_32_fixed(Integer.parseInt(seed)).hashString("foo", StandardCharsets.UTF_8);
...
Example 1
se ejecuta correctamente, pero cualquier persona con acceso a esta funcionalidad puede manipular el valor de inicialización utilizado para aplicar hash a la contraseña modificando la propiedad seed
. Una vez que se haya distribuido el programa, puede resultar difícil deshacer un problema relacionado con valores de inicialización controlados por el usuario, dado que no puede saber si un usuario malintencionado ha determinado o no el valor de inicialización del hash de la contraseña.k
que debe ser criptográficamente aleatorio, mantenerse en secreto y que no debe reutilizarse nunca. Si un atacante puede adivinar el valor de k
o engañar al firmante para que use un valor proporcionado en su lugar, puede recuperar la clave privada y luego falsificar cualquier firma, haciéndose pasar por el firmante legítimo. De manera similar, un atacante puede recuperar la clave privada si el valor de k
se reutiliza para firmar varios mensajes.k
que debe ser criptográficamente aleatorio, mantenerse en secreto y que no debe reutilizarse nunca. Si un atacante puede adivinar el valor de k
o engañar al firmante para que use un valor proporcionado en su lugar, puede recuperar la clave privada y luego falsificar cualquier firma, haciéndose pasar por el firmante legítimo. De manera similar, un atacante puede recuperar la clave privada si el valor de k
se reutiliza para firmar varios mensajes.k
que debe ser criptográficamente aleatorio, mantenerse en secreto y que no debe reutilizarse nunca. Si un atacante puede adivinar el valor de k
o engañar al firmante para que use un valor proporcionado en su lugar, puede recuperar la clave privada y luego falsificar cualquier firma, haciéndose pasar por el firmante legítimo. De manera similar, un atacante puede recuperar la clave privada si el valor de k
se reutiliza para firmar varios mensajes.k
que debe ser criptográficamente aleatorio, mantenerse en secreto y que no debe reutilizarse nunca. Si un atacante puede adivinar el valor de k
o engañar al firmante para que use un valor proporcionado en su lugar, puede recuperar la clave privada y luego falsificar cualquier firma, haciéndose pasar por el firmante legítimo. De manera similar, un atacante puede recuperar la clave privada si el valor de k
se reutiliza para firmar varios mensajes.
...
DSA dsa = new DSACryptoServiceProvider(1024);
...
...
DSA_generate_parameters_ex(dsa, 1024, NULL, 0, NULL, NULL, NULL);
...
...
dsa.GenerateParameters(params, rand.Reader, dsa.L1024N160)
privatekey := new(dsa.PrivateKey)
privatekey.PublicKey.Parameters = *params
dsa.GenerateKey(privatekey, rand.Reader)
...
...
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", "SUN");
SecureRandom random = SecureRandom.getInstance("SHA256PRNG", "SUN");
keyGen.initialize(1024, random);
...
...
from Crypto.PublicKey import DSA
key = DSA.generate(1024)
...
require 'openssl'
...
key = OpenSSL::PKey::DSA.new(1024)
...
EVP_SignUpdate
, lo que producirá la creación de una firma basada en ningún dato:
...
rv = EVP_SignInit(ctx, EVP_sha512());
...
rv = EVP_SignFinal(ctx, sig, &sig_len, key);
...
update
, lo que producirá la creación de una firma basada en ningún dato:
...
Signature sig = Signature.getInstance("SHA256withRSA");
sig.initSign(keyPair.getPrivate());
...
byte[] signatureBytes = sig.sign();
...
Ejemplo 2: El siguiente código deshabilita la validación segura de la firma XML con
Properties props = System.getProperties();
...
properties.setProperty("org.jcp.xml.dsig.secureValidation", "false");
XMLCryptoContext.setProperty
:
DOMCryptoContext cryptoContext = new DOMCryptoContext() {...};
...
cryptoContext.setProperty("org.jcp.xml.dsig.secureValidation", false);
...
CCCrypt(kCCEncrypt,
kCCAlgorithmDES,
kCCOptionPKCS7Padding,
key,
kCCKeySizeDES, // 64-bit key size
iv,
plaintext,
sizeof(plaintext),
ciphertext,
sizeof(ciphertext),
&numBytesEncrypted);
...
...
let iv = getTrueRandomIV()
...
let cStatus = CCCrypt(UInt32(kCCEncrypt),
UInt32(kCCAlgorithmDES),
UInt32(kCCOptionPKCS7Padding),
key,
keyLength,
iv,
plaintext,
plaintextLength,
ciphertext,
ciphertextLength,
&numBytesEncrypted)
...
String
puede suponer una pérdida significativa de entropía.String
.String
.
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
...
KeyGenerator keygen = KeyGenerator.newInstance("AES");
...
SecretKey cryptoKey = keygen.generateKey();
byte[] rawCryptoKey = cryptoKey.getEncoded();
...
String key = new String(rawCryptoKey);
...
String
utilizando el conjunto de caracteres del sistema predeterminado. Sin embargo, no se especifica lo que ocurre cuando se da al constructor bytes fuera del rango válido de este conjunto de caracteres. De esta forma, key
ocasionará una pérdida significativa de entropía en comparación con la clave de cifrado original rawCryptoKey
.
static public byte[] EncryptWithRSA(byte[] plaintext, RSAParameters key) {
try {
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(key);
return rsa.Encrypt(plaintext, false);
}
catch(CryptographicException e) {
Console.WriteLine(e.Message);
return null;
}
}
void encrypt_with_rsa(BIGNUM *out, BIGNUM *in, RSA *key) {
u_char *inbuf, *outbuf;
int ilen;
...
ilen = BN_num_bytes(in);
inbuf = xmalloc(ilen);
BN_bn2bin(in, inbuf);
if ((len = RSA_public_encrypt(ilen, inbuf, outbuf, key, RSA_NO_PADDING)) <= 0) {
fatal("encrypt_with_rsa() failed");
}
...
}
...
import "crypto/rsa"
...
plaintext := []byte("Attack at dawn")
cipherText, err := rsa.EncryptPKCS1v15(rand.Reader, &k.PublicKey, plaintext)
...
public Cipher getRSACipher() {
Cipher rsa = null;
try {
rsa = javax.crypto.Cipher.getInstance("RSA/NONE/NoPadding");
}
catch (java.security.NoSuchAlgorithmException e) {
log("this should never happen", e);
}
catch (javax.crypto.NoSuchPaddingException e) {
log("this should never happen", e);
}
return rsa;
}
+ (NSData *) encryptData:(NSData *) plaintextData withKey:(SecKeyRef *) publicKey {
CFErrorRef error = nil;
NSData *ciphertextData = (NSData*) CFBridgingRelease(
SecKeyCreateEncryptedData(*publicKey,
kSecKeyAlgorithmRSAEncryptionPKCS1,
(__bridge CFDataRef) plaintextData,
&error));
if (error) {
// handle error ...
}
return ciphertextData;
}
function encrypt($input, $key) {
$output='';
openssl_public_encrypt($input, $output, $key, OPENSSL_NO_PADDING);
return $output;
}
...
from Crypto.PublicKey import RSA
message = 'Attack at dawn'
key = RSA.importKey(open('pubkey.der').read())
ciphertext = key.encrypt(message)
...
require 'openssl'
...
key = OpenSSL::PKey::RSA.new 2048
public_encrypted = key.public_encrypt(data) #padding type not specified
...
Example 1
, OpenSSL::PKey::RSA#public_encrypt
solo se llama con una cadena y no especifica el tipo de relleno a utilizar. El relleno se establece de forma predeterminada en OpenSSL::PKey::RSA::PKCS1_PADDING
.
func encrypt(data plaintextData:Data, publicKey:SecKey) throws -> Data {
var error: Unmanaged<CFError>?
guard let ciphertextData = SecKeyCreateEncryptedData(publicKey,
.rsaEncryptionPKCS1,
plaintextData as CFData,
&error) else {
throw error!.takeRetainedValue() as Error
}
return ciphertextData as Data;
}