Exam 2022-10-20

Here is the exam from 2022-10-20.


Start by reading through all questions.

PETER HAS GOT A COLD and won't visit the exam. If you find any question unclear, ask an exam supervisor (tentavakt in Swedish) to call him, and he will try to clarify.

Max score is 30 points:

  • For grade 3, 40% of max score (12 points) is required
  • For grade 4, 60% of max score (18 points) is required
  • For grade 5, 80% of max score (24 points) is required

You are not allowed to use any aids except:

  • The computer you sit at to only answer the questions on this exam
  • A dictionary to translate to/from English from/to your native language
  • Pen and paper to sketch with (should not be submitted)

Write your answers in either English or Swedish. If you write your answers in Swedish, make sure to not introduce any translation confusement. Write proper sentences (spelling, upper/lower case characters, punctuation, etc.). Answers that do not do this good enough/are vague/are not understandable will not receive full score on the questions.

Answers that are more or less copies of sample answers given to you or copies of text found somewhere else will be rewarded 0 points. Use your own words to answer the questions.

Good luck!

HTTP

Question 1 (1p)

Question

Name the method one should use in HTTP when the request is about:

  1. Deleting a resource
  2. Retrieving a resource
  3. Creating a new resource

Note: This question is about HTTP when used properly, and has nothing to do with HTML, web browsers, nor websites.

You will get:

  • 0.33 points for each correct name (spelling must be correct)

Sample answer

  1. DELETE
  2. GET
  3. POST

Marking guidelines

  • 0.33 points for each correct name (spelling must be correct)

Question 2 (1p)

Question

Give an example of an HTTP request where you need to use the Content-Type header. Your answer is expected to be an HTTP request with as many details as you know.

Note: This question is about HTTP when used properly, and has nothing to do with HTML, web browsers, nor websites.

Sample answer

  • Method: POST
  • URI: /movies
  • Content-Type: application/x-www-form-urlencoded
  • Content-Length: 19
  • Body: title=Shrek&year=2001

Marking guidelines

  • 0.25 points for a valid method
  • 0.25 points for a valid URI
  • 0.25 points for one relevant header name with a relevant value
  • 0.25 points for valid body
  • Point reduction for small mistakes:
    • -0.1 points for header value wrong
    • -0.1 points for body in wrong format

Question 3 (1p)

Question

Explain why the URI /get-all-movies is considered a bad URI in HTTP.

Note: This question is about HTTP when used properly, and has nothing to do with HTML, web browsers, nor websites.

Sample answer

In HTTP, the URI should only identify which resource(s) the request is about. It should not contain the get- part in this example, because the method should be used to indicate what to do with the resource(s) (e.g. GET to retrieve it/them).

Marking guidelines

  • 1 point for a valid justification for why the given URI is bad
  • Point reductions for saying something more that is wrong:
    • -0.5 points for saying it's bad because - is used in the URI

OR:

  • 0.75 points for suggesting that /movies is better, but with an incorrect justification (for example /get-all-movies is too long)

OR:

  • 0.5 points for an answer that is on the right track but a bit vague

Question 4 (1p)

Question

Write the HTTP status code for the following reason phrases:

  1. Bad Request
  2. Not Found
  3. Internal Server Error
  4. OK

Note: This question is about HTTP when used properly, and has nothing to do with HTML, web browsers, nor websites.

You'll get:

  • 0.25 points for each correct answer

Sample answer

  1. 400
  2. 404
  3. 500
  4. 200

Marking guidelines

  • 0.25 points for each correct answer

HTML

Question 5 (1p)

Question

Place the lines of code below in such order that they form a valid HTML5 document (only place one line of code in each box).

  • <head>
  • <h1>Welcome!</h1>
  • </body>
  • <title>Welcome!</title>
  • <!DOCTYPE html>
  • </html>
  • </head>
  • <html>
  • <body>

Note: All must be correct to get points on this question.

Sample answer

<!DOCTYPE html>
<html>
    <head>
        <title>Welcome!</title>
    </head>
    <body>
        <h1>Welcome!</h1>
    </body>
</html>

Marking guidelines

  • 1 point for all in correct order

Question 6 (1p)

Question

Write the name of one HTML tag that always causes the web browser to send an HTTP GET request when the user clicks on it.

Note: Just write the name of the tag; do not include < and >.

Sample answer

  • a

Marking guidelines

  • 1 point for a valid tag name

Question 7 (1p)

Question

