Logo
Afbeelding

Gebruik van Logging in de Audit

Geschreven door The Audit Analytics | 7 minuten

Logging is als een soort “zwarte doos” in een vliegtuig: het vertelt je wat er achter de schermen is gebeurd, wanneer het is gebeurd en (soms) door wie. Dit is superhandig bij een audit, omdat het kan helpen bij het in kaart brengen van processen of juist om processen te controleren. In dit artikel staan we stil bij de verschillende soorten audit logs, waar je op moet letten voor je het wil gebruiken in je controle en wat voor checks je kunt doen om zeker te zijn van een betrouwbare set.

Logging in audit

Welke logging kom je vaak tegen?

In de praktijk zie je verschillende soorten auditlogs voorbijkomen. Hieronder heb ik een paar voorbeelden en waarom ze interessant zijn:

  1. Toegangs- en gebruikerslogging

    • Denk aan inlogpogingen (succesvol en niet succesvol), sessies die worden gestart en beëindigd, en wijzigingen in gebruikersrechten.

    • Het is handig om te zien wie wanneer in het systeem is geweest en of er niet stiekem iemand te veel rechten heeft. Heeft iemand bijvoorbeeld een verouderd wachtwoord of teveel rechten? Dan kun je hiermee kijken of iemand ook daadwerkelijk heeft ingelogd.

  2. Database- en systeemlogging

    • Logt op een lager niveau wat er in de database of het besturingssysteem gebeurt (bijvoorbeeld query’s en wijzigingen aan tabellen, of wijzigingen in serverconfiguraties).

    • Handig als je veranderingen in de basisconfiguratie of rechtenstructuur wilt controleren.

  3. Transactie- en proceslogging

    • Deze logs noteren activiteiten rondom specifieke bedrijfsprocessen, zoals het aanmaken van een verkooporder, het inboeken van een factuur, het wijzigen van stamdata of het goedkeuren van een betaling.

    • Hier kun je tal van voorbeelden voor bedenken. Vaak wordt er gekeken naar het aanpassen van stamdata; bankrekeningen van crediteuren of verkoopprijzen bijvoorbeeld, maar ook goedkeuringen kunnen relevant zijn.

Afhankelijk van je doel kun je inzoomen op één soort log of juist verschillende bronnen combineren.

Aandachtspunten in het systeem

Klinkt natuurlijk allemaal heel mooi, maar lang niet alles wordt gelogd en zelfs als er gelogd wordt, moet je nog kritisch zijn. Hier een aantal aandachtspunten:

Logconfiguratie

Check of logging wel aan staat, correct is geconfigureerd en of alle relevante gebeurtenissen worden vastgelegd. Het is echt per systeem verschillend wat standaard gelogd wordt en of je hier als eindgebruiker hierop nog invloed hebt. Mocht dat laatste het geval zijn, moet je ook kritisch kijken of dit gebeurd is.

Wat wel? Maar ook: wat niet?

Te veel of te weinig logging kan problemen opleveren. Zorg voor een goede balans en log alle kritische gebeurtenissen. Je wil niet 100 GB aan data binnenhalen (en dat wil je ook niet opslaan binnen je systemen).

Bewaartermijn van logs

Als logs na korte tijd worden gewist, heb je niets aan je audit. Check hoe lang ze bewaard blijven en sla ze tijdig op.

Hoe zit het met de GITC?

Logging is vaak niet aan te sluiten met andere documentatie; dat maakt een betrouwbare systeemomgeving des te belangrijker. Zo kunnen nieuwe wijzigingen aan het systeem logging beïnvloeden (change management), maar ook als je de logging wil gebruiken om te weten wie wat gedaan heeft moet de authenticatie goed zijn. En tenslotte, mocht logging aan en uit te zetten zijn, wie heeft die rechten?

Het is aan te raden om tijdig te beginnen om te onderzoeken of er logging beschikbaar is en vervolgens bovenstaande controles uit te zoeken. Systeembeheerders zijn hier vaak niet dagelijks mee bezig en moeten waarschijnlijk ook het een en ander uitzoeken.

