E6: IT services cybersecurity

Lama Zoo - SLAM, May 2023 session

Methodology and annotated worked solution: E6: IT services cybersecurity, BTS SIO.

  • Duration 4h
  • Pathway SLAM
  • Session May 2023

Lockbay annotated solution

Official exam paper

Lama Zoo case study - 2023 session, U6/E6 (SLAM), duration 4h, coef 4, out of 80 points (3 sections: A 30 pts, B 20 pts, C 30 pts). 📄 Download official Lama Zoo exam paper (réseaucerta.org)

Lockbay does not host the exam paper: this model answer is an original Lockbay production answering the questions from the official paper. Exam paper © Éducation nationale.

The Lama Zoo zoological park, hit by ransomware in 2019, is modernising its security. Three sections: redesigning the business application authorisation system (DBMS roles, triggers, transactions), securing review collection (XSS / CodeIgniter), and securing animal sponsorship (phishing, CSRF, data compartmentalisation). Question-by-question solutions.

Section A - Overhaul of the authorisation system 30 pts

Mission - Incident analysis and authorisation design

A.1

a) A brute-force attack automatically tests a large number of combinations (often drawn from common password dictionaries) until it finds the right one. It succeeded against Mr Breto because his password 1234Travail is weak and predictable ('1234' sequence + dictionary word): it appears in the most common lists, drastically reducing the number of attempts. No rate limiting or lockout after failed attempts slowed the attacker down.

b) Two methods: run training sessions / workshops (strong passwords, session locking); distribute reminder materials (posters, IT charter, awareness emails) and run simulated phishing campaigns.

A.2

a) Lack of traceability: without individual authentication, the application cannot attribute actions to a specific user. In the event of fraudulent activity, identifying the perpetrator is impossible: accountability cannot be established, and logs are unusable.

b) Loss of confidentiality: anyone accessing a workstation (unattended active session, intruder) has unrestricted access to all data, without access controls. Data is exposed to unauthorised individuals, without role-based restrictions.

A.3

Benefits of application roles at the connection driver level

Each role corresponds to a distinct DBMS account with specific privileges (SELECT, INSERT... restricted to certain tables/views). By connecting the application to the database using the user's role account, the DBMS enforces least privilege:

  • the user can only execute operations authorised by their role, even if an application vulnerability sent an unexpected query;
  • defence is enforced by the DBMS itself (defence in depth), not just by application code;
  • in the event of a breach, the impact is confined to the privileges of that role.
A.4

a) Why these shortcomings are vulnerabilities:

  • Authorisations with no lifespan: temporary access for interns/seasonal staff (Ms Moreau) does not expire automatically -> a forgotten account retains permissions indefinitely (residual access, misuse of access that should have been revoked).
  • Multiple roles for the same application: violates the 'single role per application' rule -> uncontrolled accumulation of permissions, implicit privilege escalation, impossible to audit.

b) Database changes - on table EstHabilite:

  • Add validity dates (start date and end date) to limit the lifespan of an authorisation;
  • Restrict the primary key to (numMatriculePerso, idAppli) so that a staff member can only have a single role per application (instead of the current key including idRoleAppli).
EstHabilite (numMatriculePerso, idAppli, idRoleAppli, dateDebut, dateFin)
   Clé primaire : numMatriculePerso, idAppli
   Clé étrangère : numMatriculePerso → Personnel
   Clé étrangère : idAppli, idRoleAppli → RoleApplicatif

A mechanism (scheduled task or application check) deletes or ignores permissions whose dateFin has expired.

A.5

after_update_habilitation trigger

Based on after_delete_habilitation, but triggered AFTER UPDATE and using old (old role) and new (new role):

CREATE TRIGGER `after_update_habilitation`
AFTER UPDATE ON `EstHabilite`
FOR EACH ROW
BEGIN
    INSERT INTO HistoHabilitation
    VALUES (NOW(), old.numMatriculePerso, old.idAppli,
            CONCAT('Modification du rôle ', old.idRoleAppli,
                   ' à ', new.idRoleAppli));
END
A.6