Write the name of one HTML tag that always causes the web browser to send an HTTP GET request when the web browser receives the HTML code for that tag.

Note: Just write the name of the tag; do not include < and >.

Sample answer

  • img

Marking guidelines

  • 1 point for a valid tag name

Question 8 (2p)

Question

Name the HTML tag you would use to mark some text as:

  1. a paragraph
  2. the title of a main chapter on the webpage/the HTML document
  3. the main content on the webpage/the HTML document
  4. a list item in a list

Note: Just write the name of the tag; do not include < and >.

You'll get:

  • 0.5 points for each correct answer (spelling needs to be correct)

Sample answer

  1. p
  2. h1
  3. main
  4. li

Marking guidelines

  • 0.5 points for each correct answer (spelling needs to be correct)

Question 9 (1p)

Question

If a user comes to a website with the form below and submits it without making any changes to it, what would the body of the request look like? Write the body as your answer.

<form action="/login" method="POST">
   Username: <input type="text" name="un" value="James">
   Password: <input type="text" name="pw" value="Bond">
   <input type="submit" value="Login!">
</form>

Sample answer

un=James&pw=Bond

Marking guidelines

  • 0.5 points for correct un name and value (James)
  • 0.5 points for correct pw name and value (Bond)
  • Point reductions for errors:
    • -0.1 points for surrounding value with quotes
    • -0.25 points for including /login? in the body
    • -0.5 points for using another data format than un=James&pw=Bond (such as JSON)

CSS

Question 10 (1p)

Question

Name and describe 2 different CSS properties of your choice. For each, provide also an example of a value it can have, and explain the result of using the property with that value.

Sample answer

The CSS property color determines which color the text should have. For example, the value red would make the text red.

The CSS property font-size determines how big the text should be. For example, the value 16px would make the text 16 pixels big.

Marking guidelines

  • 1 point for an answer that is largely correct
  • Point reductions for errors:
    • -0.5 points for only one good declaration
    • -0.25 points for no description of the result of applying the value to the property

Question 11 (1p)

Question

Explain what a media query can be used for in CSS.

Sample answer

A media query can be used to conditionally apply CSS rules based on properties of the device the webpage is being displayed on (for example based on how big the screen is).

Marking guidelines

  • 1 point for a correct explanation

Question 12 (1p)

Question

Here is some CSS code:

div#hello .p{
  width: 50%;
}

Write HTML code that contains a match for the CSS selector in the code above. Write as little HTML code as possibly (don't write any extra elements or attributes that are not needed).

Note: You should only write the HTML code found in the <body> element (including the <body> element), you should not write the code for an entire HTML document.

Sample answer

<body>
    <div id="hello">
        <span class="p">I'm selected!</span>
    </div>
</body>

Marking guidelines

  • 0.5 points for <div id="hello"> in <body>
  • 0.5 points for <X class="p"> in <div id="hello">
  • Point reductions for errors:
    • -0.1 points for each unnecessary HTML element
    • -0.1 points for each unnecessary HTML attribute

Question 13 (1p)

Question

Write a CSS selector that selects the element in the HTML code below that contains the text SELECT ME. The selector should select only that element, and no other.

<body>
    <p id="p1">Here is <span>some</span> text.</p>
    <p class="c1">Here is some more text <span>SELECT ME</span>.</p>
    <p>Here is <span>some other</span> text.</p>
    <div class="c1">Here is <span>some additional</span> text.</div>
</body>

Sample answer

p.c1 span

Marking guidelines

  • 1 point for an answer that works

Website

Question 14 (2p)

Question

Explain how a middleware is implemented in Express. Don't explain how a specific middleware is implemented, just give a general description, so others that would like to implement their own middleware in Express know how to do it.

Sample answer

A middleware in Express is implemented as a function. The function will be called each time the Express application receives an HTTP request. When it's called, it will be passed 3 arguments:

  • request, which is an object containing information about the HTTP request that is being received
  • response, which is an object containing information about the HTTP response that should be sent back to the client
  • next, which is a function one should call if the next middleware in the Express application should be invoked

Marking guidelines

  • 0.5 points for function
  • 0.5 points for req/request parameter
  • 0.5 points for res/response parameter
  • 0.5 points for next parameter

OR:

  • 0.5 points for mentioning the middleware is passed to expressAppObject.use()
  • 0.5 points for a general description of how a middleware works without mentioning any details about how a middleware is implemented in Express

Question 15 (1p)

Question

Explain the difference between using a double curly bracket expression and a triple curly bracket expression in Handlebars.

Sample answer

When using a triple curly bracket expression in Handlebars, the text from the expression will be inserted as it is.

When using a double curly bracket expression in Handlebars, the characters in the text from the expression that has special meaning in HTML (<, >, ...) will be replaced by their character entities (&lt;, &gt;, ...).

Marking guidelines

  • 1 point for explaining the difference

OR:

  • 0.5 points for saying something that is on the right track, such as triple curly brackets is more secure/protects against XSS), or being a bit vague about the actual difference

