<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Secure by Design on jyukki's Blog</title><link>https://jyukki.com/tags/secure-by-design/</link><description>Recent content in Secure by Design on jyukki's Blog</description><generator>Hugo -- 0.147.0</generator><language>ko-KR</language><lastBuildDate>Fri, 30 Oct 2026 10:06:00 +0900</lastBuildDate><atom:link href="https://jyukki.com/tags/secure-by-design/index.xml" rel="self" type="application/rss+xml"/><item><title>2026 개발 트렌드: 메모리 안전 전환, 전면 재작성 대신 위험 표면 예산으로 시작하기</title><link>https://jyukki.com/posts/2026-10-30-memory-safety-migration-risk-surface-budget-trend/</link><pubDate>Fri, 30 Oct 2026 10:06:00 +0900</pubDate><guid>https://jyukki.com/posts/2026-10-30-memory-safety-migration-risk-surface-budget-trend/</guid><description>메모리 안전을 전사 언어 교체 구호가 아니라 공격 표면·변경 비용·운영 증거를 줄이는 포트폴리오로 운영하는 실무 기준을 정리합니다.</description><content:encoded><![CDATA[<p>메모리 안전은 더 이상 “언젠가 고려할 언어 선택”만은 아닙니다. 취약점 보고, 규제 요구, 공급망 심사, 제품 보안 약속이 얽히면서 팀은 C/C++ 또는 광범위한 <code>unsafe</code> 경계를 어떻게 줄일지 설명해야 합니다. 그러나 이 흐름을 “전면 Rust 재작성”으로 받아들이면 실패하기 쉽습니다. 오래된 드라이버, 고성능 codec, OS API, vendor SDK, 수년간 검증된 라이브러리를 한 번에 옮기면 새로운 결함과 배포 위험도 함께 커지기 때문입니다.</p>
<p>최근 실무의 현실적인 방향은 <strong>새 위험 표면에는 memory-safe 기본값을 두고, 남는 native 경계에는 측정 가능한 위험 예산과 방어층을 붙이는 것</strong>입니다. 이 글은 <a href="/posts/2026-10-01-rust-compiler-performance-ci-change-budget-trend/">Rust compiler 성능과 CI change budget</a>, <a href="/posts/2026-10-12-ebpf-observability-platform-adoption-trend/">eBPF observability 플랫폼 도입</a>, <a href="/posts/2026-10-15-runtime-reachability-evidence-vulnerability-prioritization-trend/">런타임 reachability 기반 취약점 우선순위</a>, <a href="/posts/2026-08-06-security-default-setup-rollout-contract-trend/">Security Default rollout 계약</a>을 연결해 언어 전환을 운영 가능한 위험 감소로 바꾸는 방법을 정리합니다.</p>
<h2 id="이-글에서-얻는-것">이 글에서 얻는 것</h2>
<ul>
<li>어떤 구성요소부터 memory-safe 기본값을 적용할지 공격 표면과 변경 비용으로 우선순위를 정할 수 있습니다.</li>
<li>Rust 같은 언어를 도입해도 남는 FFI·<code>unsafe</code>·native dependency 경계를 별도 위험으로 다룰 수 있습니다.</li>
<li>코드 줄 수 대신 취약 표면·검증·복구 능력을 보여 주는 지표를 만들 수 있습니다.</li>
<li>90일 파일럿에서 성능·빌드·운영 비용을 잃지 않고 전환 가설을 검증할 수 있습니다.</li>
</ul>
<h2 id="핵심-개념이슈">핵심 개념/이슈</h2>
<h3 id="1-메모리-안전은-언어-라벨이-아니라-경계의-성질이다">1) 메모리 안전은 언어 라벨이 아니라 경계의 성질이다</h3>
<p>Rust, Java, Go를 쓴다고 전체 시스템이 자동으로 안전해지는 것은 아닙니다. network packet을 parse하는 native library, <code>unsafe</code> 블록, FFI pointer, C ABI plugin, kernel interface는 여전히 경계에 남습니다. 반대로 C/C++도 작은 권한, 강한 sandbox, fuzzing, sanitizer, 최소 parsing surface를 적용하면 위험을 크게 낮출 수 있습니다.</p>
<p>첫 질문은 “무슨 언어를 표준으로 정할까?”가 아니라 “어떤 입력이 어떤 권한으로 메모리 경계를 넘는가?”여야 합니다. 인터넷·업로드 파일 같은 비신뢰 입력, parser·codec·compression의 bytes 처리, root·CI runner·secret 접근 권한, 주간 배포와 반복되는 crash가 동시에 있으면 우선순위를 올립니다. 안정된 내부 수치 계산보다 외부 ZIP을 푸는 upload worker와 privileged update agent가 먼저 후보입니다. <a href="/learning/deep-dive/2026-10-22-archive-extraction-security-budget-playbook/">Archive extraction 보안 예산</a>처럼 입력 크기와 resource limit은 언어 교체 전에도 적용할 수 있습니다.</p>
<h3 id="2-위험-표면-예산이-전면-재작성을-실행-순서로-바꾼다">2) 위험 표면 예산이 전면 재작성을 실행 순서로 바꾼다</h3>
<p><code>Rust code ratio 30%</code>는 보기 쉬워도 low-risk CLI를 많이 옮겨 가장 위험한 parser가 남아 있으면 보안 효과를 설명하지 못합니다. 서비스별로 위험 표면 점수를 만들고 분기마다 줄일 예산을 정하는 편이 낫습니다.</p>
<table>
  <thead>
      <tr>
          <th>점수 축</th>
          <th>1점</th>
          <th>3점</th>
          <th>5점</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>입력 신뢰도</td>
          <td>내부 고정 입력</td>
          <td>partner API</td>
          <td>인터넷·업로드 파일</td>
      </tr>
      <tr>
          <td>권한·영향</td>
          <td>읽기 전용</td>
          <td>서비스 계정</td>
          <td>host·CI·고객 데이터 접근</td>
      </tr>
      <tr>
          <td>복잡도</td>
          <td>단순 변환</td>
          <td>stateful protocol</td>
          <td>parser·codec·custom allocator</td>
      </tr>
      <tr>
          <td>변경 빈도</td>
          <td>분기 1회 이하</td>
          <td>월간</td>
          <td>주간 이상</td>
      </tr>
      <tr>
          <td>방어 증거</td>
          <td>unit test만</td>
          <td>sanitizer 또는 fuzzing</td>
          <td>fuzzing+isolation+rollback</td>
      </tr>
  </tbody>