Welke checks op de logging zelf?

Mocht je dan uiteindelijk de gewenste logging binnen hebben, wil je natuurlijk weten of je volledig bent. Zoals al eerder benoemd, kun je het vaak nergens mee aansluiten. Dus moet je de betrouwbaarheid op een andere manier vaststellen.

1. Heb je alles?

Vaak wordt er in het systeem aangegeven hoeveel records er geëxporteerd zijn. Controleer of het aantal in jouw dataset met dat aantal overeenkomt. Zo weet je zeker dat er geen rijen missen.

2. Unieke & oplopende ID’s

Elke gebeurtenis zou een uniek ID moeten hebben. Soms worden die ID’s ook nog oplopend gegenereerd. Dan kun je controleren of er geen hiaten in de reeks zitten. Als je bijvoorbeeld weet dat de ID’s 1 t/m 1000 moeten zijn, maar in je logbestand missen 435 t/m 450, dan wijst dat op gemiste records.

3. Integriteit en consistentie

Controleer of de juiste velden zijn opgenomen en altijd gevuld.

4. Tijds- en datumvalidatie

Controleer het datum/tijd veld. Zijn tijdstempels chronologisch? Geen onverklaarbare gaten van dagen in je log, terwijl er wel activiteit was?

Voorbeelden van checks met Python (met Pandas)

Ter referentie heb ik de checks die we hiervoor besproken hebben ook verwerkt in python. We werken daarvoor met pandas.

import pandas as pd
from datetime import datetime

def check_completeness(df):
    # Voorbeeld check: tellen of het aantal records logisch is.
    total_records = len(df)
    print(f"Totaal aantal logregels: {total_records}")
    
    # Stel, we verwachten 9500 regels
    if total_records != 9500:
        print("Mogelijk ontbreken er logregels!")
    else:
        print("Aantal logregels lijkt in orde.")

def check_ids(df):
    # Check op unieke en eventueel oplopende ID's. 
    if 'event_id' not in df.columns:
        print("Geen 'event_id'-kolom gevonden!")
        return
    
    # Check of 'event_id' uniek is
    duplicates = df[df.duplicated(subset=['event_id'], keep=False)]
    if not duplicates.empty:
        print("Dubbele event_id gevonden!")
        print(duplicates)
    
    # Voor oplopende ID's (optioneel, hangt af van het systeem)
    df_sorted = df.sort_values('event_id')
    expected_range = range(df_sorted['event_id'].min(), df_sorted['event_id'].max() + 1)
    actual_ids = df_sorted['event_id'].tolist()
    missing_ids = set(expected_range) - set(actual_ids)
    if missing_ids:
        print(f"Er ontbreken event_id's in de reeks: {missing_ids}")

def check_timestamps(df):
    # Controleer of tijdstempels oplopen en of ze niet buiten een verwacht bereik vallen.
    if 'timestamp' not in df.columns:
        print("Geen 'timestamp'-kolom gevonden!")
        return
    
    # Probeer de timestamp kolom te parsen als datetime
    try:
        df['timestamp_parsed'] = pd.to_datetime(df['timestamp'])
    except ValueError as e:
        print(f"Kon timestamps niet parsen: {e}")
        return
    
    # Check chronologische volgorde (optioneel, afhankelijk van je scenario)
    df_sorted = df.sort_values('timestamp_parsed')
    if not df_sorted['timestamp_parsed'].is_monotonic_increasing:
        print("Waarschuwing: timestamps zijn niet strikt oplopend.")


def main():
    log_path = 'mijn_logging.csv'
    df = pd.read_csv(log_file_path))
    check_completeness(df)
    check_ids(df)
    check_timestamps(df)

if __name__ == '__main__':
    main()

Conclusie

Dat was hem weer! Heb jij al een idee hoe je logging kunt inzetten voor jouw audit?