info343/lectures/security-browser-compatibility/files/c/8ball.js

// 8ball.js
// 7 Dec 2011
// JavaScript file loaded using Cross-Site Scripting injection
// INFO 343 Autumn 2011, Morgan Doocy
// (from CSE 190 M, Marty Stepp)

// when the page has finished loading...
document.observe('dom:loaded', function() {
   // ...attach a 'click' event handler to the ask button
   $('ask').observe('click', ask);
   
   // was a 'question' parameter passed?
   var matches = location.search.match(/question=([^&]+)/);
   if (matches) {
      // it was; decode the value in the URL
      var question = decodeURI(matches[1]);
      
      // sanitize it for HTML context
      question = question.replace(/</g, '&lt;');
      question = question.replace(/>/g, '&gt;');
      question = question.replace(/'/g, '&#x27;');
      question = question.replace(/"/g, '&quot;');
      
      // inject it into #questionoutput and #questioninput
      $('questioninput').value = $('questionoutput').innerHTML = question;
   } else if (matches = location.search.match(/imgfile=([^&]+)/)) {
      // look for an 'imgfile' parameter as well: filename
      // illustrates vulnerability in a different context: could pass 'empty.gif" onload="...' to exploit
      var imgfile = decodeURI(matches[1]);
      
      // sanitize it for HTML context
      question = question.replace(/</g, '&lt;');
      question = question.replace(/>/g, '&gt;');
      question = question.replace(/'/g, '&#x27;');
      question = question.replace(/"/g, '&quot;');
      
      // compose img tag HTML string with sanitized parameter
      var imgcode = '<img src="' + imgfile + '" alt="some descriptive content" />';
      $('questionoutput').innerHTML = imgcode;
   } else {
      // initially hide the response area (if there was no parameter passed)
      $('response').hide();
   }
});

// displays the question asked, and initiates an AJAX request to fetch possible responses
function ask() {
   var question = $('questioninput').value;
   $('questionoutput').innerHTML = question;
   $('response').show();
   $('answer').hide();
   new Ajax.Request('sayings.txt', {
      method: 'get',
      onSuccess: gotResponse,
      onFailure: ajaxFailure,
      onException: ajaxFailure
   });
}

// list of answers has come back from server; select a random response make it appear
function gotResponse(ajax) {
   var sayings = ajax.responseText.split(/\r?\n/);
   var rand = Math.floor(Math.random() * sayings.length);
   $('answer').innerHTML = sayings[rand];
   $('answer').appear();
}

// called in case of request failure or JavaScript/DOM exception
function ajaxFailure(ajax, exception) {
   alert("Error making Ajax request:" + 
            "\n\nServer status:\n" + ajax.status + " " + ajax.statusText + 
            "\n\nServer response text:\n" + ajax.responseText);
   if (exception) {
      throw exception;
   }
}