Пример #1
0
def process_msg(mozmsg, msg):
    """Normalization function for auth0 msg.
    @mozmsg: MozDefEvent (mozdef message as DotDict)
    @msg: DotDict (json with auth0 raw message data).

    All the try-except loops handle cases where the auth0 msg may or may not contain expected fields.
    The msg structure is not garanteed.
    See also https://auth0.com/docs/api/management/v2#!/Logs/get_logs
    """
    details = DotDict({})

    # key words used to set category and success/failure markers
    authentication_words = ["Login", "Logout", "Silent", "Enrollment", "OTP", "Recovery", "Authentication", "Code", "Signup", "Push"]
    authorization_words = ["Authorization", "Access", "Delegation"]
    administration_words = ["API", "Operation", "Change", "Update", "Deleted", "unenrolled", "updated", "CORS", "Connector", "Blocked", "Breached", "Deletion", "block", "User", "released"]
    success_words = ["Success"]
    failed_words = ["Failed"]

    # fields that should always exist
    mozmsg.timestamp = msg.date
    details["messageid"] = msg._id
    details["sourceipaddress"] = msg.ip

    try:
        details["userid"] = msg.user_id
    except KeyError:
        pass

    try:
        if msg.user_name:
            details["username"] = msg.user_name
    except KeyError:
        pass

    try:
        # the details.request/response exist for api calls
        # but not for logins and other events
        # check and prefer them if present.
        if type(msg.details.response.body) is not list:
            details["action"] = msg.details.response.body.name
    except KeyError:
        pass

    try:
        if "email" in msg.details.response.body and msg.details.response.body.email is not None:
            details["email"] = msg.details.response.body.email
    except KeyError:
        pass

    try:
        details["useragent"] = msg.user_agent
    except KeyError:
        pass

    try:
        if msg.client_name:
            details["clientname"] = msg.client_name
    except KeyError:
        pass

    try:
        if msg.connection:
            details["connection"] = msg.connection
    except KeyError:
        pass

    try:
        if msg.client_id:
            details["clientid"] = msg.client_id
    except KeyError:
        pass

    try:
        # auth0 calls these events with an acronym and name
        details["eventname"] = log_types[msg.type].event
        # determine the event category
        if any(authword in details["eventname"] for authword in authentication_words):
            mozmsg.set_category("authentication")
        if any(authword in details["eventname"] for authword in authorization_words):
            mozmsg.set_category("authorization")
        if any(adminword in details["eventname"] for adminword in administration_words):
            mozmsg.set_category("administration")
        # determine success/failure
        if any(failword in details["eventname"] for failword in failed_words):
            details.success = False
        if any(successword in details["eventname"] for successword in success_words):
            details.success = True
    except KeyError:
        # New message type, check https://manage-dev.mozilla.auth0.com/docs/api/management/v2#!/Logs/get_logs for ex.
        logger.error("New auth0 message type, please add support: {}".format(msg.type))
        details["eventname"] = msg.type

    # determine severity level
    if log_types[msg.type].level == 3:
        mozmsg.set_severity(mozdef.MozDefEvent.SEVERITY_ERROR)
    elif log_types[msg.type].level > 3:
        mozmsg.set_severity(mozdef.MozDefEvent.SEVERITY_CRITICAL)

    # default description
    details["description"] = ""
    try:
        if "description" in msg and msg.description is not None:
            # use the detailed description of the operation sent from auth0
            # Update a rule, add a site, update a site, etc
            details["description"] = msg.description
    except KeyError:
        pass

    # set the summary
    # make summary be action/username (success login [email protected])
    # if no details.username field exists we don't add it.

    # Build summary if neither email, description, nor username exists
    if 'eventname' in details:
        mozmsg.summary = "{event}".format(event=details.eventname)
        if 'description' in details and details['description'] != "None":
            mozmsg.summary += " {description}".format(event=details.eventname, description=details.description)
        if 'username' in details and details['username'] != "None":
            mozmsg.summary += " by {username}".format(username=details.username)
        if 'email' in details and details['email'] != "None":
            mozmsg.summary += " account: {email}".format(email=details.email)
        if 'clientname' in details and details['clientname'] != "None":
            mozmsg.summary += " to: {clientname}".format(clientname=details.clientname)

    # Get user data if present in response body
    try:
        if "multifactor" in msg.details.response.body and type(msg.details.response.body.multifactor) is list:
            details.mfa_provider = msg.details.response.body.multifactor
    except KeyError:
        pass

    try:
        if "ldap_groups" in msg.details.response.body and type(msg.details.response.body.ldap_groups) is list:
            details.ldap_groups = msg.details.response.body.ldap_groups
    except KeyError:
        pass

    try:
        if "last_ip" in msg.details.response.body and msg.details.response.body.last_ip is not None:
            details.user_last_known_ip = msg.details.response.body.last_ip
    except KeyError:
        pass

    try:
        if "last_login" in msg.details.response.body and msg.details.response.body.last_login is not None:
            details.user_last_login = msg.details.response.body.last_login
    except KeyError:
        pass

    # Differentiate auto login (session cookie check validated) from logged in and had password verified

    try:
        for i in msg.details.prompt:
            # Session cookie check
            if i.get("name") == "authenticate":
                details["authtype"] = "Login succeeded due to a valid session cookie being supplied"
            elif i.get("name") == "lock-password-authenticate":
                details["authtype"] = "Login succeeded due to a valid plaintext password being supplied"
    except KeyError:
        pass

    mozmsg.details = details

    return mozmsg
