Exam 2023-08-16
Here you find sample answers and marking guidelines to the questions on the exam 2023-08-16.
Peter will not visit the exam. If you find any question unclear, ask an exam supervisor (tentavakt in Swedish) to call Peter, 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 enter answers to 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:
- Deleting a resource
- Updating a resource
- 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
DELETE
PUT
POST
Marking guidelines
- 0.33 points for each correct name (spelling must be correct)
Question 2 (1p)
Question
Explain why the URI /movies/search?title=Bond
(that identifies all movies whose title contains the word/character sequence Bond
) 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 resources. It should not contain verbs, such as search
, so the URI in this case should rather be /movies?title=Bond
.
Marking guidelines
- 1 point for
search
should not be in the URI
Question 3 (1p)
Question
Name an HTTP header of your choice, explain what it represents/means, show a sample value it can have, and explain how that sample value should be interpreted/what it means.
Note: This question is about HTTP when used properly, and has nothing to do with HTML, web browsers, nor websites.
Sample answer
The HTTP header Content-Type
can be used in HTTP requests and responses, and it indicates in which data format the body of the request/response is written in. For example, the value application/json
means the body of the request/response is written in JSON format.
Marking guidelines
- 0.25 points for name
- 0.25 points for explanation
- 0.25 points for sample value
- 0.25 points for explanation of sample value
Question 4 (1p)
Question
Explain when the server should send back the status code 400
in an HTTP response, and when it should send back the status code 500
.
Note: This question is about HTTP when used properly, and has nothing to do with HTML, web browsers, nor websites.
You'll get:
- 0.5 points for each correct answer
Sample answer
The server should send back the status code 400
when there is something wrong with the request, for example when the data in the request contains validation errors.
The server should send back the status code 500
when there is nothing wrong with the request, but something is wrong on the server that prevents it from carrying out the request, for example if it needs to read data from a database, but it currently can't communicate with the database.
Marking guidelines
- 0.5 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).
<h1>Welcome!</h1>
<!DOCTYPE html>
</body>
</head>
<body>
<title>Welcome!</title>
<head>
</html>
<html>
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
Name the attribute <a>
elements can have that indicates which page the user should come to when the user clicks on the element.
Sample answer
href
Marking guidelines
- 1 point for correct answer
- -0.25 points for answering with something more than just the attribute name that is wrong or makes it unclear what your answer is
Question 7 (1p)
Question
What type of HTTP request (the name of the method) does the web browser send when it receives the HTML code for an <img>
element that contains the src
attribute?
Sample answer
GET
Marking guidelines
- 1 point for correct method name
Question 8 (2p)
Question
Name 3 different inline elements in HTML.
Note: Just write the name of the tag; do not include <
and >
.
Note: Writing inline-block elements is also OK, but not block elements.
You'll get:
- 0.66 points for each correct answer (spelling needs to be correct)
- Only 0.5 points if spelling is wrong
Sample answer
a
span
i
Marking guidelines
- 0.66 points for each correct answer (spelling needs to be correct)
- Only 0.5 points if spelling is wrong
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 URI of the request look like? Write the URI as your answer.
<form action="/sum" method="POST">
Number 1: <input type="number" name="x" value="123">
Number 2: <input type="number" name="y" value="456">
<input type="submit" value="Compute sum!">
</form>
Sample answer
/sum
(Since the method
is POST
, the web browser will send a POST request, and pass the data from the form in the body of the request (x=123&y=456
). The data is only passed in the querystring of the URI if the method
is GET
)
Marking guidelines
- 1 point for correct answer
Question 10 (1p)
Question
Name one HTML tag of your choice that is valid to write in the <head>
element in addition to <title>
.
Note: Just write the name of the tag; do not include <
and >
.
Sample answer
link
Marking guidelines
- 1 point for a valid tag
CSS
Question 11 (1p)
Question
Name and describe 2 different CSS properties of your choice except color
and width
. 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 background-color
determines which background color the element should have. For example, the value red
would give the element a red background.
The CSS property font-size
determines how big the text in the element should be. For example, the value 16px
would make the text in the element 16 pixels big.
Marking guidelines
- 0.125 points for each valid property name
- 0.125 points for each correct property description
- 0.125 points for each valid sample value
- 0.125 points for each correct sample value description
Question 12 (1p)
Question
What color will the text in the paragraph in the HTML code below have?
<style>
.p{
color: brown;
}
p{
color: pink;
}
#p{
color: white;
}
</style>
<p id="p" class="p">Some text.</p>
Sample answer
white
Marking guidelines
- 1 point for a correct answer
Question 13 (1p)
Question
Here is some CSS code:
div p #a.b{
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>
<p>
<span id="a" class="b">I will be matched!</span>
</p>
</div>
</body>
Marking guidelines
- 1 point for an answer that is correct/close to correct
- Point deduction for small errors in close to correct answers:
- -0.25 points for missing
<body>
- -0.25 points for putting
id
and/orclass
on wrong element<p>
- -0.25 points for missing an element in
<p>
- -0.25 points for missing
Question 14 (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>
<div>Here is <span class="p">SELECT ME</span> some text.</div>
<div>Here <span>is some</span> text.</div>
<div>Here <i class="p">is some</i> text.</div>
<p>Here <span class="p">is some</span> text.</p>
</body>
Sample answer
div span.p
Marking guidelines
- 1 point for an answer that works
- 0.5 points for
div span .p
Website
Question 15 (2p)
Question
Explain what a session is, give one example of what it can be used for, and explain how sessions can be implemented (in general, and not in a specific framework/library/package).
Sample answer
A session is a collection of values the server wants to remember about a client/user that is stored on the server. They can for example be used to remember if the user has logged in on the website or not.
The sessions can for example be stored in a database on the server. Each session gets it's own id (known as the session id), which should be hard to guess (so a hacker can't guess other users' session ids), so they are usually long strings of random characters. When a user starts using the website, the server can insert a new post in the database that contains the information the server wants to remember about the user together with a new session id.
The server can then send back the session id in a cookie in the response to the user, and the user should then send back this cookie to the server in all requests it sends to the server in the future. When the server receives these request, it can fetch the session from the database with the session id from the cookie in the request, and that way read out the information it wanted to remember about the user.
Marking guidelines
- 0.5 points for what a session is (collection of values/information to remember about a user)
- 0.5 points for example
- 1 points for implementation details (session id + stored on server + cookie)
Question 16 (1p)
Question
Explain the difference between a webpage and a website.
Sample answer
A webpage is a single HTML document that can be shown in a web browser. All such HTML documents part of the same domain constitutes a website.
Marking guidelines
- 0.5 points for explaining webpage
- 0.5 points for explaining website (multiple webpages)
Question 17 (1p)
Question
Name two different middlewares one can add to an Express application, for example two middlewares you have used in the application you built in your project work, and briefly explain what they do.
Sample answer
express.urlencoded()
(previouslybodyParser.urlencoded()
): A middleware that makes it possible for us to access the body in HTTP requests usingrequest.body
(if it's written in the data formatapplication/x-www-form-urlencoded
)expressSession()
: A middleware that makes it possible for us to userequest.session
to access the user's session
Marking guidelines
- 0.25 points for each name
- 0.25 points for each explanation
Security
Question 18 (1p)
Question
On a properly implemented website, is it likely that a user can get the session id 10
? Justify your answer.
Sample answer
No, that is unlikely. Since session ids should be hard to guess, they should be big numbers or long strings, so a hacker can't "guess" user's session id. If a hacker knows or manages to guess another user's session id, then that hacker can start to use that session id too, and that way act as that user to the server, and that's a security risc.
Marking guidelines
- 1 point for correct answer and valid justification
Question 19 (2p)
Question
On a website with blogposts, the blogposts are stored in an SQLite database in a table named blogposts
that looks like this:
keyword | title | content | author |
---|---|---|---|
html | HTML is fun! | ... | Alice |
css | CSS is fun too! | ... | Bob |
js | JS is most fun! | ... | Alice |
... | ... | ... | ... |
content
is not shown in the table above, since that one is quite long, and not all rows are shown, since they are quite many.
Claire should add a webpage to the website users can use to search for blogposts matching an entered keyword
or an entered title
. It should not be possible to search for blogposts matching an entered author
, since easily retrieving all blogposts written by a specific user is considered to be a security vulnerability on this website.
Claire adds a webpage with the following HTML code:
<h1>Search blogposts</h1>
<form method="GET" action="/blogposts/search">
<div>
Select field to search:
<select name="field">
<option value="keyword">Keyword</option>
<option value="title">Title</option>
</select>
</div>
<div>
Enter value to match in field:
<input type="text" name="value">
</div>
<input type="submit" value="Search!">
</form>
To handle the search request, she adds the following JS code to the app.js
file:
app.get('/blogposts/search', function(request, response){
const field = request.params.field
const value = request.params.value
const query = "SELECT * FROM blogposts WHERE "+field+" = ?"
const values = [value]
db.all(query, values function(error, blogposts){
// Let us assume no database error occurred, so we ignore that.
const model = {
blogposts
}
// The file blogposts.hbs is not shown here, but it
// shows all the blogposts in the model to the user.
response.render('blogposts.hbs', model)
})
})
Does Claire's implementation contain a security vulnerability or not? Justify your answer.
Sample answer
Claire's implementation does contain a security vulnerability. In the HTML code for the <form>
, it looks like the user can only choose among the fields keyword
and title
, but the HTML code can easily be changed client-side by a hacker, so a hacker can easily add author
as a third option in the <select>
element (i.e. <option value="author">Author</option>
), and that way send a request that would search for blogpost written by a specific user. I.e.
(in addition to that:
- A hacker can craft her own HTTP request from scratch, and write
author
instead ofkeyword
ortitle
directly in the HTTP request - By using string concatenation in the SQL query, she has created an SQL injection vulnerability, so a hacker can easily modify the
WHERE
part of the query to perform much more complicated searches than what is intended. Also note that using a placeholder (?
) instead of"+field+"
won't work, since it's not a value in the SQL syntax that should be inserted, and this alone would not solve the problem anyway
)
Marking guidelines
- 2 points for correct answer and valid justification
- Only 1.5 points for answers identifying an SQL vulnerability, and suggesting using placeholders solve the problem
Question 20 (1p)
Question
What is the biggest problem with the code below? Justify your answer.
Note: Any user should be able to anonymously create blogposts.
app.js:
//...
app.post('/blogposts/create', function(request, response){
const title = request.body.title
const content = request.body.content
const errorMessages = []
if(50 < title.length){
errorMessages.push("The title is too long.")
}
if(5000 < content.length){
errorMessages.push("The content is too long.")
}
if(0 < errorMessages.length){
const model = {
title,
content,
errorMessages,
}
response.render("create-blogpost.hbs", model)
}
const query = "INSERT INTO blogposts (title, content) VALUES (?, ?)"
const values = [title, content]
db.run(query, values, function(error){
if(error){
response.render('internal-server-error.hbs')
}else{
response.redirect('/blogposts/'+this.lastID)
}
})
})
//...
Sample answer
Looking at the code, one can see that it validates the blogpost that should be created, and given the conditional statement with the condition 0 < errorMessages.length
, the intent seems to be to only create the blogpost (store it in the database) if there are no validation errors. However, this if statement contains no return
statement, so even if we enter it and send back a response that shows the validation errors to the user, the rest of the code will continue to execute, so we will create blogposts that contains validation errors. That is the biggest problem with the code.
(then there exist other problems as well, such as:
- the code will crash if a hacker sends a request without a
title
orcontent
(that is bad, but no harm done) - the error message
The title is too long.
is not enough informative to the user (i.e. it doesn't mention what the allowed maximum length is)) 50
and5000
have been hardcoded
but none of these are as problematic as creating a blogpost that contains validation errors)
Marking guidelines
- 1 point for correct answer
- 0.1 points for saying the database can be spammed
Database
Question 21 (1p)
Question
Below is the table humans
found in an SQLite database (not all rows are shown).
id | name | age |
---|---|---|
1 | Alice | 10 |
2 | Bob | 20 |
3 | Claire | 15 |
... | ... | ... |
Write an SQL query that sends back all information about 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
SELECT * FROM humans WHERE name = "Bob"
(in SQLite, when testing for equality, both =
and ==
can be used)
Marking guidelines
- 1 point for an answer that is largely correct
- Point deductions for errors:
- -0.1 points for missing
*
- -0.25 points for
SELECT humans
instead ofSELECT * FROM
- -0.25 points for
'name = Bob'
instead ofname = 'Bob'
- -0.5 points for
GET humans
instead ofSELECT * FROM
- -0.5 points for
RETRIEVE humans
instead ofSELECT * FROM
- -0.75 points for
get ALL
instead ofSELECT * FROM
- -0.1 points for missing
Question 22 (1p)
Question
Below is the table humans
found in an SQLite database (not all rows are shown).
id | name | age |
---|---|---|
1 | Alice | 10 |
2 | Bob | 20 |
3 | Claire | 15 |
... | ... | ... |
Write an SQL query that changes the age of all humans named Claire
to 30
.
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 = 30 WHERE name = "Claire"
(in SQLite, when testing for equality, both =
and ==
can be used)
Marking guidelines
- 1 point for an answer that is largely correct
- Point deduction for errors:
- -0.1 points for not using quotes around strings
- -0.25 points for changing the age to
10
instead of30
OR:
- 0.5 points for a query that contains most required SQL parts, but in wrong order
- Point deduction for errors:
- -0.1 points for using
FROM
instead ofSET
- -0.1 points for using
JavaScript
Question 23 (1p)
Question
Implement the JavaScript function getSumUntil(excludedTerm)
, that receives an integer as argument, and returns the sum of the integers between 0
and the integer it receives (including 0
BUT EXCLUDING the received integer).
Sample usage:
getSumUntil(5) // --> 10 (0 + 1 + 2 + 3 + 4)
getSumUntil(2) // --> 1 (0 + 1)
getSumUntil(1) // --> 0
Note: You can expect excludedTerm
to always be greater than 0
.
Sample answer
function getSumUntil(excludedTerm){
let sum = 0
for(let term=0; term<excludedTerm; term++){
sum += term
}
return sum
}
Marking guidelines
- 1 point for an answer that largely works
- Point deduction for small mistakes:
- -0.1 points for using global variable
- -0.1 points for using bad name on variable
- -0.1 points for
Function
instead offunction
- -0.1 points for including
excludedTerm
in the sum
OR:
- 0.25 points for iterating over correct values
Question 24 (1p)
Question
Implement the JavaScript function isAnyGreaterThan10(numbers)
, that receives an array with numbers and returns:
true
if at least one of the numbers in the array is greater than10
false
otherwise
Sample usage:
isAnyGreaterThan10([3, 7, 1, 8]) // --> false
isAnyGreaterThan10([5, 3, 15, 5]) // --> true
isAnyGreaterThan10([15, 51, 50]) // --> true
isAnyGreaterThan10([]) // --> false
(if the array is empty, then returning false
is what makes most sense, so that's how your implementation should work as well)
Sample answer
function isAnyGreaterThan10(numbers){
for(const number of numbers){
if(10 < number){
return true
}
}
return false
}
Marking guidelines
- 1 point for an answer that largely works
- Point deduction for smaller mistakes:
- -0.1 points for using global variable
- -0.25 points for iterating over indexes instead of values
OR:
- 0.25 points for correctly using the for of loop with good names
Question 25 (2p)
Question
In JavaScript, a movie with a title, a category and a runtime (in minutes) can be represented as an object like this:
const movie = {
title: "Dumb and Dumber",
category: "comedy"
runtimeInMinutes: 106
}
Implement the function getNumberOfMoviesInCategories(movies, category1, category2)
, which receives an array with movie objects and two categories, and returns the number of movies in respective categories as an array containing the two numbers.
Sample usage:
getNumberOfMoviesInCategories([
{title: "Dumb and Dumber", category: "comedy" runtimeInMinutes: 106},
{title: "Shrek", category: "comedy" runtimeInMinutes: 90},
{title: "Titanic", category: "drama" runtimeInMinutes: 195},
{title: "Shrek 2", category: "comedy" runtimeInMinutes: 92},,
{title: "Love Actually", category: "romantic" runtimeInMinutes: 136},
], "comedy", "romantic") // --> [3, 1]
Sample answer
function getNumberOfMoviesInCategories(movies, category1, category2){
let numberOfMovies1 = 0
let numberOfMovies2 = 0
for(const movie of movies){
if(movie.category == category1){
numberOfMovies1 += 1
}
if(movie.category == category2){
numberOfMovies2 += 1
}
}
return [numberOfMovies1, numberOfMovies2]
}
Marking guidelines
- 2 points for an answer that largely works
- Point deduction for smaller mistakes:
- -0.25 points for not returning an array
- -0.25 points for iterating over indexes instead of values
Question 26 (1p)
Question
Alice has created the asynchronous functions add1(number, callback)
and add5(number, callback)
:
function add1(number, callback){
callback(number + 1)
}
function add5(number, callback){
callback(number + 5)
}
Implement the function add6(number, callback)
, that can be used like this:
add6(10, function(numberPlus6){
console.log("10 + 6 = "+numberPlus6)
})
In your implementation of add6
you may not use any mathematical operation yourself, but you have to call add1
and add5
to compute the new number based on the number you receive.
Sample answer
function add6(number, callback){
add1(number, function(numberPlus1){
add5(numberPlus1, function(numberPlus6){
callback(numberPlus6)
})
})
}
Marking guidelines
- 1 point for an answer that largely works