소프트웨어 개발 보안과 DevSecOps 실천 방법
소프트웨어 개발 생명주기에 보안을 통합하는 SDL과 DevSecOps, 취약점 대응, 보안 테스트 및 조직 운영 방식을 정리한다.
2026-08-14 · 최초 발행 2025-06-28
보안 결함은 개발 흐름 안에서 다뤄야 한다
소프트웨어 개발 보안은 개발 생명주기 전반에 보안을 포함하는 체계적 접근이다. 설계부터 배포와 유지보수까지 보안 요소를 함께 검토하는 방식이며, 최근 사이버 공격의 70% 이상이 애플리케이션 계층을 대상으로 하고 이에 따른 비용은 연간 수조 원에 달한다.
보안 결함을 개발 초기에 수정하는 비용은 운영 단계 대비 약 1/30 수준이다. 보안을 배포 직전의 검사로 미루지 않고, 개발 과정의 의사결정과 검증 절차에 넣는 이유다.
SDL에 보안 활동을 연결하는 방식
Microsoft가 제안한 Security Development Lifecycle은 개발 전 과정에 보안 활동을 통합한다. 요구사항 단계에서는 보안 요구사항과 위험을 정리하고, 설계에서는 위협 모델링과 보안 아키텍처를 다룬다. 구현 단계에는 시큐어 코딩과 정적 분석이, 테스트에는 동적 분석과 침투 테스트가 포함된다.
배포 시점에는 최종 보안 검토와 인시던트 대응 계획을 준비한다. 운영 이후에도 취약점을 모니터링하고 패치를 관리해야 흐름이 닫힌다.
입력과 출력이 만나는 지점
SQL 인젝션은 데이터베이스에 무단으로 접근하거나 정보를 유출·조작하게 할 수 있다. 쿼리 문자열을 직접 조합하는 대신 매개변수화된 쿼리, 저장 프로시저, ORM을 사용해 입력을 분리한다.
// 취약한 코드
String query = "SELECT * FROM users WHERE username = '" + username + "'";
// 안전한 코드
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE username = ?");
stmt.setString(1, username);
XSS는 사용자 세션 탈취, 악성 코드 실행, 피싱 공격으로 이어질 수 있다. 입력값 검증과 출력 인코딩, CSP(Content Security Policy) 적용이 대응 수단이다.
// 취약한 코드
response.getWriter().println("<div>" + userInput + "</div>");
// 안전한 코드
response.getWriter().println("<div>" + escapeHtml(userInput) + "</div>");
CSRF는 사용자가 인지하지 못한 상태에서 중요 기능을 실행하거나 권한 상승을 유발할 수 있다. Anti-CSRF 토큰, SameSite 쿠키 속성, Referrer 검증으로 대응한다.
인증, 권한, 암호화의 경계
인증 및 세션 관리가 약하면 계정 탈취, 세션 하이재킹, 권한 우회가 발생할 수 있다. 다중 인증(MFA), 안전한 세션 관리, 적절한 세션 타임아웃을 함께 적용한다.
접근 제어는 수평적·수직적 권한 우회와 권한 상승을 막아야 한다. 최소 권한 원칙을 바탕으로 역할 기반 접근 제어(RBAC)나 속성 기반 접근 제어(ABAC)를 적용한다.
암호화가 부실하면 민감 정보 노출과 데이터 무결성 침해가 발생한다. 강력한 암호화 알고리즘, 키 관리, TLS/SSL 적용이 필요하다.
// 취약한 암호화
MD5, SHA-1, DES
// 안전한 암호화
PBKDF2, BCrypt, Argon2, AES-256
상태 변화와 오류가 드러내는 취약점
경쟁 조건(Race Condition)은 데이터 일관성을 손상시키거나 권한 우회로 이어질 수 있다. 상호 배제(Mutual Exclusion), 트랜잭션 관리, 원자적 연산으로 상태 변경을 통제한다.
세션 고정과 세션 하이재킹도 상태 관리 취약점에 속한다. 인증 후 세션을 재생성하고, 세션 타임아웃과 보안 쿠키 속성을 적용해야 한다.
오류 메시지에 시스템 정보를 그대로 노출하면 공격자에게 공격 벡터를 제공할 수 있다. 사용자는 이해할 수 있는 메시지를 받도록 하고, 상세 오류는 로그에 남겨야 한다.
// 취약한 에러 처리
try {
// 코드
} catch (Exception e) {
response.getWriter().println("Error: " + e.toString());
}
// 안전한 에러 처리
try {
// 코드
} catch (Exception e) {
logger.error("처리 중 오류 발생", e);
response.getWriter().println("처리 중 오류가 발생했습니다. 관리자에게 문의하세요.");
}
하드코딩된 비밀은 자격 증명 노출과 권한 있는 접근을 허용할 수 있으므로 환경 변수, 보안 저장소, 비밀 관리 서비스를 사용한다. 사용하지 않는 기능과 코드는 공격 표면을 넓힐 수 있어 최소 기능 원칙과 코드 검토로 제거한다.
서로 다른 관점의 보안 검증
SAST는 코드 수준에서 보안 취약점을 찾고 빌드 파이프라인에 통합해 자동화할 수 있다. SonarQube, Fortify, Checkmarx, ESLint Security가 주요 도구다.
DAST는 실행 중인 애플리케이션을 대상으로 보안 테스트를 수행하므로 실제 환경의 취약점을 발견하는 데 효과적이다. OWASP ZAP, Burp Suite, Acunetix를 활용할 수 있다.
SCA는 사용 중인 오픈소스 라이브러리의 알려진 취약점을 검사하고 의존성 관리와 업데이트를 지원한다. OWASP Dependency-Check, Snyk, WhiteSource가 여기에 해당한다.
침투 테스트는 실제 공격자 관점에서 취약점을 검증한다. 복잡한 취약점 체인을 찾는 데 유용하며, 정기적으로 수행해 보안 상태를 점검한다.
CI/CD 흐름에 보안 게이트를 두기
DevSecOps는 개발(Dev), 보안(Sec), 운영(Ops)을 통합하는 접근이다. CI/CD 파이프라인에 자동화된 보안 테스트를 연결하고, 중요 취약점이 발견되면 보안 게이트를 통해 빌드나 배포를 중단한다.
운영 환경에서는 지속적인 모니터링과 피드백 체계를 유지해 다음 개발 주기에 반영한다.
산업별로 달라지는 준수 요구
금융 산업에서는 PCI DSS와 금융보안원 전자금융감독규정을 고려한다. 강력한 인증, 암호화, 접근 제어, 로깅, 정기적 취약점 점검이 주요 요구사항이다.
의료 산업은 HIPAA와 개인정보보호법에 따라 민감한 의료정보를 보호해야 한다. PHI 보호, 접근 제어, 감사 추적, 위험 평가가 요구된다.
공공 부문은 전자정부 SW 개발·운영자를 위한 소프트웨어 개발보안 가이드와 행정안전부 정보시스템 구축·운영 지침을 따른다. 시큐어 코딩, 취약점 점검, 보안 테스트가 핵심이다.
보안을 팀의 일상적인 작업으로 만들기
개발자 보안 교육 프로그램과 보안 챔피언 프로그램은 보안 책임을 특정 조직에만 두지 않게 한다. 버그 바운티 또는 내부 취약점 보고 시스템을 마련하고, 게임화(Gamification)를 통해 보안 인식을 높일 수 있다.
보안 성과를 측정하고 개선하는 과정도 필요하다. 기술적 통제만으로는 부족하며, 프로세스와 사람을 함께 다루는 균형이 장기적인 운영을 좌우한다.
보안 중심 개발이 남긴 변화
A 금융기관은 초기 개발 단계에 위협 모델링을 도입하고 CI/CD 파이프라인에 자동화된 보안 테스트를 통합했다. 그 결과 운영 환경 취약점은 70% 감소했고, 보안 사고 대응 시간은 50% 단축됐다.
B 전자상거래 기업은 시큐어 코딩 표준을 수립해 교육하고 코드 검토 과정에 보안 전문가를 참여시켰다. 고객 정보 유출 위험 감소, PCI DSS 인증 획득, 브랜드 신뢰도 향상으로 이어졌다.
Shift Left 접근은 초기 설계부터 보안을 고려하게 한다. 자동화된 보안 테스트, 지속적인 교육, 조직 문화가 함께 작동할 때 개발 보안은 비용 항목이 아니라 운영을 위한 투자로 자리 잡는다.