Security

Question 16 (1p)

Question

Alice has been told by her boss to create a website where users can create their own accounts by entering their email and a password. In case users forget their passwords, Alice's boss wants the website to have a page where the user can enter the same email address that was used when creating the account, and the website would then send an email with the user's password to the user.

Alice says this is a very bad idea, and she's right. Explain why Alice is right.

Sample answer

For that functionality to work, the passwords on the website needs to be stored in plain text. That is very bad, because if a hacker manages to hack the database, he can see all users' passwords. It's better to store the hash values of the users' passwords, and not have that functionality.

Instead of having this functionality, most websites sends a link to the user's email that leads to a page where the user can enter a new password instead. This way, passwords never needs to be stored in plain text.

Marking guidelines

  • 1 point for explaining passwords should never be stored in plain text (neither in a database nor in an email)
    • -0.25 points for saying something more that is wrong or not explained

Question 17 (1p)

Question

Explain why storing the information isLoggedIn=true in a cookie is a bad idea.

Sample answer

Since cookies are stored on the client, any user can create and change them without the server telling them to do so. The cookie in the question is obviously intended to be used to remember that a user has logged in, but there is nothing stopping a bad user (hacker) from creating her own cookie with that information without having logged in. When the server receives requests with that cookie, it would think the user has logged in before, but she hasn't.

So this is not a secure way to remember that a user has logged in.

Marking guidelines

  • 1 point for correct explanation (users can create/change cookies manually)
  • Point reductions:
    • -0.1 points for including irrelevant things to the question, such as sessions
    • -0.1 points for saying something like cookie id (unclear what that is)

OR:

  • 0.4 points for saying something like cookies remain in the web browser after the user is done using the website, so other users using the web browser later would be logged in too (not really a problem; could use a short-lived cookie, and even so, the big problem (the user create her own cookie) still exists)

OR:

  • 0.25 points for answers not indicating that a hacker can create/change her own cookie, but saying something like:
    • it's insecure
    • anyone has access to cookies
    • hackers can come over cookies

Question 18 (2p)

Question

On a website where the admin can create blogposts, an SQLite table is used to store them. The table looks like this (content is not shown, since that one is quite long, and not all rows are shown):

idtitlecontentisPublished
1HTML is fun!...1
2CSS is fun too!...0
3JS is most fun!...0

The idea is that a user should only be able to read the blogposts that have the value 1 for isPublished.

When receiving an HTTP request to send back a blogpost with a specific id, it is handled like this:

app.js

app.get('/blogposts/:id', function(request, response){
    
    const id = request.params.id
    
    const query = 'SELECT * FROM blogposts WHERE isPublished = 1 AND id = '+id
    
    db.get(query, function(error, blogpost){
        // Let us assume no database error occurred, so we ignore that.
        
        const model = {
            blogpost
        }
        
        response.render('blogpost.hbs', model)
        
    })
    
})

views/blogpost.hbs

<h1>{{blogpost.title}}</h1>
<div>{{blogpost.content}}</div>

As your answer, write a URL a hacker can send to read a blogpost that hasn't been published yet (for example a URL that would send back the blogpost with id 2).

Sample answer

/blgoposts/-1 OR id=2

Marking guidelines

  • 2 points for an answer that largely works
  • -0.5 points for each error in an answer that almost works, such as:
    • /blogposts/ missing
    • No value for the id field in the query is provided, e.g. /blogposts/OR id=2
    • Quotes are used, e.g. /blogposts/"-1 OR id=2"
    • Wrong operator is used, e.g. /blogposts/-1 & id=2 (only -0.1 points for ||)
    • Using an extra WHERE

Note

The answer /blogposts/1 OR id=2 is really not correct, because that could send back the blogpost with id 1, which has been published, and the task was to write a URL to send back a blogpost that hasn't been published, but these type of answers has been accepted anyway.

Question 19 (1p)

Question

Bob claims encoding and encrypting is the same thing. Alice points out that there is one very important difference between them. Which difference is that?

