SY110: Intro to the Web: Client-Side Scripting


Intro to the Web: Client-Side Scripting

Learning Outcomes

After completing these activities you should be able to:



Web Programming with HTML and JavaScript

As part of Intro the World-Wide-Web (WWW) classes, we have covered web programming languages HTML and JS to provide a foundation into how information is processed from (inputs) and/or presented to the user (outputs). Manipulating data provided through both system and users serve a particular purpose, be it presenting information on a webpage or passing data to other systems that result in transactions or calculations. As a markup language, tags are identified by the browser to organize how data is presented by HyperText Markup Language (HTML). Starting from the top and working down, a web page is loaded once the code is received from a server. Because HTML is limited, JS can pick up where it falls short by invoking advanced programming structures and capabilities. We previously provided basic functionality into the user interface but with this lesson we are going to cover how web code is presented to the application users interact with, or the client-side.

Client-Server Model

When a user visits a website, such as https://www.archive.org, they enter a Uniform Resource Locator (URL) into the browser's address bar. The browser then sends a HyperText Transfer Protocol (HTTP) request to the server to retrieve the resource specified in the URL (e.g., a webpage). The server processes this request and responds with an HTTP response that includes the requested resource, along with a status code (such as 200 for a successful request or 404 when the resource is not found). There are multiple types of HTTP methods a client can use; GET and POST are among the most common.

Client-Server Model

(Note: The additional steps involved in making the request work, such as resolving human-readable URLs into IP addresses, will be covered later in the course.)

Activity: Viewing Browser Code

Take a look at the code used by your browser to render the page on the client-side. Open the webpage https://www.usna.edu/CyberDept/sy110/resources/student_renders/ex2.html and follow the instructions below:

For Google Chrome:

  1. Click on the vertical ellipses in the upper right corner to expand the menu and select More tools followed by Developer tools or use the shortcut Ctl+Shift+I.
  2. Ensure the Elements tab is selected and expand the HTML code to view data rendered on the webpage.
  3. Now select the Network tab and refresh the webpage, observing the time and data being loaded.
  4. Try to identify the data sources for each of the files.

For Mozilla Firefox:

  1. Click on the hamburger menu in the upper right corner to expand the menu and select More tools followed by Web Developer tools or use the shortcut Ctl+Shift+I.
  2. Ensure the Inspector tab is selected and expand the HTML code to view data rendered on the webpage.
  3. Now select the Network tab and refresh the webpage, observing the time and data being loaded.
  4. Try to identify the data sources for each of the files.

Knowledge Check: How many GET-REQUESTS were submitted by the browser when visiting the website?

Dynamic Web Pages

try clicking on the pluses!
+ the beginning
+ the middle
+ the end

The web pages primarily seen up to this point have been static web 1.0 pages. Content may look like it's changing but is done by loading different web pages. Here is a good example of a static webpage. Every link accessed loads a new web page and everyone looking at that page sees exactly the same thing. All but the most basic sites these days have dynamic content, which means that changes occur to the current page, with or without user interaction, and websites have pages that look different to different users. More complex websites, like Google Maps, are built around the idea of dynamic web content. The box on right is an example of a basic form of dynamic content. Click on the +'s and -'s and see what happens. Note that the URL address at the top of the page never changes!

Dynamic content is possible through the execution of a snippet of code called a script. The snippet of code can execute on either client machine (meaning in the web browser) or on the web server. So we can have either client-side scripting or server-side scripting. Scripts can also be either event or non-event driven. What this means is that the scripts can either run in response to user action, such as clicking on something (event driven), or can run automatically when the web page is loaded (non-event driven). The boxes with the +'s and -'s that you clicked on are event driven since you, as the user, had to take an action for the event to take place.