a) Purpose of transactions: deleting a role performs two inseparable operations (DBMS account + RoleApplicatif row). The transaction guarantees atomicity: either both succeed (commit), or everything is rolled back (rollback) in the event of an error. This avoids an inconsistent state (a DBMS account with no associated record, or vice versa), which would constitute an access management vulnerability.

b) Code for deleteRole() - symmetrical to createRole(): first delete the record from RoleApplicatif, then the user account from the DBMS, all within the transaction.

$this->monPdo->beginTransaction(); // début de la transaction

$req = $this->monPdo->prepare(
    'DELETE FROM RoleApplicatif WHERE idAppli = :idAppli AND idRoleAppli = :idRole ;');
$req->bindParam(':idAppli', $idAppli, PDO::PARAM_STR);
$req->bindParam(':idRole',  $id,      PDO::PARAM_STR);
$resultat = $req->execute();

$req = $this->monPdo->prepare('DROP USER :idUser ;');
$req->bindParam(':idUser', $id, PDO::PARAM_STR);
$resultat = $resultat + $req->execute();

$this->monPdo->commit(); // fin de la transaction par un commit
Part B - Securing review collection 20 pts

Mission - Fix an XSS vulnerability in comments (CodeIgniter)

B.1

a) Role of the before method in AuthGuard: this is a filter executed before the controller. It checks that the session contains isLoggedIn; if the user is not authenticated, it halts processing and redirects them to /connexion. It therefore protects the routes associated with the authGuard filter.

b) Is authentication required to post a comment? Yes. Routes /ateliers/commentform/(:num) and /ateliers/commentstore both use the ['filter' => 'authGuard'] filter (document B3), and commentStore() only executes if ($session->get('isLoggedIn')) (document B1, line 14). The attacker must therefore be authenticated (possess an account) to submit a malicious review.

B.2

a) Why is it stored XSS: the injected JavaScript is saved in the database (via EvaluerModel->save(), document B1) and then re-displayed each time the reviews page is viewed (/ateliers/comments/5). The payload persists on the server side and executes on every display - the definition of stored XSS (as opposed to reflected XSS, where the payload travels via the URL and affects only one targeted victim at a time).

b) Why it affects more visitors: the stored payload is delivered to any visitor viewing the page -> every user executes the script without taking any action, potentially leading to thousands of victims. Reflected XSS, by contrast, requires enticing each victim to click a poisoned link: limited and targeted distribution.

B.3

a) Filter data from the database before display: stored data must never be trusted (inserted through an uncontrolled path, an insecure earlier version, or via injection). Escaping on display ensures that malicious content already in the database will not execute - the primary defence against XSS.

b) Filter data from the form before writing: prevents storing a malicious payload (sanitisation at source), limits propagation to other channels (APIs, exports), and protects processes that might not re-escape on display.

B.4

a) Method commentStore (AteliersController, document B1) - escape the comment before saving. Modified line:

27.   'commentaireEvaluer' => esc($this->request->getVar('comment')),

b) View coms.php (document B2) - escape each comment on display. Modified line:

4.        echo esc($com)."<br/>";

The esc() method (document B6) converts <br> into &lt;br&gt;, for example: the injected code is displayed as inert text and is no longer interpreted as HTML/JavaScript.

Part C - Securing animal sponsorship 30 pts

Mission 1 - Phishing and offences

C.1

Five signs of phishing

(document C1):

  1. Inconsistent sender address: [email protected] outside the official domain @lamazoo.com.
  2. Spelling mistakes: « nous vous offront », « 4 entrées gratuite », « Léquipe zoo ».
  3. Offer too good to be true / bait: 4 free tickets « pour vous remercier » -> incentive to click.
  4. Misleading link: the displayed text (« cestla fete enfamille ») conceals a URL pointing to a sensitive action https://lamazoo.com/profil/supprcmptconfirm (account deletion), completely unrelated to the offer.
  5. Generic nature: impersonal greeting (« cher Parrain »), vague signature, absence of verifiable contact details.
C.2

Two offences identified

