軟體安全性並非安全性軟體。我們關注驗證、Access Control、保密性、加密以及權限管理之類的主題。
server.servlet.session.cookie.persistent=true
session_set_cookie_params(time()+60*60*24*365*10, "/", "www.example.com", false, true);
Secure
旗標未設為 true
。Secure
旗標。若已設定旗標,則瀏覽器僅會透過 HTTPS 傳送 Cookie。透過未加密的通道傳送 Cookie,易使 Cookie 受到網路攔截攻擊,因此安全旗標可維持 Cookie 值的機密性。若 Cookie 包含隱私資料或附帶階段作業識別碼,這將更為重要。Secure
旗標。
...
<configuration>
<system.web>
<authentication mode="Forms">
<forms requireSSL="false" loginUrl="login.aspx">
</forms>
</authentication>
</system.web>
</configuration>
...
Secure
旗標,則在後續的 HTTP 要求期間,也會傳送在 HTTPS 要求時所傳送的 Cookie。透過未加密的無線連線攔截網路流量,對攻擊者而言是稀鬆平常之事,所以透過 HTTP 傳送 Cookie (尤其是含階段作業 ID 的 Cookie) 可能會造成應用程式資料外洩。Secure
旗標。若已設定旗標,則瀏覽器僅會透過 HTTPS 傳送 Cookie。透過未加密的通道傳送 Cookie,易使 Cookie 受到網路攔截攻擊,因此安全旗標可維持 Cookie 值的機密性。若 Cookie 包含隱私資料或附帶階段作業識別碼,這將更為重要。Secure
旗標。
server.servlet.session.cookie.secure=false
Secure
旗標,則在後續的 HTTP 要求期間,也會傳送在 HTTPS 要求時所傳送的 Cookie。隨後攻擊者可能會攔截未加密的網路流量,進而危及 Cookie,這在無線網路會更加容易。Secure
旗標設為 true
Secure
旗標。若已設定旗標,則瀏覽器僅會透過 HTTPS 傳送 cookie。透過未加密的通道傳送 cookie,易使 cookie 受到網路攔截攻擊,因此安全旗標可維持 cookie 值的機密性。若 cookie 包含隱私資料或附帶階段作業識別碼,這將更為重要。Secure
旗標。
...
setcookie("emailCookie", $email, 0, "/", "www.example.com");
...
Secure
旗標,則在後續的 HTTP 要求期間,也會傳送在 HTTPS 要求時所傳送的 Cookie。隨後攻擊者可能會攔截未加密的網路流量,進而危及 Cookie,這在無線網路會更加容易。SESSION_COOKIE_SECURE
屬性明確設為 True
,或是將其設為 False
。Secure
旗標。若已設定旗標,則瀏覽器僅會透過 HTTPS 傳送 cookie。透過未加密的通道傳送 cookie,易使 cookie 受到網路攔截攻擊,因此安全旗標可維持 cookie 值的機密性。如果 Cookie 包含私人資料或階段作業識別碼,或附帶 CSRF 權杖,這將更為重要。Secure
位元。
...
MIDDLEWARE = (
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'csp.middleware.CSPMiddleware',
'django.middleware.security.SecurityMiddleware',
...
)
...
Secure
旗標,則在後續的 HTTP 要求期間,也會傳送在 HTTPS 要求時所傳送的 Cookie。隨後攻擊者可能會攔截未加密的網路流量,進而危及 Cookie,這在無線網路會更加容易。
<cfquery name = "GetCredentials" dataSource = "master">
SELECT Username, Password
FROM Credentials
WHERE DataSource="users"
</cfquery>
...
<cfquery name = "GetSSNs" dataSource = "users"
username = "#Username#" password = "#Password#">
SELECT SSN
FROM Users
</cfquery>
...
master
表格的存取權,便能夠讀取 Username
和 Password
的值。如果心懷不軌的員工擁有此資訊的存取權,他們可以利用此資訊來進入並破壞系統。
...
<cfquery name = "GetSSNs" dataSource = "users"
username = "scott" password = "tiger">
SELECT SSN
FROM Users
</cfquery>
...
...
Credentials.basic("hardcoded-username", password);
...
...
PARAMETERS: p_input TYPE sy-mandt.
SELECT *
FROM employee_records
CLIENT SPECIFIED
INTO TABLE tab_output
WHERE mandt = p_input.
...
SY-MANDT
之外的用戶端檢視員工詳細資料。SECRET_KEY
設定來儲存階段作業資料。如果 SECRET_KEY
遭洩漏,攻擊者無法僅偽造階段作業資料,但如果應用程式使用 Pickle 將階段作業資料序列化到 Cookie 中,則攻擊者將能夠製作惡意的序列化資料,此資料將在還原序列化之後執行任意程式碼。Host
表頭,攻擊者便可傳送虛假的 Host
值,此值可用於跨網站偽造要求、快取破壞攻擊,以及電子郵件中的破壞連結。*
" 做為 ALLOWED_HOSTS
設定中的項目。django.http.HttpRequest.get_host()
使用此設定來驗證 Host
表頭。值 "*
" 將允許在 Host
表頭中使用任何主機。攻擊者可能將此用於發起快取破壞攻擊,或用於電子郵件中的破壞連結。Host
值進行建構,以參照執行重設密碼功能的網站,從而避免硬式編碼的 URL。例如:
...
def reset_password(request):
url = "http://%s/new_password/?token=%s" % (request.get_host(), generate_token())
send_email(reset_link=url)
redirect("home")
...
Host
表頭值,來重設受害者的密碼。受害者將收到一封電子郵件,內含重設密碼系統的連結,如果受害者決定造訪該連結,其將會造訪由攻擊者控制的網站,網站上將執行虛假表單以收集受害者的憑證。SECRET_KEY
遭洩漏,則攻擊者將能夠在階段作業 Cookie 中儲存任意資料,此資料將在伺服器中還原序列化,從而導致任意程式碼執行。SECRET_KEY
(如果在 settings.py
組態設定檔案中經過硬式編碼):
...
def some_view_method(request):
url = request.GET['url']
if "http://" in url:
content = urllib.urlopen(url)
return HttpResponse(content)
...
Example 1
方法透過確認 URL 中是否存在「http://」,來確認 url
參數是否為有效的 URL。惡意攻擊者可能會傳送以下 URL,以洩漏可能包含 SECRET_KEY
的 settings.py
組態設定檔案:
file://proc/self/cwd/app/settings.py#http://
script
標籤:
<script src="http://www.example.com/js/fancyWidget.js"></script>
www.example.com
的內容以載入自己的 JavaScript。
permissions := strconv.Atoi(os.Getenv("filePermissions"));
fMode := os.FileMode(permissions)
os.chmod(filePath, fMode);
...
String permissionMask = System.getProperty("defaultFileMask");
Path filePath = userFile.toPath();
...
Set<PosixFilePermission> perms = PosixFilePermissions.fromString(permissionMask);
Files.setPosixFilePermissions(filePath, perms);
...
$rName = $_GET['publicReport'];
chmod("/home/". authenticateUser . "/public_html/" . rName,"0755");
...
publicReport
,如「../../localuser/public_html/.htpasswd
」,應用程式會指定攻擊者可讀取那個檔案。
...
$mask = $CONFIG_TXT['perms'];
chmod($filename,$mask);
...
permissions = os.getenv("filePermissions");
os.chmod(filePath, permissions);
...
...
rName = req['publicReport']
File.chmod("/home/#{authenticatedUser}/public_html/#{rName}", "0755")
...
publicReport
,如「../../localuser/public_html/.htpasswd
」,應用程式會指定攻擊者可讀取那個檔案。
...
mask = config_params['perms']
File.chmod(filename, mask)
...
SECURE_CROSS_ORIGIN_OPENER_POLICY = 'unsafe-none'
<authorization>
<allow verbs="GET,POST" users="admin"/>
<deny verbs="GET,POST"users="*" />
</authorization>
<security-constraint>
<display-name>Admin Constraint</display-name>
<web-resource-collection>
<web-resource-name>Admin Area</web-resource-name>
<url-pattern>/pages/index.jsp</url-pattern>
<url-pattern>/admin/*.do</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<description>only admin</description>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<http-method>
標籤中未明確定義如 HEAD 的動詞,因此可透過以 HEAD 要求替代 GET 或 POST 要求,來執行管理功能。為了能讓 HEAD 要求執行管理功能,條件 3 必須適用 - 應用程式必須依據 POST 以外的動詞執行指令。某些網路/應用程式伺服器會接受任意的非標準 HTTP 動詞,並以具有指定 GET 要求的型態回應。若情況為此,攻擊者將可使用要求中的任意動詞,來檢視管理頁面。
GET /admin/viewUsers.do HTTP/1.1
Host: www.example.com
FOO /admin/viewUsers.do HTTP/1.1
Host: www.example.com
FORM GenerateReceiptURL CHANGING baseUrl TYPE string.
DATA: r TYPE REF TO cl_abap_random,
var1 TYPE i,
var2 TYPE i,
var3 TYPE n.
GET TIME.
var1 = sy-uzeit.
r = cl_abap_random=>create( seed = var1 ).
r->int31( RECEIVING value = var2 ).
var3 = var2.
CONCATENATE baseUrl var3 ".html" INTO baseUrl.
ENDFORM.
CL_ABAP_RANDOM->INT31
函數為其所產生的收據頁面產生「唯一」識別碼。由於 CL_ABAP_RANDOM
是統計式 PRNG,攻擊者很容易就能猜到其所產生的字串。雖然收據系統的基礎設計也存在錯誤,但是如果它使用一個不會產生可預測收據識別碼的亂數產生器 (例如加密式 PRNG),那就會安全很多。
string GenerateReceiptURL(string baseUrl) {
Random Gen = new Random();
return (baseUrl + Gen.Next().toString() + ".html");
}
Random.Next()
函數為其所產生的收據頁面產生「唯一」識別碼。由於 Random.Next()
是統計式 PRNG,攻擊者很容易就能猜到其所產生的字串。雖然收據系統的基礎設計也存在錯誤,但是如果它使用一個不會產生可預測收據識別碼的亂數產生器 (例如加密式 PRNG),那就會安全很多。
char* CreateReceiptURL() {
int num;
time_t t1;
char *URL = (char*) malloc(MAX_URL);
if (URL) {
(void) time(&t1);
srand48((long) t1); /* use time to set seed */
sprintf(URL, "%s%d%s", "http://test.com/", lrand48(), ".html");
}
return URL;
}
lrand48()
函數為其所產生的收據頁面產生「唯一」識別碼。由於 lrand48()
是統計式 PRNG,攻擊者很容易就能猜到其所產生的字串。雖然收據系統的基礎設計也存在錯誤,但是如果它使用一個不會產生可預測收據識別碼的亂數產生器,那就會安全很多。
<cfoutput>
Receipt: #baseUrl##Rand()#.cfm
</cfoutput>
Rand()
函數為其所產生的收據頁面產生「唯一」識別碼。由於 Rand()
是統計式 PRNG,攻擊者很容易就能猜到其所產生的字串。雖然收據系統的基礎設計也存在錯誤,但是如果它使用一個不會產生可預測收據識別碼的亂數產生器 (例如加密式 PRNG),那就會安全很多。
import "math/rand"
...
var mathRand = rand.New(rand.NewSource(1))
rsa.GenerateKey(mathRand, 2048)
rand.New()
函數為 RSA 金鑰產生隨機性。由於 rand.New()
是統計式 PRNG,所以攻擊者很容易就能猜到其所產生的值。
String GenerateReceiptURL(String baseUrl) {
Random ranGen = new Random();
ranGen.setSeed((new Date()).getTime());
return (baseUrl + ranGen.nextInt(400000000) + ".html");
}
Random.nextInt()
函數為其所產生的收據頁面產生「唯一」識別碼。由於 Random.nextInt()
是統計式 PRNG,攻擊者很容易就能猜到其所產生的字串。雖然收據系統的基礎設計也存在錯誤,但是如果它使用一個不會產生可預測收據識別碼的亂數產生器 (例如加密式 PRNG),那就會安全很多。
function genReceiptURL (baseURL){
var randNum = Math.random();
var receiptURL = baseURL + randNum + ".html";
return receiptURL;
}
Math.random()
函數為其所產生的收據頁面產生「唯一」識別碼。由於 Math.random()
是統計式 PRNG,攻擊者很容易就能猜到其所產生的字串。雖然收據系統的基礎設計也存在錯誤,但是如果它使用一個不會產生可預測收據識別碼的亂數產生器 (例如加密式 PRNG),那就會安全很多。
fun GenerateReceiptURL(baseUrl: String): String {
val ranGen = Random(Date().getTime())
return baseUrl + ranGen.nextInt(400000000).toString() + ".html"
}
Random.nextInt()
函數為其所產生的收據頁面產生「唯一」識別碼。由於 Random.nextInt()
是統計式 PRNG,攻擊者很容易就能猜到其所產生的字串。雖然收據系統的基礎設計也存在錯誤,但是如果它使用一個不會產生可預測收據識別碼的亂數產生器 (例如加密型 PRNG),那就會安全很多。
function genReceiptURL($baseURL) {
$randNum = rand();
$receiptURL = $baseURL . $randNum . ".html";
return $receiptURL;
}
rand()
函數為其所產生的收據頁面產生「唯一」識別碼。由於 rand()
是統計式 PRNG,攻擊者很容易就能猜到其所產生的字串。雖然收據系統的基礎設計也存在錯誤,但是如果它使用一個不會產生可預測收據識別碼的亂數產生器 (例如加密式 PRNG),那就會安全很多。
CREATE or REPLACE FUNCTION CREATE_RECEIPT_URL
RETURN VARCHAR2
AS
rnum VARCHAR2(48);
time TIMESTAMP;
url VARCHAR2(MAX_URL)
BEGIN
time := SYSTIMESTAMP;
DBMS_RANDOM.SEED(time);
rnum := DBMS_RANDOM.STRING('x', 48);
url := 'http://test.com/' || rnum || '.html';
RETURN url;
END
DBMS_RANDOM.SEED()
函數為其所產生的收據頁面產生「唯一」識別碼。由於 DBMS_RANDOM.SEED()
是統計式 PRNG,攻擊者很容易就能猜到其所產生的字串。雖然收據系統的基礎設計也存在錯誤,但是如果它使用一個不會產生可預測收據識別碼的亂數產生器,那就會安全很多。
def genReceiptURL(self,baseURL):
randNum = random.random()
receiptURL = baseURL + randNum + ".html"
return receiptURL
rand()
函數為其所產生的收據頁面產生「唯一」識別碼。由於 rand()
是統計式 PRNG,攻擊者很容易就能猜到其所產生的字串。雖然收據系統的基礎設計也存在錯誤,但是如果它使用一個不會產生可預測收據識別碼的亂數產生器 (例如加密式 PRNG),那就會安全很多。
def generateReceiptURL(baseUrl) {
randNum = rand(400000000)
return ("#{baseUrl}#{randNum}.html");
}
Kernel.rand()
函數為其所產生的收據頁面產生「唯一」識別碼。由於 Kernel.rand()
是統計式 PRNG,攻擊者很容易就能猜到其所產生的字串。
def GenerateReceiptURL(baseUrl : String) : String {
val ranGen = new scala.util.Random()
ranGen.setSeed((new Date()).getTime())
return (baseUrl + ranGen.nextInt(400000000) + ".html")
}
Random.nextInt()
函數為其所產生的收據頁面產生「唯一」識別碼。由於 Random.nextInt()
是統計式 PRNG,攻擊者很容易就能猜到其所產生的字串。雖然收據系統的基礎設計也存在錯誤,但是如果它使用一個不會產生可預測收據識別碼的亂數產生器 (例如加密式 PRNG),那就會安全很多。
sqlite3_randomness(10, &reset_token)
...
Function genReceiptURL(baseURL)
dim randNum
randNum = Rnd()
genReceiptURL = baseURL & randNum & ".html"
End Function
...
Rnd()
函數為其所產生的收據頁面產生「唯一」識別碼。由於 Rnd()
是統計式 PRNG,攻擊者很容易就能猜到其所產生的字串。雖然收據系統的基礎設計也存在錯誤,但是如果它使用一個不會產生可預測收據識別碼的亂數產生器 (例如加密式 PRNG),那就會安全很多。CL_ABAP_RANDOM
類別或其變體) 提供種子,則可收集大量 PRNG 輸出的攻擊者將可預測由 GET_NEXT
、INT
和用於傳回或指派值的類似方法傳回的值。random_gen1
可以預測由物件 random_gen2
產生的值。
DATA: random_gen1 TYPE REF TO cl_abap_random,
random_gen2 TYPE REF TO cl_abap_random,
var1 TYPE i,
var2 TYPE i.
random_gen1 = cl_abap_random=>create( seed = '1234' ).
DO 10 TIMES.
CALL METHOD random_gen1->int
RECEIVING
value = var1.
WRITE:/ var1.
ENDDO.
random_gen2 = cl_abap_random=>create( seed = '1234' ).
DO 10 TIMES.
CALL METHOD random_gen2->int
RECEIVING
value = var2.
WRITE:/ var2.
ENDDO.
random_gen1
和 random_gen2
被提供完全相同的種子,因此 var1 = var2
srand(unsigned int)
的函數) 向虛擬亂數產生器 (例如 rand()
) 提供種子,則可收集大量 PRNG 輸出的攻擊者將可預測由 rand()
和用於傳回或指派值的類似方法傳回的值。
srand(2223333);
float randomNum = (rand() % 100);
syslog(LOG_INFO, "Random: %1.2f", randomNum);
randomNum = (rand() % 100);
syslog(LOG_INFO, "Random: %1.2f", randomNum);
srand(2223333);
float randomNum2 = (rand() % 100);
syslog(LOG_INFO, "Random: %1.2f", randomNum2);
randomNum2 = (rand() % 100);
syslog(LOG_INFO, "Random: %1.2f", randomNum2);
srand(1231234);
float randomNum3 = (rand() % 100);
syslog(LOG_INFO, "Random: %1.2f", randomNum3);
randomNum3 = (rand() % 100);
syslog(LOG_INFO, "Random: %1.2f", randomNum3);
randomNum1
和 randomNum2
的結果以完全相同的方式提供種子,因此在向虛擬亂數產生器 srand(2223333)
提供種子的呼叫後,每次對 rand()
的呼叫都將按照相同的呼叫順序產生相同的輸出。例如,輸出可能如下所示:
Random: 32.00
Random: 73.00
Random: 32.00
Random: 73.00
Random: 15.00
Random: 75.00
math.Rand.New(Source)
等函數) 作為種子,則可收集大量 PRNG 輸出的攻擊者將可預測由 math.Rand.Int()
和用於回傳或指派值的類似方法回傳的值。
randomGen := rand.New(rand.NewSource(12345))
randomInt1 := randomGen.nextInt()
randomGen.Seed(12345)
randomInt2 := randomGen.nextInt()
randomGen.Seed(12345)
) 提供種子的呼叫後,每次對 nextInt()
的呼叫都按照相同的順序產生相同的輸出。Random.setSeed()
等的函數) 向虛擬亂數產生器 (例如 Random
) 提供種子,則可收集大量 PRNG 輸出的攻擊者將可預測由 Random.nextInt()
和用於回傳或指派值的類似方法回傳的值。Random
物件 randomGen1
可以預測由 Random
物件 randomGen2
產生的值。
Random randomGen1 = new Random();
randomGen1.setSeed(12345);
int randomInt1 = randomGen1.nextInt();
byte[] bytes1 = new byte[4];
randomGen1.nextBytes(bytes1);
Random randomGen2 = new Random();
randomGen2.setSeed(12345);
int randomInt2 = randomGen2.nextInt();
byte[] bytes2 = new byte[4];
randomGen2.nextBytes(bytes2);
randomGen1
與 randomGen2
以完全相同的方式提供種子,因此 randomInt1 == randomInt2
以及陣列 bytes1[]
與 bytes2[]
的對應值相等。Random(Int)
等的函數) 向虛擬亂數產生器 (例如 Random
) 提供種子,則可收集大量 PRNG 輸出的攻擊者將可預測由 Random.nextInt()
和用於回傳或指派值的類似方法回傳的值。Random
物件 randomGen1
可以預測由 Random
物件 randomGen2
產生的值。
val randomGen1 = Random(12345)
val randomInt1 = randomGen1.nextInt()
val byteArray1 = ByteArray(4)
randomGen1.nextBytes(byteArray1)
val randomGen2 = Random(12345)
val randomInt2 = randomGen2.nextInt()
val byteArray2 = ByteArray(4)
randomGen2.nextBytes(byteArray2)
randomGen1
與 randomGen2
以完全相同的方式提供種子,因此 randomInt1 == randomInt2
以及陣列 byteArray1
與 byteArray2
的對應值相等。
...
import random
random.seed(123456)
print "Random: %d" % random.randint(1,100)
print "Random: %d" % random.randint(1,100)
print "Random: %d" % random.randint(1,100)
random.seed(123456)
print "Random: %d" % random.randint(1,100)
print "Random: %d" % random.randint(1,100)
print "Random: %d" % random.randint(1,100)
...
random.seed(123456)
) 提供種子的呼叫後,每次對 randint()
的呼叫都將按照相同的順序在同一輸出中產生相同的輸出。例如,輸出可能如下所示:
Random: 81
Random: 80
Random: 3
Random: 81
Random: 80
Random: 3
Random.setSeed()
的函數) 向虛擬亂數產生器 (例如 Random
) 提供種子,則可收集大量 PRNG 輸出的攻擊者將可預測由 Random.nextInt()
和用於傳回或指派值的類似方法傳回的值。Random
物件 randomGen1
可以預測由 Random
物件 randomGen2
產生的值。
val randomGen1 = new Random()
randomGen1.setSeed(12345)
val randomInt1 = randomGen1.nextInt()
val bytes1 = new byte[4]
randomGen1.nextBytes(bytes1)
val randomGen2 = new Random()
randomGen2.setSeed(12345)
val randomInt2 = randomGen2.nextInt()
val bytes2 = new byte[4]
randomGen2.nextBytes(bytes2)
randomGen1
與 randomGen2
以完全相同的方式提供種子,因此 randomInt1 == randomInt2
以及陣列 bytes1[]
與 bytes2[]
的對應值相等。CL_ABAP_RANDOM
(或其變體)。否則,攻擊者會藉此控制用於為虛擬亂數產生器提供種子的值,從而推測透過呼叫以下 (包括但不限於) 方法所產生的值的序列: GET_NEXT
, INT
, FLOAT
, PACKED
.rand()
) (它們會被傳送種子 (例如 srand()
)),不應使用受感染的引數來呼叫這些函數。否則,攻擊者會藉此控制用於為虛擬亂數產生器提供種子的值,從而推測透過呼叫虛擬亂數產生器所產生的值 (通常是整數) 的序列。ed25519.NewKeyFromSeed()
) 的函數;不應使用受感染的引數呼叫這些函數。否則,攻擊者會藉此控制用於為虛擬亂數產生器提供種子的值,從而推測透過呼叫虛擬亂數產生器所產生的值的序列。Random.setSeed()
。否則,攻擊者會藉此控制用於為虛擬亂數產生器提供種子的值,從而能推測透過呼叫 Random.nextInt()
、Random.nextShort()
、Random.nextLong()
所產生、由 Random.nextBoolean()
傳回或 Random.nextBytes(byte[])
中設定的值 (通常是整數) 的序列。Random.setSeed()
。否則,攻擊者會藉此控制用於為虛擬亂數產生器提供種子的值,從而能推測透過呼叫 Random.nextInt()
、Random.nextLong()
、Random.nextDouble()
所產生、由 Random.nextBoolean()
回傳或 Random.nextBytes(ByteArray)
中設定的值 (通常是整數) 的序列。random.randint()
) 的函數;不應使用受感染的引數呼叫這些函數。否則,攻擊者會藉此控制用於為虛擬亂數產生器提供種子的值,從而能夠預測透過呼叫虛擬亂數產生器所產生的值 (通常是整數) 的序列。Random.setSeed()
。否則,攻擊者會藉此控制用於為虛擬亂數產生器提供種子的值,從而能推測透過呼叫 Random.nextInt()
、Random.nextShort()
、Random.nextLong()
所產生、由 Random.nextBoolean()
回傳或 Random.nextBytes(byte[])
中設定的值 (通常是整數) 的序列。
...
srand (time(NULL));
r = (rand() % 6) + 1;
...
...
import time
import random
random.seed(time.time())
...
createSocket()
將 InetAddress 做為函數參數,不執行主機名稱驗證。 getInsecure()
會傳回 SSL 通訊端因數,且所有 SSL 檢查皆停用。https://safesecureserver.banking.com
時,會立即接受核發給 https://hackedserver.banking.com
的憑證。現在,此應用程式可能會在有漏洞的 SSL 連線上將使用者敏感資訊洩漏給被駭客入侵的伺服器。