Cart

After my Gmail History Records post earlier this month, there was a great discussion in our Community where Andris Reinman shared his findings on dates hidden in Gmail Message ID and Thread ID values. This prompted me to post this update to our Dates in Hiding series and write about what these data points are, where to find them, and how to uncover the hidden timestamps.

What Are Gmail Message IDs and Thread IDs?

When accessed via Gmail API, each message has an ID and a Thread ID. Message ID is the immutable identifier of a message while Thread ID indicates the thread to which the message belongs. Both of these values are represented in hexadecimal form, along the lines of 1736ccf5d7b4d452.

In addition to Gmail API, these values can be queried over IMAP using the IMAP Extensions provided by Gmail as the X-GM-MSGID and X-GM-THRID attributes. When queried over IMAP, the attributes are represented in decimal form as in 1672749667872724050.

Please note that the Gmail Message ID of a message is different than its Message-Id header field which might look something like this:

Message-Id: <13eba327.EAAAAO8sA-QAAcgxWv4AAAd9o_wAAAAIijYAAAAAAAYklQBfFbYb@mailjet.com>

Similarly, the Gmail Thread ID of a message is different than the Thread-Index that is found in some messages which would look as below. Thread-Index is the Conversation Index in Base64 encoded form.

Thread-Index: AdZVP5FZ1lMVdyWGSQmgf4yUt3eB7w==

Hidden Dates in Gmail Message IDs and Thread IDs

The below listing is an abbreviated version of Forensic Email Collector‘s Downloaded Items log and shows how the Message ID and Thread ID values appear in context (here, the Message ID is called “Service ID”).

Service IDMIME Hash [Sha256]Gmail LabelsThread ID
172ed79b0337c14f3C00EFB2…UNREAD;CATEGORY_PERSONAL;INBOX172ec7ef9fe17621
172ec89ed6c23410097A244C…UNREAD;CATEGORY_PERSONAL;INBOX172ec7ef9fe17621
172ec7ef9fe1762167285628…UNREAD;CATEGORY_PERSONAL;INBOX172ec7ef9fe17621
172ec173895583adCB89482E…UNREAD;CATEGORY_UPDATES;INBOX172ec173895583ad
172ec132c7c030735B93D6B4…CATEGORY_PROMOTIONS;UNREAD;Product Hunt;SPAM172ec132c7c03073

Note that while the Message IDs are unique, the Thread IDs are not. The ID of the third message is also the ID of the thread that the first three messages belong to. This thread ID ties them together.

Before we decode the dates, let’s look at a few example Gmail Message IDs:

172ed79b0337c14f
10010541f50c6918
1000a75140863eff
ffff4cdc5fe0758
ffff3432161af8b

You can see that the last two IDs are 15 digits long while the first three are 16 digits! This is because on November 3, 2004 at 7:53:47.775 PM (UTC), the date part of the IDs overflowed and started to require 11 digits instead of 10. The next overflow will happen on June 23, 2527 at 6:20:44.415 AM (UTC). So, it is safe to say that, unless Gmail changes things up, we should expect hexadecimal Gmail Message IDs to be 15 or 16 digits long in the foreseeable future.

Decoding the dates can be accomplished by dropping the last 5 digits of the ID and treating the rest as a hex Epoch date with millisecond precision. For instance:

ffff3432161af8b ➫ ffff343216 — drop last 5 digits

ffff343216 ➫ Wednesday, November 3, 2004 4:11:11.254 PM (UTC) — Convert from HEX Epoch date to human-readable date

Similarly, for a more recent ID:

172ed79b0337c14f ➫ 172ed79b033 — drop last 5 digits

172ed79b033 ➫ Thursday, June 25, 2020 9:54:34.675 PM (UTC) — Convert from HEX Epoch date to human-readable date

What Is The Forensic Relevance?

It is possible to find numerous timing artifacts in Gmail messages—or email messages in general—including in trace header fields, MIME boundary delimiters, DKIM signatures, Message-Id header fields, and more. The timestamps discussed above are yet another data point that can be used to verify the authenticity of a message.

One key difference is that Gmail Message IDs and Thread IDs are data points kept on the server rather than as parts of the message. Does this make them immune to manipulation? Not quite! But especially the Thread ID can be a very valuable data point as it reflects the timestamp of the parent message in a conversation thread. For instance, finding out that the Thread ID of a message, whose apparent date is in 2015, decodes to a date in 2017 would raise a red flag.

References:

  • https://developers.google.com/gmail/api/v1/reference/users/messages—Gmail API Users.messages Resource