I've found a voting contest on my country and after realizing that there's people getting a lot of votes on it (like 6k on 4 days), I've been trying to satisfy my curiosity about it without finding a proper answer.
It's a voting contest without any captcha, you just need to click a "Vote" button. But it does have some JS code to avoid more than one vote from the same computer per hour (IP + cookie, as far as I could see), which I think some people managed to avoid, and uses a JSON callback to construct a random confirmation link, which some people might also have managed to construct (which would allow the faster vote possible):
http://ws.discoverybrasil.com/curiosity/concurso/altaVoto.php?jsoncallback=jQuery164036090815054306025_1321401398889&video=1327&tema=3®ion=2&_=1321401584457
Here's the full JS involved on the voting procedure:
<script>
var TEMA_ELEGIDO = 0;
var DATOS = {};
$(document).ready(function(){
TEMA_ELEGIDO = getQueryVariable('tema','');
mostrar_tema();
detallar_video();
if(typeof(FB)!='undefined') FB.XFBML.parse(); // lanzo el FB JS SDK (viene en los includes de Discovery).
});
function mostrar_tema(){
$.getJSON(APPSERVER+'/listarTemas.php?jsoncallback=?', function(response){
if(!response){ alert('Erro no envio de dados. Tente novamente, por favor.'); return };
if(response.resultado != 1){ alert(response.errormsg); return };
for(var i in response.lista){
if(response.lista[i].id == TEMA_ELEGIDO){
$('#curiosity_tema').html(response.lista[i].titulo);
TEMA_ELEGIDO = response.lista[i].id;
}
}
});
}
function detallar_video(){
var id = getQueryVariable('id');
if(id=='') return;
$.getJSON(APPSERVER+'/detalleContenido.php?jsoncallback=?',{
'id': id
}, function(response){
if(!response){ alert('Erro no envio de dados. Tente novamente, por favor.'); return };
if(response.resultado != 1){
alert('Error: '+ response.errormsg);
return;
}
DATOS = response;
$('#curiosity_usuario').html( (response.nombre+' '+response.apellido).replace('<','') );
$('#curiosity_locacion').html( (response.ciudad+', '+response.pais).replace('<','') );
/^http\:\/\/www.youtube.com\/.*[\?&]+v[=\/]?([\w\d-_]{11})[^&#]*/.test(response.video_link);
if(RegExp.$1 == '') /^http\:\/\/youtu.be\/([\w\d-_]{11})/.test(response.video_link);
var embed = '<object width="854" height="510"><param name="movie" value="http://www.youtube.com/v/'+ (RegExp.$1).replace('<','') +'?version=3&rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/'+ (RegExp.$1).replace('<','') +'?version=3&rel=0" type="application/x-shockwave-flash" width="854" height="510" allowscriptaccess="always" allowfullscreen="true"></embed></object>';
$('#curiosity_video').html(embed);
$('#curiosity_votos').html(response.votos +' votos');
if(!puede_votar(response.id)) inhabilitar_voto();
});
}
function inhabilitar_voto(){
$('#curiosity a.votar').css({opacity:0.3, cursor:'default'}).html('Votado');
}
function votar(){
if(!puede_votar(DATOS.id)){
alert('Você só pode votar 1 vez por hora para cada vídeo.');
return false;
}
$.getJSON(APPSERVER+'/altaVoto.php?jsoncallback=?',{
'video': DATOS.id,
'tema': TEMA_ELEGIDO,
'region': REGION,
}, function(response){
if(!response){ alert('Erro no envio de dados. Tente novamente, por favor.'); return };
if(response.resultado != 1){
if(response.resultado == 2){
alert('Você só pode votar 1 vez por hora para cada vídeo.');
}else{
alert('Error: '+ response.errormsg);
}
$('#curiosity a.votar').animate({opacity:1});
return;
}
recordar_voto(DATOS.id);
inhabilitar_voto();
$('#curiosity_votos').html( (parseInt(DATOS.votos,10)+1) +' votos' );
});
}
function puede_votar(video_id){
var puede = true;
var ahora = (new Date()).getTime();
var votos = (getCookie('votos')).split('&');
if(votos.length > 0){
for(var i in votos){
var pair = votos[i].split('=');
if(pair.length != 2) continue;
if(pair[0] != video_id) continue;
if(parseInt(pair[1]) <= 0) continue;
if( (1000*pair[1])+3600000 > ahora ){ puede = false; break; }
}
}
return puede;
}
function recordar_voto(video_id){
var ahora = (new Date()).getTime() / 1000;
var existente = false;
var votos = (getCookie('votos')).split('&');
if(votos.length > 0){
for(var i in votos){
var pair = votos[i].split('=');
if(pair.length != 2) continue;
if(pair[0] != video_id) continue;
existente = true;
votos[i] = video_id+'='+ahora;
}
}
if(!existente) votos.push(video_id+'='+ahora);
setCookie('votos', votos.join('&'), 365);
}
function ver_mas(){
location.href='galeria.shtml?tema='+TEMA_ELEGIDO;
}
</script>
So, my question is: am I going nuts or it's possible to block the code that avoids more than one vote per computer per hour or make a random JSON callback like the one used by the website to vote directly (using Greasemonkey or building a random request using Fiddler, maybe?)? Or am I missing something?
I'm not even on the contest, which is finishing by now, but such a high amount of votes really made me curious about it - I really doubt they have 200 or 300 valid and fast proxies to vote per hour using an automation tool (like iMacros).
Thank you very much!
I took a look at the code, and there are basically two barriers to prevent double voting:
There's a function called puede_votar(), which apparently takes a video id and returns true if you haven't voted for that particular video in the last 60 minutes or false otherwise. This is relying on cookies, so it can be easily defeated by just clearing your cookies.
If you can get past that, it sends a request to APPSERVER + '/altaVoto.php with the video id you want to vote on. This will return a response code, possibly a failure. One of these failures is code 2, which lets you know that you're trying to vote more than once within an hour.
This most certainly relies on your IP address. And since this is all validated on the server side, your only option would be to get a new IP. So yes, I believe whoever did this just had a lot of time in their hands and a lot of proxies. They could've been using something like Tor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With