Пример #2
0
def process_msg(mozmsg, msg):
    """Normalization function for auth0 msg.
    @mozmsg: MozDefEvent (mozdef message as DotDict)
    @msg: DotDict (json with auth0 raw message data).

    All the try-except loops handle cases where the auth0 msg may or may not contain expected fields.
    The msg structure is not garanteed.
    See also https://auth0.com/docs/api/management/v2#!/Logs/get_logs
    """
    details = DotDict({})
    # defaults
    details.username = "******"
    details.userid = "UNKNOWN"

    # key words used to set category and success/failure markers
    authentication_words = ['Login', 'Logout', 'Auth']
    authorization_words = ['Authorization', 'Access', 'Delegation']
    success_words = ['Success']
    failed_words = ['Failed']

    # default category (might be modified below to be more specific)
    mozmsg.set_category('iam')
    mozmsg.source = 'auth0'
    # fields that should always exist
    mozmsg.timestamp = msg.date
    details['messageid'] = msg._id
    details['sourceipaddress'] = msg.ip

    try:
        details['userid'] = msg.user_id
    except KeyError:
        pass

    try:
        details['username'] = msg.user_name
    except KeyError:
        pass

    try:
        # the details.request/response exist for api calls
        # but not for logins and other events
        # check and prefer them if present.
        details['username'] = msg.details.request.auth.user.name
        details['action'] = msg.details.response.body.name
    except KeyError:
        pass

    try:
        details['useragent'] = msg.user_agent
    except KeyError:
        pass

    try:
        # auth0 calls these events with an acronym and name
        details['eventname'] = log_types[msg.type].event
        # determine the event category
        if any(authword in details['eventname']
               for authword in authentication_words):
            mozmsg.set_category("authentication")
        if any(authword in details['eventname']
               for authword in authorization_words):
            mozmsg.set_category("authorization")
        # determine success/failure
        if any(failword in details['eventname'] for failword in failed_words):
            details.success = False
        if any(successword in details['eventname']
               for successword in success_words):
            details.success = True
    except KeyError:
        # New message type, check https://manage-dev.mozilla.auth0.com/docs/api/management/v2#!/Logs/get_logs for ex.
        debug('New auth0 message type, please add support: {}'.format(
            msg.type))
        details['eventname'] = msg.type

    # determine severity level
    if log_types[msg.type].level == 3:
        mozmsg.set_severity(mozdef.MozDefEvent.SEVERITY_ERROR)
    elif log_types[msg.type].level > 3:
        mozmsg.set_severity(mozdef.MozDefEvent.SEVERITY_CRITICAL)

    # default description
    details['description'] = ""
    try:
        if 'description' in msg and msg.description is not None:
            # use the detailed description of the operation sent from auth0
            # Update a rule, add a site, update a site, etc
            details['description'] = msg.description
    except KeyError:
        details['description'] = ""

    # set the summary
    if 'auth' in mozmsg._category:
        # make summary be action/username (success login [email protected])
        mozmsg.summary = "{event} {desc}".format(event=details.eventname,
                                                 desc=details.username)

    else:
        # default summary as action and description (if it exists)
        mozmsg.summary = "{event} {desc}".format(event=details.eventname,
                                                 desc=details.description)

    try:
        details['clientname'] = msg.client_name
    except KeyError:
        pass

    try:
        details['connection'] = msg.connection
    except KeyError:
        pass

    try:
        details['clientid'] = msg.client_id
    except KeyError:
        pass

    # Differenciate auto login (session cookie check validated) from logged in and had password verified

    try:
        for i in msg.details.prompt:
            # Session cookie check
            if i.get('name') == 'authenticate':
                details[
                    'authtype'] = 'Login succeeded due to a valid session cookie being supplied'
            elif i.get('name') == 'lock-password-authenticate':
                details[
                    'authtype'] = 'Login succeeded due to a valid plaintext password being supplied'
    except KeyError:
        pass

    mozmsg.details = details
    mozmsg.details['raw'] = str(msg)

    return mozmsg
