Skip to main content

One of the common issues when examining Google email data, especially from free Gmail accounts, is the lack of a detailed activity log. Gmail offers basic logs that cover recent account access and security events, but not events concerning user activity within the account. Gmail History Records are an often overlooked data point that can fill that gap in some cases.

What Are Gmail History Records?

Gmail History Records are a data point I typically list as part of “server metadata” when talking about email forensics. This is because the data is kept on the server and is not exported as part of the individual messages that are acquired—whether it be via Gmail API, IMAP, or Takeout.

History Records are exposed by Gmail API primarily to allow email clients to efficiently synchronize mailboxes. When an email client first connects to a Gmail mailbox, it performs a full synchronization and keeps track of the historyId of the most recent message for future partial synchronizations. In the future, instead of requesting a listing of everything in the mailbox, the email client requests history records based on this historyId and performs a partial synchronization. If the requested history records are no longer available, the email client would need to perform another full synchronization.

What Information Do Gmail History Records Contain?

Gmail History Records are returned in chronological order and contain lists of labels that were added to and removed from messages, and messages that were added to and removed from the mailbox as well as an ID.

What Is The Forensic Relevance?

Let’s look at a few examples of what we can glean from history records:

Labels added & removed: Some of the user activity is reflected in Gmail labels, and finding out labels that were added to and removed from messages can help shed light on user activity in the mailbox. For example, reading a message would cause the “Unread” label to be removed from that message. Soft deleting a message would cause the “Trash” label to be applied to the message. Marking a previously read message as “unread” would cause the “Unread” label to be applied to the message.

Messages added & removed: History records themselves do not have timestamps (although, they are returned in chronological order with ascending IDs). However, messages that are added to the mailbox have associated timestamps, and history records that reference added messages serve as anchor points that can be used to date other events in the mailbox.

On the other hand, the list of removed messages can help determine if any messages were deleted from the mailbox in a critical time period—for instance, after a litigation hold was issued. If a message was permanently deleted (rather than being moved to Trash), we can obtain its ID via History Records but not the rest of the message data or metadata. In some cases, if prior History Records or a preservation copy of the mailbox is available, it may be possible to reference that ID and find more information about the message that was deleted.

Example Scenario

Let’s work through an example to see what we can find in History Records. In this example, our suspect does the following:

Action #1—On June 30, 2020 at around 9:40 PM (UTC), using Gmail’s web interface, he opens and reads a message with the subject “☕️ Worried” that was dated June 25, 2020. This causes the message to be marked “Read”.

Action #2—About a minute later, he opens another message with the subject “Now I Know: Why We Have a Silent B”, reads it, and soft deletes it.

Action #3—About a minute later, he opens another message with the subject “☕️Catch 19”, soft deletes it, and then deletes it from Trash—causing it to become inaccessible via Gmail’s web interface.

Action #4—At 9:48 PM (UTC), he goes back to the message he read earlier with the subject “☕️ Worried”, and marks it as “Unread” via Gmail’s web interface.

I’ve acquired the Gmail History Records from this mailbox starting at June 29, 2020 using Forensic Email Collector, and removed some of the unrelated records for clarity. The records look as follows (anchor dates highlighted). Note that some of the message IDs below also contain hidden timestamps, which can be great corroborating evidence!

------ HISTORY RECORD ID: 167481 ------
   Messages Added:
      ID: 173072c6f767d3b4
      Folder Path: All Mail
      Subject: Verify Your Email Address for NextDraft
      From: NextDraft <dave@davenetics.com>
      To: <lmisf01@gmail.com>
      Message ID: <ed102783e87fee61c1a534a9da581528a3b.20200630214016@mail1.davenetics.com>
      Date: 2020-06-30 21:40:16Z
      
------ HISTORY RECORD ID: 167547 ------
   Labels Removed:
      Removed Label ID: UNREAD

      From Message:
         ID: 173072c6f767d3b4
         Folder Path: All Mail
         Subject: Verify Your Email Address for NextDraft
         From: NextDraft <dave@davenetics.com>
         To: <lmisf01@gmail.com>
         Message ID: <ed102783e87fee61c1a534a9da581528a3b.20200630214016@mail1.davenetics.com>
         Date: 2020-06-30 21:40:16Z
         
------ HISTORY RECORD ID: 167624 ------
   Labels Removed:
      Removed Label ID: UNREAD

      From Message:
         ID: 172eb359bd8a1fa8
         Folder Path: All Mail
         Subject: ☕️ Worried
         From: Morning Brew <crew@morningbrew.com>
         To: lmisf01@gmail.com
         Message ID: <20200625061937.20719468.1585531@sailthru.com>
         Date: 2020-06-25 10:19:37Z
         
