자격/SW보안약점진단원
구현단계 보안약점 제거 기준-잘못된 세션에 의한 데이터 정보 노출
Ignatius Heo
2023. 7. 6. 15:30
작성일: 230706
※ 본 게시글은 학습 목적으로 행정안전부·KISA의 소프트웨어 보안약점 진단 가이드, 소프트웨어 개발보안 가이드를 참고하여 작성하였습니다.
정리 내용: 소프트웨어 보안약점 진단 가이드(469~475p)
구분 | - 세션통제, 캡슐화 |
설계단계 | - 세션통제 https://cryptocurrencyclub.tistory.com/109 |
개요 | 다중 스레드 환경에서는 싱글톤(Singleton) 객체 필드에 경쟁조건(Race Condition) 발생할 수 있다. 따라서, 다중 스레드 환경인 Java의 서블릿(Servlet) 등에서는 정보를 저장하는 멤버변수가 포함되지 않도록 하여, 서로 다른 세션에서 데이터를 공유하지 않도록 해야 한다. * 싱글톤 패턴 : 하나의 프로그램 내에서 하나의 인스턴스만을 생성해야만 하는 패턴. Connection Pool, Thread Pool과 같이 Pool 형태로 관리되는 클래스의 경우 프로그램 내에서 단하나의 인스턴트로 관리해야 하는 경우를 말함. java에서는 객체로 제공됨 |
진단 세부사항 (설계단계) |
① 세션 간 데이터가 공유되지 않도록 설계해야 한다. 세션 간 데이터 공유로 인한 정보노출이나 오류가 발생하지 않도록 설계되어 있는지 확인한다. ㅇ 스레드로 동작되는 클래스 설계 시 읽기/쓰기가 가능한 스레드 간 공유데이터의 설계 여부 확인 - Servlet, Controller의 경우 클래스 멤버변수, 클래스 변수 선언 - JSP의 경우 선언부에 변수 선언 ② 세션이 안전하게 관리되도록 해야 한다. 세션 생성과 종료, 타임아웃 시간설정 등 안전한 세션 관리방안의 설계 여부를 확인한다. ㅇ 로그인에 성공 시 세션 재할당 코딩규칙 정의 여부 확인 ㅇ 로그아웃 시 할당된 세션 완전 제거 코딩규칙 정의 여부 확인 ㅇ 사용자의 일방적인 연결종료에 대해 할당된 세션이 제거되도록 프로그램의 설계 여부 확인 ㅇ 오랫동안 사용하지 않는 세션에 대해 타임아웃을 설정하여 할당된 세션이 제거되도록 설계되어 있는지 확인 - 중요기능은 2~5분, 위험도가 낮은 경우 15~30분 ㅇ 비밀번호 변경 시 재 인증을 수행하여 새로운 세션이 할당되도록 설계되어 있는지 확인 ③ 세션ID가 안전하게 관리되도록 해야 한다. 세션ID가 안전하게 관리될 수 있도록 설계되어 있는지 확인한다. ㅇ 세션ID 생성을 서버에서 생성하도록 웹서버 환경설정 계획이 수립되어 있는지 확인 ㅇ 세션ID 전송 방법을 쿠키로 제한하며 쿠키의 속성에 HttpOnly가 설정되도록 웹서버 환경설정 계획이 수립되어 있는지 확인 ㅇ 장시간 접속되어 있는 경우 일정 시간 주기적으로 세션ID가 재할당하도록 웹서버 환경설정 계획이 수립되어 있는지 확인 ㅇ 로그인 수행 전에 할당받은 세션ID는 로그인 성공 후 재할당하도록 코딩규칙이 정의되어 있는지 확인 |
보안대책 (구현단계) |
싱글톤 패턴을 사용하는 경우, 변수 범위(Scope)에 주의를 기울여야 한다. 특히 Java에서는 HttpServlet 클래스의 하위클래스에서 멤버 필드를 선언하지 않도록 하고, 필요한 경우 지역 변수를 선언하여 사용한다. |
진단방법 (구현단계) |
HttpServlet의 하위클래스에 멤버필드가 선언되어 있고 final이 아닌 경우는 취약한 것으로 판단한다. |
다. 코드예제
ㅇ 분석
1: <%@page import="javax.xml.namespace.*"%>
2: <%@page import="gov.mogaha.ntis.web.frs.gis.cmm.util.*" %>
3: <%!
4: // JSP에서 String 필드들이 멤버 변수로 선언됨
5: String username = "/";
6: String imagePath = commonPath + "img/";
7: String imagePath_gis = imagePath + "gis/cmm/btn/";
8: ……
9: %>
ㅇ 수정
1: <%@page import="javax.xml.namespace.*"%>
2: <%@page import="gov.mogaha.ntis.web.frs.gis.cmm.util.*" %>
3: <%
4: // JSP에서 String 필드들이 로컬 변수로 선언됨
5: String commonPath = "/";
6: String imagePath = commonPath + "img/";
7: String imagePath_gis = imagePath + "gis/cmm/btn/";
8: ……
9: %>
ㅇ 내용
1. 이거 왜이렇게 뒤로 갈수록 교재에 에러가 많냐 진짜............... 개정 안하나???????????????????????????????????????
ㅇ 분석
1: @Controller
2: public class TrendForecastController {
3: // Controller에서 int 필드가 멤버 변수로 선언되어 스레드간에 공유됨
4: private int currentPage = 1;
5: public void doSomething(HttpServletRequest request) {
6: currentPage = Integer.parseInt(request.getParameter("page"));
7: }
8: ……
ㅇ 수정
1: @Controller
2: public class TrendForecastController {
3: public void doSomething(HttpServletRequest request) {
4: // 지역변수로 사용하여 스레드간 공유되지 못하도록 한다.
5: int currentPage = Integer.parseInt(request.getParameter("page"));
6: }
7: ……
ㅇ 내용
1. 안으로 묶음
ㅇ 분석
1: class DataLeakBetweenSessions : IHttpHandler
2: {
3: //다중 스레드 환경에서 IHttpHandler 를 구현하는 클래스에 정보를 저장하는 필드가
포함되어서는 안됩니다.
4: private String id;
5: public void ProcessRequest(HttpContext ctx)
6: {
7: var json = new JSONResonse()
8: {
9: Success = ctx.Request.QueryString["name"] != null,
10: Name = ctx.Request.QueryString["name"]
11: };
12: ctx.Response.ContentType = "application/json";
13: ctx.Response.Write(JsonConvert.SerializeObject(json));
14: }
15: public bool IsReusable
16: {
17: get { return false; }
18: }
19: }
ㅇ 수정
1: class DataLeakBetweenSessions : IHttpHandler
2: {
3: public void ProcessRequest(HttpContext ctx)
4: {
//지역 변수나 세션변수를 선언해서 사용해야 합니다.
5: ctx.Session["id"] = ctx.Request.QueryString["id"];
6: var json = new JSONResonse()
7: {
8: Success = ctx.Request.QueryString["name"] != null,
9: Name = ctx.Request.QueryString["name"]
10: };
11: ctx.Response.ContentType = "application/json";
12: ctx.Response.Write(JsonConvert.SerializeObject(json));
13: }
14: public bool IsReusable
15: {
16: get { return false; }
17: }
18: }
ㅇ 내용
끝.