보안 관련 JavaScript 오류 방지

Adobe AIR 1.0 이상

이러한 보안 제한으로 인해 샌드박스에서의 사용이 제한되는 코드를 호출하면 런타임에서 JavaScript 오류: "응용 프로그램 보안 샌드박스에서의 JavaScript 코드에 대한 Adobe AIR 런타임 보안 위반"을 전달합니다. 이 오류를 방지하려면 이러한 코딩 방법을 따르십시오.

보안 관련 JavaScript 오류의 원인

문서 load 이벤트가 발생하고 load 이벤트 핸들러가 종료된 경우 문자열을 평가 및 실행하는 대부분의 작업에서는 응용 프로그램 샌드박스에서 코드를 실행할 수 없습니다. 잠재적으로 안전하지 않은 문자열을 평가 및 실행하는 다음 유형의 JavaScript 명령문을 사용하려고 하면 JavaScript 오류가 생성됩니다.

다른 샌드박스에 응용 프로그램 매핑

대부분의 경우 보안 관련 JavaScript 오류를 방지하기 위해 응용 프로그램을 다시 작성하거나 다시 구조화할 수 있습니다. 그러나 다시 작성 또는 다시 구조화를 수행할 수 없는 경우에는 비 응용 프로그램 샌드박스로 응용 프로그램 내용 로드 에 설명되어 있는 기술을 사용하여 응용 프로그램 내용을 다른 샌드박스로 로드할 수 있습니다. 해당 내용이 AIR API에 액세스할 수 있는 경우 샌드박스 브리지 인터페이스 설정 에 설명되어 있는 대로 샌드박스 브리지를 만들 수 있습니다.

eval() 함수

응용 프로그램 샌드박스에서 eval() 함수는 페이지 load 이벤트 이전 또는 load 이벤트 핸들러 동안에만 사용할 수 있습니다. 페이지를 로드한 후 eval() 을 호출하면 코드가 실행되지 않습니다. 그러나 다음 경우 eval() 사용을 방지하도록 코드를 다시 작성할 수 있습니다.

객체에 속성 할당

다음과 같이 속성 접근자를 작성하도록 문자열을 파싱하는 대신

eval("obj." + propName + " = " + val);

다음과 같이 대괄호 표기법을 사용하여 속성에 액세스합니다.

obj[propName] = val;

컨텍스트에서 사용할 수 있는 변수를 포함하는 함수 만들기

다음과 같은 명령문을

function compile(var1, var2){ 
    eval("var fn = function(){ this."+var1+"(var2) }"); 
    return fn; 
}

다음으로 바꿀 수 있습니다.

function compile(var1, var2){ 
    var self = this; 
    return function(){ self[var1](var2) }; 
}

클래스 이름을 문자열 매개 변수로 사용하여 객체 만들기

다음 코드로 정의된 가상 JavaScript 클래스를 검토합니다.

var CustomClass =  
    { 
        Utils: 
        { 
            Parser: function(){ alert('constructor') } 
        }, 
        Data:  
        { 
         
        } 
    }; 
var constructorClassName = "CustomClass.Utils.Parser";

인스턴스를 만드는 가장 간단한 방법은 eval() 을 사용하는 것입니다.

var myObj; 
eval('myObj=new ' + constructorClassName +'()')

그러나 클래스 이름의 각 구성 요소를 파싱하고 대괄호 표기법을 통해 새 객체를 작성하여 eval() 에 대한 호출을 방지할 수 있습니다.

function getter(str) 
{ 
    var obj = window; 
    var names = str.split('.'); 
    for(var i=0;i<names.length;i++){ 
        if(typeof obj[names[i]]=='undefined'){ 
            var undefstring = names[0]; 
            for(var j=1;j<=i;j++) 
                undefstring+="."+names[j]; 
            throw new Error(undefstring+" is undefined"); 
        } 
        obj = obj[names[i]]; 
    } 
    return obj; 
}

이 인스턴스를 만들려면 다음을 사용합니다.