------ HISTORY RECORD ID: 167679 ------
   Labels Removed:
      Removed Label ID: UNREAD

      From Message:
         ID: 172c7dd331fec2cf
         Folder Path: All Mail
         Subject: Now I Know: Why We Have a Silent B
         From: Dan Lewis <dan@nowiknow.com>
         To: <lmisf01@gmail.com>
         Message ID: <2889002ad89d45ca21f50ba46.84d419bcde.20200618141650.9673d35bd3.ed230edf@mail142.atl61.mcsv.net>
         Date: 2020-06-18 14:17:02Z
         
------ HISTORY RECORD ID: 167740 ------
   Labels Added:
      Added Label ID: TRASH

      To Message:
         ID: 172c7dd331fec2cf
         Folder Path: All Mail
         Subject: Now I Know: Why We Have a Silent B
         From: Dan Lewis <dan@nowiknow.com>
         To: <lmisf01@gmail.com>
         Message ID: <2889002ad89d45ca21f50ba46.84d419bcde.20200618141650.9673d35bd3.ed230edf@mail142.atl61.mcsv.net>
         Date: 2020-06-18 14:17:02Z
         
------ HISTORY RECORD ID: 167741 ------
   Labels Removed:
      Removed Label ID: INBOX

      From Message:
         ID: 172c7dd331fec2cf
         Folder Path: All Mail
         Subject: Now I Know: Why We Have a Silent B
         From: Dan Lewis <dan@nowiknow.com>
         To: <lmisf01@gmail.com>
         Message ID: <2889002ad89d45ca21f50ba46.84d419bcde.20200618141650.9673d35bd3.ed230edf@mail142.atl61.mcsv.net>
         Date: 2020-06-18 14:17:02Z
         
------ HISTORY RECORD ID: 167774 ------
   Labels Removed:
      Removed Label ID: UNREAD

      From Message:
         ID: 172c1e296e257050
         Folder Path: All Mail
         Subject: ☕️Catch 19
         From: Morning Brew <crew@morningbrew.com>
         To: lmisf01@gmail.com
         Message ID: <20200617061105.20640144.1612142@sailthru.com>
         Date: 2020-06-17 10:11:05Z
         
------ HISTORY RECORD ID: 167834 ------
   Labels Added:
      Added Label ID: TRASH

      To Message:
         ID: 172c1e296e257050
         Folder Path: All Mail
         Subject: ☕️Catch 19
         From: Morning Brew <crew@morningbrew.com>
         To: lmisf01@gmail.com
         Message ID: <20200617061105.20640144.1612142@sailthru.com>
         Date: 2020-06-17 10:11:05Z
         
------ HISTORY RECORD ID: 167835 ------
   Labels Removed:
      Removed Label ID: INBOX

      From Message:
         ID: 172c1e296e257050
         Folder Path: All Mail
         Subject: ☕️Catch 19
         From: Morning Brew <crew@morningbrew.com>
         To: lmisf01@gmail.com
         Message ID: <20200617061105.20640144.1612142@sailthru.com>
         Date: 2020-06-17 10:11:05Z
         
------ HISTORY RECORD ID: 167867 ------
   Messages Deleted:
      ID: 172c1e296e257050
      Folder Path: All Mail
      Subject: ☕️Catch 19
      From: Morning Brew <crew@morningbrew.com>
      To: lmisf01@gmail.com
      Message ID: <20200617061105.20640144.1612142@sailthru.com>
      Date: 2020-06-17 10:11:05Z
      
------ HISTORY RECORD ID: 167874 ------
   Messages Added:
      ID: 1730730a11a26765
      Folder Path: All Mail
      Subject: Pleased to meet you
      From: theSkimm <dailyskimm@morning7.theskimm.com>
      To: lmisf01@gmail.com
      Message ID: <20200630214453.5efbb255de38f651496c7f51@sailthru.com>
      Date: 2020-06-30 21:44:53Z
      
------ HISTORY RECORD ID: 167950 ------
   Messages Added:
      ID: 1730730cf0d2d31a
      Folder Path: All Mail
      Subject: NextDraft: Subscription Confirmed
      From: NextDraft <dave@davenetics.com>
      To: <lmisf01@gmail.com>
      Message ID: <ed102783e87fee61c1a534a9da581528a3b.20200630214505@mail1.davenetics.com>
      Date: 2020-06-30 21:45:05Z
      