</table>
<p>합계 18점 이상은 첫 전환 후보, 12~17점은 방어 강화와 모듈 분리가 우선인 후보로 둡니다. 점수는 자동 승인 도구가 아닙니다. vendor component의 교체 비용, latency SLO, 운영 인력도 같이 적어야 합니다. 목적은 “왜 이것을 먼저 하는가”를 재현 가능하게 만드는 것입니다.</p>
<h3 id="3-ffi는-안전한-섬과-위험한-바다의-접점이다">3) FFI는 안전한 섬과 위험한 바다의 접점이다</h3>
<p>memory-safe wrapper를 작성해도 pointer·길이·lifetime 검사를 C library에 맡기면 안전한 API 모양만 얻고 위험은 남습니다. FFI boundary는 입력 길이, nullability, ownership, allocator, error code, thread affinity, cancellation을 명시한 작은 계약이어야 합니다.</p>
<ul>
<li><strong>borrowed buffer</strong>: native가 호출 중에만 읽고 caller가 해제한다.</li>
<li><strong>transferred ownership</strong>: 누가 어떤 allocator로 언제 해제하는지 ABI에 명시한다.</li>
<li><strong>opaque handle</strong>: 생성·사용·종료 thread와 종료 뒤 호출 금지를 wrapper가 강제한다.</li>
</ul>
<p>경계 함수가 raw parameter를 20개 이상 받거나 <code>void*</code>와 길이가 여러 쌍으로 흩어져 있거나 오류가 boolean 하나라면 API를 분할할 신호입니다. 실패 의미가 모호한 native 호출은 <a href="/posts/2026-10-29-agent-tool-error-contract-trend/">Agent tool 오류 계약</a>처럼 성공·실패·부분 실행을 추측하게 만드는 운영 부채가 됩니다.</p>
<h3 id="4-성능-우려는-금지-근거가-아니라-benchmark-계약이다">4) 성능 우려는 금지 근거가 아니라 benchmark 계약이다</h3>
<p>“Rust가 C++보다 느린가”에는 일반 답이 없습니다. hot loop, SIMD, allocator, syscall, copy 수, build profile이 결과를 바꿉니다. endpoint와 artifact에 맞는 측정 계약을 만드세요. throughput, p50/p99 latency, peak RSS, CPU seconds, binary size, cold start, build time을 함께 봅니다. 기존 대비 p99가 5% 이상 악화하거나 RSS가 15% 이상 늘면 원인을 분해하기 전 승격을 멈추는 guardrail을 둡니다. 평균 속도보다 fallback·오류·tail latency가 운영 결정을 바꾼다는 점은 <a href="/posts/2026-10-25-http3-quic-edge-fallback-observability-trend/">HTTP/3와 QUIC edge fallback 관측</a>과 같습니다.</p>
<h2 id="실무-적용">실무 적용</h2>
<h3 id="1-90일-파일럿은-고위험-경계-하나로-제한한다">1) 90일 파일럿은 고위험 경계 하나로 제한한다</h3>
<p>공용 runtime을 교체하지 말고 외부 파일 metadata 검사, webhook signature verifier, format decoder처럼 입력과 출력이 작고 rollback 가능한 component 하나를 고릅니다. 첫 30일에는 threat model, input corpus, ownership, benchmark 기준선을 문서화합니다. 다음 30일에는 safe implementation 또는 wrapper를 만들고 fuzzing·sanitizer·negative test를 CI에 넣습니다. 마지막 30일에는 1% canary, crash-free rate, latency, 운영자 진단 시간을 보고 승격 또는 중단합니다.</p>
<p>신규 native component에는 외부 입력의 size·time·memory 상한, <code>unsafe</code>·FFI의 owner review와 boundary test, network-facing component의 fuzz target과 24시간 안정 실행 증거를 요구합니다. 권한 높은 process는 sandbox·least privilege·crash restart 제한을 함께 검토합니다. 이는 기존 코드를 벌주는 정책이 아니라 새 위험이 쌓이는 속도를 줄이는 기본값입니다.</p>
<h3 id="2-보고-지표를-코드량에서-위험-감소로-옮긴다">2) 보고 지표를 코드량에서 위험 감소로 옮긴다</h3>
<table>
  <thead>
      <tr>
          <th>지표</th>
          <th style="text-align: right">초기 목표</th>
          <th>해석</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>신규 high-risk native surface</td>
          <td style="text-align: right">분기당 0 또는 승인 100%</td>
          <td>위험이 다시 쌓이는지</td>
      </tr>
      <tr>
          <td>18점 이상 component의 방어 증거 충족률</td>
          <td style="text-align: right">90% 이상</td>
          <td>fuzzing·isolation·rollback 누락</td>
      </tr>
      <tr>
          <td>FFI boundary당 raw pointer parameter</td>
          <td style="text-align: right">기준선 대비 20% 감소</td>
          <td>계약 단순화 정도</td>
      </tr>
      <tr>
          <td>sanitizer/fuzz 발견 후 완화 p95</td>
          <td style="text-align: right">14일 이하</td>
          <td>발견을 수정으로 잇는 속도</td>
      </tr>
      <tr>
          <td>memory-safety production incident</td>
          <td style="text-align: right">분기별 감소</td>
          <td>사용자 영향의 실제 변화</td>
      </tr>
  </tbody>