Пример #3
0
def process_msg(mozmsg, msg):
    """Normalization function for auth0 msg.
    @mozmsg: MozDefEvent (mozdef message as DotDict)
    @msg: DotDict (json with auth0 raw message data).

    All the try-except loops handle cases where the auth0 msg may or may not contain expected fields.
    The msg structure is not garanteed.
    See also https://auth0.com/docs/api/management/v2#!/Logs/get_logs
    """
    details = DotDict({})
    # defaults
    details.username = "******"
    details.userid = "UNKNOWN"

    # key words used to set category and success/failure markers
    authentication_words = ["Login", "Logout", "Auth"]
    authorization_words = ["Authorization", "Access", "Delegation"]
    success_words = ["Success"]
    failed_words = ["Failed"]

    # default category (might be modified below to be more specific)
    mozmsg.set_category("iam")
    mozmsg.source = "auth0"
    # fields that should always exist
    mozmsg.timestamp = msg.date
    details["messageid"] = msg._id
    details["sourceipaddress"] = msg.ip

    try:
        details["userid"] = msg.user_id
    except KeyError:
        pass

    try:
        details["username"] = msg.user_name
    except KeyError:
        pass

    try:
        # the details.request/response exist for api calls
        # but not for logins and other events
        # check and prefer them if present.
        details["username"] = msg.details.request.auth.user.name
        details["action"] = msg.details.response.body.name
    except KeyError:
        pass

    try:
        details["useragent"] = msg.user_agent
    except KeyError:
        pass

    try:
        # auth0 calls these events with an acronym and name
        details["eventname"] = log_types[msg.type].event
        # determine the event category
        if any(authword in details["eventname"] for authword in authentication_words):
            mozmsg.set_category("authentication")
        if any(authword in details["eventname"] for authword in authorization_words):
            mozmsg.set_category("authorization")
        # determine success/failure
        if any(failword in details["eventname"] for failword in failed_words):
            details.success = False
        if any(successword in details["eventname"] for successword in success_words):
            details.success = True
    except KeyError:
        # New message type, check https://manage-dev.mozilla.auth0.com/docs/api/management/v2#!/Logs/get_logs for ex.
        debug("New auth0 message type, please add support: {}".format(msg.type))
        details["eventname"] = msg.type

    # determine severity level
    if log_types[msg.type].level == 3:
        mozmsg.set_severity(mozdef.MozDefEvent.SEVERITY_ERROR)
    elif log_types[msg.type].level > 3:
        mozmsg.set_severity(mozdef.MozDefEvent.SEVERITY_CRITICAL)

    # default description
    details["description"] = ""
    try:
        if "description" in msg and msg.description is not None:
            # use the detailed description of the operation sent from auth0
            # Update a rule, add a site, update a site, etc
            details["description"] = msg.description
    except KeyError:
        details["description"] = ""

    # set the summary
    if "auth" in mozmsg._category:
        # make summary be action/username (success login [email protected])
        mozmsg.summary = "{event} {desc}".format(event=details.eventname, desc=details.username)

    else:
        # default summary as action and description (if it exists)
        mozmsg.summary = "{event} {desc}".format(event=details.eventname, desc=details.description)

    try:
        details["clientname"] = msg.client_name
    except KeyError:
        pass

    try:
        details["connection"] = msg.connection
    except KeyError:
        pass

    try:
        details["clientid"] = msg.client_id
    except KeyError:
        pass

    # Differenciate auto login (session cookie check validated) from logged in and had password verified

    try:
        for i in msg.details.prompt:
            # Session cookie check
            if i.get("name") == "authenticate":
                details["authtype"] = "Login succeeded due to a valid session cookie being supplied"
            elif i.get("name") == "lock-password-authenticate":
                details["authtype"] = "Login succeeded due to a valid plaintext password being supplied"
    except KeyError:
        pass

    mozmsg.details = details
    mozmsg.details["raw"] = str(msg)

    return mozmsg