본문 바로가기
소프트웨어(SW) 보안약점 진단원/구현단계 보안약점 제거 기준

구현단계 보안약점 기준 - 종료되지 않는 반복문 또는 재귀 함수

by 브루노W 2025. 6. 4.
유형 시간 및 상태
보안약점 종료되지 않는 반복문 또는 재귀 함수
개요
재귀의 순환횟수를 제어하지 못하여 할당된 메모리나 프로그램 스택 등의 자원을 과다하게 사용하면 위험하다.
 
대부분의 경우, 귀납 조건(Base Case)이 없는 재귀함수는 무한 루프에 빠져 들게 되고 자원 고갈을 유발함으로써 시스템의 정상적인 서비스를 제공할 수 없게 한다.
보안대책
모든 재귀 호출시, 재귀 호출 횟수를 제한하거나, 초기값을 설정(상수)하여 재귀 호출을 제한해야 한다.
진단방법
자신을 호출하는 재귀함수나 메소드가 존재하는지 식별하고, 해당 함수 내에 제어문으로 해당 함수에서 리턴될 수 있는지 확인한다.
제어문으로 재귀함수를 빠져나올 수 있으면 안전하다.
연관된 설계단계 기준 -

 

코드예제

 

● 안전하지 않은 코드 예 (C)

#include <stdio.h>
int factorial(int i) {
    // 재귀함수 탈출 조건을 설정하지 않아 무한루프가 된다.
    return i * factorial(i - 1);
}
int main() {
    int num = 5;
    int result = factorial(num);
    printf("%d! : %d\n", num, result);
    return 0;
}

 

● 안전한 코드 예 (C)

#include <stdio.h>
int factorial(int I) {
    // 재귀함수 사용 시에는 아래와 같이 탈출 조건을 사용해야 한다.
    if (i <= 1) {
    	return 1;
    }
    return i * factorial(i - 1);
}
int main() {
    int num = 5;
    int result = factorial(num);
    printf("%d! : %d\n", num, result);
    return 0;
}

 

 

진단방법
 
자신을 호출하는 재귀함수나 메소드가 존재하는지 식별하고, 해당 함수 내에 제어문으로 해당 함수에서 리턴될 수 있는지 확인한다.
제어문으로 재귀함수를 빠져나올 수 있으면 안전하다.

 

 

● 일반적인 진단의 예

…
public int factorial(int n) {
	return n * factorial(n – 1); ··············①
}
…

 


● 정탐코드

public class RecursiveCall {
    private int a;

    public void func(int a) {
    	this.a = a;
    }

    public void func(String a) {
    	func(a);
    }
}

재귀함수는 함수 내부에서 자신을 호출하는 경우이다. 함수명과 파라미터의 개수, 파라미터의 자료형이 일치하는 경우 취약하다.

 

 

● 오탐코드

public class RecursiveCall {
    private int a

    public void func(int a) {
    	this.a = a;
    }

    public void func(String a) {
    	func(Integer.parseInt(a));
    }
}

같은 이름에 파라미터가 다른 함수가 있는 경우는 취약하지 않다. func(String a)에서 func(int a)를 호출하고 있는데 recursive call 이 아닌 다른 함수의 호출이므로 안전하다.

 

 

● 오탐코드

public MenuVO getFirstLeafChildMenu(int menuSeq) {
    List<MenuVO> childMenuList = menuMap.get(menuSeq).getChildMenuList();
    if (CollectionUtils.isEmpty(childMenuList)) {
    	return menuMap.get(menuSeq);
    }
    return getFirstLeafChildMenu(childMenuList.get(0).getMenuSeq());
}

제어조건이 존재하여 제어가 되는 재귀인 경우 취약하지 않다.