1. 시큐어 코딩 개요 * 공급망 보안
보안 사고 사례 분석과 교훈:
- 계정 관리 미흡 관련 사고 교훈: 정기적인 계정 감사, 접근 제한, 보안 시스템 상시 모니터링 필요
- 주기적인 계정 관리 부재로 SQL 인젝션 공격에 취약
- 침입 탐지/차단 시스템 운영 미흡
- 외부에서 관리자 사이트 접근 가능
- 취약한 인증 시스템 관련 사고 교훈: 다중 인증(MFA) 구현, 직원 정보 보호 강화 필요
- 단순 ID/비밀번호 인증만 사용
- 임직원 메일 주소 노출
- 솔라윈즈 공급망 공격 교훈: 공급망 보안 관리, 코드 서명 보안 강화 필요
- 신뢰할 수 있는 업데이트에 악성코드 삽입
- 코드 서명 인증서 유출
SQL 인젝션 공격 도구들
- SQLMap, Mole, Havij 등 자동화 도구가 존재하여 공격이 더욱 쉬워짐
- 데이터베이스 전체가 유출될 수 있으며, 오프라인 패스워드 크래킹도 가능
이러한 사례들을 통해 시큐어 코딩의 중요성과 함께 포괄적인 보안 전략이 필요함을 알 수 있습니다.
보안 위험도 평가 공식: Risk = V * A * T
이 공식은 보안 위험도(Risk)를 계산하는 데 사용되는 기본적인 수식으로, 세 가지 요소의 곱으로 표현됩니다.
1. V (Vulnerability, 취약점)
- 시스템이나 애플리케이션에 존재하는 보안 취약점
- 소프트웨어 버그, 설정 오류, 암호화 미적용 등
- 예: SQL 인젝션 취약점, 약한 비밀번호 정책
- 값이 높을수록 시스템이 더 취약함을 의미
2. A (Asset Value, 자산 가치)
- 보호해야 할 자산의 중요도나 가치
- 금전적 가치, 평판, 법적 영향 등을 고려
- 예: 고객 개인정보, 영업 비밀, 재무 데이터
- 자산의 가치가 높을수록 위험도도 증가
3. T (Threat, 위협)
- 취약점을 실제로 공격할 수 있는 위협의 가능성
- 공격자의 능력, 동기, 공격 발생 확률 등
- 예: 해커 그룹의 활동 수준, 악성코드 감염률
- 위협 수준이 높을수록 실제 공격 가능성 증가
공식의 의미
- 세 요소 중 하나라도 0이면 위험도는 0
- 모든 요소가 높을수록 위험도는 지수적으로 증가
- 위험도를 낮추려면 세 요소 중 하나 이상을 감소시켜야 함
실제 적용 예시
예시 1: 중요 고객 데이터베이스
- V = 8 (SQL 인젝션 취약점 존재)
- A = 9 (고객 개인정보의 높은 가치)
- T = 7 (해커 그룹의 활발한 활동)
- Risk = 8 * 9 * 7 = 504 (매우 높은 위험도)
예시 2: 내부 테스트 서버
- V = 5 (기본 보안 설정만 적용)
- A = 2 (중요 데이터 없음)
- T = 3 (외부 접근 제한됨)
- Risk = 5 * 2 * 3 = 30 (낮은 위험도)
위험도 관리 전략
- 취약점 감소: 패치 적용, 시큐어 코딩, 보안 설정 강화
- 자산 가치 관리: 데이터 분류, 중요 자산 분리 보관
- 위협 감소: 방화벽, IDS/IPS, 접근 제어 강화
이 공식을 통해 조직은 리소스를 효율적으로 배분하고 우선순위를 정하여 보안 위험을 체계적으로 관리할 수 있습니다.
국내외 주요 시큐어코딩 표준 및 가이드
국내 표준 및 가이드
1. 행정안전부 - 소프트웨어 개발보안 가이드
- 시큐어코딩 의무화 근거 제공
- 47개 보안약점 제시
- 입력데이터 검증 및 표현, 보안기능, 시간 및 상태, 에러처리, 코드오류, 캡슐화, API 오용 등 7개 영역
2. 한국인터넷진흥원(KISA) - 시큐어코딩 가이드
- Java, C, Android, PHP 등 언어별 가이드라인 제공
- 실제 코드 예제와 함께 취약점 및 대응방안 설명
- 주기적 업데이트 및 신규 취약점 반영
3. 금융보안원 - 금융권 소프트웨어 개발보안 가이드
- 금융 시스템 특화 보안 가이드라인
- 금융거래 관련 취약점 중점 관리
- 개인정보보호 및 금융정보 보안 강화
4. 국가정보원 - 소프트웨어 보안약점 진단가이드
- 국가·공공기관 대상 보안약점 진단 기준
- 보안약점 진단 도구 및 방법론 제시
- 주요 정보시스템 보안 강화
국제 표준 및 가이드
1. OWASP (Open Web Application Security Project)
- OWASP Top 10: 웹 애플리케이션 10대 보안 위협
- OWASP ASVS: 애플리케이션 보안 검증 표준
- OWASP Secure Coding Practices: 보안 코딩 실무 지침
- 전 세계적으로 가장 널리 사용되는 가이드
2. CWE (Common Weakness Enumeration)
- MITRE 주관 소프트웨어 보안약점 분류 체계
- 800개 이상의 보안약점 카탈로그
- CWE/SANS Top 25: 가장 위험한 소프트웨어 오류
3. CERT Secure Coding Standards
- 카네기 멜론 대학 SEI 개발
- C, C++, Java 등 언어별 코딩 표준
- 규칙(Rules)과 권고사항(Recommendations) 구분
4. ISO/IEC 표준
- ISO/IEC 27034: 애플리케이션 보안 표준
- ISO/IEC 15408: 공통평가기준(Common Criteria)
- ISO/IEC 29147: 취약점 공개 프로세스
5. NIST (미국 국립표준기술연구소)
- NIST SP 800-53: 보안 및 개인정보보호 통제
- NIST SP 800-64: 시스템 개발 생명주기의 보안 고려사항
- NIST SP 800-160: 시스템 보안 엔지니어링
업종별/기술별 특화 가이드
1. PCI DSS (Payment Card Industry Data Security Standard)
- 신용카드 결제 시스템 보안 표준
- 카드 정보 처리/저장/전송 관련 보안 요구사항
2. HIPAA Security Rule
- 의료정보 보호를 위한 보안 가이드라인
- 개인 건강정보(PHI) 보호 기준
3. OWASP Mobile Security
- 모바일 애플리케이션 개발 보안 가이드
- iOS, Android 플랫폼별 보안 권고사항
4. Cloud Security Alliance
- 클라우드 서비스 보안 가이드라인
- SaaS, PaaS, IaaS 환경별 보안 고려사항
주요 언어별 시큐어코딩 가이드
1. Java
- Oracle Java Secure Coding Guidelines
- CERT Oracle Secure Coding Standard for Java
2. C/C++
- SEI CERT C/C++ Coding Standard
- MISRA C/C++ Guidelines
3. Python
- Python Security Best Practices
- OWASP Python Security Project
4. JavaScript
- Node.js Security Checklist
- OWASP JavaScript Security Guide
시큐어코딩 도구 및 자동화
1. 정적 분석 도구 (SAST)
- SonarQube, Checkmarx, Fortify
- 소스코드 레벨에서 취약점 검출
2. 동적 분석 도구 (DAST)
- OWASP ZAP, Burp Suite
- 실행 중인 애플리케이션 취약점 검사
3. 의존성 검사 도구
- OWASP Dependency-Check
- Snyk, WhiteSource
- 오픈소스 컴포넌트 취약점 검사
적용 및 준수 방안
- 정책 수립: 조직 내 시큐어코딩 정책 및 가이드라인 수립
- 교육 훈련: 개발자 대상 정기적인 보안 교육 실시
- 코드 리뷰: 보안 관점의 코드 리뷰 프로세스 도입
- 자동화 도구 활용: SAST/DAST 도구를 CI/CD 파이프라인에 통합
- 정기 감사: 준수 여부 모니터링 및 개선사항 도출
설계 단계 시큐어코딩 적용 방안
NIST SSDF 개요
NIST SSDF는 미국 국립표준기술연구소(NIST)에서 개발한 안전한 소프트웨어 개발 프레임워크로, 소프트웨어 개발 생명주기 전반에 걸쳐 보안을 통합하는 지침을 제공합니다.
주요 특징
- NIST SP 800-218 문서로 발행 (2022년 2월)
- 소프트웨어 개발 전 과정의 보안 활동 체계화
- 산업 모범 사례와 국제 표준을 통합
- 조직 규모에 상관없이 적용 가능
NIST SSDF의 4가지 주요 그룹
1. 조직 준비 (Prepare the Organization, PO)
- PO.1: 보안 요구사항 정의 및 전달
- PO.2: 역할과 책임 정의
- PO.3: 지원 도구 구현
- PO.4: 보안 검사 및 검증 환경 구축
- PO.5: 보안 기준 구현 및 유지
2. 소프트웨어 보호 (Protect the Software, PS)
- PS.1: 모든 형태의 코드 보호
- PS.2: 코드 무결성 검증 메커니즘 제공
- PS.3: 무단 접근 및 변조로부터 보호
3. 안전한 소프트웨어 생산 (Produce Well-Secured Software, PW)
- PW.1: 보안 요구사항을 기반으로 소프트웨어 설계
- PW.2: 설계 검토
- PW.3: 코딩 방식 재사용 및 보안 기능 생성
- PW.4: 안전한 코딩 실무 사용
- PW.5: 소프트웨어 구성 및 빌드 설정
- PW.6: 실행 코드 검토 및 분석
- PW.7: 실행 가능한 코드 테스트
- PW.8: 보안 검사 결과 검증
- PW.9: 취약점 공개 대응
4. 취약점 대응 (Respond to Vulnerabilities, RV)
- RV.1: 취약점 식별 및 확인
- RV.2: 취약점 위험도 평가 및 우선순위 지정
- RV.3: 취약점 분석, 확인 및 해결
NIST SSDF 구현 시 주요 고려사항
1. 위험 기반 접근
- 조직의 위험 프로필에 맞춤
- 우선순위에 따른 구현
- 비용-효과 분석
2. 기존 프로세스와의 통합
- DevSecOps 통합
- CI/CD 파이프라인과 연계
- 기존 보안 프레임워크와 조화
3. 지속적 개선
- 정기적인 검토 및 업데이트
- 교훈 학습 및 적용
- 성숙도 모델 적용
4. 도구 및 자동화
- SAST/DAST 도구 활용
- 취약점 스캐너 통합
- 자동화된 보안 테스트
NIST SSDF와 다른 표준과의 관계
1. OWASP SAMM과의 관계
- SAMM은 더 상세한 성숙도 모델 제공
- SSDF는 더 포괄적인 프레임워크
- 상호 보완적 사용 가능
2. ISO/IEC 27034와의 관계
- ISO 27034는 애플리케이션 보안에 초점
- SSDF는 전체 개발 프로세스 포함
- 두 표준 모두 조직적 접근 강조
3. BSIMM과의 관계
- BSIMM은 실제 조직 관행 기반의 모델
- SSDF는 규범적 접근
- BSIMM을 SSDF 구현 측정에 활용 가능
DBMS 조회 및 결과 검증에서 filter, interceptor, validator는 모두 데이터의 흐름을 제어하거나 검증하는 역할을 하는 개념들입니다. 각 개념에 대해 간단히 설명하겠습니다.
- Filter (필터):
- 역할: 데이터 조회 또는 결과를 가공하기 전에 데이터를 필터링하는 역할을 합니다.
- 용도: 주로 데이터를 DBMS에 요청할 때 또는 조회 결과가 클라이언트로 반환되기 전에 특정 조건을 만족하는 데이터만 선별하는 데 사용됩니다.
- 예시: 예를 들어, 특정 날짜 범위에 해당하는 데이터만 조회하고 싶을 때 필터를 사용하여 불필요한 데이터를 제외할 수 있습니다.
- Interceptor (인터셉터):
- 역할: 요청이나 응답의 흐름을 가로채서 처리를 추가하는 역할을 합니다.
- 용도: 주로 로깅, 트랜잭션 관리, 보안 인증 등을 처리할 때 사용됩니다. 데이터베이스 조회가 실행되기 전이나 후에 추가적인 작업을 삽입할 수 있습니다.
- 예시: 데이터베이스 조회 요청을 가로채어 쿼리 실행 시간을 로깅하거나, 쿼리 실행 전에 사용자 인증 정보를 검사하는 등의 기능을 추가할 수 있습니다.
- Validator (밸리데이터):
- 역할: 데이터가 유효한지 검증하는 역할을 합니다.
- 용도: 사용자가 입력한 데이터나 조회된 결과가 예상되는 형식, 범위 또는 규칙에 맞는지 확인하는 데 사용됩니다.
- 예시: 데이터 조회 후, 특정 필드 값이 비어 있지 않거나 예상 범위 내의 값인지 확인하는 등의 유효성 검사 작업을 할 수 있습니다.
CSRF(Cross-Site Request Forgery, 크로스 사이트 요청 위조)는 공격자가 사용자를 속여서 의도하지 않은 요청을 웹 서버에 보내게 만드는 공격입니다. 이 공격은 사용자가 인증된 상태에서, 즉 로그인된 상태에서 발생할 수 있습니다. 공격자는 사용자가 특정 웹사이트에 로그인한 상태에서 악성 웹 페이지나 이메일을 통해 특정 요청을 보냄으로써, 사용자의 권한을 악용할 수 있습니다.
예를 들어, 사용자가 은행 웹사이트에 로그인한 상태에서 공격자가 악성 링크를 클릭하게 만들면, 그 링크가 사용자의 이름으로 돈을 송금하는 요청을 은행 서버로 보내게 할 수 있습니다. 사용자는 이 요청을 의도하지 않았지만, 공격자는 사용자의 권한을 이용해 원하지 않는 작업을 수행할 수 있게 됩니다.
CSRF 공격이 발생하는 과정
- 사용자가 웹사이트에 로그인하여 세션을 유지합니다.
- 사용자가 공격자의 악성 웹사이트를 방문합니다.
- 공격자는 사용자가 인증된 상태로 서버에 요청을 보내는 악성 코드를 포함한 페이지를 만듭니다.
- 사용자가 악성 페이지를 방문하면, 사용자의 세션 정보를 통해 웹 서버에 요청이 전송되고, 서버는 이를 정당한 요청으로 처리합니다.
CSRF 방어 대책
- CSRF 토큰 사용
- 서버는 각 요청에 대해 고유한 CSRF 토큰을 생성하여, 클라이언트가 서버로 요청을 보낼 때 이 토큰을 함께 보내도록 요구합니다. 서버는 이 토큰을 검증하여 요청이 합법적인지 확인합니다.
- 이 방법은 요청이 정상적인 경로에서 온 것인지 확인할 수 있게 하여, 공격자가 토큰을 알지 못하면 공격을 실패하게 만듭니다.
- SameSite 쿠키 속성
- 쿠키에 SameSite 속성을 설정하여, 동일한 도메인에서만 쿠키가 전송되도록 할 수 있습니다. 예를 들어, SameSite=Lax나 SameSite=Strict로 설정하면, 다른 사이트에서 요청을 보낼 때 세션 쿠키가 포함되지 않도록 할 수 있습니다.
- SameSite=Strict는 더욱 강력한 보안을 제공하며, 완전히 다른 도메인에서의 요청을 차단합니다.
- Referer 헤더 확인
- 서버는 요청에 포함된 Referer 헤더를 검사하여, 요청이 같은 도메인에서 온 것인지 확인할 수 있습니다. 만약 다른 도메인에서 요청이 온 경우, 이를 차단할 수 있습니다.
- 사용자 입력 검증
- 중요한 요청(예: 비밀번호 변경, 이메일 주소 변경 등)에 대해 추가적인 인증 절차를 두는 방법입니다. 예를 들어, 비밀번호를 변경할 때는 사용자에게 추가적인 인증을 요구하거나, 이메일로 확인 코드를 보내는 방법이 있습니다.
- GET 요청에 대한 제한
- 중요한 상태 변경 요청을 GET 방식이 아니라 POST 방식으로 처리하도록 합니다. CSRF 공격은 보통 GET 요청을 통해 이루어지기 때문에, 상태 변경 작업을 GET 요청으로 허용하지 않는 것이 좋습니다.
실습
' OR '1'='1 도 되고 1도 아이디로 넣어도 로그인이 되는 문제점
OR 조건을 이용한 SQL 인젝션이 로그인을 우회하는 원리를 설명해 드리겠습니다.
일반적인 로그인 처리를 위한 SQL 쿼리는 다음과 같은 형태입니다:
SELECT * FROM users WHERE username = '입력된_사용자명' AND password = '입력된_비밀번호'
사용자가 다음과 같이 입력하면:
- 아이디: john이고 ' OR '1'='1
- 비밀번호: test아고 ' OR '1'='1
실제 실행되는 쿼리는 다음과 같이 변형됩니다
SELECT * FROM users WHERE username = 'john' OR '1'='1' AND password = 'test' OR '1'='1'
이 쿼리에서 '1'='1'은 항상 참(TRUE)인 조건입니다. 따라서:
- username = 'john' OR '1'='1' 부분은 username이 'john'이든 아니든 항상 TRUE가 됩니다.
- password = 'test' OR '1'='1' 부분도 마찬가지로 항상 TRUE가 됩니다.
- 따라서 전체 WHERE 조건이 항상 TRUE가 되어, 데이터베이스의 첫 번째 사용자 레코드를 반환하게 됩니다.
암호키 관리
암호키 관리는 암호화 시스템에서 사용되는 키를 안전하게 생성, 저장, 배포, 교체, 폐기하는 전체 프로세스를 말합니다.
암호키 관리의 주요 원칙:
- 키 생성: 충분한 엔트로피와 적절한 길이를 가진 암호학적으로 안전한 난수 생성기(CSPRNG)를 사용해야 합니다.
- 키 저장: 키는 항상 안전하게 저장되어야 합니다.
- 하드웨어 보안 모듈(HSM) 사용
- 키 관리 시스템(KMS) 활용
- 키 암호화 키(KEK) 방식 적용
- 키 교체: 정기적인 키 교체로 키 노출 시 피해 최소화
- 정해진 주기에 따라 자동 교체
- 키 손상 의심 시 즉시 교체
- 키 백업 및 복구: 키 손실 방지를 위한 백업 및 복구 절차 수립
- 키 권한 관리: 최소 권한 원칙에 따른 접근 통제
- 키 폐기: 불필요해진 키의 안전한 폐기
쿠키 세션 관리
쿠키는 웹 서버가 사용자의 브라우저에 저장하는 작은 데이터 조각으로, 세션 관리는 이를 통해 사용자의 상태를 유지하는 메커니즘입니다.
안전한 쿠키 세션 관리 방법:
- 세션 ID의 안전한 생성:
- 충분한 길이와 엔트로피를 가진 랜덤 값 사용
- 예측 불가능한 세션 ID 생성
- 보안 쿠키 속성:
- Secure: HTTPS 연결에서만 쿠키 전송
- HttpOnly: JavaScript로 쿠키 접근 방지
- SameSite: CSRF 공격 방지
- Domain 및 Path 제한
- 세션 타임아웃:
- 적절한 세션 만료 시간 설정
- 비활성 타임아웃 구현
- 세션 무효화:
- 로그아웃 시 세션 완전 파기
- 서버 측에서 세션 상태 관리
- 세션 고정화 공격 방지:
- 인증 성공 후 세션 ID 재생성
- 세션 데이터 보호:
- 민감한 정보는 서버 측에만 저장
- 필요한 최소한의 정보만 포함
실제 구현 예시:
// 안전한 세션 쿠키 설정 (Java 예시)
Cookie sessionCookie = new Cookie("SESSIONID", generateSecureRandomId());
sessionCookie.setHttpOnly(true);
sessionCookie.setSecure(true);
sessionCookie.setSameSite("Strict");
sessionCookie.setMaxAge(1800);// 30분
response.addCookie(sessionCookie);
암호키 관리와 쿠키 세션 관리는 모두 컴플라이언스(GDPR, PCI DSS 등) 요구사항의 중요 부분이며, 주기적인 보안 감사와 취약점 점검을 통해 지속적으로 관리해야 합니다.
'Java' 카테고리의 다른 글
KISA K-Shield Spring 프레임워크 시큐어코딩(SSRF, XSS, CSRF, 파일업로드,탐지, 테스트) (3) | 2025.05.02 |
---|---|
Http Get 요청 - 인증된 사용자만 세션키 받아오기 (0) | 2023.09.09 |
자바 Map 인터페이스 (0) | 2022.10.06 |