Sample answer

Encoding is about representing data in another format, such as representing characters as numbers (e.g. A as 65, B as 66, etc.). How something has been encoded in not a secret, and anyone can decode the encoded data to obtain the original data.

Encrypting is about hiding the meaning of data, so others can't read it even if they can see it. To read encrypted data, it needs to be decrypted, which only the receiver of the encrypted data should be able to do.

Marking guidelines

  • 1 point for pointing out the difference

OR:

  • 0.5 points for explaining what encoding is
  • 0.5 points for explaining what encrypting is

Question 20 (1p)

Question

Bob claims encryption and hashing are the same thing. Alice points out that there is one very important difference between them. Which difference is that?

Sample answer

Encryption is designed to be reversible (if you have encrypted a message, you can later decrypt it to obtain the original message). Hashing on the other hand is designed to be very hard (optimally impossible) to reverse (only available method is brute-force).

Marking guidelines

  • 1 point for pointing out the difference (encryption is designed to be reversible, hashing is not)
  • -0.25 points for saying something that is not correct

OR:

  • 0.5 points for explaining what encryption is
  • 0.5 points for explaining what hashing is
  • -0.25 points for saying something that is not correct

Note

Many students write that hash values consist of random characters/hashing is random. That is not the case; encryption and hashing are both deterministic, and you always end up with the same encrypted value/hash value for the same input as long as you use the same encryption/hashing algorithm.

What can be OK to write is that the hash value consists of characters that looks random to humans, or similar.

Database

Question 21 (1p)

Question

Below is the table humans found in an SQLite database (not all rows are shown).

idnameage
1Alice10
2Bob20
3Claire15

Write an SQL query that sets age to 18 for all humans that currently has an age lower than 18.

Note: Don't use placeholders, like ?, in your query. You don't need to worry about SQL injections, since this is a pure database question, and has nothing to do with web applications.

Sample answer

UPDATE humans SET age = 18 WHERE age < 18

Marking guidelines

  • 1 point for an answer that is largely correct
  • Point reductions for small mistakes:
    • -0.1 points for putting numbers in quotes
    • -0.1 points for using extra words that shouldn't be there, such as:
      • FROM
      • *
      • TABLE
    • -0.1 points for using wrong words, such as:
      • TO instead of SET
      • LESS THAN instead of <
    • -0.1 points for having the wrong order of the SET clause and the WHERE clause
    • -0.5 points for not having a WHERE clause at all

OR:

  • 0.75 points for an answer that has the UPDATE humans part wrong, but otherwise is correct, like:
    • SELECT * FROM humans SET age = 18 WHERE age < 18
    • SET age = 18 FROM humans WHERE age < 18

OR:

  • 0.25 points for an answer that do contain most relevant parts but in wrong order/use the wrong keywords/syntax, like:
    • SELECT * FROM humans WHERE age<18 and SET age = 18
    • SELECT * FROM humans WHERE age = <18 UPDATE age = 18

Question 22 (1p)

Question

Below is the table humans found in an SQLite database (not all rows are shown).

idnameage
1Alice10
2Bob20
3Claire15

Write an SQL query that deletes all humans with the name Bob.

Note: Don't use placeholders, like ?, in your query. You don't need to worry about SQL injections, since this is a pure database question, and has nothing to do with web applications.

Sample answer

DELETE FROM humans WHERE name = "Bob"

Note: In SQLite, = and == both means to compare values, so either works in this case.

Marking guidelines

  • 1 point for an answer that is largely correct
  • Point reductions for small mistakes:
    • -0.1 points for not surrounding Bob with quotes
    • -0.1 points for using extra words that shouldn't be there, such as:
      • *
      • (id, name, age)
    • -0.1 points for missing word, such as:
      • FROM
      • WHERE
    • -0.1 points for using the wrong word, such as:
      • if instead of WHERE
    • -0.1 points for not using the name field in the WHERE clause
    • -0.1 points for writing things in wrong order, e.g. name="Bob" before FROM humans
    • -0.2 points for query not including the name of the table (humans)
    • -0.4 points for using the wrong WHERE clause

JavaScript

Question 23 (1p)

Question

Implement the JavaScript function getSumBetween(firstInt, lastInt), that receives two integers as argument and returns the sum of the integers between them (including the integers themselves).

Sample usage:

getSumBetween(5, 7) // --> 18 (5 + 6 + 7)
getSumBetween(-1, 2) // --> 2 (-1 + 0 + 1 + 2)
getSumBetween(8, 8) // --> 8

