INF226 Exam – Spring 2023
This exam has 7 questions and counts for 60% of your final grade. All parts (a,b,c…) of each exercise should be answered.
- Allowed support materials: any written or printed material ("open book"). For your convenience, some resources are attached to the exam as PDFs.
- Please justify your answers, unless otherwise specified.
- Use precise language and read the exercise text carefully.
- Read through the whole exercise set first so you get a good overview and can plan your time appropriately. Make a note of any questions you might have.
- The percentages indicate the approximate weight (out of 60%). The final (8th) 40% ‘exercise’ is just a placeholder for the compulsory assignment results.
- If you get stuck somewhere, take a break or move on to the next exercise – you can always come back later if you have time!
- If you don't know the answer to some part of an exercise, it's ok to assume you've answered it when answering the other parts.
- You might write longer answers than suggested if that's easier for you – but avoid writing several pages instead of several sentences. It's ok to keep the answers fairly brief.
Good luck!
1. True or false? (8%)
Decide which of the following claims are true or false. 1 point for correct, -0.5 points for incorrect and 0 points for no answer.
Stack canaries prevent cross-site scripting attacks.
Select an alternative
☐ True
☐ False
Modern C compilers eliminate the risk of buffer overflows.
Select an alternative
☐ True
☐ False
Writing code which is easy to understand can help prevent security issues.
Select an alternative
☐ True
☐ False
The encryption used in current HTTPS applications is trivial to break.
Select an alternative
☐ True
☐ False
Many security critical bugs occur when the program enters an unexpected state.
Select an alternative
☐ True
☐ False
If a website’s database with user’s personal information is broken into, the website operators must, by European law, report this to its users.
Select an alternative
☐ True
☐ False
We can trust user input in a web application as long as we do security checks in the browser (with JavaScript) and set the Content Security Policy
Select an alternative
☐ True
☐ False
Best practice for enforcing access control policies and preventing unauthorized access is to implement a robust and layered security model that includes both authentication and authorization mechanisms.
Select one alternative:
☐ True
☐ False
2. Multiple Choice (4%)
Select the correct alternative. If in doubt, pick the one you think fits best. 1 point for a correct choice, -0.5 for a wrong choice and 0 points for no answer.
What is a buffer overflow attack?
Select one alternative:
☐ When an attacker takes advantage of a programming error to overwrite memory with malicious code
☐ When an attacker disguises a harmful file as a legitimate file to gain access to a system
☐ When an attacker floods a network with traffic to overload a server
☐ When an attacker gains unauthorized access to a system by bypassing security measures
Which of the following is a common method used to protect against SQL injection attacks?
Select one alternative
☐ Input validation
☐ Implementing multi-factor authentication
☐ Running anti-virus software
☐ Using secure sockets layer (SSL) encryption
Which of the following is a security best practice for login pages in web applications?
Select one alternative
☐ Using SSL/TLS to encrypt login credentials
☐ Allowing users to reset their passwords via email
☐ Storing user passwords in plaintext and using hashed challenge-response authentication
☐ Providing users with the option to reuse previously used passwords
What is the purpose of a session token in web applications?
Select one alternative
☐ To identify and block suspicious network traffic
☐ To enforce access control policies and prevent unauthorized access
☐ To keep users logged in after they leave a web application
☐ To protect sensitive data during transit between client and server
3. Web Chat (12%)
A web chat service, where people can log in and chat, supports user-created channels. The links to the different channels give the channel as a variable (for instance the foo channel is found on `https://example.com/view/?channel=foo``).
Here is part of the code which generates the HTML for the chat channels:
if (checkAuthenticationCookie()) {
String channel = request.getValue("channel");
html.add("<h1> Welcome to the " + channel + " channel!</h1>");
// ...
}
a) Identify a possible vulnerability in the above code.
b) Explain how an attacker could create a malicious link, which steals the authentication cookie from a legitimate user if they click it.
c) How would you mitigate this vulnerability?
4. It wasn't me (8%)

Explain the concept of non-repudiation and how it relates to software security.
(Write a few paragraphs, maybe 150–400 words in total (roughly).)
5. Crossing Sites (8%)

Cross-site request forgery (CSRF) vulnerabilities are common in web-applications.
Explain the concept of Cross-Site Request Forgery (CSRF) and the techniques used to prevent it.
For example – what is it, how does it occur, what sort of threats does it pose to web applications and how can we mitigate CSRF vulnerabilities?
(Write a few paragraphs, maybe 150–400 words in total (roughly).)
6. Random Canaries (8%)

Explain what stack canaries and address space layout randomization (ASLR) are, and how they can help prevent buffer overflow attacks.
(Write a few paragraphs, maybe 150–400 words in total (roughly).)
7. Securing a Good Grade (12%)
The INF226 Gradinator is a web app that lets you check your exam results – the scores for each question, which quartile the score lies in (red for first, yellow for second and green for third), and whether you're close to the next higher/lower grade. It's implemented as a RESTful single-page app, with a Python/Flask app on the server and JavaScript running in the browser. The client sends queries to the `/results`` endpoint on the server, and gets the result as JSON data which is then nicely formatted and presented in the browser.
In order to make sure that students can only access their own results, they have to enter their candidate number, grade and a secret code / password.
a) Examine the code for the server's
results()
function – it has at least one fairly obvious vulnerability. Identify the vulnerability and explain how exploit it, and how to fix it.b) There is at least one more problem / seriously bad practice in the code for
results()
. Please explain briefly, and recommend improvements.c) To make matters worse, the code seems to leak information to unauthenticated users. Explain briefly.
Look at the JavaScript code for the client's
submit()
function – it has a similar (potential) vulnerability.d) What kind of vulnerability do you see in the
submit()
function? Can you see a way to exploit it? If not, can you think of circumstances where it would be exploitable? (You may assume the worst about the rest of the system and its users.)e) (Bonus!) Can you think of a more secure way to design such a system? (Assuming, of course, that we don't want it to be deliberately exploitable for the enjoyment of INF226 students...)
results()
(Python)
app.py – @app.route('/results', methods=['GET'])
def results():
"""Returns exam scores for a given candidate id – with grade and secret password used as crude authentication."""
candidateId = request.args.get('id', '0')
grade = request.args.get('grade', '')
password = request.args.get('password', '')
if user_exists(candidateId, grade):
stmt = "SELECT id, qNo, score, grade, grade_detailed, lastname " \
+ "FROM students NATURAL JOIN scores " \
+ f"WHERE id = '{candidateId}' AND grade = '{grade}' AND password = '{password}' ORDER BY id, qNo"
cursor = g.db.execute(stmt) # query the database
# return rows in JSON format
return {
'rows' : [row_to_dict(row,cursor) for row in cursor],
'status':'ok',
'questions':questions # list of question names
}
else:
# web site will display this error message
return {
'status':'error',
'message':f'unknown candidate candidateId={candidateId}, grade={grade}'
}
submit()
(JavaScript)
index.html – async function submit() {
const params = new URLSearchParams({id: idField.value, grade: gradeField.value, password: passwordField.value});
const res = await fetch(`results?${params}`); // send request to server
if (res.ok) { // successful request
const result = await res.json();
log_request(params, res, result);
if (result.status === 'ok') { // we got an actual result
display_results(result);
} else if (result.status === 'error') { // we got an error message
resultElt.innerHTML = `<p class="error">${result.message}</p>`;
}
} else { // failed with HTTP error
resultElt.innerHTML = `<p class="error">HTTP request failed: ${res.status} ${res.statusText}</p>`;
log_request(params, res, { status: 'error', error: 'HTTP request failed' });
}
};
8. Oblig (40%)
The results from your compulsory exercises will be inserted here.