try{ 
    var Parser = getter(constructorClassName); 
    var a = new Parser(); 
    }catch(e){ 
        alert(e); 
}

setTimeout() 및 setInterval()

핸들러 함수로 전달한 문자열을 함수 참조 또는 객체로 바꿉니다. 예를 들어 다음과 같은 명령문을

setTimeout("alert('Timeout')", 100);

다음으로 바꿀 수 있습니다.

setTimeout(function(){alert('Timeout')}, 100); 

또는 함수를 사용하기 위해 호출자가 this 객체를 설정해야 하는 경우 다음과 같은 명령문을

this.appTimer = setInterval("obj.customFunction();", 100);

다음으로 바꿉니다.

var _self = this; 
this.appTimer = setInterval(function(){obj.customFunction.apply(_self);}, 100);

함수 생성자

new Function(param, body) 에 대한 호출을 인라인 함수 선언으로 바꾸거나 페이지 load 이벤트를 처리하기 이전에만 사용할 수 있습니다.

javascript: URL

javascript: URL 스킴을 사용하여 링크에 정의된 코드는 응용 프로그램 샌드박스에서 무시됩니다. 안전하지 않은 JavaScript 오류는 생성되지 않습니다. 다음과 같이 javascript: URL을 사용하는 링크를

<a href="javascript:code()">Click Me</a>

다음으로 바꿀 수 있습니다.

<a href="#" onclick="code()">Click Me</a>

innerHTML 및 outerHTML 문의 onevent 특성을 통해 할당된 이벤트 콜백

innerHTML 또는 outerHTML을 사용하여 문서의 DOM에 요소를 추가할 때 onclick 또는 onmouseover 와 같이 명령문 내에 할당된 모든 이벤트 콜백은 무시됩니다. 보안 오류는 생성되지 않습니다. 대신 addEventListener() 메서드를 사용하여 새 요소에 id 특성을 할당하고 이벤트 핸들러 콜백 함수를 설정할 수 있습니다.

예를 들어 다음과 같이 문서에 대상 요소가 있는 경우

<div id="container"></div>

다음과 같은 명령문을

document.getElementById('container').innerHTML =  
    '<a href="#" onclick="code()">Click Me.</a>';

다음으로 바꿀 수 있습니다.

document.getElementById('container').innerHTML = '<a href="#" id="smith">Click Me.</a>'; 
document.getElementById('smith').addEventListener("click", function() { code(); });

응용 프로그램 설치 디렉토리 외부에서 JavaScript 파일 로드

응용 프로그램 샌드박스 외부에서 스크립트 파일을 로드할 수 없습니다. 보안 오류는 생성되지 않습니다. 응용 프로그램 샌드박스에서 실행되는 모든 스크립트 파일은 응용 프로그램 디렉토리에 설치되어야 합니다. 페이지의 외부 스크립트를 사용하려면 해당 페이지를 다른 샌드박스로 매핑해야 합니다. 비 응용 프로그램 샌드박스로 응용 프로그램 내용 로드 를 참조하십시오.

document.write() 및 document.writeln()

document.write() 또는 document.writeln() 에 대한 호출은 페이지 load 이벤트를 처리한 이후 무시됩니다. 보안 오류는 생성되지 않습니다. 대신 DOM 조작 기술을 사용하여 새 파일을 로드하거나 문서의 본문을 바꿀 수 있습니다.

load 이벤트 이전 또는 load 이벤트 핸들러 동안의 동기 XMLHttpRequests

페이지 load 이벤트 이전 또는 load 이벤트 핸들러 동안에 시작된 동기 XMLHttpRequests는 내용을 반환하지 않습니다. 비동기 XMLHttpRequests는 시작될 수 있지만 load 이벤트 이후에만 반환됩니다. load 이벤트가 처리되어야 동기 XMLHttpRequests가 정상적으로 작동합니다.

동적으로 만든 스크립트 요소

innerHTML 또는 document.createElement() 메서드를 사용하여 만든 스크립트 요소와 같이 동적으로 만든 스크립트 요소는 무시됩니다.