Randomise Ticket ID

Hello !

I’m in the process of deploying RT 5.0.7 with RTIR 5.0.6 for my company, and we’ve noticed a point that we think is important to resolve: ticket IDs.

In fact, with our CISO, we noticed that this could be a security problem, as users who create a ticket can access other tickets by entering their IDs in the subject line of their e-mails, instead of the ID for the ticket they have created.

However, we want to randomize these IDs to make it more complicated to reply to a ticket that isn’t ours.

Do you know ore have an idea of how we can do this? (via a script or a parameter to be configured in RT or RTIR itself?)

Technical information:

Database : PostgreSQL 14.12
OS : Ubuntu 22.04.4 LTS
Docker version 26.1.4, build 5650f9b

Note:

We are using an Docker version of RTIR from Firefart : firefart/requesttracker - Docker Image | Docker Hub

Re,

While waiting for a concrete solution integrated (maybe) to RT, I set up a SQL script coupled to a cron modifying each day the value of the starting increment so that it is unique.

It’s not ideal, but it’s better than nothing.

Users should not be able to affect, or even read, tickets to which they have no access. Mailgate should throw an error if they try to correspond with a ticket to which they have no access. If it doesn’t do that, that’s a bug that ought to be reported. I’ve tested it on my instance and I can’t correspond with a ticket I don’t have access to.

That said, if it is a ticket to which they have access, they can change, or indeed add, the ticket number in the subject to direct an email to a given ticket.

Can you provide more detail on the unwanted behaviour?

Simon.

Hi!

In fact, with our CISO, we wanted to randomize the ticket IDs that are generated so that it’s as hard as possible to guess. Even if only the people concerned by the ticket can answer it.

It’s a wish of our CISO and so I’m looking to see if such a means exists and if so, which one.

You could try changing the function that generates the nextval in Postgres.

                                              Table "public.tickets"
     Column      |            Type             | Collation | Nullable |                  Default
-----------------+-----------------------------+-----------+----------+-------------------------------------------
 id              | integer                     |           | not null | nextval('tickets_id_seq'::text::regclass)

I’ve not tried it but I found this link that might help - sql - Replacing sequence with random number - Stack Overflow
Be aware that performance may fall off a cliff as I have no idea what effect a sparsely populated id field would have on index performance.
Also several pieces of code will expect an incrementing id, for instance the rt-externalize-attachments script stores the “highwater mark” ticket number, representing the most recent ticket id it’s processed. For that to work properly you would need to change it to use the createddate as the highwater mark. There will inevitably be many other examples of that in the code, but I use that example as I’ve just been working on that code (I’m not an RT dev or a Best Practical employee, I’ve just been using it for a really long time)

I did wonder whether you could utilise a custom field in the ticket to record a ticket reference different from the id. You could use this in email templates and amend on create and other scrips to match a real id number. BUT - RT exposes the true id in a number of different ways in the email headers, including (from one of my instance tickets):

References: <RT-Ticket-94360@digitalcraftsmen.com>
Message-ID: <rt-4.4.2-2274-1720009605-411.94360-4-0@digitalcraftsmen.com>
X-RT-Ticket: DCL #94360

So that route probably won’t be enough to disguise the true ID without a lot of code changes.

Of course, security through obscurity is no security at all, as your CISO really ought to know, however if they really want to have a flexible ticket reference format that was different from the internal ID, I’m sure Best Practical would be able to implement such a feature, for a suitable fee :wink:

Users should not be able to affect, or even read, tickets to which they have no access. Mailgate should throw an error if they try to correspond with a ticket to which they have no access. If it doesn’t do that, that’s a bug that ought to be reported. I’ve tested it on my instance and I can’t correspond with a ticket I don’t have access to.

I think they have probably granted the ReplyToTicket right to the Everyone group. In fact, mailgate suggests givung that right when rejecting emails. Such configuration can be useful so e.g. Alice is able to follow-up on a ticket originally opened by Bob. On the other hand, that allow a third party to send unrelated emails to existing tickets.

That’s very true - we’ve moved the permission from the Global group settings to a per-Queue model. One could have one inbound queue that accepts mail from anyone, and then move the ticket off to another queue that doesn’t. That would prevent someone replying to a ticket to which they are not the Requestor, and you can further refine the permissions to allow CCs to reply, but nobody else.
If you’ve enabled $ParseNewMessageForTicketCcs then any new CCs will be automatically added to RT.

@SimonW @Angel Thanks for your help ! :smiley:

I’ve created a bash script that runs automatically every day at 00:01 via cron until such a function is implemented (maybe one day) natively in RT :

#!/bin/bash

# Define log file
LOG_FILE="/var/log/rtir/update_sequence.log"

# Create or empty log file
> $LOG_FILE

# Message logging function
log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> $LOG_FILE
}

log "Script started."

# Retrieve and format the current date
formatted_date=$(date +%y%m%d000)
log "Formatted date: $formatted_date"

# Define database variables
DB_NAME="rt"
TABLE_NAME="tickets"
COLUMN_NAME="id"
SEQUENCE_NAME="${TABLE_NAME}_${COLUMN_NAME}_seq"

cd /home/postgres-home

# Update sequence
log "Updating sequence $SEQUENCE_NAME to start with $formatted_date..."
if sudo -u postgres psql -d $DB_NAME -c "ALTER SEQUENCE $SEQUENCE_NAME RESTART WITH $formatted_date;" >> $LOG_FILE 2>&1; then
    log "Sequence updated successfully."
else
    log "Error updating sequence."
    exit 1
fi

# Check the update
log "Verifying sequence update..."
if sudo -u postgres psql -d $DB_NAME -c "SELECT nextval('$SEQUENCE_NAME');" >> $LOG_FILE 2>&1; then
    log "Sequence verification successful."
else
    log "Error verifying sequence."
    exit 1
fi

log "Script finished."
1 Like