IgnatiusHeo

구현단계 보안약점 제거 기준-부적절한 인가 본문

자격/SW보안약점진단원

구현단계 보안약점 제거 기준-부적절한 인가

Ignatius Heo 2023. 7. 4. 19:26

작성일: 230704

 

※ 본 게시글은 학습 목적으로 행정안전부·KISA의 소프트웨어 보안약점 진단 가이드, 소프트웨어 개발보안 가이드를 참고하여 작성하였습니다.

 

정리 내용: 소프트웨어 보안약점 진단 가이드(319~324p)

구분 - 보안기능
설계단계 - 중요자원 접근통제
https://cryptocurrencyclub.tistory.com/103
개요
프로그램이 모든 가능한 실행경로에 대해서 접근제어를 검사하지 않거나 불완전하게 검사하는 경우, 공격자는 접근 가능한 실행경로 정보를 유출할 수 있다.

진단 세부사항
(설계단계)
 
 ① 중요자원에 대한 접근통제 정책을 수립하여 적용해야 한다. 중요자원에 대한 접근통제가 이루어지도록 설계되어 있는지 확인한다.
  ㅇ  중요자원의 식별 여부 확인
  ㅇ  중요자원에 접근하는 사용자/프로그램 분류 여부 확인
  ㅇ  중요자원에 접근하는 사용자/프로그램의 접근권한이 최소권한으로 할당되도록 설계되어 있는지 확인
  ㅇ  중요자원에 접근하는 사용자/프로그램의 접근권한이 자원별로 분리되어 할당되도록 설계되어 있는지 확인
  ㅇ  중요자원에 대한 접근통제 정책(ACL/RBAC)이 설정되고 접근통제 기능을 구현하는 프로그램이 설계되어 있거나 접근통제 기능을 제공하는 라이브러리를 활용하도록 설계되어 있는지 확인
  ㅇ  접근통제 기능의 적용방식이 프레임워크의 컴포넌트를 활용하여 적용하여 경우, 중요자원을 사용하는 모든 요청에 적용될 수 있도록 설계되어 있는지 확인
  ㅇ  접근통제 기능의 적용방식이 개별 프로그램에서 적용하는 경우, 대상 프로그램과 통제 기능 호출방식에 대한 코딩규칙이 개발가이드에 반영되어 있는지 확인
  ㅇ  중요자원별로 할당된 접근 권한 외의 작업을 요청하여 접근권한 통제가 안전하게 수행되는지를 점검하기 위한 테스트 계획의 수립 여부 확인
 
 ② 중요기능에 대한 접근통제 정책을 수립하여 적용해야 한다. 중요기능에 대한 접근통제가 설계되어 있는지 확인한다.
  ㅇ  중요기능이 분석 단계 산출물에서 식별되어 있는지 확인
  ㅇ  중요기능에 접근하는 사용자/프로그램이 분류되어 있는지 확인
  ㅇ  중요자원에 접근하는 사용자/프로그램의 접근권한이 최소권한으로 할당되도록 설계되어 있는지 확인
  ㅇ  중요자원에 접근하는 사용자/프로그램의 접근권한이 자원별로 분리되어 할당되도록 설계되어 있는지 확인
  ㅇ  중요자원에 대한 ACL/RBAC 등이 설정되고 접근 통제 기능을 구현하는 프로그램이 설계되어 있거나 접근통제 기능을 제공하는 라이브러리를 활용하도록 설계되어 있는지 확인
  ㅇ  접근통제 기능의 적용방식이 프레임워크의 컴포넌트를 활용하여 적용하는 경우, 중요자원을 사용하는 모든 요청에 적용될 수 있도록 설계되어 있는지 확인
  ㅇ  접근통제 기능의 적용방식이 개별 프로그램에서 적용하는 경우, 대상 프로그램과 통제 기능 호출 방식에 대한 코딩규칙이 개발가이드에 반영되어 있는지 확인
 
 ③ 관리자 페이지에 대한 접근통제 정책을 수립하여 적용해야 한다. 관리자 페이지 접근통제 정책이 설계되어 있는지 확인한다.
  ㅇ  관리자 페이지를 사용하는 포트가 일반 사용자 페이지와 다른 포트를 사용하고 있는지 확인
  ㅇ  외부 네트워크로부터 관리자 페이지의 접근 차단 설계 여부 확인
  ㅇ  관리자 페이지에 접근 가능한 IP주소의 정의/설계 반영 여부 확인
  ㅇ  관리자 페이지 접속 시 반드시 암호화된 통신의 사용 설계 여부 확인
  ㅇ  관리자 페이지 접속 시 접속자, 접속페이지 정보의 로깅 기능 설계 여부 확인

보안대책
(구현단계)

