Here is an example code from Google about how to safely initialize its recaptcha service https://developers.google.com/recaptcha/docs/loading
<script async src="https://www.google.com/recaptcha/api.js"></script>
<script>
if(typeof grecaptcha === 'undefined') {
grecaptcha = {};
}
grecaptcha.ready = function(cb){
//How is it possible for grecaptcha to be undefined here?
if(typeof grecaptcha === 'undefined') {
const c = '___grecaptcha_cfg';
window[c] = window[c] || {};
(window[c]['fns'] = window[c]['fns']||[]).push(cb);
} else {
cb();
}
}
grecaptcha.ready(function(){
grecaptcha.render("container", {
sitekey: "ABC-123"
});
});
</script>
As you can see grecaptcha.ready is a function and it again checks if(typeof grecaptcha === 'undefined'). But how can grecaptcha be undefined at the time when grecaptcha.ready is called? As I understand grecaptcha has already been initialized as a property of global object and it’s value is {} hence it’s type should be "object"
Advertisement
Answer
It’d have to be code elsewhere, but sure, it’s a global object, so a malicious actor could potentially overwrite it, e.g. you could have something like:
var grecaptcha = {
start() {
var that = this;
return new Promise((resolve, reject) => {
setTimeout(() => {
if (that.ready) {
that.ready(that)
}
resolve(true);
}, 5000);
let remaining = 4;
let interval = setInterval(() => {
console.log(remaining--);
if (remaining == 0) {
clearInterval(interval);
}
}, 1000);
});
}
};
grecaptcha.start().then(() => console.log('But we still do stuff with it'));
if(typeof grecaptcha === 'undefined') {
grecaptcha = {};
}
grecaptcha.ready = function(cb){
console.log(typeof grecaptcha);
}
setTimeout(() => grecaptcha = undefined, 1000)