When thinking about whether the script is executing on the client machine or the server, there are some important considerations:

  1. Allowing code to execute, whether in response to user action or automatically, could pose a security risk. In client-side scripting, the client incurs the risk as it is running on their local machine. In server side scripting, the server incurs the risk as the script is running on the remote server.
  2. Client-side scripts only require the initial communication to GET the web page HTML file. No additional communication with the server is required. With server-side scripts, there is additional back and forth communication as your web browser tells the server to execute the script and the server then replies back with the web page changed by the result of running the script.
  3. Executing scripts costs CPU cycles. Server-side scripts cause more work for the server machine, client-side scripts cause more work for the client-side machine.

Embedding Scripts

JS is a vital web language for businesses across the world and is also why it's the most popular as websites and mobile apps rely on distributing many services for users and consumers. JS is invoked in HTML code through the use of <SCRIPT> tags in order to embed scripts, with the type attribute, which identifies the language used:

<SCRIPT type="text/javascript">...</SCRIPT>
Properties of Object Oriented Languages
Properties of Object Oriented Languages (OOL). Depiction of classes, objects, methods,
and functions in programming.

Document Object Model (DOM). The use of JS embedded scripts leverages DOMs, which is a World Wide Web Consortium (W3C) standard model and programming interface that defines HTML elements as objects, the properties of HTML elements, methods to access all HTML elements, and the events for all HTML elements. What does that mean? The HTML DOM is a standard for how to get, change, add, or delete HTML elements.

Objects in programming languages are created and referenced as you would physical objects around you. There are tables and chairs in the classroom, all of which are objects that are referred to by names. Tables and chairs comprise of parts, such as legs and surfaces, but these parts or classes are different for each of the objects. Once the tables and chairs are assembled using the appropriate classes, these objects may now be referred to with actions, called methods for executing actions, such as move the table or sit on the chair. This series of statements within the classroom now establishes a function. As such, classes define properties of objects, objects are referenced in methods for moving, copying, manipulating, and storing data associated with objects, and functions are a series of statements that perform tasks but not associated with objects, like methods would be.

The World Wide Web Consortium (W3C) is an organization that is responsible for the development of many standards for the web. HTML is one of those standards. The W3C has a lot of nice tools for learning about HTML and related standards. You can read their material on the DOM starting here.

Structuring programming languages in this way allows for easy referencing and consistent processes for developers to build applications. The primary use of DOM in JS will be document in order to leverage the use of dynamic HTML. The DOM document will accomplish the following:

Non-Event Driven Scripts

Within the document object in JS, document.write and document.location are examples that can depict the use of non-event driven scripts. These methods are not exclusive to non-event driven scripts but they will be employed in examples for event-driven scripts.

DOM: document.write

document.write sends data to HTML output and is used to insert text, elements, or a combination. Its usage and syntax uses the document object to manipulate HTML code.

With the ability to reference an object using JS, calculations can now be performed to write to a web page. The code below is an example of what can be accomplished with embedded scripts:

Every time you visit this page, the latest time remaining until graduation will be provided without any user input or changes to the HTML code. The output in the box is a result of an embedded script that calculates the time remaining based on the time the page was loaded, leveraging document.write to get the browser to render the output. The time will vary, so the time remaining will change when the page is refreshed.

We can create another version of code given the requirement and ability to code a timer that counts down without having to reload the page:
Whenever this page is refreshed, the two clocks will briefly be in sync.

More examples of DOM object use of document.write are provided, along with its code. In ex0.html, a while loop is leveraged to write GONAVY to HTML output 1,000 times. What would be a tedious task has now been simplified with a few lines of code and is useful for iterative content.


ex0.html (see how this page is rendered)   ex3.html (see how this page is rendered)
<html>
<head></head>
<body>
<script type="text/javascript">
  var iter = 0;
  while(iter < 1000)
  {
    iter = iter + 1;
    document.write("G O N A V Y ! ");   
  }
</script>
</body>
</html>
 
<html>
<head></head>
<body>
<script type="text/javascript">
  var iter = 0;
  while(iter < 1000)
  {
    iter = iter + 1;
    document.write('<span style="color: #ff0000">G O</span> <b>N A</b> V Y ! ');
  }