응용프로그램이 제공하는 정보와 기능을 역할에 따라 배분함으로써 공격자에게 노출되는 공격노출면(Attack Surface)을 최소화하고 사용자의 권한에 따른 ACL(Access Control List)을 관리한다.

JAAS Authorization Framework나 OWASP ESAPI Access Control 등의 프레임워크를 사용해서 취약점을 제거할 수도 있다.

진단방법
(구현단계)

해당 취약점은 보안특성 중 외부 시스템(웹서버, DB서버, LADP 등)의 권한 설정과 관련된 취약점으로 정적도구를 사용하여 이를 판단하는 것은 쉽지 않다.

먼저 중요정보를 저장할 수 있는 외부시스템이 존재하는지 식별하고 해당시스템에 접근(열람) 및
변경(생성 ․ 삭제 ․ 수정 등)에 대한 권한을 사전에 적절하게 정의하였는지 확인한다.

① 해당 정보 또는 기능(접근 ․ 변경)을 호출하는 함수에서, 사전에 정의한 권한 소유여부를 검사하는지 확인한다.

또한 접근제어를 서버측이 아닌 JavaScript 등과 같이 클라이언트측에서 제어 하여 우회가 가능한지 확인한다.

 

다. 코드예제

 

ㅇ 분석

1: private BoardDao boardDao;
2: String action = request.getParameter("action");
3: String contentId = request.getParameter("contentId");
//요청을 하는 사용자의 delete 작원 권한 확인 없이 수행하고 있어 안전하지 않다.
4: if (action != null && action.equals("delete")) {
5: boardDao.delete(contentId);
6: }

ㅇ 내용

1. 게시글 지우는 기능에 사용자 확인 기능이 없음.

2. 게시글 작성자 or 관리자 권한을 확인하는 절차가 있어야 할듯

 

ㅇ 수정

1: private BoardDao boardDao;
2: String action = request.getParameter("action");
3: String contentId = request.getParameter("contentId");
// 세션에 저장된 사용자 정보를 얻어온다.
4: User user= (User)session.getAttribute("user");
//사용자정보에서 해당 사용자가 delete작업의 권한이 있는지 확인한 뒤 삭제 작업을 수행한다.
5: if (action != null && action.equals("delete") && checkAccessControlList(user,action)) {
6: boardDao.delete(contenId);
7: }
8: }

ㅇ 내용

1. 세션에서 현재 접속중인 사용자 정보를 받아서 -> 권한 보유 여부 확인


ㅇ 분석

// 운영자 권한 검사 없이 컨트롤러와 내부의 개별 액션에 접근 가능
1: public class AdministrationController : Controller
2: {
3: …
4: }

ㅇ 내용

1. 이건뭔데

 

ㅇ 수정

// 운영자 권한 검사 후 개별 액션에 접근
1: [Authorize(Roles = "Administrator")]
2: public class AdministrationController : Controller
3: {
4: ...
5 }

ㅇ 내용

1. 관리자 여부를 확인한 듯

 


ㅇ 분석

1: #define FIND_DN "uid=han,ou=staff,dc=example,dc=com"
2: int searchData2LDAP(LDAP *ld, char *username) {
3: unsigned long rc;
4: char filter[20];
5: LDAPMessage *result;
6: snprintf(filter, sizeof(filter),"(name=%s)", username);
// 사용자의 인증 없이 LDAP 검색을 시도합니다.
7: rc = ldap_search_ext_s(ld, FIND_DN, LDAP_SCOPE_BASE, filter, NULL, 0,
NULL,NULL, LDAP_NO_LIMIT, LDAP_NO_LIMIT, &result);
8: return rc;
9: }

ㅇ 내용

1. username이 현재 기능을 시도하려는 user인거같은데 ACL 여부 확인이 안된듯?

 

ㅇ 수정

1: #define FIND_DN "uid=han,ou=staff,dc=example,dc=com"
2: int searchData2LDAP(LDAP *ld, char *username, char *password) {
3: unsigned long rc;
4: char filter[20];
5: LDAPMessage *result
//username을 인증합니다.
6: if ( ldap_simple_bind_s(ld, username, password) != LDAP_SUCCESS ) {
7: printf("authorization error");
8: return(FAIL);
9: }
// username 이 로그인 정보와 일치하는지 검사합니다.
10: if ( strcmp(username,getLoginName()) != 0 ) {
11: printf("Login error");
12: return(FAIL);
13: }
14: snprintf(filter, sizeof(filter), "(name=%s)", username);
15: rc = ldap_search_ext_s(ld, FIND_DN, LDAP_SCOPE_BASE, filter, NULL, 0, NULL,
NULL, LDAP_NO_LIMIT, LDAP_NO_LIMIT, &result);
16: return rc;
17: }

ㅇ 내용

1. 패스워드까지 입력받아서 사용함?

2. 로그인 정보도 확인함(우회 접속 체크하는듯)

 

 

 

 

끝.