java-squid / effective-java

effective java 3e study
105 stars 38 forks source link

[아이템 50] 적시에 방어적 복사본을 만들라 #50

Closed 102092 closed 3 years ago

ghojeong commented 3 years ago

복사본을 만들 시에 동일한 변수명을 활용하면 일어나는 재미있는 예시 를 찾게 되어서 공유해봅니다.

tmdgusya commented 3 years ago

복사본을 만들 시에 동일한 변수명을 활용하면 일어나는 재미있는 예시 를 찾게 되어서 공유해봅니다.

읽어봤는데 되게 흥미롭네요 ㅋㅋㅋ 은밀히 객체를 복사하여, 개발자의 훈련강도를 높인다니 이번 제 챕터는 사실 이러한 공격수단이 있다는 것을 알고, 자신이 다른 객체를 참조하여 작업할때는 해당 객체에 Setter 를 통한 공격이 가능한지? 혹은 그러한 공격이 영향을 미칠수 있는 요인들이 있는지를 잘 알아봐야겠다는 생각이 드네요.

kses1010 commented 3 years ago

늦게 질문 드려서 죄송합니다!

p305 네이티브 메서드나 리플렉션 같이 언어 외적인 수단을 동원하지 않고는...

여기서 네이티브 메서드나 리플렉션을 이용해서 불변식을 위배하는 방법이 어떤지 알고 싶습니다.

kses1010 commented 3 years ago

이건 조금 이상한 질문이겠지만, 대체 이 공격은 누가 하는 건가요?

ghojeong commented 3 years ago

대체 이 공격은 누가 하는 건가요?

같이 일하는 동료, 새로 들어온 후임, 지금 퇴사하고 없는 선임 개발자 분들이 하시지요 ㅋㅋㅋ

kses1010 commented 3 years ago

허허허 이해했습니다. 그러면 동료가 아니고 적이군요. 공격자라길래 저는 해커나 이런사람을 의미하는건가 라고 생각했습니다. 사실상 협업할 때 다른 개발자가 실수하는 걸 막는 용도라고 생각하면 되겠네요 ㅎㅎ

tmdgusya commented 3 years ago

이건 조금 이상한 질문이겠지만, 대체 이 공격은 누가 하는 건가요?

음 여러가지 인터넷을 뒤지다보니, 자바가 권한을 통해서 해킹이가능한데, private 생성자로 해두더라도 최상위 권한을 가지고 있다면 생성자 호출이 가능하다고 합니다. 그래서 해당 생성자 호출을 통해서 시스템에 오류를 일으키는 공격이 가능하다고 하네요. 이 부분은 저도 잘 읽어봤는데 이해가 되지 않아서, 일단은 pyro 가 말한것처럼, 저런 부작용이 발생할 수 있다는 것에 초점을 두어도 좋을듯 합니다.

늦게 질문 드려서 죄송합니다!

p305 네이티브 메서드나 리플렉션 같이 언어 외적인 수단을 동원하지 않고는...

여기서 네이티브 메서드나 리플렉션을 이용해서 불변식을 위배하는 방법이 어떤지 알고 싶습니다.

간단하게 reflection 을 통한 공격방법을 소개해드립니다. 지금 간략하게 짜본 방법인데, 리플렉션이라는 기능을 이용하면 아래와 같은 코드로 공격이 가능합니다. 리플렉션이란 객체가 호출될 당시 시점에 객체를 생성가능하도록 해주는 기법이라고 합니다. 초기 자바에는 이렇게 동적으로 객체를 생성해주는 것이 존재하지 않았는데, 이를 보완하기 위해 Reflection 이라는 기능이 도입됬다고 합니다. 객체의 형태를 투영시키는 기법이라고 생각하시고 아래코드를 보시면, 해당 클래스가 있는지 없는지를 일단 판단한 후에 아래 getMethods(), getFields() 등으로 정보 취득을 한뒤 아래와 같은 set Method 등을 통해 공격이 가능한 것을 의미하는 듯 합니다.

public class test {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException {
        Class<?> StringClassReflection = Class.forName("java.lang.String");
        Method[] reflectionMethods = StringClassReflection.getMethods();
        Field[] reflectionField = StringClassReflection.getFields();
        System.out.println(Arrays.toString(reflectionMethods));
        System.out.println(Arrays.toString(reflectionField));
        Field field = reflectionField[0];
        field.set(field, "10");
    }
}