패치 적용 시간 메트릭: Qualys와 Elastic을 사용한 생존 분석 접근 방식
서문
다양한 환경과 팀에서 취약점이 얼마나 빨리 해결되는지 이해하는 것은 강력한 보안 태세를 유지하는 데 매우 중요합니다. 이 문서에서는 Elastic Stack을 사용해 Qualys VMDR의 취약성 관리(VM) 데이터에 생존 분석을 적용한 방법에 대해 설명합니다. 이를 통해 팀 속도(팀이 얼마나 빨리 작업을 완료하는지)와 해결 능력(얼마나 많은 문제를 해결할 수 있는지)에 대한 일반적인 가정을 확인할 수 있었을 뿐만 아니라 측정 가능한 인사이트도 도출할 수 있었습니다. 대부분의 보안 데이터는 Elastic Stack에 있으므로 이 프로세스는 다른 보안 데이터 소스로 쉽게 재현할 수 있어야 합니다.
구축한 이유
저희의 주된 동기는 일반적인 가정에서 데이터에 기반한 인사이트로 전환하는 것이었습니다:
- 다양한 팀과 환경에서 취약점을 패치하는 속도
- 패치 적용 성능이 내부 서비스 수준 목표(SLO)를 충족하는지 여부
- 병목 현상이나 지연이 자주 발생하는 곳
- 패치 성능에 영향을 줄 수 있는 기타 요인
왜 생존 분석인가? 평균 해결 시간을 단축하는 더 나은 대안
취약점이 얼마나 빨리 패치되는지 추적하기 위해 평균 치료 시간(MTTR)이 일반적으로 사용되지만 평균과 중앙값 모두 상당한 한계가 있습니다(이 글의 뒷부분에서 예시를 제공합니다). 평균은 이상값에매우 민감하며[^1], 실제로는 거의 발생하지 않는 평균 교정 시간을 중심으로 교정 시간이 균등하게 균형을 이룬다고 가정합니다. 중앙값은 극단에 덜 민감하지만 분포의 형태에 대한 정보를 삭제하고 패치가 느린 취약점의 롱테일에 대해서는 아무 말도 하지 않습니다. 어느 쪽도 미해결 사례, 즉 관찰 기간 이후에도 여전히 열려 있는 취약점을 설명하지 못하며, 이는 종종 완전히 제외됩니다. 실제로 가장 오랫동안 열려 있는 취약점이 바로 우리가 가장 우려해야 하는 취약점입니다.
생존 분석은 이러한 한계를 해결합니다. 의료 및 보험 계리 분야에서 시작된 이 솔루션은 검열된 관찰 데이터, 즉 여전히 열려 있는 취약점을 명시적으로 통합하면서 이벤트 발생 시점 데이터를 모델링합니다. (취약점 관리에 대한 적용에 대한 자세한 내용은 "메트릭 매니페스토"를 적극 권장합니다.) 생존 분석은 수정 동작을 단일 수치로 축소하는 대신 시간이 지나도 취약점이 패치되지 않은 상태로 남아있을 확률을 추정합니다(예 90% 취약점 중 30 일 이내에 해결됨). 이를 통해 SLO 내에서 패치된 취약점의 비율(예: 30일, 90일 또는 180 일 이내)과 같은 보다 의미 있는 평가를 할 수 있습니다.
생존 분석은 취약점이 시간이 지나도 패치되지 않은 채로 남아있을 확률을 추정하는 생존 함수를 제공합니다.
::: 이 방법을 사용하면 취약점이 얼마나 오래 지속되는지뿐만 아니라 시스템, 팀 또는 심각도 수준별로 취약점 수정 동작이 어떻게 다른지 평가할 수 있으므로 수정 성과를 더 잘 파악할 수 있습니다. 특히 불완전하고 왜곡된 경우가 많으며 정상이라는 가정에 저항하는 보안 데이터에 적합합니다. :::
컨텍스트
다양한 환경, 팀, 조직에 걸쳐 생존 분석을 적용했지만, 이 블로그에서는 Elastic Cloud 프로덕션 환경에 대한 결과에 초점을 맞춥니다.
취약성 연령 계산
취약성 연령을 계산하는 방법에는 여러 가지가 있습니다.
취약점 준수 SLO와 같은 내부 지표의 경우, 취약점 수명은 취약점이 마지막으로 발견된 시점과 처음 발견된 시점(일반적으로 공개 후 며칠 후)의 차이로 정의합니다. 이 접근 방식은 오래된 기본 이미지에서 다시 도입되는 취약점에 불이익을 주는 것을 목표로 합니다. 과거에는 기본 이미지가 만족할 만큼 자주 업데이트되지 않았습니다. 새 인스턴스가 생성되면 취약점은 발견 첫날부터 상당한 기간(예: 100 일)이 경과할 수 있습니다.
이 분석에서는 마지막으로 발견된 날짜와 처음 발견된 날짜 사이의 일수를 기준으로 나이를 계산하는 것이 더 적절하다고 판단했습니다. 이 경우 연령은 시스템이 효과적으로 노출된 일수를 나타냅니다.
"모든 것을 패치" 전략
클라우드 환경에서는 모든 패치를 적용하는 정책을 유지하고 있습니다. 이는 모든 인스턴스에서 거의 동일한 기본 이미지를 거의 독점적으로 사용하기 때문입니다. Elastic Cloud는 컨테이너에서 완전히 작동하기 때문에 시스템에 직접 설치되는 특정 애플리케이션 패키지(예: Elasticsearch)가 없습니다. 그 결과 저희 차량은 동질성을 유지합니다.
데이터 파이프라인
데이터를 수집하고 Elastic Stack에 매핑하는 작업은 번거로울 수 있습니다. 다행히도 이러한 문제를 기본적으로 처리하는 보안 통합 솔루션이 많이 있으며, Qualys VMDR도 그중 하나입니다.
3 이 통합은 사용자 정의 수집 방법(예 스크립트, 비트, ...):
- 강화 파이프라인을 구성할 필요 없이 기본적으로 Qualys 지식 기반에서 취약성 데이터를 보강하여 CVE ID, 위협 인텔리전스 정보 등을 추가합니다.
- 예를 들어, CVE는 항상 취약성.id 필드에 저장됩니다. Qualys 데이터는 이미 어떤 소스에서 가져오든 데이터를 표현하는 표준화된 방식인 Elastic Common Schema에 매핑되어 있습니다, 소스와는 독립적입니다.
- 최신 취약점이 포함된 트랜스폼이 이미 설정되어 있습니다. 이 인덱스를 쿼리하여 최신 취약점 상태를 확인할 수 있습니다.
Qualys 상담원 통합 구성
생존 분석을 위해서는 활성 취약점과 패치된 취약점을 모두 수집해야 합니다. 특정 기간을 분석하려면 필드에 일 수를 설정해야 합니다 max_days_since_detection_updated. 저희 환경에서는 매일 Qualys 데이터를 수집하기 때문에 이미 수집해 왔기 때문에 오랜 기간의 고정 데이터를 수집할 필요가 없습니다.
Qualys VMDR 탄력적 에이전트 통합은 다음과 같이 구성되었습니다:
| 속성 | Value | 댓글 |
|---|---|---|
| (설정 섹션) 사용자 이름 | ||
| (설정 섹션) 비밀번호 | Qualys에서는 사용할 수 있는 API 키가 없으므로 기본 인증으로만 인증할 수 있습니다. 이 계정에서 SSO가 비활성화되어 있는지 확인합니다. | |
| URL | https://qualysapi.qg2.apps.qualys.com (미국2용) | https://www.qualys.com/platform-identification/ |
| 간격 | 4h | 수집된 이벤트 수에 따라 조정합니다. |
| 입력 매개변수 | show_asset_id=1& include_vuln_type=confirmed&show_results=1&max_days_since_detection_updated=3&status=New,Active,Re-Opened,수정됨&filter_supersed_qids=1&use_tags=1&tag_set_by=name&tag_include_selector=all&tag_exclude_selector=any&tag_set_include=status:실행 중&tag_set_exclude=status:terminated,status:stopped,status:stale&show_tags=1&show_cloud_tags=1 | show_asset_id=1: 자산 ID 검색 show_results=1: 현재 설치된 패키지와 설치해야 하는 버전에 대한 세부 정보 max_days_since_detection_updated=3: 지난 3 일 동안 업데이트되지 않은 취약점을 필터링합니다(예. 3 일보다 오래 전에 패치된 상태=새로운,활성,재오픈,수정됨: 모든 취약점 상태가 수집됨 filter_supersed_qids=1: 대체된 '취약점 무시 태그: 태그별로 필터링 show_tags=1: Qualys 태그 검색 show_cloud_tags=1: 클라우드 태그 검색 |
데이터가 완전히 수집되면, Kibana Discover(로그-* 데이터 보기 -> data_stream.dataset : "qualys_vmdr.asset_host_detection" ) 또는 Kibana 보안 앱(결과 -> 취약성)에서 검토할 수 있습니다.
Elasticsearch 클라이언트로 Python으로 데이터 로드하기
생존 분석 계산은 Python으로 수행되므로, Elastic에서 Python 데이터 프레임으로 데이터를 추출해야 합니다. 이를 달성하는 방법에는 여러 가지가 있으며, 이 글에서는 그 중 두 가지에 중점을 두겠습니다.
ES|QL 사용
가장 쉽고 편리한 방법은 화살표 형식의 ES|QL을 활용하는 것입니다. 파이썬 데이터 프레임(행과 열)이 자동으로 채워집니다. 자세한 내용은 블로그 게시물 ES|QL에서 파이썬의 네이티브 판다 데이터프레임까지를 읽어보시기 바랍니다.
from elasticsearch import Elasticsearch
import pandas as pd
client = Elasticsearch(
"https://[host].elastic-cloud.com",
api_key="...",
)
response = client.esql.query(
query="""
FROM logs-qualys_vmdr.asset_host_detection-default
| WHERE elastic.owner.team == "platform-security" AND elastic.environment == "production"
| WHERE qualys_vmdr.asset_host_detection.vulnerability.is_ignored == FALSE
| EVAL vulnerability_age = DATE_DIFF("day", qualys_vmdr.asset_host_detection.vulnerability.first_found_datetime, qualys_vmdr.asset_host_detection.vulnerability.last_found_datetime)
| STATS
mean=AVG(vulnerability_age),
median=MEDIAN(vulnerability_age)
""",
format="arrow",
)
df = response.to_pandas(types_mapper=pd.ArrowDtype)
print(df)
현재 ESQL에는 결과 페이지 매김을 할 수 없다는 한계가 있습니다. 따라서 출력 문서는 10K(서버 구성이 수정된 경우 100K)로 제한됩니다. 이 개선 요청을 통해 진행 상황을 확인할 수 있습니다.
DSL 사용
Elasticsearch Python 클라이언트에는 투명한 페이지 매김으로 쿼리에서 모든 데이터를 추출하는 기본 기능이 있습니다. 어려운 부분은 DSL 쿼리를 만드는 것입니다. 검색에서 쿼리를 생성한 다음 검사, 요청 탭을 차례로 클릭하여 DSL 쿼리를 가져오는 것이 좋습니다.
query = {
"track_total_hits": True,
"query": {
"bool": {
"filter": [
{
"match": {
"elastic.owner.team": "awesome-sre-team"
}
},
{
"match": {
"elastic.environment": "production"
}
},
{
"match": {
"qualys_vmdr.asset_host_detection.vulnerability.is_ignored": False
}
}
]
}
},
"fields": [
"@timestamp",
"qualys_vmdr.asset_host_detection.vulnerability.unique_vuln_id",
"qualys_vmdr.asset_host_detection.vulnerability.first_found_datetime",
"qualys_vmdr.asset_host_detection.vulnerability.last_found_datetime",
"elastic.vulnerability.age",
"qualys_vmdr.asset_host_detection.vulnerability.status",
"vulnerability.severity",
"qualys_vmdr.asset_host_detection.vulnerability.is_ignored"
],
"_source": False
}
results = list(scan(
client=es,
query=query,
scroll='30m',
index=source_index,
size=10000,
raise_on_error=True,
preserve_order=False,
clear_scroll=True
))
생존 분석
코드를 참조하여 데이터 세트에서 코드를 이해하거나 재현할 수 있습니다.
학습한 내용
사이엔티아 연구소의 연구를 참고하여 평균, 중앙값, 생존 곡선을 사용하여 취약점을 수정하는 데 걸리는 시간을 측정하는 몇 가지 방법을 살펴봤습니다. 각 방법은 패치까지의 시간 데이터를 이해할 수 있는 서로 다른 렌즈를 제공하며, 어떤 방법을 사용하느냐에 따라 취약점이 얼마나 잘 해결되고 있는지에 대해 매우 다른 결론을 도출할 수 있기 때문에 비교가 중요합니다.
첫 번째 방법은 이미 폐쇄된 취약점에만 집중합니다. 패치를 적용하는 데 걸린 시간의 중앙값과 평균을 계산합니다. 이 방법은 직관적이고 간단하지만 데이터의 잠재적으로 크고 중요한 부분(여전히 열려 있는 취약점)을 놓치게 됩니다. 그 결과, 특히 일부 취약점이 다른 취약점보다 훨씬 더 오래 열려 있는 경우 수정하는 데 걸리는 실제 시간을 과소평가하는 경향이 있습니다.
두 번째 방법은 지금까지 취약점이 열려 있던 시간을 사용하여 닫힌 취약점과 열려 있는 취약점을 모두 포함하려고 합니다. 공개 취약점에 대한 패치 시점을 추정하는 방법은 여러 가지가 있지만, 여기서는 간단하게 하기 위해 보고 시점에 취약점이 패치되었다고(패치될 것이라고?) 가정했지만 사실이 아님을 알고 있습니다. 하지만 그 존재를 고려할 수 있는 방법을 제공합니다.
세 번째 방법은 생존 분석을 사용합니다. 특히 카플란-마이어 추정기를 사용하여 특정 시점에 취약점이 여전히 열려 있을 가능성을 모델링했습니다. 이 방법은 취약점이 패치된 것처럼 가장하는 대신 '검열된' 데이터로 취급하여 공개 취약점을 적절히 처리합니다. 생존 곡선은 시간이 지남에 따라 감소하여 며칠 또는 몇 주가 지나도 여전히 열려 있는 취약점의 비율을 보여줍니다.
취약점은 얼마나 오래 지속되나요?
현재 6개월 스냅샷[^2]에서 비공개 전용 패치까지의 시간은 중앙값이 ~33일, 평균이 ~35일입니다. 표면적으로는 합리적으로 보이지만 카플란-마이어 곡선은 이 숫자가 숨기는 것을 보여줍니다. 33 일수에서 ~54%, 35 일수에서 ~46% 여전히 열려 있습니다. 따라서 '일반적인' 한 달이 지났을 때에도 약 절반의 문제가 해결되지 않은 채로 남아 있습니다.
또한 관찰된 지금까지의 통계(측정 기간이 끝날 때 취약점이 패치된 것처럼 처리)도 계산했습니다. 이 기간 동안에는 거의 동일한 기간(중앙값 ~33일, 평균 ~35일)이 발생하는데, 이는 현재 열려 있는 항목의 기간이 한 달에 가깝게 모여 있기 때문입니다. 이러한 우연의 일치로 인해 평균이 안정적으로 보일 수 있지만, 스냅샷을 월간 패치 푸시 직전으로 이동하면 기본 프로세스의 변화 없이 동일한 통계가 급격히 떨어집니다(관찰된 중앙값은 ~19일, 평균은 ~15일로 관찰되었습니다).
생존 곡선은 "% 30일/60일/90일 후에도 여전히 열려 있는가"라는 질문에 답하고 한 달이 지나도 열려 있는 롱테일에 대한 가시성을 제공하기 때문에 이러한 함정을 피할 수 있습니다.
모든 곳에 동일한 방식으로 패치를 적용하시나요?
계층화된 생존 분석은 생존 곡선에 대한 개념을 한 단계 더 발전시킨 것입니다. 모든 취약점을 하나의 큰 풀에서 함께 보는 대신, 의미 있는 특성에 따라 그룹(또는 '계층')으로 분리합니다. 분석에서는 심각도, 자산 중요도, 환경, 클라우드 제공업체, 팀/부서/조직별로 취약성을 계층화했습니다. 각 그룹은 고유한 생존 곡선을 가지며, 여기 예제 그래프에서는 시간이 지남에 따라 서로 다른 취약성 심각도가 얼마나 빨리 해결되는지 비교합니다.
이 접근 방식의 장점은 집계에 숨겨져 있던 차이점을 드러낼 수 있다는 점입니다. 전체 생존 곡선만 살펴본다면 전반적으로 개선 성과에 대한 결론을 내릴 수 있을 뿐입니다. 그러나 계층화를 통해 다른 팀, 환경 또는 심각도 문제가 다른 팀보다 더 빨리 해결되는지, 그리고 우리의 경우 모든 패치 전략이 실제로 일관성이 있는지를 알 수 있습니다. 이러한 수준의 세부 정보는 목표에 맞게 개선하는 데 중요하며, 일반적으로 문제를 해결하는 데 걸리는 시간뿐만 아니라 실제 병목 현상이 존재하는지 여부와 그 위치를 파악하는 데 도움이 됩니다.
팀은 얼마나 빨리 행동하나요?
생존 곡선은 취약점이 얼마나 오랫동안 열려 있는지를 강조하지만, 누적 분포 함수(CDF)를 사용하면 관점을 전환할 수 있습니다. CDF는 취약점이 얼마나 빨리 패치되었는지에 중점을 두어 특정 시점까지 수정된 취약점의 비율을 보여줍니다.
CDF를 플로팅하면 치료 속도를 명확하게 파악할 수 있지만, 이 버전에는 관찰된 기간 내에 패치된 취약점만 포함된다는 점에 유의해야 합니다. 전체 라이프사이클을 파악하기 위해 6개월 코호트 단위로 계산하는 생존 곡선과 달리, CDF는 해당 월에 마감된 항목에 대해 월별로 계산됩니다[^3].
따라서 팀이 취약점을 수정한 후 얼마나 빨리 취약점을 수정했는지를 알려주며, 해결되지 않은 취약점이 얼마나 오랫동안 열려 있는지는 반영하지 않습니다. 예를 들어, 이번 달에 종료된 취약점 중 83.2%(% )가 첫 발견 후 30 일 이내에 해결된 것으로 나타났습니다. 이는 최근에 성공적으로 패치된 취약점에 대한 패치 속도를 강조하지만, 여전히 열려 있고 패치까지 더 오랜 시간이 걸릴 가능성이 있는 오래된 취약점은 고려하지 않습니다. 따라서 단기적인 대응 행동을 이해하기 위해 CDF를 사용하는 반면, 전체 수명 주기 역학은 CDF와 생존 분석의 조합으로 제공됩니다. CDF는 팀이 패치한 후 얼마나 빨리 대응하는지를 설명하는 반면 생존 곡선은 취약점이 실제로 얼마나 오래 지속되는지를 보여줍니다.
생존 분석과 평균/중앙값의 차이점
잠깐만요, 이상값의 영향을 피하기 위해 패치 시간을 분석하는 것이 생존 분석이 더 낫다고 말씀드렸습니다. 그러나 이 예제에서는 평균/중앙값 및 생존 분석이 비슷한 결과를 제공합니다. 부가가치는 무엇인가요? 그 이유는 간단합니다. 패치 프로세스가 완전히 자동화되고 효과적이기 때문에 프로덕션 환경에는 이상값이 없습니다.
이기종 데이터에 미치는 영향을 보여드리기 위해 자동화된 패치가 없는 비프로덕션 환경의 오래된 예시를 사용하겠습니다.
ESQL 쿼리:
FROM qualys_vmdr.vulnerability_6months
| WHERE elastic.environment == "my-outdated-non-production-environment"
| WHERE qualys_vmdr.asset_host_detection.vulnerability.is_ignored == FALSE
| EVAL vulnerability_age = DATE_DIFF("day", qualys_vmdr.asset_host_detection.vulnerability.first_found_datetime, qualys_vmdr.asset_host_detection.vulnerability.last_found_datetime)
| STATS
count=COUNT(*),
count_closed_only=COUNT(*) WHERE qualys_vmdr.asset_host_detection.vulnerability.status == "Fixed",
mean_observed_so_far=MEDIAN(vulnerability_age),
mean_closed_only=MEDIAN(vulnerability_age) WHERE qualys_vmdr.asset_host_detection.vulnerability.status == "Fixed",
median_observed_so_far=MEDIAN(vulnerability_age),
median_closed_only=MEDIAN(vulnerability_age) WHERE qualys_vmdr.asset_host_detection.vulnerability.status == "Fixed"
| 지금까지 관찰된 사항 | 휴무일만 | |
|---|---|---|
| 개수 | 833 | 322 |
| 평균 | 178.7(일) | 163.8(일) |
| 중앙값 | 61(일) | 5 (일) |
| 중앙 생존 기간 | 527(일) | 해당 없음 |
이 예에서는 평균과 중앙값을 사용하면 매우 다른 결과를 얻을 수 있습니다. 하나의 대표 지표를 선택하는 것은 어렵고 오해의 소지가 있을 수 있습니다. 생존 분석 그래프는 이러한 환경 내에서 취약점을 해결하는 데 있어서의 효율성을 정확하게 보여줍니다.
최종 생각
생존 분석을 사용하면 보다 정확한 측정뿐만 아니라 병목 현상이 발생하는 위치, 패치 속도에 영향을 미치는 요인, SLO에 부합하는지를 보여주는 패치 동작의 역학에 대한 통찰력을 얻을 수 있다는 이점이 있습니다. 기술 통합 관점에서 보면, 운영 워크플로우와 보고의 일부로 생존 분석을 사용하는 것은 현재 Elastic Stack 설정에 최소한의 추가 변경만으로 달성할 수 있습니다. 생존 분석은 패치 주기와 동일한 주기로 실행될 수 있으며 결과는 시각화를 위해 Kibana로 다시 푸시됩니다. 장기적인 추세와 단기적인 성과 추적을 위해 기존의 운영 지표와 생존 분석을 결합하는 것이 결정적인 이점입니다.
앞으로 도착률, 번다운률, 탈출률과 같은 새로운 지표를 추가로 실험하여 취약점이 실제로 어떻게 처리되는지 보다 역동적으로 파악할 수 있는 방법을 모색하고 있습니다.
도착률은 새로운 취약점이 환경에 얼마나 빨리 유입되는지를 측정하는 척도입니다. 예를 들어 매달 50개의 새로운 CVE가 나타난다는 사실을 알면 패치 측정을 시작하기도 전에 워크로드에서 예상되는 사항을 알 수 있습니다. 따라서 도착률은 백로그에 대한 정보가 아니라 시스템에 가해지는 압력에 대한 정보를 제공하는 지표입니다.
번다운 속도 (추세)는 방정식의 나머지 절반, 즉 취약점이 얼마나 빨리 해결되고 있는지와 취약점이 얼마나 빨리 발견되는지를 보여줍니다.
이스케이프 레이트는 보안이 적용되어야 할 지점을 빠져나가는 취약점에 집중함으로써 또 다른 차원을 추가합니다. 여기서 이스케이프는 패치 기간을 놓치거나 SLO 임계값을 초과하는 CVE에 대한 것입니다. 탈출률이 높다는 것은 취약점이 존재한다는 것뿐만 아니라 패치 주기가 너무 느리거나 자동화 프로세스가 부족하거나 보상 제어가 의도대로 작동하지 않는 등 취약점을 제어하도록 설계된 프로세스가 실패하고 있음을 의미합니다.
도착률은 새로운 위험이 얼마나 많이 유입되고 있는지, 번다운 추세는 이러한 압박에 보조를 맞추고 있는지 또는 압도당하고 있는지, 탈출률은 계획된 통제에도 불구하고 취약성이 지속되는 부분을 드러내는 등, 메트릭을 함께 사용하면 더 나은 그림을 그릴 수 있습니다.
[1]: 통계에서 이상값은 중심 경향에서 매우 멀리 떨어져 있거나 데이터 집합의 나머지 값과 멀리 떨어져 있는 데이터 포인트입니다. 예를 들어, 대부분의 취약점이 30 일 이내에 패치되지만 600 일이 걸리는 취약점이 있다면 그 600일 사례는 이상치입니다. 이상값은 '일반적인' 경험을 반영하지 않는 방식으로 평균을 상향 또는 하향 조정할 수 있습니다. 패치 맥락에서 볼 때, 이러한 취약점은 특히 패치가 느린 취약점이며 일반적인 취약점보다 훨씬 더 오래 열려 있습니다. 쉽게 업데이트할 수 없는 시스템이나 광범위한 테스트가 필요한 패치와 같이 드물지만 중요한 상황을 나타낼 수 있습니다.
[2]: 참고: 현재 6개월 데이터 세트에는 관찰 기간이 끝날 때 열려 있는 모든 취약점(열려 있는 기간/처음 발견된 시기와 무관)과 6개월 기간 동안 닫힌 모든 취약점이 모두 포함됩니다. 이러한 혼합 코호트 접근 방식에도 불구하고, 이전 관찰 기간의 생존 곡선은 특히 곡선의 초기 부분에서 일관된 추세를 보여줍니다. 첫 30~60일 동안의 모양과 기울기는 스냅샷 전반에 걸쳐 매우 안정적인 것으로 입증되었으며, 이는 패치까지의 평균 시간 및 초기 단계의 문제 해결 행동과 같은 지표가 짧은 관찰 기간의 인공물이 아님을 시사합니다. 장기 추정치(예 90 백분위수)는 짧은 스냅샷에서는 여전히 불완전하지만, 이러한 코호트에서 도출된 결론은 여전히 지속적이고 신뢰할 수 있는 패치 역학을 반영합니다.
[3]:우리는 운영 보고(당월에 완료된 작업에 대한 처리량 및 SLO 준수)를 위해 CDF를 월 단위로 유지한 반면, 카플란-마이어는 검열을 적절히 처리하고 더 광범위한 코호트에서 꼬리 위험을 노출하기 위해 6개월 주기를 사용했습니다.
