2010-12-14 1 views
1

클래스가 해당 ID를 가장 할 수 있습니까? 예를 들어, 클래스 A은 클래스 B 메소드에 액세스하려고 시도합니다. Class B 메서드는 getClass().getName()을 사용하여 클래스 A을 확인하여 그것이 누구인지 확인합니다. 가장 (impersonation)이 일어날 수 있습니까? 예 : Class CA을 가장하여 getclass().getName() 클래스 B을 사용하여 검사를 통과합니까?클래스 기반의 가장

클래스 B이 아래 샘플 메서드에서 유효한 체크 용으로 getClass().getName()을 구현하려는 경우 아래 예제 코드에서이를 올바르게 구현하는 방법은 무엇입니까?

public byte[] getStoragePrivateKey(String application) { 
    if (application.getClass().getName().equals("correctClass") { 
     // Allow access to Private Key. 
    } else { 
     // Access denied 
    } 
} 

위의 예는 시스템의 내부 키 서버 데이터베이스에 액세스하려는 시스템의 플러그인 애플릿을 시뮬레이션 한 것입니다.

+1

는 당신이 달성하기 위해 노력하고 무엇을? Java 내에서 보안을 가능하게하는 여러 가지 방법이 보안 정책 중 가장 간단합니다. 먼저 액세스 제어를 강력한 방식으로 제공 할 수 있으므로 먼저 살펴 보겠습니다. http://download.oracle.com/javase/1.4.2/docs/guide/security/permissions.html –

답변

2

여러 클래스 로더로이 작업을 수행 할 수 있습니다. 각 클래스 laoder는 같은 이름의 클래스를 가질 수 있습니다.

그러나, 나는 당신이 바이 패스 검증을 작성하는 간단한 방법이 "보안"

을 위해 할 수있는 경우에 당신이 단지 반사를 사용하는 것이 좋습니다 것은 검증을 구현하는 개선 된 방법

if (application.getClass() == CorrectClass.class) { 

이입니다 사용하기

StackTraceElement[] stes = Thread.currentThread().getStackTrace(); 
if (stes[0].getClassName().equals("correctClass") { 

이렇게하면 호출자가 올바른 클래스 이름에서 왔는지 확인할 수 있습니다. 클래스 로더로 스푸핑 될 수 있습니다.

sun.misc.Unsafe 클래스는 getUnsafe() 메서드를 보호하기 위해 후자와 같은 것을 사용합니다. 해결할 표준 작업이 있습니다.

Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); 
theUnsafe.setAccessible(true); 
Unsafe unafe = theUnsafe.get(null); 

Unsafe가 보호되는 이유와 액세스하려는 이유가 궁금한 경우 방법 목록을 살펴보십시오. ;)

EDIT : Unsafe.getUnsafe()는 (는) 최근에는 보호되었지만 최신 소스에서는 더 이상 보이지 않습니다. 아마도 수표가 쉽게 우회 될 수 있기 때문일 수 있습니다. ??

+1

가짜 java. * 클래스를로드하거나 대개 상위 클래스 로더가로드 한 클래스. –

+1

@Tom Hawtin, 라이센스 계약을 위반하지 않고. 그러나 기술적으로 가능합니다. 필자는 gc()에 대한 호출이 어디에서 발생했는지를보고하는 런타임 인 ​​자체 압축 String의 사용에 관한 기사를 작성했습니다. Terracotta는 런타임에 java. * 클래스를 변경하고 Profiler는 코드를 추가 클래스를 통해 클래스에 주입하여 추가 정보를 얻습니다. 그러나, 나는 그들이 여러 복사본을로드 믿지 않아요. –

+0

@Peter Lawrey Java 라이브러리의 일부를'-Xbootclasspath' 또는 유사하게 바꿀 수는 있지만 클래스 로더를 사용해서는 안됩니다. –

2

이것은 작동하지 않습니다 : 예제에서 application.getClass().getName()은 "application"매개 변수 유형을 얻는 동안 항상 "java.lang.String"을 반환합니다.

또한 Java에서 호출 된 메소드는 호출되는 유형을 찾을 수 없기 때문에 다른 유형의 액세스 제어를 구현하여 디자인을 점검해야합니다.

편집 : 나, 당신은 호출자의 종류를 확인을 시도 할 수 있습니다, 그것은 다른 소스에서 호출을 피할 얼마나 어떻게 당신의 코드를 기반으로, 예를 추가 할 수 있습니다 :

//Change the String for an Object, to allow the invoker pass a 
//reference to itself 
public byte[] getStoragePrivateKey(Object application) { 
    if (application.getClass().getName().equals("correctClass") { 
     // Allow access to Private Key. 
    } else { 
     // Access denied 
    } 
} 

참조하는 A 형에서 호출이 될 수 있습니다 :는 C "흉내"클래스에서 호출

B b=new B(); 
    byte[] key=b.getStoragePrivateKey(this); 

가, 실패, 이것은 C. 그대로클래스 인스턴스 :

B b=new B(); 
    byte[] key=b.getStoragePrivateKey(this); 

하지만,대로로 쉽게 검증 피 :

B b=new B(); 
    A a=new A(); 
    byte[] key=b.getStoragePrivateKey(a);