Detect excessive transaction volumes from users

JozsefB
Tera Expert

Is there a way to find out if a user is misusing the platform, and use his/her credentials to run automated  solutions?

 

In order to keep operational stability, and avoid performance issues, we would like to catch (and maybe block) if someone starts to create too many transactions. Like if someone creates a script and starts running tons of table APIs, or running web automation tools on Prod.

 

Is there a good way to catch these events? Querying constantly the Transaction Log doesn't sound too good for me.  

1 ACCEPTED SOLUTION

Shashank_Jain
Kilo Sage

@JozsefB , 

You can use this script as per your requirement :

(function() {
    var minutesBack = 50;  // How far back we want to look in transaction history (in minutes)
    var threshold = 5;   // Max allowed transactions per user in the given time window
    // Array to store summary of suspicious users
    var suspiciousUsers = [];
    var gr = new GlideAggregate('syslog_transaction');
    gr.addAggregate('COUNT', 'sys_created_by');
    gr.addEncodedQuery('sys_created_on>=javascript:gs.minutesAgoStart(' + minutesBack + ')');
    gr.groupBy('sys_created_by');
    gr.query();

    while (gr.next()) {
        var userSysId = gr.sys_created_by.toString();
        var count = parseInt(gr.getAggregate('COUNT', 'sys_created_by'), 10);
        var userGr = new GlideRecord('sys_user');
        if (userGr.get(userSysId)) {
            var userName = userGr.name.toString();
            if (count > threshold) {
                gs.eventQueue('custom.suspicious.activity', userSysId, count, '');
                gs.warn('Suspicious activity detected: User [' + userName + '] | Sys ID: ' + userSysId + ' made ' + count + ' transactions in the last ' + minutesBack + ' minutes.');
                suspiciousUsers.push({
                    name: userName,
                    sysId: userSysId,
                    count: count
                });
            }
        }
    }
    if (suspiciousUsers.length > 0) {
        gs.warn('=== Suspicious User Summary (Last ' + minutesBack + ' mins, Threshold: ' + threshold + ' transactions) ===');
        suspiciousUsers.forEach(function(user) {
            gs.warn('User: ' + user.name + ' | Sys ID: ' + user.sysId + ' | Transactions: ' + user.count);
        });
        gs.warn('=== End of Summary ===');
    } else {
        gs.info('No suspicious activity detected in the last ' + minutesBack + ' minutes.');
    }
})();

 

This script checks who has made too many actions in ServiceNow in the last few minutes.
If someone crosses the limit, it records their details and will show the results.

 

I tried it on PDI for a small time period and for less number of transactions.

Used Values :

var minutesBack = 50;  // How far back we want to look in transaction history (in minutes)
var threshold = 5;   // Max allowed transactions per user in the given time window
 
Screenshot (10).png
 
If this helps, please consider marking my answer as accepted — it motivates me to stay active in the community and also helps others find relevant solutions more easily.
 
Thank you!
If this works, please mark it as helpful/accepted — it keeps me motivated and helps others find solutions.
Shashank Jain

View solution in original post

3 REPLIES 3

Shashank_Jain
Kilo Sage

@JozsefB , 

You can use this script as per your requirement :

(function() {
    var minutesBack = 50;  // How far back we want to look in transaction history (in minutes)
    var threshold = 5;   // Max allowed transactions per user in the given time window
    // Array to store summary of suspicious users
    var suspiciousUsers = [];
    var gr = new GlideAggregate('syslog_transaction');
    gr.addAggregate('COUNT', 'sys_created_by');
    gr.addEncodedQuery('sys_created_on>=javascript:gs.minutesAgoStart(' + minutesBack + ')');
    gr.groupBy('sys_created_by');
    gr.query();

    while (gr.next()) {
        var userSysId = gr.sys_created_by.toString();
        var count = parseInt(gr.getAggregate('COUNT', 'sys_created_by'), 10);
        var userGr = new GlideRecord('sys_user');
        if (userGr.get(userSysId)) {
            var userName = userGr.name.toString();
            if (count > threshold) {
                gs.eventQueue('custom.suspicious.activity', userSysId, count, '');
                gs.warn('Suspicious activity detected: User [' + userName + '] | Sys ID: ' + userSysId + ' made ' + count + ' transactions in the last ' + minutesBack + ' minutes.');
                suspiciousUsers.push({
                    name: userName,
                    sysId: userSysId,
                    count: count
                });
            }
        }
    }
    if (suspiciousUsers.length > 0) {
        gs.warn('=== Suspicious User Summary (Last ' + minutesBack + ' mins, Threshold: ' + threshold + ' transactions) ===');
        suspiciousUsers.forEach(function(user) {
            gs.warn('User: ' + user.name + ' | Sys ID: ' + user.sysId + ' | Transactions: ' + user.count);
        });
        gs.warn('=== End of Summary ===');
    } else {
        gs.info('No suspicious activity detected in the last ' + minutesBack + ' minutes.');
    }
})();

 

This script checks who has made too many actions in ServiceNow in the last few minutes.
If someone crosses the limit, it records their details and will show the results.

 

I tried it on PDI for a small time period and for less number of transactions.

Used Values :

var minutesBack = 50;  // How far back we want to look in transaction history (in minutes)
var threshold = 5;   // Max allowed transactions per user in the given time window
 
Screenshot (10).png
 
If this helps, please consider marking my answer as accepted — it motivates me to stay active in the community and also helps others find relevant solutions more easily.
 
Thank you!
If this works, please mark it as helpful/accepted — it keeps me motivated and helps others find solutions.
Shashank Jain

Thanks for this nice script Shashank.

It would solve the problem for a small company, and runs nice on a PDI. But our transaction log, and workload of the instance is way higher. SRE team would immediately kill the running script (and me 🙂  ) if I would like to run it in production.

Also the transaction limit should be different for a business user, and ITIL user and a support agent.

 

But I appreciate your help. Your code really does the job, but unfortunately not for us.

@JozsefB ,

You can make update in the code if needed as per the business requirement.

But that's okay, I guess running this again and again will be a issue too for an instance with large data.

 

If this was helpful and correct. Can you please mark it as accepted so it help other future readers.

That will be much appreciated.

 

 

 

If this works, please mark it as helpful/accepted — it keeps me motivated and helps others find solutions.
Shashank Jain