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)