</script>
</body>
</html>
Short program, long web page!   Remember, document.write() allows us to insert arbitrary HTML code! So this time we've added formatting.

A key consideration for the use of embedded scripts is when they are executed. The location of the script in the HTML file determines where the code appears, replacing <SCRIPT type="text/javascript">...</SCRIPT> when rendering in the browser and reading from the top, down.

DOM: document.location

Input a JavaScript expression or statement and press enter
js>
Another method of the document object is document.location. This variable holds the URL for the current page. Enter
alert(document.location);
into the interpreter field to the right and an alert box will pop up displaying the URL for this page. Setting the variable document.location to a new string value that contains a valid URL sequence causes the browser to load that page. Try entering the following code into the interpreter:
document.location = "https://www.westpoint.edu";
If you've taken a detour and returned to this page, redirection to other websites is levergaged with the use of document.location. This is useful for redirecting users that may have bookmarked or linked an outdated page. Here's an example:
redirect.html (see how this page is rendered)
<html>
 <head></head>
 <body>
  <script type="text/javascript">
   document.location = 'https://www.westpoint.edu';
  </script>
 </body>
</html>

When hovering over the link, it will look like the site will go to the redirect.html page, but it will actually send you to another site! What happened?? Well, the link does load redirect.html but then it immediately redirects you to https://www.westpoint.edu.

HTML and email

Most email clients allow you to write and read emails with HTML formatting, not just plaintext. Combining this with JavaScript allows for some malicious possibilities. For example, HTML can automatically send you to a different website without having to click on any links! If an email client executes JS embedded code in an HTML-formatted email, we can craft it in such a way that opening the email sends the machine's browser to a malicious website. You are safer with an email client that does not execute HTML or embedded JS!

All email clients allow attachments, to include HTML files. If the recipient opens the attachment, it will be rendered by the recipient's browser and will almost certainly execute JS! Thus, leveraging document.location to redirect the recipient to a malicious page. As long as the recipient opens the attachment, we can send them to any page — automatically.

Event-driven JavaScript

Now that we have covered some common non-event driven scripts, we will learn to identify, understand, and write scripts for web pages that are event driven, meaning that the script executes when some action, typically initiated by the user, occurs. DOM methods covered will include document.getElementById, which allow us to gain access to a specific HTML field and change it after the web page has already been loaded and document.forms. There are two fundamental requirements we will cover that allow a comprehensive understanding of client-side scripting:

Leveraging events for redirection will be an important concept in cybersecurity as attackers intend to redirect targets to malicious servers they control. Once redirected, it's easy to determine browser versions being used and vulnerabilities within the application can be exploited, resulting in delivering malware to users' computers.

DOM: document.getElementById

Identifying HTML content with the id Attribute

In order to manipulate HTML elements, the tags have to be identified using the id attribute. This ability to identify a specific HTML element is the key to allowing our event driven code to modify content within a web page, providing each user with an interactive experience. Once the HTML element has been identified, the document object can be invoked.

In HTML code. The HTML element is assigned an identifier using the id attribute. Two HTML elements below have been assigned an identifier, (1) <p> is assigned foo and (2) <b> is assigned bar. Another way of stating it, the line of code below assigns the id of "foo" to the paragraph element, whereas the id of "bar" is assigned to the bold element.

<p id="foo">The <b id="bar">quick</b> brown fox jumps over the lazy dog.</p>


In JS code. The method document.getElementByID("foo") references the HTML element <p> and document.getElementByID("bar") references the HTML element <b>. The resulting value returned by this method would be referencing the content of that specific element.

Observe the changes in the text below when interacting with the buttons to change the paragraph color and the bold text. What is the expected outcome when referencing foo by clicking on the button as compared to bar?

The quick brown fox jumps over the lazy dog.

id="foo"
id="bar"

