// Yahoo mail prompted me to change my password today, and redirected me to a page that kept crashing with // Javascript exceptions. So I investigated, and found some pretty crazy code. Here's a fully unobfusticated // snippet. Not sure what's my favorite part: the 14 level deep nested if statement, using eval to match // regexes, or the inexplicable lengthToDataArray. The script crashes because of a typo in line 210, and an // undefined reference in line 209. Anyone else find anything awesomely bad? Fortunately the broken script // didn't prevent me from changing my password! passwordMeter = function (e, obj) { var testResult = "weak"; var myPassword = Y.one(obj[0]).get("value"); var len = false; var letters = false; var numbers = false; var name = false; var specials = false; var repeat = false; var order = false; var testLength = function (str) { var len = str.length; if (len > 7 && len < 33) { return true; } return false; }; var testLetters = function (str) { if (str.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/)) { return true; } return false; }; var testNumbers = function (str) { var hasNumber = false; var hasLetter = false; if (str.match(/\d+/)) { hasNumber = true; } if (str.match(/[a-z].*/i)) { hasLetter = true; } return (hasNumber && hasLetter); }; var testSpecials = function (str) { var allSpecials = str; allSpecials = allSpecials.replace(/[!@#\$%^&\*?_~\(\)]*/, ""); if (allSpecials != "" && str.match(/[!,@,#,\$,%,^,&,\*,?,_,~]/)) { return true; } return false; }; var testName = function (str) { return validPassword(e, validate.password); }; var testLetterCase = function (str) { if (str.match(/[a-z,A-Z]/)) { if (!(str.match(/[A-Z]/))) { return false; } } return true; }; var updateMeter = function (strength) { bgcolor = "meterEmpty"; meterMsg = infoMessages.password_initialState; switch (strength) { case "strongest": meterMsg = infoMessages.password_strongest; boxes = 4; bgcolor = "meterGood"; break; case "strong": meterMsg = infoMessages.password_strong; boxes = 3; bgcolor = "meterGood"; break; case "mediocre": meterMsg = infoMessages.password_mediocre; boxes = 2; bgcolor = "meterFair"; break; case "weak": meterMsg = infoMessages.password_mediocre; boxes = 1; bgcolor = "meterBad"; break; case "invalid": meterMsg = infoMessages.password_invalid; boxes = 1; bgcolor = "meterBad"; break; default: meterMsg = infoMessages.password_initialState; boxes = 0; bgcolor = "meterEmpty"; break; } Y.one("#pwdmlabel").set("innerHTML", meterMsg); for (i = 1; i < 5; i++) { var meterBox = Y.one("#pwdm" + i); if (meterBox) { meterBox.set("className", ""); if (i > boxes) { bgcolor = "meterEmpty"; } meterBox.addClass(bgcolor); } } }; var results = []; if (myPassword.length > 0) { len = testLength(myPassword); letters = testLetters(myPassword); numbers = testNumbers(myPassword); specials = testSpecials(myPassword); name = testName(myPassword); letterCase = testLetterCase(myPassword); } testResult = "weak"; if (myPassword.length < 1) { testResult = "lame"; } else { if (name) { testResult = "invalid"; } else { if (!len) { testResult = "weak"; } else { if (!letterCase) { testResult = "weak"; } else { if (!len && !letters && !numbers && !specials) { testResult = "weak"; } else { if (len && !letters && !numbers && !specials) { testResult = "weak"; } else { if (len && letters && !numbers && !specials) { testResult = "weak"; } else { if (len && !letters && numbers && !specials) { testResult = "weak"; } else { if (len && !letters && !numbers && specials) { testResult = "weak"; } else { if (len && !letters && numbers && specials) { testResult = "weak"; } else { if (len && letters && !numbers && specials) { testResult = "weak"; } else { if (len && letters && numbers && !specials) { testResult = "strongest"; } else { if (len && letters && numbers && specials) { testResult = "strongest"; } else { testResult = "weak"; } } } } } } } } } } } } } updateMeter(testResult); }; validPassword = function (e, obj) { var errorType; var myPassword = Y.one(obj[0]).get("value"); var oldPassword = Y.one("#opw").get("value"); var fname = config.fname.get("value"); var lname = config.lname.get("value"); var yid = config.yid.get("value"); if (myPassword === "") { hasError = true; errorType = "empty"; } else { hasError = false; } if (!hasError && myPassword) { var numCheck = false; var splCheck = false; if (myPassword.match(/\d+/)) { numCheck = true; } if (myPassword.match(/[!,@,#,\$,%,^,&,\*,?,_,~]/)) { splCheck = true; } if (!(numCheck || splCheck)) { hasError = true; errorType = "alphaonlypwd"; } if (!numCheck) { hasError = true; errorType = "nonumber"; } } if (!hasError && myPassword) { if (!(myPassword.match(/[A-Z]/))) { hasError = true; errorType = "nouppercasepwd"; } } if (!hasError && myPassword && myPassword.length > 7 && myPassword.length < fuzzyLengthUpperLimit) { var validationStatus = isSimmilar(fname, lname, myPassword); validationStatus = (validationStatus === 0 ? true : false); Y.fire("isSimilarToName", validationStatus); if (!validationStatus) { hasError = true; errorType = "pwdsimilartoname"; } } if (!hasError && myPassword && oldPassword) { var validationStatus = isSimmilarLD(myPassword, oldPassword); validationStatus = (validationStatus === 1 ? true : false); Y.fire("isSimilarToPrevPassword", validationStatus); if (!validationStatus) { hasError = true; errorType = "pwdsimilartoold"; } } var len = myPassword.length; if (len < 8 || len > 32) { hasError = true; writeLog("validPassword says: " + hasError); errorType = "pwdwronglength"; } var errorArray = new Array(); var regex = ""; var original = myPassword; var re = ""; var lengthArray = new Array(); var lengthToDataArray = new Array(); if (fname != "") { lengthArray[lengthArray.length] = fname.length; lengthToDataArray[fname.length] = fname; } if (lname != "") { lengthArray[lengthArray.length] = lname.length; if (lengthToDataArray[lname.length] != undefined) { lengthToDataArray[lname.length] += "|" + lname; } else { lengthToDataArray[lname.length] = lname; } } if (yid != "") { lengthArray[lengthArray.length] = yid.length; if (lengthToDataArray[yid.length] != undefined) { lengthToDataArray[yid.length] += "|" + yid; } else { lengthToDataArray[yid.length] = yid; } } var pwd = "password"; lengthArray[lengthArray.length] = pwd.length; if (lengthToDataArray[pwd.length] != undefined) { lengthToDataArray[pwd.length] += "|" + pwd; } else { lengthToDataArray[pwd.length] = pwd; } lengthArray.sort(function (a, b) { return b - a; }); for (var i in lengthArray) { if (lengthToDataArray[lengthArray[i]] != undefined && lengthToDataArray[lengthArray[i]] == null) { continue; } else { if (lengthToDataArray[lengthArray[i]] != undefined && lengthToDataArray[lengthArray[i]] != null) { re += lengthToDataArray[lengthArray[i]] + "|"; lengthToDataArray[lengthArray[i]] = null; } } } re = eval("/" + re + "/gi"); myPassword = myPassword.replace(re, ""); if (myPassword.length < 3) { var pwdre = /password/gi; if (original) { if (pwdre.test(original)) { hasError = true; errorType = "pwdcontainspwdword"; } } if (fname) { var fnamere = eval("/" + escapeRegEx(fname) + "/gi"); if (fnamere.test(original)) { hasError = true; errorType = "pwdcontainsfname"; } } if (lname) { var lnamere = eval("/" + escapeRegEx(lname) + "/gi"); if (lnamere.test(original)) { hasError = true; errorType = "pwdcontainslname"; } } if (yid) { var yidre = eval("/" + yid + "/gi"); if (yidre.test(original)) { hasError = true; errorType = "pwdcontainsyid"; } } } else { if (fname != "" && myPassword.indexOf(fname) != -1) { hasError = true; errorType = "pwdcontainsfname"; } if (lname != "" && myPassword.indexOf(lname) != -1) { hasError = true; errorType = "pwdcontainslname"; } if (yid != "" && myPassword.indexOf(yid) != -1) { hasError = true; errorType = "pwdcontainsyid"; } if (myPassword.indexOf(pwd) != -1) { hasError = true; errorType = "pwdcontainspwdword"; } } var myElementMsg = Y.one(obj[1] + "ErrorMsg"); var myParent = Y.one(obj[1] + "Field"); if (hasError === true) { writeLog("error type: " + errorType); handleError(myParent, myElementMsg, errorCode[errorType]); writeLog("Found Error, final " + obj[0]); } else { clearError(myParent, myElementMsg); } return hasError; }; escapeRegEx = function (text) { return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); };