against the perpetrator:

  • Fraudulent access to and remaining in an automated data processing system (STAD) - Art. 323-1 of the French Criminal Code (along with interfering with system operation / data deletion, Arts. 323-2 and 323-3, resulting from the account deletion).
  • Fraud / fraudulent data collection through identity theft: impersonating Lama Zoo to deceive the victim - fraud (Art. 313-1) and identity theft (Art. 226-4-1), as well as unfair collection of personal data (Art. 226-18).

Mission 2 - CSRF protection (CodeIgniter)

C.3

a) Items stored client-side / server-side for both patterns (document C2):

Design patternServer-sideClient-side
Synchronizer TokenThe CSRF token is stored in a session variable on the serverThe token is inserted into a hidden form field (or URL parameter)
Double Submit (cookie)Nothing is stored server-side (the server only compares the two received values)The token is sent twice: in a cookie and in the request body (hidden field)

b) Enabling the Synchronizer Token:

  • In the Security class (document B4): change the $csrfProtection property from 'cookie' to 'session':
    public $csrfProtection = 'session';
  • In the Filters class: enable the csrf filter before each request by adding it to the $globals['before'] array:
    'before' => [ 'honeypot', 'invalidchars', 'csrf', ],
  • In views, developers must add the <?= csrf_field() ?> call (document C3) into each form to be protected, which generates the hidden field containing the token.
C.4

a) Why API routes are no longer responding: CSRF protection is enabled globally (csrf filter in before). However, /ws/… routes are web services called without an HTML form: they transmit no CSRF token. Finding no expected token, the filter rejects all requests. Since these routes are public and read-only, a CSRF scenario makes no sense: they must be exempted.

b) Whitelist in Filters - use the except key of the csrf filter with a regular expression matching all /ws/… routes (document C3):

public $filters = [
    'csrf' => ['except' => ['ws/*']],
];

'ws/*' excludes the three API routes in document B3 (ws/animaux, ws/hebergements, ws/ateliers) from the CSRF filter.

Mission 3 - Partition data access using a SQL view

C.5

Requested queries

: revoke excessive privileges from site_public, create a view exposing only the fields from the public profile (document C6: name, species, year of birth, weight, comment), then grant only SELECT on this view.

-- 1. Retirer les droits actuels (trop larges : ALL sur la table animal)
REVOKE ALL ON BdAnimaux.animal FROM 'site_public';

-- 2. Créer la vue n'exposant que les informations publiques
CREATE VIEW BdAnimaux.vueAnimal AS
SELECT a.nomAnimal,
       e.nomCommunEspece,
       YEAR(a.dateNaissAnimal) AS anneeNaissance,
       a.poidsAnimal,
       a.commentaire,
       a.photoAnimal
FROM Animal a
JOIN Espece e ON a.numEspece = e.numEspece;

-- 3. N'accorder qu'un droit de lecture sur la vue
GRANT SELECT ON BdAnimaux.vueAnimal TO 'site_public';

The view hides sensitive fields (paysOriAnimal, numZone, lineage...) that would facilitate animal theft, and the account no longer has direct access to the tables or write privileges.

C.6

Pseudonymised roll of honour

The initial table discloses personal data (full name). To comply with data minimisation (GDPR) while allowing each sponsor to identify themselves, the data is pseudonymised: for example, displaying first name + surname initial (or a pseudonym chosen by the sponsor), and never a direct identifier (full name, email, city).

RankSponsorSponsored animalAmount
1Edwin H.Serge (llama)… €
2Lucie P.…… €
3A. M***…… €

Marking scheme points (reminder)

SectionExpectationPoints
ABrute force & awareness, traceability/confidentiality, DBMS roles (least privilege), lifespan & uniqueness of permissions, UPDATE trigger, transactions & deleteRole()30
BAuthGuard filter, stored vs reflected XSS, input/output escaping, fixing commentStore & coms.php with esc()20
CPhishing indicators, criminal offences, CSRF (synchroniser token, client/server, activation), API whitelist, SQL view & least privilege, pseudonymisation30
Total80
Official exam paper © Éducation nationale - published by Réseau CERTA - Éducation nationale (source link). Annotated solutions and methodology © Lockbay Academy.