2012-04-22 17 views
5

जावास्क्रिप्ट में वैश्विक संपत्ति/फ़ंक्शन को ओवरराइट किया गया है, तो वैश्विक ऑब्जेक्ट के गुणों और कार्यों को ओवरराइट करना आसान बनाता है। मैं यह जांचने का एक तरीका ढूंढना चाहता हूं कि वैश्विक संपत्ति का मूल संस्करण बदल दिया गया है या नहीं।जांचें कि जावास्क्रिप्ट

<script type="text/javascript"> 
    window.encodeURIComponent = eval; 
</script> 
<script type="text/javascript" src="myscript.js"></script> 

myscript.js कहीं encodeURIComponent फ़ंक्शन को कॉल करते हैं, तो यह अब अप्रत्याशित व्यवहार होगा:

कोई अपने HTML में इस डाल पर विचार करें। तो क्या कोई तरीका है कि मैं myscript.js के अंदर जांच कर सकता हूं अगर किसी ने इसे इस्तेमाल करने से पहले उस फ़ंक्शन को अधिलेखित कर दिया हो?

उत्तर

1

यह ब्राउज़र विशिष्ट है और निश्चित रूप से गैर-कार्यों के लिए काम नहीं करेगा, लेकिन:

एक समारोह के toString विधि कॉलिंग की तरह कुछ का उत्पादन करना चाहिए:

Chrome: 

"function encodeURIComponent() { [native code] }" 

Firefox: 

"function encodeURIComponent() { 
    [native code] 
}" 

IE 7/8/9: 
" 
function encodeURIComponent() { 
    [native code] 
} 
" 

गौर करें कि समारोह के नाम संपत्ति के नाम से मेल खाता , और इसके शरीर को "[native code]" द्वारा प्रतिस्थापित किया गया है। विचार इस स्ट्रिंग से सभी व्हाइटस्पेस को निकालना है और इसकी तुलना अपेक्षित परिणाम, "functionxxx(){[nativecode]}" से करें।

var pattern = 'function' + propertyName + '(){[nativecode]}'; 
var func = window[propertyName].toString(); 
if(func.replace(/\s+/g, '') !== pattern) { 
    throw new Error("Property window." + propertyName + " has been modified!"); 
} 
6

केवल एक चीज मैं जानता हूँ कि समारोह की स्ट्रिंग प्रतिनिधित्व के विश्लेषण के साथ एक स्पष्ट दृष्टिकोण है:

मैं अगर यह सभी ब्राउज़रों/कार्यों के लिए काम करता है, कि के परीक्षण और त्रुटि पता नहीं है। आम तौर पर, कोड

window.encodeURIComponent.toString() 

कुछ इस तरह का उत्पादन करना चाहिए:

function encodeURIComponent() { [native code] } 

जो आसानी से और मुख्य जानकारी function encodeURIComponent के लिए पार्स किया जा सकता है।

समारोह eval द्वारा ओवरराइट किया गया है, तो अपने उदाहरण के रूप में, आप प्राप्त करेंगे:

function eval() { [native code] } 

सामान्य तौर पर, जाँच window गुणों के लिए, आप एक नकली आइफ्रेम बना सकते हैं और iframe.contentWindow.[property].toString() साथ window.[property].toString() तुलना कर सकते हैं। यदि तुलना false देता है, तो संपत्ति बदल दी गई है।

+0

यह करने का यह वास्तव में चालाक और क्रॉस-ब्राउज़र तरीका है। – sg3s

+0

धन्यवाद स्टेन। क्या आप यह भी सुनिश्चित करना चाहते हैं कि 'eval' की toString प्रॉपर्टी को' function() {return "function encodeURIComponent() {[मूल कोड]}" जैसे कुछ के साथ ओवरराइट नहीं किया गया है; } '? –

+0

'toString' को पार्स करने और कॉल करने के बजाय आप इसे' window.encodeURIComponent.name' 'कर सकते हैं .. किसी भी तरह से इस http://stackoverflow.com/a/10266791/474290 –

