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


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.