소프트웨어 보안은 보안 소프트웨어가 아닙니다. 여기서는 인증, 액세스 제어, 기밀성, 암호화, 권한 관리 등의 항목에 대해 설명합니다.
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를 통해 쿠키를 전송하기만 합니다. 암호화되지 않은 채널을 통해 쿠키를 전송하면 네트워크 염탐 공격에 노출될 수 있으므로 안전한 플래그를 사용하는 것이 쿠키의 값 자격 증명을 유지하는 데 도움을 줍니다. 이것은 쿠키가 개인 정보를 포함하거나 세션 ID를 전하는 경우 특히 중요합니다.Secure
플래그를 설정하지 않고 응답에 추가되는 구성입니다.
...
<configuration>
<system.web>
<authentication mode="Forms">
<forms requireSSL="false" loginUrl="login.aspx">
</forms>
</authentication>
</system.web>
</configuration>
...
Secure
플래그를 설정하지 않는 경우, HTTPS 요청 중에 전송된 쿠키는 다음 HTTP 요청 중에도 전송됩니다. 암호화되지 않은 무선 연결을 통한 네트워크 트래픽 염탐은 공격자에게는 간단한 작업이므로 HTTP를 통한 쿠키(특히 세션 ID가 있는 쿠키) 전송은 응용 프로그램을 손상시킬 수 있습니다.Secure
플래그를 지원합니다. 플래그가 설정되면 브라우저는 HTTPS를 통해 쿠키를 전송하기만 합니다. 암호화되지 않은 채널을 통해 쿠키를 전송하면 네트워크 염탐 공격에 노출될 수 있으므로 안전한 플래그를 사용하는 것이 쿠키의 값 자격 증명을 유지하는 데 도움을 줍니다. 이것은 쿠키가 개인 정보를 포함하거나 세션 ID를 전하는 경우 특히 중요합니다.Secure
플래그를 끕니다.
server.servlet.session.cookie.secure=false
Secure
플래그를 설정하지 않는 경우, HTTPS 요청 중에 전송된 쿠키는 다음 HTTP 요청 중에도 전송됩니다. 그러면 공격자가 암호화되지 않은 네트워크 트래픽을 염탐(무선 네트워크를 통하는 경우 특히 쉬움)하여 쿠키를 손상시킬 수 있습니다.Secure
플래그를 true
로 설정하지 않고 세션 쿠키를 생성합니다.Secure
플래그를 지원합니다. 플래그가 설정되면 브라우저는 HTTPS를 통해 쿠키를 전송하기만 합니다. 암호화되지 않은 채널을 통해 쿠키를 전송하면 네트워크 염탐 공격에 노출될 수 있으므로 안전한 플래그를 사용하는 것이 쿠키의 값 자격 증명을 유지하는 데 도움을 줍니다. 이것은 쿠키가 개인 정보를 포함하거나 세션 ID를 전하는 경우 특히 중요합니다.Secure
플래그를 설정하지 않고 쿠키를 응답에 추가합니다.
...
setcookie("emailCookie", $email, 0, "/", "www.example.com");
...
Secure
플래그를 설정하지 않는 경우, HTTPS 요청 중에 전송된 쿠키는 다음 HTTP 요청 중에도 전송됩니다. 그러면 공격자가 암호화되지 않은 네트워크 트래픽을 염탐(무선 네트워크를 통하는 경우 특히 쉬움)하여 쿠키를 손상시킬 수 있습니다.SESSION_COOKIE_SECURE
속성을 True
로 명시적으로 설정하지 않거나 False
로 설정합니다.Secure
플래그를 지원합니다. 플래그가 설정되면 브라우저는 HTTPS를 통해 쿠키를 전송하기만 합니다. 암호화되지 않은 채널을 통해 쿠키를 전송하면 네트워크 염탐 공격에 노출될 수 있으므로 안전한 플래그를 사용하는 것이 쿠키의 값 자격 증명을 유지하는 데 도움을 줍니다. 이는 쿠키가 개인 데이터 또는 세션 ID를 포함하거나 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
플래그를 설정하지 않는 경우, HTTPS 요청 중에 전송된 쿠키는 다음 HTTP 요청 중에도 전송됩니다. 그러면 공격자가 암호화되지 않은 네트워크 트래픽을 염탐(무선 네트워크를 통하는 경우 특히 쉬움)하여 쿠키를 손상시킬 수 있습니다.
<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
설정을 위한 Django 도구를 통해 저장됩니다. SECRET_KEY
가 누출되는 경우 공격자는 세션 데이터를 왜곡할 수 있을 뿐 아니라, 응용 프로그램에서 Pickle을 사용하여 세션 데이터를 쿠키로 직렬화하면 공격자가 역직렬화 시 임의의 코드를 실행하는 악의적으로 피클링된 데이터를 만들 수 있습니다.Host
헤더를 확인하지 않으면 공격자가 Cross-Site Request Forgery, 캐시 감염 공격, 전자 메일의 링크 감염에 사용할 수 있는 허위 Host
값을 보낼 수 있습니다.*
"를 ALLOWED_HOSTS
설정의 항목으로 지정합니다. 이 설정은 django.http.HttpRequest.get_host()
에서 Host
헤더를 확인하는 데 사용됩니다. 값이 "*
"이면 Host
헤더에서 모든 호스트가 허용됩니다. 공격자는 이를 캐시 감염 공격이나 전자 메일의 링크를 감염시키는 데 사용할 수 있습니다.Host
값을 사용하여 생성할 수 있습니다. 예:
...
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
가 누출되면 공격자는 세션 쿠키에 임의의 데이터를 저장했다가 나중에 서버에서 역직렬화하여 임의의 코드가 실행되도록 할 수 있습니다.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");
...
../../localuser/public_html/.htpasswd
" 등과 같이 publicReport
에 대해 악성 값을 제공할 경우, 응용 프로그램은 지정된 파일을 공격자가 읽을 수 있게 합니다.
...
$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")
...
../../localuser/public_html/.htpasswd
" 등과 같이 publicReport
에 대해 악성 값을 제공할 경우, 응용 프로그램은 지정된 파일을 공격자가 읽을 수 있게 합니다.
...
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 요청으로 GET 또는 POST 요청을 대신하여 관리 기능이 수행 가능합니다. 관리 기능을 실행하기 위한 HEAD 요청의 경우 조건 3이 유지되어야 합니다. 즉, 응용 프로그램이 POST 이외의 동사를 기반으로 명령을 수행해야 합니다. 일부 웹/응용 프로그램 서버는 임의의 비표준 HTTP verb를 허용하고 GET 요청을 받은 것처럼 응답합니다. 그런 경우, 공격자는 요청에서 임의의 verb를 사용하여 관리 페이지를 볼 수 있습니다.
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
함수를 사용하여 생성되는 영수증 페이지에 대한 "고유한" ID를 생성합니다. CL_ABAP_RANDOM
은 통계적 PRNG이므로 생성되는 문자열을 공격자가 쉽게 추축할 수 있습니다. 영수증 시스템의 기본 설계에도 오류가 있지만 암호화 PRNG와 같이 예측 가능한 영수증 ID를 생성하지 않는 난수 발생기를 사용했다면 훨씬 안전했을 것입니다.
string GenerateReceiptURL(string baseUrl) {
Random Gen = new Random();
return (baseUrl + Gen.Next().toString() + ".html");
}
Random.Next()
함수를 사용하여 생성되는 영수증 페이지에 대한 "고유한" ID를 생성합니다. Random.Next()
은 통계적 PRNG이므로 생성되는 문자열을 공격자가 쉽게 추축할 수 있습니다. 영수증 시스템의 기본 설계에도 오류가 있지만 암호화 PRNG와 같이 예측 가능한 영수증 ID를 생성하지 않는 난수 발생기를 사용했다면 훨씬 안전했을 것입니다.
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()
함수를 사용하여 생성되는 영수증 페이지에 대한 "고유한" ID를 생성합니다. lrand48()
은 통계적 PRNG이므로 생성되는 문자열을 공격자가 쉽게 추축할 수 있습니다. 영수증 시스템의 기본 디자인에도 결함이 있지만 예측 가능한 영수증 ID를 생성하지 않는 난수 발생기를 사용하는 것이 보다 안전했을 것입니다.
<cfoutput>
Receipt: #baseUrl##Rand()#.cfm
</cfoutput>
Rand()
함수를 사용하여 생성되는 영수증 페이지에 대한 "고유한" ID를 생성합니다. Rand()
은 통계적 PRNG이므로 생성되는 문자열을 공격자가 쉽게 추축할 수 있습니다. 영수증 시스템의 기본 설계에도 오류가 있지만 암호화 PRNG와 같이 예측 가능한 영수증 ID를 생성하지 않는 난수 발생기를 사용했다면 훨씬 안전했을 것입니다.
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()
함수를 사용하여 생성되는 영수증 페이지에 대한 "고유한" ID를 생성합니다. Random.nextInt()
은 통계적 PRNG이므로 생성되는 문자열을 공격자가 쉽게 추축할 수 있습니다. 영수증 시스템의 기본 설계에도 오류가 있지만 암호화 PRNG와 같이 예측 가능한 영수증 ID를 생성하지 않는 난수 발생기를 사용했다면 훨씬 안전했을 것입니다.
function genReceiptURL (baseURL){
var randNum = Math.random();
var receiptURL = baseURL + randNum + ".html";
return receiptURL;
}
Math.random()
함수를 사용하여 생성되는 영수증 페이지에 대한 "고유한" ID를 생성합니다. Math.random()
은 통계적 PRNG이므로 생성되는 문자열을 공격자가 쉽게 추축할 수 있습니다. 영수증 시스템의 기본 설계에도 오류가 있지만 암호화 PRNG와 같이 예측 가능한 영수증 ID를 생성하지 않는 난수 발생기를 사용했다면 훨씬 안전했을 것입니다.
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()
함수를 사용하여 생성되는 영수증 페이지에 대한 "고유한" ID를 생성합니다. rand()
은 통계적 PRNG이므로 생성되는 문자열을 공격자가 쉽게 추축할 수 있습니다. 영수증 시스템의 기본 설계에도 오류가 있지만 암호화 PRNG와 같이 예측 가능한 영수증 ID를 생성하지 않는 난수 발생기를 사용했다면 훨씬 안전했을 것입니다.
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()
함수를 사용하여 생성되는 영수증 페이지에 대한 "고유한" ID를 생성합니다. DBMS_RANDOM.SEED()
은 통계적 PRNG이므로 생성되는 문자열을 공격자가 쉽게 추축할 수 있습니다. 영수증 시스템의 기본 디자인에도 결함이 있지만 예측 가능한 영수증 ID를 생성하지 않는 난수 발생기를 사용하는 것이 보다 안전했을 것입니다.
def genReceiptURL(self,baseURL):
randNum = random.random()
receiptURL = baseURL + randNum + ".html"
return receiptURL
rand()
함수를 사용하여 생성되는 영수증 페이지에 대한 "고유한" ID를 생성합니다. rand()
은 통계적 PRNG이므로 생성되는 문자열을 공격자가 쉽게 추축할 수 있습니다. 영수증 시스템의 기본 설계에도 오류가 있지만 암호화 PRNG와 같이 예측 가능한 영수증 ID를 생성하지 않는 난수 발생기를 사용했다면 훨씬 안전했을 것입니다.
def generateReceiptURL(baseUrl) {
randNum = rand(400000000)
return ("#{baseUrl}#{randNum}.html");
}
Kernel.rand()
함수를 사용하여 생성되는 영수증 페이지에 대한 "고유한" ID를 생성합니다. 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()
함수를 사용하여 생성되는 영수증 페이지에 대한 "고유한" ID를 생성합니다. Random.nextInt()
은 통계적 PRNG이므로 생성되는 문자열을 공격자가 쉽게 추축할 수 있습니다. 영수증 시스템의 기본 설계에도 오류가 있지만 암호화 PRNG와 같이 예측 가능한 영수증 ID를 생성하지 않는 난수 발생기를 사용했다면 훨씬 안전했을 것입니다.
sqlite3_randomness(10, &reset_token)
...
Function genReceiptURL(baseURL)
dim randNum
randNum = Rnd()
genReceiptURL = baseURL & randNum & ".html"
End Function
...
Rnd()
함수를 사용하여 생성되는 영수증 페이지에 대한 "고유한" ID를 생성합니다. Rnd()
은 통계적 PRNG이므로 생성되는 문자열을 공격자가 쉽게 추축할 수 있습니다. 영수증 시스템의 기본 설계에도 오류가 있지만 암호화 PRNG와 같이 예측 가능한 영수증 ID를 생성하지 않는 난수 발생기를 사용했다면 훨씬 안전했을 것입니다.CL_ABAP_RANDOM
클래스 또는 해당 변형)에서 특정 상수 값을 사용하여 시드가 생성되면 다수의 PRNG 출력을 수집할 수 있는 공격자가 GET_NEXT
, INT
및 값을 반환하거나 할당하는 이와 유사한 메서드를 통해 반환되는 값을 예측할 수 있게 됩니다.random_gen2
객체에서 생성되는 값을 random_gen1
객체에서 예측할 수 있습니다.
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
입니다.rand()
)에서 특정 값(srand(unsigned int)
같은 함수 사용)을 사용하여 시드가 생성되면 다수의 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()
및 값을 반환하거나 할당하는 이와 유사한 메서드를 통해 반환되는 값을 예측할 수 있게 됩니다.
r := rand.New(rand.NewSource(12345))
i := r.nextInt()
r.Seed(12345)
j := r.nextInt()
randomGen.Seed(12345)
)의 시드를 생성한 호출 이후의 모든 nextInt()
호출은 동일한 출력과 동일한 순서로 나타납니다.Random
)에서 특정 값(Random.setSeed()
같은 함수 사용)을 사용하여 시드가 생성되면 다수의 PRNG 출력을 수집할 수 있는 공격자가 Random.nextInt()
및 값을 반환하거나 할당하는 이와 유사한 메서드를 통해 반환되는 값을 예측할 수 있게 됩니다.Random
개체 randomGen2
를 통해 생성되는 값을 Random
개체 randomGen1
에서 예측할 수 있습니다.
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
)에서 특정 값(Random(Int)
같은 함수 사용)을 사용하여 시드가 생성되면 다수의 PRNG 출력을 수집할 수 있는 공격자가 Random.nextInt()
및 값을 반환하거나 할당하는 이와 유사한 메서드를 통해 반환되는 값을 예측할 수 있게 됩니다.Random
개체 randomGen2
를 통해 생성되는 값을 Random
개체 randomGen1
에서 예측할 수 있습니다.
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
)에서 특정 값(Random.setSeed()
같은 함수 사용)을 사용하여 시드가 생성되면 다수의 PRNG 출력을 수집할 수 있는 공격자가 Random.nextInt()
및 값을 반환하거나 할당하는 이와 유사한 메서드를 통해 반환되는 값을 예측할 수 있게 됩니다.Random
개체 randomGen2
를 통해 생성되는 값을 Random
개체 randomGen1
에서 예측할 수 있습니다.
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
클래스 또는 해당 변형을 감염된 인수로 초기화해서는 안 됩니다. 그렇게 하면 공격자가 의사 난수 발생기(PRNG)의 시드 생성에 사용되는 값을 제어할 수 있게 되므로 다음과 같은 메서드(단, 이에 국한하지는 않음)를 호출하여 생성되는 값의 시퀀스를 예측할 수 있게 됩니다. GET_NEXT
, INT
, FLOAT
, PACKED
.srand()
)가 전달되어 난수 또는 의사 난수(예: rand()
) 값을 생성하는 함수는 감염된 인수로 호출해서는 안 됩니다. 그렇게 하면 공격자가 의사 난수 발생기(PRNG)의 시드 생성에 사용되는 값을 제어할 수 있게 되므로 의사 난수 발생기를 호출하여 생성되는 값(대개 정수)의 시퀀스를 예측할 수 있게 됩니다.ed25519.NewKeyFromSeed()
와 같이 의사 난수 값을 생성하는 함수는 감염된 인수로 호출해서는 안 됩니다. 그렇게 하면 공격자가 의사 난수 발생기의 시드를 생성하는 데 사용되는 값을 제어한 후에 의사 난수 발생기 호출로 인해 생성되는 값의 순서를 예측할 수 있습니다.Random.setSeed()
는 감염된 정수 인수로 호출해서는 안 됩니다. 그렇게 하면 공격자가 의사 난수 발생기(PRNG)의 시드 생성에 사용되는 값을 제어할 수 있게 되므로 Random.nextInt()
, Random.nextShort()
, Random.nextLong()
을 호출하여 생성되거나, Random.nextBoolean()
에서 반환되거나, Random.nextBytes(byte[])
에 설정되는 값(대개 정수)의 시퀀스를 예측할 수 있게 됩니다.Random.setSeed()
는 감염된 정수 인수로 호출해서는 안 됩니다. 그렇게 하면 공격자가 의사 난수 발생기(PRNG)의 시드 생성에 사용되는 값을 제어할 수 있게 되므로 Random.nextInt()
, Random.nextLong()
, Random.nextDouble()
을 호출하여 생성되거나, Random.nextBoolean()
에서 반환되거나, Random.nextBytes(ByteArray)
에 설정되는 값(대개 정수)의 시퀀스를 예측할 수 있게 됩니다.random.randint()
)을 생성하는 함수는 감염된 인수로 호출해서는 안 됩니다. 그렇게 하면 공격자가 의사 난수 발생기(PRNG)의 시드 생성에 사용되는 값을 제어할 수 있게 되므로 의사 난수 발생기를 호출하여 생성되는 값(대개 정수)의 시퀀스를 예측할 수 있게 됩니다.Random.setSeed()
는 감염된 정수 인수로 호출해서는 안 됩니다. 그렇게 하면 공격자가 의사 난수 발생기(PRNG)의 시드 생성에 사용되는 값을 제어할 수 있게 되므로 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()
에 대한 호출은 호스트 이름 확인을 수행하지 않습니다. getInsecure()
에 대한 호출은 모든 SSL 검사가 비활성화된 SSL 소켓 팩토리를 반환합니다.https://safesecureserver.banking.com
연결을 시도할 때 https://hackedserver.banking.com
에 발급된 인증서를 즉시 수락합니다. 그러면 이제 응용 프로그램은 해킹당한 서버에 대한 손상된 SSL 연결에서 민감한 사용자 정보를 누출할 가능성이 있습니다.