While checking the local news, Sarat discovered an “income ranker” widget on a news site. He put in his monthly income, and discovered that he was in the top 0.08% richest households in India. Surprised to discover that he was a gazillionaire, Sarat took a look at the JavaScript code which ran the widget.
The function definition started with function submitmyform()
, which already looked pretty bad. Sarat looked for the block responsible for calculating the result, and found this charming anti-pattern:
if(fmval<1001){document.getElementById("totlcalc").innerHTML='<span>100</span>';return false;}
if(fmval>1000 && fmval<2001){document.getElementById("totlcalc").innerHTML='<span>92.7</span>';return false;}
if(fmval>2000 && fmval<3001){document.getElementById("totlcalc").innerHTML='<span>75.20</span>';return false;}
if(fmval>3000 && fmval<4001){document.getElementById("totlcalc").innerHTML='<span>58.70</span>';return false;}
if(fmval>4000 && fmval<5001){document.getElementById("totlcalc").innerHTML='<span>41.7</span>';return false;}
if(fmval>5000 && fmval<6001){document.getElementById("totlcalc").innerHTML='<span>31.20</span>';return false;}
/* Let's skip 100 lines */
if(fmval>99000 && fmval<100001){document.getElementById("totlcalc").innerHTML='<span>0.08</span>';return false;}
if(fmval>100000){document.getElementById("totlcalc").innerHTML='<span>0.08</span>';return false;}
Well, that was ugly, but it didn’t answer Sarat’s main question- why did the application
think he was so rich? His income was much closer to one of those first if
s than the final one. He scrolled back up a bit and looked at the validation code.
var fmval = document.calcfrm.calctxtname.value;
var iChars = "!@#$%^&*()+=-[]\\\';,./{}|\":<>?";
for (var i = 0; i < fmval.length; i++)
{
if (iChars.indexOf(fmval.charAt(i)) != -1)
{
fmval = fmval.replace(fmval.charAt(i),"");
}
}
fmval = fmval.replace(' ','').replace(' ','').replace(' ','');
if(fmval!=""){
fmval=parseInt(fmval);
}
if(isNaN(fmval)){alert("Please Enter Numeric value Only");return false;}
Despite the ugly formatting of the code, it was easy for Sarat to see what was wrong. He had entered his income out to two decimal places. The sanitizing code had its own opinion about what level of detail it expected, and decimal points weren't on the menu.