In this example, when you change the color of "foo" after changing "bar," the word "quick" inside "bar" does not change color. This occurs because "bar" has its own specific color set, which overrides the inherited color from "foo." In CSS, inheritance controls how styles are passed from parent elements to child elements. If desired, this behavior can be adjusted by modifying the CSS properties to ensure that changes to the parent element's style are reflected in its child elements.

Within JS, the object that's returned by this method can be manipulated in many ways. Every element has an .innerHTML value that stores whatever is between the start and end tags of the element. Every element also has an .style that contains values (of type string) for the many properties that affect the way an element looks in the browser. These .style properties have the ability to change the formatting of text displayed.

  .innerHTML stores whatever is between the start and end tags of the element as a string. If there are other elements nested within the string value, the .innerHTML will contain tags.

  .style.color stores the color of the text. Colors are specified as RGB byte-values in hex, so "#FF0000" references the color red.

  .style.background stores the background color.

  .style.fontFamily stores the font type. You can specify a particular font, or generic fonts like: serif, sans-serif, monospace, cursive or fantasy.

  .style.fontSize stores the size of the font. There are several variations for referencing units including pt (points), px (pixels) and em (multiple of current font-size, so 1em is the current font-size, 2em is twice the current font-size, etc).

User Interaction (Mouse Events)

The events that we're most used to in web-browsing are mouse related — specifically with clicks. Any element can be given an onclick attribute whose value is a chunk of JS code to be executed whenever the mouse is clicked within that element. Here's an example (Note that document.body is a default HTML object without having to define an id):

content   Code that makes it happen

Clicking anywhere within the bold text causes the text to go red! Refresh the page to return sanity.
 
Clicking anywhere
<b onclick='document.body.style.color="#ff0000"'>within the bold text</b>
causes the text to go red!  Refresh the page to return sanity.

Mouse Event Types

There are actually a number of mouse events that are scriptable this way via the following attributes:

  • onclick — Script to be run on a mouse click
  • ondblclick — Script to be run on a mouse double-click
  • onmousedown — Script to be run when mouse button is pressed
  • onmousemove — Script to be run when mouse pointer moves
  • onmouseout — Script to be run when mouse pointer moves out of an element
  • onmouseover — Script to be run when mouse pointer moves over an element
  • onmouseup — Script to be run when mouse button is released

Using Events for Redirection and Content Changes

The intent for learning document.getElementById in this course isn't to make interactive websites but to gain a better understanding of the cybersecurity issues associated with allowing scripting languages to run in our browser. In this section we build upon what we have learned above to better understand how redirection can be leveraged in malicious ways.

Obfuscation. What you see isn't always what you get. Because of the ability to run embedded scripts, the browser has the potential to mislead users into thinking certain actions will be conducted. Hover your cursor over the link to see what website is referenced in the status bar, then click on it to see where it actually takes you to.

Check out www.usna.edu, the Naval Academy's new home page.
The browser's status bar indicates that it will open www.usna.edu, and yet that's not what was opened! How did that happen? Here's what the HTML code for observing what happened:
<A id="foo" href="http://www.usna.edu"
  onclick="document.getElementById('foo').href='http://www.youtube.com/watch?v=dQw4w9WgXcQ';">
  www.usna.edu
</A>
Because the onclick script gets run before the browser reads the href attribute, that executes prior to the value in the href attribute. Quite sneaky, eh?

Unwitting Actions. Let's try using the other mouse events that would result in misleading users. Look at the following:
Don't click on anything and let your mouse pointer pass over the name: Billy.
Any innocuous element in a page can now be turned into a link that triggers an action whenever the mouse simply passes over it. How did we do that? Here's the code:
  Don't click on anything and let your mouse pointer pass over the name:
  <SPAN onmouseover='document.location = "https://www.westpoint.edu/"'>Billy</SPAN>.
The moral of this story is that we can easily manipulate web pages in unexpected ways.