------ HISTORY RECORD ID: 168042 ------
   Labels Added:
      Added Label ID: UNREAD

      To Message:
         ID: 172eb359bd8a1fa8
         Folder Path: All Mail
         Subject: ☕️ Worried
         From: Morning Brew <crew@morningbrew.com>
         To: lmisf01@gmail.com
         Message ID: <20200625061937.20719468.1585531@sailthru.com>
         Date: 2020-06-25 10:19:37Z
         
------ HISTORY RECORD ID: 168069 ------
   Messages Added:
      ID: 17307352ddb39733
      Folder Path: All Mail
      Subject: Confirm your subscription to Dixie Mech
      From: Dixie Mech <help@dixiemech.com>
      To: lmisf01@gmail.com
      Message ID: <6621db6feb9b43b1a66613375acfee7d@dixiemech.com>
      Date: 2020-06-30 21:49:51Z

Line 1—The first record lists a message that was added to the mailbox dated June 30, 2020 9:40:16 PM (UTC). This helps set a reference point for the history records that follow.

Line 11—The next record shows that the “Unread” label was removed from the message above.

Line 24—The next record shows that the “Unread” label was removed from our suspect message with the subject “☕️ Worried”, which corresponds to Action #1 above.

Line 37-74—The next three records show that the “Unread” and “Inbox” labels were removed from a message with the subject “Now I Know: Why We Have a Silent B”, and the “Trash” label was applied to it. In effect, the message was read and moved to trash—consistent with Action #2.

Line 76-123—The next four records show that the “Unread” and “Inbox” labels were removed from a message with the subject “☕️Catch 19”, the “Trash” label was applied to it, and then the message was deleted—consistent with Action #3.

Line 125-143—The next two records show that two unrelated messages arrive at the mailbox with dates June 30, 2020 9:44:53 PM (UTC) and June 30, 2020 9:45:05 PM (UTC), another point of timing reference. This shows that the actions above took place likely between 9:40:16 PM and 9:44:53 PM (UTC) on June 30, 2020.

Line 145—The next record shows that the “Unread” label was added to a message with the subject “☕️ Worried”. In effect, the message was marked as “Unread” after the fact. This is Action #4.

Line 158—The last record shows the arrival of another message, dated June 30, 2020 9:49:51 PM (UTC). This shows that the operation above likely took place between 9:45:05 PM and 9:49:51 PM (UTC) on June 30, 2020.

Important Note: In the example above, the metadata for the permanently deleted message was cached from a previous history record acquisition and FEC filled in the blanks. In the absence of prior data, the history records would only show the ID of the permanently deleted message, but not its metadata.

Any Caveats?

Yes, the biggest one is the availability of History Records. Gmail’s API documentation states that “[a] historyId is typically valid for at least a week, but in some rare circumstances may be valid for only a few hours”. In our test mailboxes, we have seen Gmail History Records being available going back approximately a month. So, this is a data point that needs to be used fairly urgently or the window of opportunity may close quickly.

Additionally, my testing shows that it is possible to influence the apparent dates of messages referenced in History Records by syncing manipulated messages into the mailbox. This is consistent with my prior findings on manipulated messages and Gmail. Therefore, it is important to validate the emails being relied upon by also examining other server data such as IMAP UIDs and Internal Dates as well as message metadata. When considered together, the sequence information from History IDs, IMAP UIDs, and IMAP Internal Dates as well as timestamps hidden in Message IDs and other internal message data and metadata help validate findings.

Conclusion

Gmail History Records are a bit of a hidden gem for forensic examiners. They are not included in conventional email exports, and not accessible via Gmail’s web interface. However, in the absence of an audit log, History Records can be very valuable in forensic email investigations. Specifically, examiners can use events with associated timestamps as anchor points for timing information, and answer questions such as “were any messages deleted after the litigation hold was issued?”, “did the user mark a previously read message as unread?”, and more. It is important to note that History Records are short-lived, and should be forensically preserved as soon as possible.

Finally, I recommend validating the dates found in connection with History Records by authenticating the messages used as anchor points. One can utilize a combination of server metadata as well as message data and metadata to confirm the validity of the relevant timestamps.

References:

  • Synchronizing Clients with Gmail — https://developers.google.com/gmail/api/guides/sync
  • Users.history: list — https://developers.google.com/gmail/api/v1/reference/users/history/list