2023. 8. 4. 10:44ㆍComputer
소프트웨어 보안은 오늘날 그 어느 때보다 중요한 요소가 되었습니다. 애플리케이션이 취약한 코드로 인해 공격받는 경우, 막대한 피해가 발생할 수 있습니다. 이 글에서는 보안 코딩을 위한 필수 체크리스트를 제공하여 안전한 소프트웨어 개발에 기여하고자 합니다.
카테고리 | 주요 항목 | 설명 |
입력 유효성 검사 | 서버 측 유효성 검사 | 모든 입력 데이터는 서버에서 검증해야 함. 클라이언트 측 검사는 신뢰할 수 없음. |
데이터 소스 분류 | 신뢰할 수 있는 데이터와 신뢰할 수 없는 데이터를 분류하고 유효성 검사를 다르게 적용. | |
문자 집합 지정 | UTF-8 같은 표준화된 문자 세트를 사용하여 입력 처리. | |
출력 인코딩 | 서버 측 출력 인코딩 | 신뢰할 수 없는 데이터는 서버에서 인코딩 처리하여 공격을 방지. |
SQL 쿼리, OS 명령 등에서 안전한 인코딩 수행 | SQL, XML, LDAP 쿼리 등에서 신뢰할 수 없는 데이터는 안전하게 삭제 또는 인코딩. | |
인증 및 비밀번호 관리 | 서버 측에서 암호 해싱 | 비밀번호는 서버에서만 암호화하고, 소금 해시를 사용하여 저장. |
비밀번호 복잡성 및 길이 요구사항 시행 | 비밀번호의 최소 길이 및 복잡성 요구 사항을 정책적으로 관리. | |
비밀번호 재설정 시 이메일 전송 | 비밀번호 재설정은 사전에 등록된 이메일 주소로만 전송하며, 만료 시간이 짧아야 함. | |
세션 관리 | 서버 측 세션 관리 | 모든 세션 식별자는 서버에서 생성되고, 안전하게 관리되어야 함. |
로그아웃 기능 제공 | 사용자가 언제든지 로그아웃할 수 있도록 기능을 제공하며, 모든 세션 종료. | |
액세스 제어 | 중앙 집중식 액세스 제어 | 중앙에서 관리되는 액세스 제어를 통해 모든 접근을 통제하고 안전하게 실패할 수 있도록 설계. |
인증된 사용자에게만 접근 허용 | 인증되지 않은 사용자는 보호된 리소스 및 기능에 접근할 수 없도록 제한. | |
암호화 관행 | TLS를 통한 민감한 정보 전송 | 모든 민감한 정보는 TLS를 사용하여 전송. 개별 암호화도 추가로 사용 가능. |
암호화 키 관리 | 암호화 키는 안전하게 관리하고 FIPS 140-2 표준을 준수해야 함. | |
데이터 보호 | 서버 측에서 민감한 데이터 암호화 | 서버에 저장된 민감한 데이터는 반드시 암호화되어야 하며, 필요하지 않으면 즉시 삭제. |
통신 보안 | TLS 인증서 사용 | 모든 민감한 정보는 TLS로 전송하며, 인증서는 올바른 도메인 이름과 유효한 상태로 관리. |
시스템 설정 | 최신 보안 패치 적용 | 서버 및 시스템 구성 요소는 최신 보안 패치를 적용하고, 불필요한 기능은 제거. |
데이터베이스 보안 | 강력한 매개변수화 쿼리 사용 | SQL 인젝션을 방지하기 위해 매개변수화된 쿼리를 사용하고, 입력 유효성 검사 및 출력 인코딩 적용. |
1. 입력 유효성 검사
입력 유효성 검사는 보안 코딩의 첫 단계입니다. 모든 데이터 입력은 잠재적으로 위험할 수 있기 때문에 철저한 검증이 필요합니다. 다음은 입력 유효성 검사에서 고려해야 할 사항들입니다.
- 서버 측 유효성 검사: 클라이언트 측에서의 검사는 신뢰할 수 없습니다. 모든 유효성 검사는 반드시 서버 측에서 수행되어야 합니다.
- 데이터 소스 분류: 데이터 소스는 신뢰할 수 있는지, 신뢰할 수 없는지 분류하고 유효성 검사를 달리 적용해야 합니다.
- 문자 집합 지정: 모든 입력 소스에 대해 UTF-8과 같은 표준화된 문자 세트를 사용하여 입력을 처리해야 합니다.
- 정규화 및 인코딩: 유효성 검사를 하기 전에 입력 데이터를 표준화하여 난독화 공격을 방지해야 합니다.
체크리스트:
- 입력 데이터가 예상된 형식과 길이를 충족하는지 확인
- 유효성 검사 실패 시 입력 거부
- 신뢰할 수 없는 소스로부터 받은 모든 데이터는 철저히 검사
2. 출력 인코딩
입력 데이터가 안전하게 처리된 후, 출력될 때는 추가적인 인코딩을 적용하여 XSS와 같은 공격을 방지해야 합니다.
- 서버 측에서만 출력 인코딩 수행: 클라이언트 측 인코딩은 안전하지 않으므로 서버에서 처리합니다.
- 출력 인코딩이 시스템에 안전한지 확인: SQL, XML, LDAP와 같은 쿼리에서 신뢰할 수 없는 데이터를 출력할 때, 그 데이터가 안전하게 처리되었는지 확인해야 합니다.
체크리스트:
- 모든 출력에 대해 UTF-8 문자 세트를 지정
- SQL 및 운영체제 명령에 대해 신뢰할 수 없는 데이터를 삭제 또는 상황에 맞는 인코딩 수행
3. 인증 및 비밀번호 관리
안전한 인증 절차와 비밀번호 관리도 매우 중요합니다. 사용자의 민감한 정보를 보호하고, 무단 접근을 막기 위해 다음 사항들을 준수해야 합니다.
- 모든 페이지에 대해 인증 요구: 인증이 필요한 페이지에는 반드시 인증 절차를 거치도록 설정해야 합니다.
- 비밀번호는 서버 측에서 해싱: 비밀번호는 반드시 서버에서 암호화해야 하며, 단방향 소금 해시를 사용합니다.
- 비밀번호 복잡성 요구사항: 최소 길이와 복잡성에 대한 요구사항을 설정하고 이를 정책적으로 시행해야 합니다.
체크리스트:
- 비밀번호 입력은 사용자 화면에서 가려지도록 설정
- 인증 실패 시 구체적인 오류 메시지를 제공하지 않음
- 암호화된 연결을 통해 비밀번호 전송
4. 세션 관리
세션 관리 또한 중요한 보안 요소 중 하나입니다. 세션 식별자 탈취를 방지하고, 세션 하이재킹을 막기 위해 안전한 세션 관리 방법을 도입해야 합니다.
- 서버 측에서 세션 식별자 생성: 모든 세션 식별자는 서버 측에서 생성되며 충분히 무작위적이어야 합니다.
- 로그아웃 기능 제공: 사용자가 언제든지 로그아웃할 수 있도록 로그아웃 기능을 제공하며, 로그아웃 시 모든 세션을 완전히 종료해야 합니다.
체크리스트:
- 모든 세션은 적절한 액세스 제어를 적용
- 새 세션 식별자를 주기적으로 생성하고 이전 식별자는 비활성화
- 세션이 HTTPS에서만 전송되도록 설정
5. 액세스 제어
애플리케이션에서 적절한 액세스 제어를 구현하여, 권한이 없는 사용자가 시스템에 접근하지 못하도록 해야 합니다.
- 중앙 집중식 액세스 제어: 모든 애플리케이션 액세스 제어는 중앙에서 관리되고, 안전하게 실패하도록 설정되어야 합니다.
- 인증된 사용자에게만 리소스 접근 허용: 인증되지 않은 사용자는 보호된 URL이나 기능에 접근할 수 없도록 제한합니다.
체크리스트:
- 인증된 사용자에게만 보호된 기능과 리소스 접근 허용
- 인증된 사용자만 직접 개체 참조를 제한
- 파일이나 기타 리소스에 대한 접근을 권한이 있는 사용자로만 제한
6. 암호화 관행
애플리케이션에서 사용하는 모든 민감한 정보는 반드시 암호화되어야 합니다. 특히 데이터 전송과 저장 시, 암호화는 필수적입니다.
- TLS를 통한 전송 보안: 모든 민감한 데이터는 TLS를 사용해 암호화된 채널을 통해 전송되어야 합니다.
- 암호화 키 관리: 모든 암호화 키는 안전하게 관리되어야 하며, FIPS 140-2 표준을 준수해야 합니다.
체크리스트:
- 모든 민감한 정보는 TLS 또는 개별 암호화로 전송
- 암호화 키 관리를 위한 정책 수립 및 활용
- 모든 암호화 모듈이 안전하게 실패하도록 설정
7. 데이터 보호
서버에 저장된 모든 중요한 데이터는 무단 접근으로부터 보호되어야 합니다. 민감한 데이터는 암호화되어야 하며, 필요할 때만 접근 가능하도록 해야 합니다.
체크리스트:
- 인증 확인 데이터와 같은 민감한 정보를 암호화
- 필요하지 않은 데이터는 즉시 삭제
- 민감한 정보가 포함된 페이지에서 클라이언트 측 캐싱 비활성화
8. 통신 보안
모든 통신 경로는 암호화되어야 하며, TLS 인증서를 사용해 데이터의 무결성을 보장해야 합니다.
체크리스트:
- 모든 민감한 정보는 TLS로 전송
- TLS 인증서는 올바른 도메인 이름을 사용하고 유효한지 확인
- 인증된 액세스가 필요한 모든 콘텐츠에 대해 TLS를 사용
결론
위에서 언급한 보안 코딩 관행은 안전한 소프트웨어 개발을 위해 필수적인 요소들입니다. 이 체크리스트를 통해 애플리케이션의 보안성을 강화하고, 잠재적인 공격으로부터 시스템을 보호할 수 있습니다. 애플리케이션을 설계하고 개발할 때 이 가이드라인을 준수하여 안전하고 신뢰할 수 있는 소프트웨어를 제공합시다.
출처
'Computer' 카테고리의 다른 글
쉽게 풀어쓴 튜링 기계와 튜링 불완전성 (0) | 2024.02.22 |
---|---|
Effective Kotlin - Prefer Sequence for big collections with more than one processing step (0) | 2021.10.28 |
Kotlin - Respect the contract of hashCode (0) | 2021.10.15 |
Effective Kotlin - Minimize elements visibility (0) | 2021.10.14 |
Effective Kotlin - Respect the contract of compareTo (0) | 2021.10.07 |