캡슐화 보안 약점

2025. 4. 9. 19:26·CS
  • 잘못된 세션에 의한 정보 노출

    멤버 변수 - 클래스 수준에서 정의된 변수 (객체가 살아있는 동안 계속 유지)(힙 영역)
    지역 변수 - 메서드 안에서만 사용되고, 메서드가 끝나면 메모리에서 사라짐(스택 영역)
    public class UserHandler {
    	private User currentUser; // 멤버 변수
        
        public void handleRequest(HttpServletRequest request) {
        	HttpSession session = request.getSession();
            this.currentUser = (User) session.getAttribute("user");
            
            
            }
    }
    - currentUser가 클래스의 멤버 변수로 선언되어 있다. 따라서 이 클래스가 여러 사용자 요청을 처리한다면, 다른 사용자가 currentUser 정보에 접근할 수 있는 것이다.
    개선코드
public class UserHandler {

    public void handleRequest(HttpServletRequest request) {
        HttpSession session = request.getSession();
        User currentUser = (User) session.getAttribute("user"); // 지역 변수

        // 이후 로직 처리
    }
}

 

2️⃣ Public 메서드로부터 반환된 Private 배열

🔍 개념 설명:

Private 필드는 외부에서 직접 접근 못하게 막지만, public 메서드를 통해 내부 배열을 반환하면 외부에서도 해당 배열을 수정할 수 있어 캡슐화가 깨지고 보안이 약해집니다.

🧨 문제 예시:

public class User {
    private String[] roles = {"user", "admin"};

    public String[] getRoles() {
        return roles; // 내부 배열을 직접 반환
    }
}

// 외부 코드에서:
user.getRoles()[0] = "hacker"; // 내부 배열이 바뀜!

🛡️ 해결 방법:

1.깊은 복사본 반환

public String[] getRoles() {
    return Arrays.copyOf(roles, roles.length);
}

2.불변 컬렉션 반환

public List<String> getRoles() {
    return Collections.unmodifiableList(Arrays.asList(roles));
}

3️⃣ Private 배열에 Public 데이터 할당

🔍 개념 설명:

외부(public) 데이터를 private 배열에 그대로 참조로 저장하면, 외부에서 해당 배열을 변경할 수 있어 객체의 내부 상태가 예상치 않게 바뀝니다.

🧨 문제 예시:

public class User {
    private String[] roles;

    public void setRoles(String[] inputRoles) {
        this.roles = inputRoles; // 참조를 직접 저장
    }
}

String[] roles = {"user"};
User user = new User();
user.setRoles(roles);

// 외부 배열을 변경하면 내부 상태도 같이 바뀜
roles[0] = "admin"; // user 객체 내부도 변경됨

🛡️ 해결 방법:

  • 입력 값 복사해서 저장 (Defensive Copying)
 
public void setRoles(String[] inputRoles) {
    this.roles = Arrays.copyOf(inputRoles, inputRoles.length);
}

 

🧾 1. 얕은 복사 (Shallow Copy)

📌 개념:

객체를 복사할 때 겉모습만 복사하고, 내부 참조 객체는 원본과 같은 주소를 공유하는 방식입니다.

📦 특징:

  • 필드가 기본 타입(int, boolean 등)인 경우 → 값 자체 복사
  • 필드가 참조 타입(배열, 객체 등)인 경우 → 참조 주소만 복사 (공유됨)

🧨 문제점:

복사본을 수정하면 원본 객체에도 영향을 줄 수 있음

✅ 예제 (Java):

class Person {
    String name;
    int[] scores;
    
    Person(String name, int[] scores) {
        this.name = name;
        this.scores = scores;
    }
}

int[] scores = {90, 80};
Person original = new Person("Alice", scores);
Person copy = original;  // 얕은 복사

copy.scores[0] = 100;
System.out.println(original.scores[0]);  // 100 → 원본도 바뀜!

🧾 2. 깊은 복사 (Deep Copy)

📌 개념:

객체뿐만 아니라 그 내부에 포함된 모든 참조 객체까지 새롭게 복사하는 방식입니다.

📦 특징:

  • 원본과 복사본이 완전히 독립된 구조
  • 복사본을 수정해도 원본에는 영향 없음
class Person {
    String name;
    int[] scores;

    Person(String name, int[] scores) {
        this.name = name;
        // 깊은 복사: 배열도 새로 복사
        this.scores = Arrays.copyOf(scores, scores.length);
    }
}

이렇게 하면 scores 배열을 변경해도 원본에는 영향을 주지 않는다.

 

🧾 3. 불변 컬렉션 (Immutable Collection)

📌 개념:

수정이 불가능한 컬렉션입니다. 생성 후에는 add, remove, set 같은 변경 작업이 전혀 불가능합니다.

📦 특징:

  • 안전하게 외부에 반환 가능 (내부 상태 보호)
  • 멀티스레드 환경에서도 안정성 ↑
  • 변경하려면 새 인스턴스를 만들어야 함
List<String> roles = Collections.unmodifiableList(Arrays.asList("user", "admin"));
roles.add("hacker");  // UnsupportedOperationException 발생


