프라이빗 변수를 제한 할 수 없기 때문에 리플렉션이 단점입니까?


14

private수정은 클래스 외부 액세스를 제한하기 위해 사용되지만, 반사 다른 클래스를 사용하여 private 메소드 및 필드에 액세스 할 수 있습니다. 그래서 요구 사항의 일부인 경우 접근성을 어떻게 제한 할 수 있는지 궁금합니다.


2
낮은 신뢰 코드는 개인 리플렉션을 사용할 수 없습니다 (적어도 다른 어셈블리에서는 세부 사항을 잊었습니다). 완전 신뢰 코드는 단순히 포인터를 사용하여 프로세스 내 제한 사항을 무시할 수 있습니다.
코드 InChaos

55
개인 액세스 수정자는 주로 프로그래머에게 "교실 외부에서 이것을 사용하지 말고 실제로 사용하는 경우 다음 버전이 코드를 위반하는 경우 불평하지 마십시오"라고 엄격하게 적용되는 보안 기능이 아닙니다.
코드 InChaos


4
사용자는 원하는대로 코드를 패치 할 수도 있습니다. DRM (지속적인 보호 기능을 제공 할만큼 강력하지 않은)에 대한 부분 예외를 제외하고는 응용 프로그램 (바이너리 또는 소스 코드)에 액세스 할 수있는 모든 사용자가 DRM을 사용하여 무엇이든 할 수 있습니다.
Brian

6
이것은 언어 특정 질문이 아닌가? 리플렉션은 언어에 따라 다르게 작동합니다. 이 질문에 Java 또는 다른 태그가 있어야하는지 궁금합니다.
Wayne Conrad

답변:


54

액세스 수정 자의 목적은 개발자에게 클래스의 공용 인터페이스에 대한 코드를 작성하도록 알리는 것입니다. 그들은 어떤 식 으로든 보안 수단이 아니며 문자 그대로 정보를 숨기거나 보호하지 않습니다.


33
이것은 보편적으로 사실이 아닙니다. 인용 에릭 Lippert의를 , "는 CLR에 액세스 수정이 보안 기능은 다음과 같습니다. 액세스 규칙은 철저히 보안 및 유형 안전 시스템으로 융합되어있다."에서 C #을, 반사가 완전 신뢰에서 실행되는 코드 만 사용할 수 있습니다. 이것은 코드를 실행 하는 시스템의 악의적 인 사용자에게는 적용되지 않으며 적용 할 수 없습니다 . 그러나 악성 플러그인에는 적용됩니다.
Brian

5
@Brian Brian이 언급 한 문제는 시스템이 타사 코드를 완전히 신뢰하지 않고 실행할 수 있도록 허용하는 경우입니다. 예를 들어 브라우저 샌드 박스 (예 : 많이 싫어하는 애플릿), Google 앱 엔진Azure가 있습니다. 신뢰할 수없는 코드가 플랫폼의 핵심 라이브러리에 대한 세부 정보를 탐색 할 수 있도록하는 것은 Azure에게는 정말 어리석은 일입니다.
JimmyJames

3
@Brian 100 % 정확하지 않습니다. 부분적으로 신뢰할 수있는 코드에서 수행 할 수있는 리플렉션 작업이 있습니다. 개인 필드에 액세스하는 것과 같은 일을 할 수는 없습니다.
Luaan

1
@Brian 누군가가 제한을 우회 할 수있는 취약점이나 사회 공학을 찾을 때까지. 그것들을 그런 식으로 사용하려는 것은 아무 의미가 없습니다. 이것이 그들의 주된 목적이 아닙니다.
jpmc26

31

클래스 액세스 권한에 대해 Herb Sutter 를 인용하려면 :

"여기서 문제는 머피 (Murphy)와 마키아 벨리 (Machiavelli)에 대한 보호, 즉 우발적 인 오용 (언어가 잘하는 것)에 대한 보호와 의도적 인 남용 (실제로는 불가능한)에 대한 보호에 관한 것입니다. 프로그래머가 시스템을 파괴하기에 충분히 원하기 때문에 방법을 찾을 것입니다. "


2
있습니다 당신이 샌드 박스 신뢰할 수없는 코드에 필요한 시간은, 그러나 그것은 어려운 작업이다. 오류 (머피)로부터 보호하는 것이 훨씬 일반적인 경우입니다.
Paul Draper