0

जावास्क्रिप्ट में यह करने के लिए एक आसान तरीका नहीं है :) लेकिन आप HTML के लिए उपयोग किया है, तो आप एक स्क्रिप्ट के अंदर इस विधि का उपयोग नहीं कर सकते ..

समारोह एक वस्तु है .. इसलिए हम किसी ऑब्जेक्ट को एक लिंक सहेज सकते हैं और बस उन लिंक की तुलना कर सकते हैं। बस एक फंक्शन के बारे में सोचें जैसे कि यह एक साधारण वस्तु है। आप वस्तुओं की तुलना कैसे कर सकते हैं?

<script type="text/javascript"> 
    var a = window.encodeURIComponent; // a === window.encodeURIComponent -> true 
</script> 
<script type="text/javascript"> 
    window.encodeURIComponent = eval; // a === window.encodeURIComponent -> false 
</script> 
<script type="text/javascript" src="myscript.js"> 
    if (a !== window.encodeURIComponent) 
    { 
     throw new Error('Someone redefined function'); 
    } 
</script> 
3

एक स्क्रिप्ट के अंदर यह करने के लिए एक दिलचस्प तरीका समारोह प्रोटोटाइप

तुलना करने के लिए डिफ़ॉल्ट रूप से है - typeof window.encodeURIComponent.prototype === "undefined"

लेकिन अगर किसी के द्वारा

window.encodeURIComponent = function() { eval(); } इस समारोह को पुनर्परिभाषित हम

मिल जाएगा

typeof window.encodeURIComponent.prototype === "Object"

पीएस: यह विधि दूसरों के बाद अधिक विश्वसनीय है, लेकिन यह आपको 100% गुरु नहीं देगा। जावास्क्रिप्ट .. सभी वस्तुओं है और सभी क्रम में .. सिर्फ इस के साथ रहती ..

अद्यतन आप दोनों विधियों को जोड़ सकते हैं मेरा और @Stans .. क्योंकि मैं wasn

इस उदाहरण से काम नहीं करते .. eval भी प्रोटोटाइप "अनिर्धारित" डिफ़ॉल्ट रूप से चल रहा है, ताकि आप इस

window.encodeURIComponent.name === "encodeURIComponent" 
//to make shure that user won't use EVAL 
&& typeof window.encodeURIComponent.prototype === "undefined" 
//to make shure that user won't use self defined function 
+0

एआई_बॉय, मैं इसे पुन: पेश नहीं कर सकता। 'typeof window.encodeURIComponent.prototype' दोनों मामलों में' अपरिभाषित "है। –

+0

एक अद्यतन देखें .. –

0

कैसे इस बारे में क्या कर सकते हैं - 'टी eval का उपयोग कर?

function isNativeWindowProperty(propertyName) { 
    var result = false; 
    var iframe = document.createElement('iframe'); 
    iframe.src = 'javascript:;'; 
    document.getElementsByTagName('body')[0].appendChild(iframe); 
    if (window[propertyName].toString() === iframe.contentWindow[propertyName].toString()) { 
     // check window[propertyName].toString override 
     if (window[propertyName].toString.toString() === iframe.contentWindow[propertyName].toString.toString()) { 
      result = true; 
     } 
    } 
    iframe.parentNode.removeChild(iframe); 
    return result; 
}; 

console.log(isNativeWindowProperty('alert')); // true 

window.alert = function() {}; 
console.log(isNativeWindowProperty('alert')); // false 

window.alert.toString = function() { 
    return 'function alert() { [native code] }'; 
}; 
console.log(isNativeWindowProperty('alert')); // false 
+0

शायद आप यह समझाने के लिए कुछ पाठ जोड़ सकते हैं कि आपका कोड खोजन का उत्तर कैसे देता है? – Kmeixner

संबंधित मुद्दे