</table>
<p>LOC는 보조 지표로만 둡니다. high-risk parser 하나를 격리한 결과가 low-risk utility 5만 줄을 포팅한 것보다 더 큰 가치를 가질 수 있습니다. <a href="/posts/2026-10-15-runtime-reachability-evidence-vulnerability-prioritization-trend/">Runtime reachability 기반 취약점 우선순위</a>처럼 “취약점이 존재한다”와 “배포 경로에서 도달 가능하다”를 구분해야 투자 순서가 맞습니다.</p>
<h3 id="3-기존-cc도-방어층을-먼저-올린다">3) 기존 C/C++도 방어층을 먼저 올린다</h3>
<p>재작성 전에도 compiler hardening, ASan/UBSan nightly test, fuzz regression corpus, parser process 격리, egress 축소, restart storm 방지, crash dump 민감정보 마스킹을 적용할 수 있습니다. sanitizer가 CI 한 번 통과했다고 안전하다고 말하면 안 됩니다. representative input, 장시간 실행, release build 차이를 확인해야 합니다. 바꾸기 어려운 vendor SDK나 kernel-facing module은 owner, version, 입력 source, 권한, sandbox, rollback artifact를 inventory에 남기고, 변경 계획이 없으면 만료일과 재검토자를 가진 risk acceptance로 다룹니다.</p>
<h2 id="트레이드오프주의점">트레이드오프/주의점</h2>
<p>memory-safe 언어 도입에는 학습·채용·빌드·debugging 비용이 있습니다. 작은 팀이 넓은 shared library를 급히 포팅하면 review 품질이 떨어지고 낯선 abstraction이 새 performance bug를 만들 수 있습니다. 반대로 <code>unsafe</code>를 0으로 만드는 숫자 게임도 위험합니다. OS API, SIMD, FFI, lock-free 구조에는 안전하지 않은 경계가 필요할 수 있으므로 작은 모듈에 가두고 안전한 wrapper와 test로 호출자를 보호해야 합니다. 언어 전환은 인증 오류, 과도 권한, dependency 탈취도 해결하지 않습니다. <a href="/posts/2026-07-30-publish-time-supply-chain-review-context-trend/">Publish-time supply chain gate</a>처럼 provenance·review·권한 분리는 계속 필요합니다.</p>
<h2 id="체크리스트-또는-연습">체크리스트 또는 연습</h2>
<ul>
<li><input disabled="" type="checkbox"> 외부 입력·권한·복잡도·변경 빈도·방어 증거로 component 위험 점수를 매겼다.</li>
<li><input disabled="" type="checkbox"> 신규 고위험 component의 memory-safe 기본값과 예외 승인 경로가 있다.</li>
<li><input disabled="" type="checkbox"> FFI boundary마다 ownership, allocator, 길이, 오류, 취소, thread 규칙을 문서화했다.</li>
<li><input disabled="" type="checkbox"> high-risk parser 또는 codec에 malformed corpus와 fuzz regression이 있다.</li>
<li><input disabled="" type="checkbox"> benchmark는 p99, RSS, CPU, build time, fallback 오류를 함께 측정한다.</li>
<li><input disabled="" type="checkbox"> 기존 native component에는 owner·version·권한·sandbox·rollback 정보가 있다.</li>
<li><input disabled="" type="checkbox"> <code>unsafe</code> 예외는 만료일과 재검토자를 가진 risk acceptance로 남긴다.</li>
</ul>
<p>연습으로 외부 입력을 받는 native 또는 <code>unsafe</code> 경계 세 개를 고르세요. 다섯 점수 축으로 순위를 매기고 1위 component의 “새 구현”, “wrapper 강화”, “sandbox·fuzzing 우선”을 비용·rollback·예상 위험 감소로 비교합니다. 이 판단표가 있으면 언어 논쟁이 다음 분기 투자 결정으로 바뀝니다.</p>
<h2 id="관련-글">관련 글</h2>
<ul>
<li><a href="/posts/2026-10-01-rust-compiler-performance-ci-change-budget-trend/">Rust compiler 성능과 CI Change Budget</a></li>
<li><a href="/posts/2026-10-12-ebpf-observability-platform-adoption-trend/">eBPF Observability 플랫폼 도입 기준</a></li>
<li><a href="/posts/2026-10-15-runtime-reachability-evidence-vulnerability-prioritization-trend/">Runtime Reachability로 취약점 우선순위 정하기</a></li>
<li><a href="/posts/2026-08-06-security-default-setup-rollout-contract-trend/">Security Default를 안전하게 rollout하는 계약</a></li>
</ul>
]]></content:encoded></item></channel></rss>