Event-driven JavaScript to Modify Content. Let's look at an example of something we might do with event-driven JS. Here's a simple word jumble puzzle that lets us show solutions:

The interactive content   How it was done

Word Jumble Challenge:
YGANOV
show solution
 
Word Jumble Challenge: YGANOV <span id="sol"></span><br>
<b id="inst" onclick='
if (document.getElementById("inst").innerHTML == "show solution") {
  document.getElementById("sol").innerHTML = "&#8594; GONAVY";
  document.getElementById("inst").innerHTML = "hide solution";
} else {
  document.getElementById("sol").innerHTML = "";
  document.getElementById("inst").innerHTML = "show solution";
}
'>show solution</b>

DOM: document.forms

User Input on Webpages

In the JS class, the prompt(); function was used to solicit input from the user. This may be a useful way of learning about JS Input/Output (I/O) but it isn't practical or common. The use of HTML Forms are prevalent ways to solicit input from a web user. This part of the class is intended to demonstrate two learning outcomes:

  • To emphasize cybersecurity risks of failing to validate or sanitize user input prior to processing; and
  • Establish the foundation of how client-side scripts feed into server-side scripts via HTML GET request, ultimately sending data to a remote server and processing it there.
There are many HTML form input types but only five you'll need to be familiar with. Their examples are provided below, both in code format as well as how the browser renders the HTML. Click around and enter values into the input fields to observe user interaction.

  Text. Allows strings of characters to be read from the user.

  Password. Masks the characters being typed to prevent anyone viewing the screen from observing what is being entered.

  Radio. Allows the user to only select one item from a list.

  Checkbox. Allows the user to select multiple items from a list.

  Button. Allows actions to be conducted with the use of embedded scripts.

The text input type is as follows:



The password input type is as follows:



Radio Examples
radio1a radio1b radio1c radio1d
radio2a radio2b radio2c radio2d

Checkbox Example
check1 check2 check3 check4

Button Example
 
<FORM name="input_types" onsubmit="return false;">
  <p>The text input type is as follows:</p>
  <INPUT type="text" name="text_field"><br><br>

  <p>The password input type is as follows:</p>
  <INPUT type="password" name="text_pswd"><br><br>

  <h5>Radio Examples</h5>
  <INPUT type="radio" name="text_radio1">radio1a
  <INPUT type="radio" name="text_radio1">radio1b
  <INPUT type="radio" name="text_radio1">radio1c
  <INPUT type="radio" name="text_radio1">radio1d<br>
  <INPUT type="radio" name="text_radio2">radio2a
  <INPUT type="radio" name="text_radio2">radio2b
  <INPUT type="radio" name="text_radio2">radio2c
  <INPUT type="radio" name="text_radio2">radio2d

  <h5>Checkbox Example</h5>
  <INPUT type="checkbox" name="text_check1">check1a
  <INPUT type="checkbox" name="text_check1">check1b
  <INPUT type="checkbox" name="text_check1">check1c
  <INPUT type="checkbox" name="text_check1">check1d

  <h5>Button Example</h5>
  <INPUT type="button" name="submit" value="Submit" onclick="alert('Thanks for
    pushing my button!')">
  <INPUT type="reset" value="Reset">
</FORM>

In HTML code. The HTML tag <FORM>...</FORM> is used to identify the elements of the form along with the <INPUT> tag to identify any input types used. Both tags will require the name attribute. Review the HTML code in the previous example to see how the radio and checkbox input types were grouped.

In JS code. Invoking document objects in JS follows the syntax document.forms.formname.inputname.value and is identified by the HTML FORM and <INPUT attribute name defined. Based on the previous form, referencing the document object for the value a user inputs into the text input field would be document.forms.input_types.text_field.value.

Knowledge Check: What is the syntax of the JS document object that would be referenced for the value of the password input field?

Input/Output with Forms

Input types can be used to solicit user data when visiting a website, serving as a foundation for many websites. Take a moment to reflect on any websites you had recently visited, how you interacted with the webpage, and if any of them had forms. Below is a form-based I/O used to perform calculations, resulting in converting two measurements of distance:

