Segurança de software não é o mesmo que software de segurança. Aqui, estamos interessados em tópicos como autenticação, controle de acesso, confidencialidade, criptografia e gestão de privilégios.
URL url = new URL("https://myserver.org");
URLConnection urlConnection = url.openConnection();
InputStream in = urlConnection.getInputStream();
SSLSocketFactory
subjacente usado pelo URLConnection
não foi alterado, ele usará o padrão que confiará em todas as ACs presentes no armazenamento de chaves padrão do Android.
val url = URL("https://myserver.org")
val data = url.readBytes()
SSLSocketFactory
subjacente usado pelo URLConnection
não foi alterado, ele usará o padrão que confiará em todas as ACs presentes no armazenamento de chaves padrão do Android.
NSString* requestString = @"https://myserver.org";
NSURL* requestUrl = [NSURL URLWithString:requestString];
NSURLRequest* request = [NSURLRequest requestWithURL:requestUrl
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:10.0f];
NSURLConnection* connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
NSURLConnectionDelegate
definidos para manipular a verificação de certificados, ele usará os sistemas que confiarão em todas as ACs presente no armazenamento de chaves padrão do iOS.
let requestString = NSURL(string: "https://myserver.org")
let requestUrl : NSURL = NSURL(string:requestString)!;
let request : NSURLRequest = NSURLRequest(URL:requestUrl);
let connection : NSURLConnection = NSURLConnection(request:request, delegate:self)!;
NSURLConnectionDelegate
definidos para manipular a verificação de certificados, ele usará os sistemas que confiarão em todas as ACs presente no armazenamento de chaves padrão do iOS.
...
private bool CertificateCheck(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
...
return true;
}
...
HttpWebRequest webRequest = (HttpWebRequest) WebRequest.Create("https://www.myTrustedSite.com");
webRequest.ServerCertificateValidationCallback = CertificateCheck;
WebResponse response = webRequest.GetResponse();
...
...
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, verify_callback);
...
...
config := &tls.Config{
// Set InsecureSkipVerify to skip the default validation
InsecureSkipVerify: true,
...
}
conn, err := tls.Dial("tcp", "example.com:443", conf)
..
...
Email email = new SimpleEmail();
email.setHostName("smtp.servermail.com");
email.setSmtpPort(465);
email.setAuthenticator(new DefaultAuthenticator(username, password));
email.setSSLOnConnect(true);
email.setFrom("user@gmail.com");
email.setSubject("TestMail");
email.setMsg("This is a test mail ... :-)");
email.addTo("foo@bar.com");
email.send();
...
smtp.mailserver.com:465
, este aplicativo aceitaria prontamente um certificado emitido para "hackedserver.com
". Agora, o aplicativo potencialmente vazaria informações confidenciais do usuário em uma conexão SSL interrompida com o servidor invadido.
...
var options = {
key : fs.readFileSync('my-server-key.pem'),
cert : fs.readFileSync('server-cert.pem'),
requestCert: true,
...
}
https.createServer(options);
...
https.Server
é criado, a configuração requestCert
é especificada como true
, mas rejectUnauthorized
não é definido, o que padroniza como false
. Isso significa que, embora o servidor tenha sido criado com a intenção de verificar os clientes via SSL, as conexões ainda serão aceitas mesmo se o certificado não for autorizado com a lista de ACs fornecidas.
var tls = require('tls');
...
tls.connect({
host: 'https://www.hackersite.com',
port: '443',
...
rejectUnauthorized: false,
...
});
rejectUnauthorized
foi definido como false, isso significa que os certificados não autorizados serão aceitos, e uma conexão segura com o servidor não identificado ainda será criada. Agora, é possível que ele deixe vazar informações confidenciais dos usuários em uma conexão SSL interrompida com o servidor invadido.NSURLConnectionDelegate
para aceitar qualquer certificado HTTPS:
implementation NSURLRequest (IgnoreSSL)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString *)host
{
return YES;
}
@end
NSURLRequest
do Example 1
, nenhum aviso ou erro resultará se o certificado solicitado do servidor for autoassinado (e, portanto, não verificado). Como resultado, o aplicativo potencialmente vazaria agora informações confidenciais do usuário por meio da conexão SSL quebrada.
...
import ssl
ssl_sock = ssl.wrap_socket(s)
...
require 'openssl'
...
ctx = OpenSSL::SSL::SSLContext.new
ctx.verify_mode=OpenSSL::SSL::VERIFY_NONE
...
NSURLConnectionDelegate
para aceitar qualquer certificado HTTPS:
class Delegate: NSObject, NSURLConnectionDelegate {
...
func connection(connection: NSURLConnection, canAuthenticateAgainstProtectionSpace protectionSpace: NSURLProtectionSpace?) -> Bool {
return protectionSpace?.authenticationMethod == NSURLAuthenticationMethodServerTrust
}
func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge) {
challenge.sender?.useCredential(NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!), forAuthenticationChallenge: challenge)
challenge.sender?.continueWithoutCredentialForAuthenticationChallenge(challenge)
}
}
NSURLConnectionDelegate
do Example 1
, nenhum aviso ou erro resultará se o certificado solicitado do servidor for autoassinado (e, portanto, não verificado). Como resultado, o aplicativo potencialmente vazaria agora informações confidenciais do usuário por meio da conexão SSL quebrada.NSURLSession
, a validação de cadeia de SSL/TLS é manipulada pelo método delegado de autenticação do aplicativo, mas, em vez de fornecer credenciais para autenticar o usuário (ou seu aplicativo) no servidor, o aplicativo verifica as credenciais fornecidas pelo servidor durante o handshake SSL/TLS e informa o sistema de carregamento de URL se ele deve aceitar ou rejeitar essas credenciais. O seguinte código mostra um NSURLSessionDelgate
que passa umaproposedCredential
do desafio recebido de volta como uma credencial para a sessão, ignorando efetivamente a verificação do servidor:
class MySessionDelegate : NSObject, NSURLSessionDelegate {
...
func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {
...
completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, challenge.proposedCredential)
...
}
...
}
...
FINAL(client) = cl_apc_tcp_client_manager=>create(
i_host = ip_adress
i_port = port
i_frame = VALUE apc_tcp_frame(
frame_type =
if_apc_tcp_frame_types=>co_frame_type_terminator
terminator =
terminator )
i_event_handler = event_handler ).
...
client
e o servidor remoto fica vulnerável a comprometimento, porque é transmitido por um canal não criptografado e não autenticado.
...
HttpRequest req = new HttpRequest();
req.setEndpoint('http://example.com');
HTTPResponse res = new Http().send(req);
...
HttpResponse
de entrada, res
, pode ter sido comprometida, pois ela é entregue através de um canal não criptografado e não autenticado.
var account = new CloudStorageAccount(storageCredentials, false);
...
String url = 'http://10.0.2.2:11005/v1/key';
Response response = await get(url, headers: headers);
...
response
, pode ter sido comprometida, pois ela é entregue por meio de um canal não criptografado e não autenticado.
helloHandler := func(w http.ResponseWriter, req *http.Request) {
io.WriteString(w, "Hello, world!\n")
}
http.HandleFunc("/hello", helloHandler)
log.Fatal(http.ListenAndServe(":8080", nil))
URL url = new URL("http://www.android.com/");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
readStream(in);
...
}
instream
, pode ter sido comprometido, pois ele é entregue através de um canal não criptografado e não autenticado.
var http = require('http');
...
http.request(options, function(res){
...
});
...
http.IncomingMessage
, res
, pode ter sido comprometido, uma vez que é entregue por meio de um canal não criptografado e não autenticado.
NSString * const USER_URL = @"http://localhost:8080/igoat/user";
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:USER_URL]];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
...
stream_socket_enable_crypto($fp, false);
...
require 'net/http'
conn = Net::HTTP.new(URI("http://www.website.com/"))
in = conn.get('/index.html')
...
in
, pode ter sido comprometido, pois ele é entregue através de um canal não criptografado e não autenticado.
val url = Uri.from(scheme = "http", host = "192.0.2.16", port = 80, path = "/")
val responseFuture: Future[HttpResponse] = Http().singleRequest(HttpRequest(uri = url))
responseFuture
, pode ter sido comprometida, pois ela é entregue através de um canal não criptografado e não autenticado.
let USER_URL = "http://localhost:8080/igoat/user"
let request : NSMutableURLRequest = NSMutableURLRequest(URL:NSURL(string:USER_URL))
let conn : NSURLConnection = NSURLConnection(request:request, delegate:self)
Config.PreferServerCipherSuites
controla se o servidor segue a preferência de conjunto de criptografia do cliente ou do servidor. O uso do conjunto de criptografia de preferência do cliente poderá introduzir vulnerabilidades de segurança, caso ele possua problemas conhecidos.PreferServerCipherSuites
como false
.
conf := &tls.Config{
PreferServerCipherSuites: false,
}
client = SSHClient()
algorithms_to_disable = { "ciphers": untrusted_user_input }
client.connect(host, port, "user", "password", disabled_algorithms=algorithms_to_disable)
SSHClient.connect(...)
a usar o algoritmo mais fraco 3DES-CBC.
...
Using(SqlConnection DBconn = new SqlConnection("Data Source=210.10.20.10,1433; Initial Catalog=myDataBase;User ID=myUsername;Password=myPassword;"))
{
...
}
...
...
insecure_config = {
'user': username,
'password': retrievedPassword,
'host': databaseHost,
'port': "3306",
'ssl_disabled': True
}
mysql.connector.connect(**insecure_config)
...
NSURLSession
, NSURLConnection
ou CFURL
no iOS 9 ou OS X El Capitan, que forçam o aplicativo a usar HTTPS
com TLS 1.2
para todas as comunicações de rede com o servidor back-end.Info.plist
irão desativar totalmente o App Transport Security:Exemplo 2: As seguintes entradas no aplicativo
<key>NSAppTransportSecurity</key>
<dict>
<!--Include to allow all connections (DANGER)-->
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Info.plist
irão desativar o App Transport Security para yourserver.com
:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>yourserver.com</key>
<dict>
<!--Include to allow subdomains-->
<key>NSIncludesSubdomains</key>
<true/>
<!--Allow plain HTTP requests-->
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
<!--Downgrades TLS version-->
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
</dict>
</dict>
</dict>
<a href="http://www.example.com/index.html"/>
www.example.com
para carregar sua própria página da Web.
...
using var channel = GrpcChannel.ForAddress("https://grpcserver.com", new GrpcChannelOptions {
Credentials = ChannelCredentials.Insecure
});
...
...
ManagedChannel channel = Grpc.newChannelBuilder("hostname", InsecureChannelCredentials.create()).build();
...
None
. Os dados enviados com configurações de credencial de canal não seguras não são confiáveis.root_certificates
será definido como None
, o valor do parâmetro private_key
será definido como None
e o valor do parâmetro certificate_chain
será definido como None
.
...
channel_creds = grpc.ssl_channel_credentials()
...
...
Server server = Grpc.newServerBuilderForPort(port, InsecureServerCredentials.create())
...
None
ou False
. Os dados enviados de e para um servidor com configurações de credenciais de servidor inseguras não são confiáveis.
...
pk_cert_chain = your_organization.securelyGetPrivateKeyCertificateChainPairs()
server_creds = grpc.ssl_server_credentials(pk_cert_chain)
...
HSTS
(HTTP Strict Transport Security), mas não aplica essa proteção a subdomínios, o que permite aos invasores roubar informações confidenciais de conexões de subdomínios realizando ataques de remoção de HTTPS.HSTS
(HTTP Strict Transport Security) é um cabeçalho de segurança que instrui o navegador a sempre se conectar a um site que retorna os cabeçalhos HSTS via SSL/TLS durante um período especificado no cabeçalho. Qualquer conexão com o servidor via HTTP é substituída automaticamente por uma conexão HTTPS, mesmo que o usuário digite uma URL com http://
na barra de URL do navegador.
<http auto-config="true">
...
<headers>
...
<hsts include-sub-domains="false" />
</headers>
</http>
HSTS
), mas falha ao aplicar essa proteção a subdomínios, permitindo aos atacantes roubar informações confidenciais das conexões de subdomínios ao realizar ataques de retirada de HTTPS.HSTS
) é um cabeçalho de segurança que instrui o navegador a sempre conectar a um site que retorne os cabeçalhos HSTS via SSL/TLS durante um período especificado no cabeçalho. Qualquer conexão ao servidor via HTTP será automaticamente substituída por uma conexão HTTPS, mesmo se o usuário digitar http://
na barra de URL do navegador.HSTS
(HTTP Strict Transport Security). Isso permite que invasores substituam conexões SSL/TLS por conexões HTTP simples e roubem informações confidenciais executando ataques de remoção de HTTPS.HSTS
(HTTP Strict Transport Security) é um cabeçalho de segurança que instrui o navegador a sempre se conectar a um site que retorna os cabeçalhos HSTS via SSL/TLS durante um período especificado no cabeçalho. Qualquer conexão com o servidor via HTTP é substituída automaticamente por uma conexão HTTPS, mesmo que o usuário digite uma URL com http://
na barra de URL do navegador.
<http auto-config="true">
...
<headers>
...
<hsts disabled="true" />
</headers>
</http>
HSTS
), o que permite que invasores substituam conexões SSL/TLS por HTTP simples e roubem informações confidenciais executando ataques de remoção de HTTPS.HSTS
) é um cabeçalho de segurança que instrui o navegador a sempre conectar a um site que retorne os cabeçalhos HSTS via SSL/TLS durante um período especificado no cabeçalho. Qualquer conexão ao servidor via HTTP será automaticamente substituída por uma conexão HTTPS, mesmo se o usuário digitar http://
na barra de URL do navegador.HSTS
), o que permite aos atacantes substituir as conexões SSL/TLS por conexões HTTP simples e roubar informações confidenciais ao realizar ataques de remoção de HTTPS.HSTS
) é um cabeçalho de segurança que instrui o navegador a sempre conectar a um site que retorne os cabeçalhos HSTS via SSL/TLS durante um período especificado no cabeçalho. Qualquer conexão ao servidor via HTTP será automaticamente substituída por uma conexão HTTPS, mesmo se o usuário digitar http://
na barra de URL do navegador.modp2
para inicializar um protocolo de troca de chaves Diffie-Hellman, que usa um número primo de 1024 bits:
const dh = getDiffieHellman('modp2');
dh.generateKeys();
...
HSTS
(HTTP Strict Transport Security) usando um tempo de expiração insuficiente. Isso permite que os invasores substituam as conexões HTTPS por HTTP simples e roubem informações confidenciais executando ataques de remoção de HTTPS.HSTS
(HTTP Strict Transport Security) é um cabeçalho de segurança que instrui o navegador a sempre se conectar a um site que retorna os cabeçalhos HSTS via SSL/TLS durante um período especificado no cabeçalho. Qualquer conexão com o servidor via HTTP é substituída automaticamente por uma conexão HTTPS, mesmo que o usuário digite uma URL com http://
na barra de URL do navegador.
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
...
http.headers(headers ->
headers.httpStrictTransportSecurity(hstsConfig ->
hstsConfig.maxAgeInSeconds(300)
)
);
...
}
HSTS
) utilizando um tempo de expiração insuficiente, o que permite aos atacantes substituir as conexões HTTPS por conexões HTTP simples e roubar informações confidenciais ao realizar ataques de remoção de HTTPS.HSTS
) é um cabeçalho de segurança que instrui o navegador a sempre conectar a um site que retorne os cabeçalhos HSTS via SSL/TLS durante um período especificado no cabeçalho. Qualquer conexão ao servidor via HTTP será automaticamente substituída por uma conexão HTTPS, mesmo se o usuário digitar http://
na barra de URL do navegador.SmtpClient
está configurado incorretamente, sem usar SSL/TLS para se comunicar com um servidor SMTP:
string to = "bob@acme.com";
string from = "alice@acme.com";
MailMessage message = new MailMessage(from, to);
message.Subject = "SMTP client.";
message.Body = @"Envie com facilidade uma mensagem de e-mail por um aplicativo.";
SmtpClient client = new SmtpClient("smtp.acme.com");
client.UseDefaultCredentials = true;
client.Send(message);
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="smtp.acme.com" />
<property name="port" value="25" />
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.auth">true</prop>
</props>
</property>
</bean>
session = smtplib.SMTP(smtp_server, smtp_port)
session.ehlo()
session.login(username, password)
session.sendmail(frm, to, content)
device.createInsecureRfcommSocketToServiceRecord(MY_UUID);
...
var options = {
port: 443,
path: '/',
key : fs.readFileSync('my-server-key.pem'),
cert : fs.readFileSync('server-cert.pem'),
...
}
https.createServer(options);
...
secureProtocol
como SSLv23_method
, o servidor será inerentemente inseguro quando secureProtocol
não for especificamente substituído.
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)
...
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
...