Paper 2 Network Security Drills

These are original Paper 2-style practice questions. They use exact data, function signatures, test calls, and expected output evidence.

Detailed answers are in Paper 2 Network Security Answers.

Revise the topic hub first:

Questions

Question 1: Password Validator

Write a function valid_password(password) that returns True only if:

  • the password has at least 8 characters;
  • it contains at least one digit.

Test:

print(valid_password("abc123"))
print(valid_password("password"))
print(valid_password("secure9x"))

Expected output:

False
False
True

[7]

Question 2: Login Attempts

Write a function simulate_login_attempts(correct_password, attempts) that processes a list of attempted passwords.

Rules:

  • the failed-attempt counter starts at 0;
  • if the account is already locked, append "LOCKED" to the result list;
  • if an attempt matches correct_password, append "SUCCESS" and reset the failed-attempt counter to 0;
  • if an attempt is wrong, increment the counter and append "FAIL";
  • once the counter reaches 3, the account becomes locked for all later attempts.

Test:

print(simulate_login_attempts("open123", ["bad", "wrong", "nope", "open123"]))

Expected output:

['FAIL', 'FAIL', 'FAIL', 'LOCKED']

[8]

Question 3: Access Log Filter

Given:

logs = [
    {"user": "amy", "event": "LOGIN_OK", "ip": "192.0.2.10"},
    {"user": "bo", "event": "LOGIN_FAIL", "ip": "192.0.2.11"},
    {"user": "cy", "event": "LOGIN_FAIL", "ip": "192.0.2.11"},
    {"user": "amy", "event": "LOGOUT", "ip": "192.0.2.10"}
]

Write a function failed_ips(logs) that returns a list of IP addresses for failed login records, in the order found.

Test:

print(failed_ips(logs))

Expected output:

['192.0.2.11', '192.0.2.11']

[6]

Question 4: Simple Hash Check

For this practice task, a stored password hash is simulated by:

stored_hash = "hash:letmein"

This is only a simplified practice simulation. It is not a secure real-world password hashing method.

Write a function authenticate(entered_password, stored_hash) that:

  • creates "hash:" + entered_password;
  • compares it with stored_hash;
  • returns True for a match and False otherwise.

Test:

print(authenticate("letmein", stored_hash))
print(authenticate("guess", stored_hash))

Expected output:

True
False

[5]

Question 5: MFA Code

Write a function mfa_login(password, code) that checks:

  • password must equal "river7";
  • one-time code must equal "481926";
  • return "ACCESS GRANTED" only if both checks pass;
  • return "PASSWORD FAILED" if the password is wrong;
  • return "CODE FAILED" if the password is correct but the code is wrong.

Test:

print(mfa_login("river7", "481926"))
print(mfa_login("wrong", "481926"))
print(mfa_login("river7", "000000"))

Expected output:

ACCESS GRANTED
PASSWORD FAILED
CODE FAILED

[6]

Question 6: Firewall Rules

Given:

rules = [
    {"port": 80, "action": "ALLOW"},
    {"port": 443, "action": "ALLOW"},
    {"port": 22, "action": "BLOCK"}
]

Write a function check_packet(port) that:

  • returns the matching action if a rule exists for the port;
  • returns "BLOCK" by default if no rule matches.

Test:

print(check_packet(80))
print(check_packet(22))
print(check_packet(25))

Expected output:

ALLOW
BLOCK
BLOCK

[8]

Question 7: IDS Alert

Given:

requests = [
    "203.0.113.5",
    "203.0.113.8",
    "203.0.113.8",
    "203.0.113.8",
    "198.51.100.2"
]

Write a function flag_ips(requests, threshold) that counts requests per IP address and returns a sorted list of IPs whose count is greater than or equal to threshold.

Test:

print(flag_ips(requests, 3))

Expected output:

['203.0.113.8']

[8]

Question 8: Encryption Demonstration

This is a simple character-shift demonstration, not secure real encryption.

Write a function shift_encrypt(text, key) that shifts uppercase letters forward by key places in the alphabet, wrapping around after Z. Non-uppercase characters should be left unchanged.

Test:

print(shift_encrypt("ATTACK AT 9", 2))

Expected output:

CVVCEM CV 9

[7]

Question 9: Signature Workflow

For this practice task, use a simplified signature simulation:

def simple_hash(message):
    return str(sum(ord(ch) for ch in message))

This is a toy simulation. Real digital signatures use different but mathematically related private and public keys. Here, the same text is used only to keep the programming task simple.

Write:

  • sign(message, private_key) returning simple_hash(message) + ":" + private_key;
  • verify(message, signature, public_key) returning True only if signature equals simple_hash(message) + ":" + public_key.

Assume the matching private/public test key text is "teacher_key".

Test:

sig = sign("submit marks", "teacher_key")
print(sig)
print(verify("submit marks", sig, "teacher_key"))
print(verify("change marks", sig, "teacher_key"))

Expected output:

1234:teacher_key
True
False

[6]

Question 10: Security Test Cases

Reuse valid_password(password) from Question 1.

Write a function run_password_tests() that returns a list of (password, result) pairs for these test cases:

PasswordExpected
abc123False
abcdefghFalse
abcd1234True

The returned result for each password should match the expected value in the table.

Test:

print(run_password_tests())

Expected output:

[('abc123', False), ('abcdefgh', False), ('abcd1234', True)]

[5]

Review Checklist

After attempting these questions, check whether you can:

  • implement security checks as exact conditions;
  • show the state change in login counters and lockout logic;
  • filter logs and count suspicious events using dictionaries/lists;
  • distinguish a teaching encryption/hash simulation from real security;
  • give exact output evidence for every test.