#define private public(실제로 정의되지 않은 동작임을 무시하고) voila 나는 외부에서 수업 의 제한된 부분 까지 완전히 액세스 할 수 있습니다.
bolov

고의적 인 남용을 방지하는 것은 이론적으로 불가능할 수 있지만 남용을 충분히 어렵게함으로써 매우 드물게 발생함으로써 효과적으로 가능합니다. 그것에 대해 명확하게하는 것이 중요합니다. 그렇지 않으면 생명에 중요한 의료 기기와 같은 상황에서 소프트웨어를 전혀 사용할 수 없습니다.
MarkJ

@MarkJ. Herb Sutter의 발언은 처음에 클래스를 작성한 개발자와 아마도 팀 동료가 의도적으로 남용한 것입니다. 언어 기능에 의한 악용을 막을 방법이 없다고 생각합니다.
Nemanja Trifunovic

@ bolov 그 스턴트는 언어에 달려 있다고 생각합니다. C / C ++ 전처리 기는 아마도 그것을 피할 수 있지만, 그것들 없이는 "#define에서 예약어를 사용할 수 없습니다"라는 오류가 발생할 것입니다.
Dan은 Firelight에 의해 조사 중입니다.

10

아니요, 이것은 실제로 중요한 이점입니다. 단순히 일부 개발자가 누군가가 내부 상태에 액세스해야한다고 생각하지 않는다고해서 합법적 인 사용 사례가 나타나지 않는다는 의미는 아닙니다. 이 경우 리플렉션을 사용하여 물체에 대한 수술을 수행하는 것이 최후의 수단이 될 수 있습니다. 이 기술을 두 번 이상 사용해야했습니다.


1
즉, 불완전한 요구 사항이나 불완전한 구현으로 인해 API가 손상되었을 가능성을 피하는 방법입니다.
Reinstate Monica

4

실행 환경이라는 한 단계 더 올라가면 접근성을 훨씬 더 제한 할 수 있습니다.

모든 언어에 이러한 개념이있는 것은 아니지만 최소한 Java에서는 개인 필드에 액세스 할 수 없도록하는 보안 관리자를 사용할 수 있습니다. 런타임시 보안 관리자를 수동으로 설치하거나 jar 파일에 보안 정책을 추가 한 후 수정되지 않도록 봉인 할 수 있습니다.

Java에서이를 수행하는 방법에 대한 추가 정보 : 리플렉션 보안


3

어떤 반성에 대해 이야기하고 있습니까?

많은 리플렉션 시스템에서 우회 캡슐화는 코드에서 가져와야하는 명시 적 기능이며 기본적으로 없습니다.

캡슐화가 염려된다면 간단한 해결책은 그것을 보존하지 않는 반사 시스템을 사용하지 않는 것입니다.


3

파이썬에는 액세스 수정자가 없습니다. 이 규칙은 클래스 외부에서 액세스 할 수없는 메소드 및 변수에 밑줄을 붙입니다. 기술적으로 타사 클래스에서 해당 필드에 액세스하지 못하게합니까? 전혀; 그러나 그렇게한다면, 당신은 자신에 있고 다른 반을 비난하지 않고 무언가를 깨뜨릴 위험이 있습니다.

C #에는 액세스 수정자가 있지만 아직 규칙은 컴파일러에 의해 적용되지만 여전히 규칙입니다. 이는 기술적으로 리플렉션을 통해 또는 게임 트레이너 처럼 메모리를 직접 조작하여 개인 변수에 액세스하고 변경할 수 있음을 의미합니다 . 결과는 정확히 동일합니다. 클래스의 변수가 다른 클래스의 리플렉션을 통해 또는 다른 응용 프로그램의 메모리 변조를 통해 변경되어 클래스의 무언가가 중단되면 오류가 아닙니다.

이로 인해 타사가 데이터에 액세스 수있는 보안 문제가 발생 합니다. 암호화 된 문자열의 변형 및 유사한 데이터 구조로 이어지는 무언가 . 그러나 이러한 사용으로부터 코드를 보호하는 것은 OS 및 코드 수준 액세스 제한 과 관련 이 있으며 Reflection 자체와 아무런 관련이 없습니다.


2
C #에서는 완전히 신뢰할 수있는 코드 만 개인 멤버를 반영 할 수 있습니다. 메모리를 처리하기 위해 직접 쓰는 것은 여전히 ​​작동하지만 기본 코드보다 어렵 습니다.
Luaan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.