🔓 Private 배열을 반환하는 Public 메서드 KISA A-6 · Private 배열 참조 반환

클래스가 내부 private 배열의 참조 그 자체를 외부에 넘겨줍니다. 호출자가 그 배열을 변조하면 객체의 보호 상태가 몰래 바뀌어, 외부에서 권한을 상승시키거나 잔액을 조작할 수 있습니다.

① getPermissions() 가 내부 배열을 반환 VULNERABLE

Account는 private permissions[]를 가집니다. 게터가 return this.permissions; — 복사본이 아닌 같은 객체를 반환합니다. 참조를 받아 변조한 뒤, 객체의 내부 상태를 다시 확인해 보세요.

객체 내부 상태 (private)

—

canDeleteUsers() / 잔액 검사

—

② 게터가 방어적 복사본을 반환 SECURE

수정된 게터는 permissions.clone()(또는 Collections.unmodifiableList(...))을 반환합니다. 호출자는 분리된 복사본을 받으므로, 변조해도 객체의 private 상태에는 영향이 없습니다.

객체 내부 상태 (private)

—

canDeleteUsers() / 잔액 검사

—

③ 취약 vs 안전 코드

VULNERABLE
// Java
public class Account {
  private String[] permissions = {"READ","WRITE"};
  private long[]   balance     = { 100 };

  // returns the LIVE internal array reference
  public String[] getPermissions() {
    return this.permissions;        // ⚠ no copy
  }
  public long[] getBalance() {
    return this.balance;            // ⚠ no copy
  }
}

// caller mutates internal state from outside:
String[] p = acct.getPermissions();
p[0] = "ADMIN";                     // object changed!
acct.getBalance()[0] = 999_999;     // balance edited
SECURE
// Java — defensive copy on return
public class Account {
  private String[] permissions = {"READ","WRITE"};
  private long[]   balance     = { 100 };

  public String[] getPermissions() {
    return permissions.clone();     // detached copy
  }
  // or, prefer immutability:
  public List<String> permissions() {
    return Collections.unmodifiableList(
        Arrays.asList(permissions));
  }
  public long[] getBalance() {
    return Arrays.copyOf(balance, balance.length);
  }
}

// caller's mutation hits only the copy — internals safe
acct.getPermissions()[0] = "ADMIN"; // no effect
왜 위험한가: 내부 배열 반환은 앨리어싱입니다. 호출자와 객체가 하나의 가변 객체를 공유하게 되어, 세터를 거치지 않고도 캡슐화와 클래스가 지키는 불변식(역할·잔액·한도)을 우회할 수 있습니다. 방어 핵심: 복사본 반환(clone(), Arrays.copyOf) 또는 불변 뷰(Collections.unmodifiableList) · 가능하면 불변 타입 사용 · 가변 내부 상태의 살아있는 참조를 절대 외부에 노출하지 않기.
⚠️ 교육용 시뮬레이션입니다. 객체·private 필드·공격자는 모두 Java 동작을 모사한 페이지 내부 JavaScript mock이며 실제 시스템은 없습니다.