軟體安全性並非安全性軟體。我們關注驗證、Access Control、保密性、加密以及權限管理之類的主題。
URL url = new URL("https://myserver.org");
URLConnection urlConnection = url.openConnection();
InputStream in = urlConnection.getInputStream();
URLConnection
使用的基礎 SSLSocketFactory
尚未變更,因此,它將使用將信任 Android 預設 Keystore 中存在的所有 CA 的預設值。
val url = URL("https://myserver.org")
val data = url.readBytes()
URLConnection
使用的基礎 SSLSocketFactory
尚未變更,因此,它將使用將信任 Android 預設 Keystore 中存在的所有 CA 的預設值。
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
方法,因此將會使用信任 iOS 預設 Keystore 中存在的所有 CA 的系統方法。
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
方法,因此將會使用信任 iOS 預設 Keystore 中存在的所有 CA 的系統方法。
...
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
時,會立即接受核發給「hackedserver.com
」的憑證。現在,此應用程式可能會在有漏洞的 SSL 連線上將使用者敏感資訊洩漏給被駭客入侵的伺服器。
...
var options = {
key : fs.readFileSync('my-server-key.pem'),
cert : fs.readFileSync('server-cert.pem'),
requestCert: true,
...
}
https.createServer(options);
...
https.Server
物件時,requestCert
設定被指定為 true
,但未設定 rejectUnauthorized
,進而預設為 false
。這表示,雖然伺服器的建立是為了透過 SSL 驗證用戶端,但是即使憑證未使用所提供之 CA 的清單進行授權,依然會接受連線。
var tls = require('tls');
...
tls.connect({
host: 'https://www.hackersite.com',
port: '443',
...
rejectUnauthorized: false,
...
});
rejectUnauthorized
已設定為 false,所以表示將接受未經授權的憑證,並且仍會與無法識別的伺服器建立連線。現在,此應用程式可能會在有漏洞的 SSL 連線上將使用者敏感資訊洩漏給被駭客入侵的伺服器。NSURLConnectionDelegate
配置為接受任何 HTTPS 憑證:
implementation NSURLRequest (IgnoreSSL)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString *)host
{
return YES;
}
@end
Example 1
的 NSURLRequest
連線到以 SSL 保護的伺服器時,如果所要求的伺服器憑證是自行簽署的憑證 (並因而不會驗證),那麼將不會產生任何警告或錯誤。因此,應用程式現在可能會透過有漏洞的 SSL 連線洩漏敏感的使用者資訊。
...
import ssl
ssl_sock = ssl.wrap_socket(s)
...
require 'openssl'
...
ctx = OpenSSL::SSL::SSLContext.new
ctx.verify_mode=OpenSSL::SSL::VERIFY_NONE
...
NSURLConnectionDelegate
配置為接受任何 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)
}
}
Example 1
的 NSURLConnectionDelegate
連線到以 SSL 保護的伺服器時,如果所要求的伺服器憑證是自行簽署的憑證 (並因而不會驗證),那麼將不會產生任何警告或錯誤。因此,應用程式現在可能會透過有漏洞的 SSL 連線洩漏敏感的使用者資訊。NSURLSession
類別中,SSL/TLS 鏈結驗證將由應用程式的驗證委派方法來處理,使用此方法時,應用程式不會提供憑證來向伺服器驗證使用者 (或應用程式),而是檢查伺服器在 SSL/TLS 交握期間提供的驗證,然後告知 URL 載入系統應接受還是拒絕這些憑證。以下程式碼顯示 proposedCredential
剛剛將所收到的挑戰之 NSURLSessionDelgate
傳回作為階段作業的憑證,以有效地避開伺服器驗證:
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
物件與遠端伺服器之間的通訊很容易遭受入侵,因為它透過未加密和未經驗證的通道傳輸。
...
HttpRequest req = new HttpRequest();
req.setEndpoint('http://example.com');
HTTPResponse res = new Http().send(req);
...
HttpResponse
物件 res
可能會遭到破解,因為它是透過未加密和未經驗證的通道傳遞。
var account = new CloudStorageAccount(storageCredentials, false);
...
String url = 'http://10.0.2.2:11005/v1/key';
Response response = await get(url, headers: headers);
...
response
安全性可能降低,因為它是透過未加密和未經驗證通道傳遞。
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
安全性可能降低,因為它是透過未加密和未經驗證通道傳遞。
var http = require('http');
...
http.request(options, function(res){
...
});
...
http.IncomingMessage
物件 res
安全性可能降低,因為它是透過未加密和未經驗證通道傳遞。
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
安全性可能降低,因為它是透過未加密和未經驗證通道傳遞。
val url = Uri.from(scheme = "http", host = "192.0.2.16", port = 80, path = "/")
val responseFuture: Future[HttpResponse] = Http().singleRequest(HttpRequest(uri = url))
responseFuture
安全性可能降低,因為它是透過未加密和未經驗證通道傳遞。
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
欄位用於控制伺服器是否遵循用戶端或伺服器的加密套件偏好設定。如果所選的加密套件具有已知弱點,則使用用戶端的偏好加密套件可能會帶來安全漏洞。PreferServerCipherSuites
欄位設定為 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(...)
使用較弱的 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
或 CFURL
時預設會啟用 App 傳輸安全性 (ATS),從而會強制應用程式搭配使用 HTTPS
與 TLS 1.2
以用於與後端伺服器的所有網路通訊。Info.plist
中的以下項目會完全停用 App 傳輸安全性:範例 2:應用程式
<key>NSAppTransportSecurity</key>
<dict>
<!--Include to allow all connections (DANGER)-->
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Info.plist
中的以下項目將停用 yourserver.com
的 App 傳輸安全性:
<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
來載入自己的網頁。
...
using var channel = GrpcChannel.ForAddress("https://grpcserver.com", new GrpcChannelOptions {
Credentials = ChannelCredentials.Insecure
});
...
...
ManagedChannel channel = Grpc.newChannelBuilder("hostname", InsecureChannelCredentials.create()).build();
...
None
。使用不安全的通道認證所傳送的資料,都不能信任。root_certificates
參數的值將設為 None
,private_key
參數的值將設為 None
,以及 certificate_chain
參數的值將設為 None
。
...
channel_creds = grpc.ssl_channel_credentials()
...
...
Server server = Grpc.newServerBuilderForPort(port, InsecureServerCredentials.create())
...
None
或 False
。當認證設定不安全時,傳送到此伺服器或來自此伺服器的資料,都不能信任。
...
pk_cert_chain = your_organization.securelyGetPrivateKeyCertificateChainPairs()
server_creds = grpc.ssl_server_credentials(pk_cert_chain)
...
HSTS
) 標頭,但無法將此保護套用至子網域,這可讓攻擊者透過執行 HTTPS 剝離攻擊,從子網域連線竊取敏感資訊。HSTS
) 是一種安全性標頭,用於指示瀏覽器在 HSTS 標頭指定的期間內,始終連線到經由 SSL/TLS 傳回標頭的網站。經由 HTTP 與伺服器的任何連線都會自動取代為 HTTPS 連線,即使使用者在瀏覽器 URL 列中輸入 http://
也一樣。
<http auto-config="true">
...
<headers>
...
<hsts include-sub-domains="false" />
</headers>
</http>
HSTS
) 表頭,但無法將此保護套用至子網域,這使得攻擊者可透過執行 HTTPS 剝離攻擊,從子網域連線竊取敏感資訊。HSTS
) 是一種安全性表頭,用於指示瀏覽器在 HSTS 表頭本身指定的期間內,永遠連線到經由 SSL/TLS 傳回 HSTS 表頭的網站。經由 HTTP 與伺服器的任何連線都將自動取代為 HTTPS 連線,即使使用者在瀏覽器 URL 列中輸入 http://
,也是如此。HSTS
) 標頭。這可讓攻擊者將 SSL/TLS 連線取代為單純 HTTP 連線,並透過執行 HTTPS 剝離攻擊來竊取敏感資訊。HSTS
) 是一種安全性標頭,用於指示瀏覽器在 HSTS 標頭指定的期間內,始終連線到經由 SSL/TLS 傳回標頭的網站。經由 HTTP 與伺服器的任何連線都會自動取代為 HTTPS 連線,即使使用者在瀏覽器 URL 列中輸入 http://
也一樣。
<http auto-config="true">
...
<headers>
...
<hsts disabled="true" />
</headers>
</http>
HSTS
) 表頭,這使得攻擊者可透過執行 HTTPS 剝離攻擊,將 SSL/TLS 連線取代為單純 HTTP 連線並竊取敏感資訊。HSTS
) 是一種安全性表頭,用於指示瀏覽器在 HSTS 表頭本身指定的期間內,永遠連線到經由 SSL/TLS 傳回 HSTS 表頭的網站。經由 HTTP 與伺服器的任何連線都將自動取代為 HTTPS 連線,即使使用者在瀏覽器 URL 列中輸入 http://
,也是如此。HSTS
) 表頭,這使得攻擊者可透過執行 HTTPS 剝離攻擊,將 SSL/TLS 連線取代為單純 HTTP 連線並竊取敏感資訊。HSTS
) 是一種安全性表頭,用於指示瀏覽器在 HSTS 表頭本身指定的期間內,永遠連線到經由 SSL/TLS 傳回 HSTS 表頭的網站。經由 HTTP 與伺服器的任何連線都將自動取代為 HTTPS 連線,即使使用者在瀏覽器 URL 列中輸入 http://
,也是如此。modp2
群組來初始化 Diffie-Hellman 金鑰交換通訊協定,其使用 1024 位元質數:
const dh = getDiffieHellman('modp2');
dh.generateKeys();
...
HSTS
) 標頭。這可讓攻擊者將 HTTPS 連線取代為單純 HTTP 連線,並藉著執行 HTTPS 剝離攻擊而竊取敏感資訊。HSTS
) 是一種安全性標頭,用於指示瀏覽器在 HSTS 標頭指定的期間內,始終連線到經由 SSL/TLS 傳回標頭的網站。經由 HTTP 與伺服器的任何連線都會自動取代為 HTTPS 連線,即使使用者在瀏覽器 URL 列中輸入 http://
也一樣。
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
...
http.headers(headers ->
headers.httpStrictTransportSecurity(hstsConfig ->
hstsConfig.maxAgeInSeconds(300)
)
);
...
}
HSTS
) 表頭,這使得攻擊者可透過執行 HTTPS 剝離攻擊,將 HTTPS 連線取代為單純 HTTP 連線並竊取敏感資訊。HSTS
) 是一種安全性表頭,用於指示瀏覽器在 HSTS 表頭本身指定的期間內,永遠連線到經由 SSL/TLS 傳回 HSTS 表頭的網站。經由 HTTP 與伺服器的任何連線都將自動取代為 HTTPS 連線,即使使用者在瀏覽器 URL 列中輸入 http://
,也是如此。SmtpClient
的配置不正確,未使用 SSL/TLS 與 SMTP 伺服器進行通訊:
string to = "bob@acme.com";
string from = "alice@acme.com";
MailMessage message = new MailMessage(from, to);
message.Subject = "SMTP client.";
message.Body = @「您可以非常輕鬆地從應用程式傳送電子郵件訊息。」;
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
的預設值設定為 SSLv23_method
,因此若沒有明確取代 secureProtocol
,伺服器在本質上就不安全。
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
...