You can assume firstInt always is lower than lastInt.

Sample answer

function getSumBetween(firstInt, lastInt){
    
    let sum = 0
    
    for(let i=firstInt; i<=lastInt; i++){
        sum += i
    }
    
    return sum
    
}

Marking guidelines

  • 1 point for an answer that largely works
  • Point reduction for small mistakes:
    • -0.5 points for bad loop
    • -0.5 points for wrong result
    • -0.5 points for syntax errors
    • -0.5 points for not initializing the counter
    • -0.5 points for not retuning a value
    • -0.5 points for using arrays wrong

Question 24 (1p)

Question

Implement the JavaScript function containsNegativeNumber(numbers), that receives an array with numbers and returns:

  • true if one or more numbers in the array is less than 0
  • false otherwise

Sample usage:

containsNegativeNumber([3, 7, 1, 8]) // --> false
containsNegativeNumber([-99]) // --> true
containsNegativeNumber([0]) // --> false
containsNegativeNumber([4, 6, -2, -6, 14]) // --> true

Sample answer

function containsNegativeNumber(numbers){
    
    for(const number of numbers){
        if(number < 0){
            return true
        }
    }
    
    return false
    
}

Marking guidelines

  • 1 point for an answer that largely works
  • Point reduction for smaller mistakes:
    • -0.5 points for misplaced return statement
    • -0.5 points for bad condition
    • -0.5 points for doing strange (and useless) things (such as adding all the numbers of the array)
    • -0.5 points for not knowing how to write length
    • -0.5 points for missing the keyword function missing

Question 25 (2p)

Question

In JavaScript, a book with a title and a number of pages can be represented as an object like this:

const book = {
    title: "Alice's Adventures in Wonderland",
    numberOfPages: 117
}

Implement the function getNumberOfLongBooks(books), which receives an array with book objects and returns the number of books that contains 100 or more pages.

Sample usage:

getNumberOfLongBooks([
    {title: "Book a", numberOfPages: 50},
    {title: "Book b", numberOfPages: 150},
    {title: "Book c", numberOfPages: 120},
    {title: "Book d", numberOfPages: 10},
    {title: "Book e", numberOfPages: 300},
    {title: "Book f", numberOfPages: 500},
    {title: "Book g", numberOfPages: 1000},
]) // --> 5

Sample answer

function getNumberOfLongBooks(books){
    
    let numberOfLongBooks = 0
    
    for(const book of books){
        if(100 <= book.numberOfPages){
            numberOfLongBooks += 1
        }
    }
    
    return numberOfLongBooks
    
}

Marking guidelines

  • 2 points for an answer that largely works
  • Point reduction for smaller mistakes:
    • -0.5 points for not returning an integer
    • -0.5 points for returning more than one value
    • -0.5 points for incorrectly written loop
    • -0.5 points for not increasing the counter by 1
    • -0.5 points for not having an if condition for the books' number of pages
    • -0.5 points for missing the keyword function missing

Question 26 (1p)

Question

Alice has created the function getMovieById(), which asynchronously fetches the movie resource with the given id from a database (in this case we assume the communication with the database always works, so we don't need to worry about error handling). Sample usage with id 7:

getMovieById(7, function(movie){
    // The "movie" parameter is an object that could look like this:
    // {id: 7, title: "Shrek"}
})

Implement the function getTwoMoviesByIds(), which receives the id of two movies, and should fetch them both from the database (using the getMovieById() function) and sends them back to the caller through a callback function. Sample usage with id 7 and 5:

getTwoMoviesByIds(7, 5, function(firstMovie, secondMovie){
    // The "firstMovie" parameter is an object that could look like this:
    // {id: 7, title: "Shrek"}
    // The "secondMovie" parameter is an object that could look like this:
    // {id: 5, title: "Titanic"}
})

Sample answer

function getTwoMoviesByIds(id1, id2, callback){
    
    getMovieById(id1, function(firstMovie){
        
        getMovieById(id2, function(secondMovie){
            
            callback(firstMovie, secondMovie)
            
        })
        
    })
    
}

Marking guidelines

  • 1 point for an answer that largely works (must be nested calls to getMovieById())
  • Point reductions for small mistakes:
    • -0.25 points for callback({firstMovie, secondMovie})

OR:

  • 0.25 points for having the signature of the function correct (e.g. function getTwoMoviesByIds(id1, id2, callback){ ... })