Conversion tool:

feet = inches
A nice feature of this converter is that you can input data in either the feet or inches box, and the program is smart enough to convert in the proper direction to fill the other box. With prompt();, this would've required two separate inputs, one to specify the number and the other to specify the direction.
Here's how the HTML Form was implemented:

<FORM name="convert" onsubmit="return false;">
  <INPUT type="text" name="feet" value="0"
    onchange="var f = document.forms.convert.feet.value;
              document.forms.convert.inches.value = f*12;">
  feet =
  <INPUT type="text" name="inches" value="0"
    onchange="var i = document.forms.convert.inches.value;
              document.forms.convert.feet.value = i/12;">
  inches
</FORM>


Recall the conditional (if-else) example provided in the class lecture on providing a +/- grade based on a score. A simple form can be created to be published on the website. Design and efficiency is a factor when working with nested conditions but we'll build on the document.getElementById("grade") method to reference the INPUT type="text" name="grade" to update the field to reflect the appropriate +/- grade value.

Score:
Within this form, there are three input types defined - two text inputs and a button. Based on user input into the score field, the conditional statements would provide a string value to the grade text input. While the data being passed is only run on the client-side, bad user inputs may lead to mistakes based on the intent of the person using this tool. The number of possible entries can be large but narrowing expected values is a good place to begin limiting the inputs. This process is referred to as validation and can occur on the client-side.

 
<FORM name="grader" onsubmit="return false;">
  <INPUT type="text" name="score" maxlength="3" size="6" value="0"
  onchange="validate();">
</FORM>

<button onclick="grade(document.forms.grader.score.value);">grade</button>

<INPUT type="text" id="grade" maxlength="2" size="6">

<script>
  function grade(score) {
    if (score >= 93) {
      document.getElementById("grade").value = "A";
    } else if (score >= 90) {
      document.getElementById("grade").value = "A-";
    } else if (score >= 87) {
      document.getElementById("grade").value = "B+";
    } else if (score >= 83) {
      document.getElementById("grade").value = "B";
    } else if (score >= 80) {
      document.getElementById("grade").value = "B-";
    } else if (score >= 77) {
      document.getElementById("grade").value = "C+";
    } else if (score >= 73) {
      document.getElementById("grade").value = "C";
    } else if (score >= 70) {
      document.getElementById("grade").value = "C-";
    } else if (score >= 67) {
      document.getElementById("grade").value = "D+";
    } else if (score >= 60) {
      document.getElementById("grade").value = "D";
    } else {
      document.getElementById("grade").value = "F";
    }
    if (score < 73) {
      alert("MAPR Required");
    }
  }
</script>
The process of converting scores into grades in this client-side script uses validation to help control input values for document.forms.grader.score.value. We do this by conditional statement that checks if score is <100 or >0 or is a number. Additionally, the maxlength attribute accepted by input text is limited to three. All other conditions fail and reset score back to a value of "0" if it is not met.  
<script>
  function validate() {
    if(document.forms.grader.score.value>100 ||
        document.forms.grader.score.value<0 ||
        isNaN(document.forms.grader.score.value)) {
    alert('Invalid score');
    document.forms.grader.score.value=0;
  }
  }
</script>

Activity: Not a Phishing Site

Several techniques have been employed when designing this site. It was intended to copy a site that may seem familiar but try to observe the number of techniques employed to mislead and deceive users that visit the site. What would this look like if it were to be used in an email or text message?


Supplemental Media:

Web Development - What is Client Server Model


Review Questions:

  1. What are the two HTML methods used by a browser to process a webpage?
  2. What are the key differences with static and dynamic web pages?
  3. What are the four document methods used by JS DOMs?
  4. How are HTML tags referenced when calling a document object?
  5. What are the five HTML form input types?
  6. What are the differences between validation and sanitization?


References