List<String> roles = List.of("user", "admin");

 

 

📊 비교 요약

항목얕은 복사깊은 복사불변 컬렉션
내부 참조 공유 ✅ (공유함) ❌ (새로 생성) ✅ (참조 가능하지만 수정 불가)
원본 영향 가능성 높음 없음 없음
안전성 낮음 높음 매우 높음
성능 빠름 느릴 수 있음 빠름 (단, 변경 불가)

 

copyOf() – 보통 "복사" (깊은 or 얕은)

📌 의미:

copyOf()는 기존 컬렉션(또는 배열)을 복사해서 새 객체를 만든다는 의미입니다.
하지만 깊은 복사인지 얕은 복사인지는 요소의 타입에 따라 다릅니다.

📍 예: Arrays.copyOf()

int[] original = {1, 2, 3};
int[] copied = Arrays.copyOf(original, original.length);
  • 이 경우는 int 배열이므로 진짜 깊은 복사 (값 자체 복사)
  • 하지만 객체 배열일 경우 내부 객체까지 복사하지는 않음 → 얕은 복사
String[] original = {"a", "b"};
String[] copied = Arrays.copyOf(original, original.length);
copied[0] = "x"; // 이건 값이니까 OK
// 하지만 만약 원소가 mutable 객체라면 내부는 공유됨 (얕은 복사)

✔️ 핵심:

  • copyOf()는 "새로운 객체를 만든다" (✅)
  • 하지만 "항상 깊은 복사"는 아니다 (⚠️)
  • 내부 객체까지 완전히 복사하려면 개별적으로 clone()하거나 새로 생성해야 함

✅ of() – 보통 "새로운 불변 객체 생성"

📌 의미:

Java 9+의 List.of(), Set.of() 등은 새로운 컬렉션 객체를 만들되, 불변(immutable)한 형태로 생성합니다.

List<String> names = List.of("Alice", "Bob");
names.add("Charlie"); // ❌ UnsupportedOperationException

✔️ 핵심:

  • of()는 항상 새 객체를 만든다 (✅)
  • 그리고 **불변(immutable)**이다 (✅)
  • 하지만 내부 요소가 참조 타입이면, 여전히 내부 내용은 수정 가능할 수도 있음 (⚠️)
List<List<String>> list = List.of(new ArrayList<>(List.of("a")));
list.get(0).add("b");  // 내부는 바뀔 수 있음

🔁 정리 비교

메서드새 객체 생성깊은 복사불변
copyOf() ✅ 대부분 ❌ (얕은 복사 가능성 있음) ❌
of() ✅ 항상 ❌ (복사 X, 그냥 새 객체 생성) ✅

 

그럼 객체의 깊은 복사의 경우 직접 구현 or 라이브러리 사용

이유 1: 깊은 복사의 정의는 상황에 따라 다름

  • 어떤 필드는 복사하고, 어떤 필드는 공유해도 되는지 비즈니스 로직마다 달라요
  • 예: 비밀번호 필드는 복사 안 함 / 리스트는 복사하되 ID는 그대로 유지 등

📌 이유 2: 자바의 기본 clone()은 얕은 복사

@Override
protected Object clone() throws CloneNotSupportedException {
    return super.clone(); // 얕은 복사
}

내부에 참조 타입(객체, 배열 등)이 있으면 그 참조 주소만 복사됨


✅ 직접 깊은 복사 구현 방법

예: 사용자 정의 클래스에서 deep copy 만들기

public class Address {
    String city;

    public Address(String city) {
        this.city = city;
    }

    public Address deepCopy() {
        return new Address(this.city);
    }
}

public class User {
    String name;
    Address address;

    public User(String name, Address address) {
        this.name = name;
        this.address = address;
    }

    public User deepCopy() {
        return new User(this.name, this.address.deepCopy());
    }
}

➡️ 이렇게 하면 User와 Address 객체 모두 독립적으로 존재하게 돼요.

'CS' 카테고리의 다른 글

디자인 패턴  (0) 2025.04.15
객체의 응집도 정리  (1) 2025.04.15
SQL 집계 함수, 그룹 함수, 윈도우 함수  (0) 2025.04.07
Mysql 사용 시 조언  (0) 2025.02.25
TCP/IP 이해  (0) 2024.11.11
'CS' 카테고리의 다른 글
  • 디자인 패턴
  • 객체의 응집도 정리
  • SQL 집계 함수, 그룹 함수, 윈도우 함수
  • Mysql 사용 시 조언
Ark B
Ark B
  • Ark B
    기록
    Ark B
  • 전체
    오늘
    어제
    • 분류 전체보기 (35) N
      • 개인 프로젝트 정리 (1)
      • JAVA (9) N
      • CS (7)
      • 프로젝트 정리 (6)
        • 인턴 (5)
        • 졸업프로젝트 (0)
      • 코딩테스트 (1)
      • 클린 코드 (3)
      • 책 정리 (1)
        • Effective Java (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    티스토리챌린지
    오블완
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Ark B
캡슐화 보안 약점
상단으로

티스토리툴바