다른 도메인의 내용 간 스크립팅

Adobe AIR 1.0 이상

AIR 응용 프로그램이 설치되면 특수 권한이 부여됩니다. 동일한 권한이 응용 프로그램에 포함되지 않은 원격 파일 및 로컬 파일을 포함하여 기타 내용에 누출되지 않아야 합니다.

AIR 샌드박스 브리지

대개 다른 도메인의 내용은 다른 도메인의 스크립트를 호출할 수 없습니다. 권한이 부여된 정보 또는 제어가 실수로 누출되지 않도록 AIR 응용 프로그램을 보호하기 위해 응용 프로그램 보안 샌드박스의 내용(응용 프로그램과 함께 설치된 내용)에 다음과 같은 제한이 적용됩니다.

  • Security.allowDomain() 메서드를 호출하여 응용 프로그램 보안 샌드박스의 코드를 다른 샌드박스에 허용할 수 없습니다. 응용 프로그램 보안 샌드박스에서 이 메서드를 호출하면 오류가 발생합니다.

  • LoaderContext.securityDomain 또는 LoaderContext.applicationDomain 속성을 설정하여 비 응용 프로그램 내용을 응용 프로그램 샌드박스로 가져올 수 없습니다.

주 AIR 응용 프로그램에서 원격 도메인의 내용이 주 AIR 응용 프로그램의 스크립트에 대한 액세스를 제어해야 하거나 그 반대의 경우가 여전히 존재합니다. 이를 위해서 런타임에서 두 샌드박스 간 게이트웨이로 사용되는 샌드박스 브리지 메커니즘을 제공합니다. 샌드박스 브리지는 원격 응용 프로그램 보안 샌드박스와 응용 프로그램 보안 샌드박스 간의 명시적인 상호 작용을 제공할 수 있습니다.

샌드박스 브리지는 로드된 스크립트와 로드 중인 스크립트 모두 액세스할 수 있는 두 객체를 표시합니다.

  • parentSandboxBridge 객체를 사용하면 로드 중인 내용이 로드된 내용의 스크립트에 속성 및 함수를 표시할 수 있습니다.

  • childSandboxBridge 객체를 사용하면 로드된 내용이 로드 중인 내용의 스크립트에 속성 및 함수를 표시할 수 있습니다.

샌드박스 브리지를 통해 표시된 객체는 참조가 아닌 값에 따라 전달됩니다. 모든 데이터가 직렬화됩니다. 즉, 브리지의 한 면에서 표시한 객체가 다른 면에 의해 설정될 수 없으며 표시된 모든 객체의 유형이 지정됩니다. 또한 간단한 객체 및 함수만 표시할 수 있으며 복잡한 객체는 표시할 수 없습니다.

자식 내용이 parentSandboxBridge 객체의 속성을 설정하려는 경우 런타임에서 SecurityError 예외가 발생합니다. 마찬가지로, 부모 내용이 childSandboxBridge 객체의 속성을 설정하려는 경우 런타임에서 SecurityError 예외가 발생합니다.

샌드박스 브리지 예(SWF)

AIR music store 응용 프로그램에서 원격 SWF 파일이 앨범 가격을 브로드캐스트할 수 있기를 원하지만 원격 SWF 파일에서 가격이 할인 가격인지 여부를 공개하길 원하지 않을 수 있습니다. 이를 위해서 StoreAPI 클래스에서 가격을 구하는 메서드를 제공하지만 할인 가격은 숨깁니다. 그러고 나서 이 StoreAPI 클래스의 인스턴스가 원격 SWF를 로드하는 Loader 객체의 LoaderInfo 객체에 대한 parentSandboxBridge 속성에 할당됩니다.

다음은 AIR music store에 대한 코드입니다.

<?xml version="1.0" encoding="utf-8"?> 
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" title="Music Store" creationComplete="initApp()"> 
    <mx:Script> 
        import flash.display.Loader; 
        import flash.net.URLRequest; 
     
        private var child:Loader; 
        private var isSale:Boolean = false; 
         
        private function initApp():void { 
            var request:URLRequest =  
                    new URLRequest("http://[www.yourdomain.com]/PriceQuoter.swf") 
 
            child = new Loader(); 
            child.contentLoaderInfo.parentSandboxBridge = new StoreAPI(this); 
            child.load(request); 
            container.addChild(child); 
        } 
        public function getRegularAlbumPrice():String { 
            return "$11.99"; 
        } 
        public function getSaleAlbumPrice():String { 
            return "$9.99"; 
        } 
        public function getAlbumPrice():String { 
            if(isSale) { 
                return getSaleAlbumPrice(); 
            } 
            else { 
                return getRegularAlbumPrice();     
            } 
        } 
    </mx:Script> 
    <mx:UIComponent id="container" /> 
</mx:WindowedApplication> 

StoreAPI 객체는 주 응용 프로그램을 호출하여 일반 앨범 가격을 가져오지만 getSaleAlbumPrice() 메서드가 호출될 때 “사용할 수 없음”을 반환합니다. 다음 코드에서는 StoreAPI 클래스를 정의합니다.

public class StoreAPI 
{ 
    private static var musicStore:Object; 
     
    public function StoreAPI(musicStore:Object) 
    { 
        this.musicStore = musicStore; 
    } 
 
    public function getRegularAlbumPrice():String { 
        return musicStore.getRegularAlbumPrice(); 
    } 
     
    public function getSaleAlbumPrice():String { 
        return "Not available"; 
    } 
     
    public function getAlbumPrice():String { 
        return musicStore.getRegularAlbumPrice();     
    } 
}

다음 코드에서는 저장소의 가격을 보고하지만 할인 가격은 보고할 수 없는 PriceQuoter SWF 파일의 예를 보여 줍니다.

package 
{ 
    import flash.display.Sprite; 
    import flash.system.Security; 
    import flash.text.*; 
     
    public class PriceQuoter extends Sprite 
    { 
        private var storeRequester:Object; 
         
        public function PriceQuoter() { 
            trace("Initializing child SWF"); 
            trace("Child sandbox: " + Security.sandboxType); 
            storeRequester = loaderInfo.parentSandboxBridge; 
             
            var tf:TextField = new TextField(); 
            tf.autoSize = TextFieldAutoSize.LEFT; 
            addChild(tf); 
             
            tf.appendText("Store price of album is: " + storeRequester.getAlbumPrice()); 
            tf.appendText("\n"); 
            tf.appendText("Sale price of album is: " + storeRequester.getSaleAlbumPrice()); 
        } 
    } 
}

샌드박스 브리지 예(HTML)

HTML 내용에서 parentSandboxBridge childSandboxBridge 속성이 자식 문서의 JavaScript window 객체에 추가됩니다. HTML 내용의 브리지 함수를 설정하는 방법에 대한 예는 샌드박스 브리지 인터페이스 설정 을 참조하십시오.

API 노출 제한

샌드박스 브리지를 표시할 때 남용 정도를 제한하는 높은 수준의 API를 표시하는 것이 중요합니다. 브리지 구현을 호출하는 내용이 코드 삽입 등을 통해 손상될 수 있습니다. 따라서 예를 들어 브리지를 통해 임의 파일의 내용을 읽는 readFile(path:String) 메서드 표시가 쉽게 남용될 수 있습니다. 경로를 사용하지 않고 특정 파일을 읽는 readApplicationSetting() API를 표시하는 것이 더 좋습니다. 보다 의미적인 접근 방식은 응용 프로그램의 일부가 손상된 경우 해당 응용 프로그램에서 유발할 수 있는 손상을 제한합니다.