Safari

Safari Sessions

Overview

Safari records the state of all open windows and tabs when the browser is closed. This session data is stored in LastSession.plist and is used by Safari to restore the user's browsing state on the next launch. For forensic investigations, session data provides a snapshot of what the user was actively browsing at the time Safari was last closed -- a high-value artifact for understanding recent user activity.

Session data captures not only the URLs and titles of open tabs but also window-level metadata including which tab was selected (active), whether the window was a Private Browsing window, and unique identifiers for each window and tab.

File Locations

FilePathFormat
Last session state~/Library/Safari/LastSession.plistBinary Property List
Recently closed tabs~/Library/Safari/RecentlyClosedTabs.plistBinary Property List
Cloud tabs~/Library/Safari/CloudTabs.dbSQLite
Tab groups~/Library/Safari/SafariTabs.dbSQLite

The primary artifact is LastSession.plist. Additional session-related files provide supplementary context.

File Format

LastSession.plist is a binary property list with a structured hierarchy of session, windows, and tabs.

Plist Structure

Root (Dictionary)
  SessionVersion (Integer)
  SessionWindows (Array)
    [0] (Dictionary) -- Window
      WindowUUID (String)
      IsPrivate (Boolean)
      SelectedTabIndex (Integer)
      TabStates (Array)
        [0] (Dictionary) -- Tab
          TabUUID (String)
          TabURL (String)
          TabTitle (String)
          LastVisitTime (Date)
          isAppInitiated (Boolean)
        [1] (Dictionary)
          ...
    [1] (Dictionary) -- Window
      ...

Window Fields

KeyTypeDescription
WindowUUIDStringUnique identifier for the window
IsPrivateBooleanWhether this is a Private Browsing window
SelectedTabIndexIntegerIndex of the active/focused tab (0-based)
TabStatesArrayArray of tab state dictionaries

Tab Fields

KeyTypeDescription
TabUUIDStringUnique identifier for the tab
TabURLStringCurrent URL loaded in the tab
TabTitleStringPage title displayed on the tab
LastVisitTimeDateTimestamp of the last visit to this tab's URL
isAppInitiatedBooleanWhether the tab was opened by the app (e.g., session restore)

Additional Session Files

RecentlyClosedTabs.plist (macOS 10.13+): Records tabs that were recently closed, enabling Safari's "Reopen Last Closed Tab" feature. Structure is similar to tab entries in LastSession.plist.

CloudTabs.db (macOS 11.0+): SQLite database containing tabs synced via iCloud from the user's other Apple devices. Can reveal browsing activity on iPhones, iPads, and other Macs linked to the same Apple ID.

SafariTabs.db (macOS 12.0+): SQLite database for the Tab Groups feature, which allows users to organise tabs into named groups. Tab group names chosen by the user can be highly informative.

Key Fields for Analysis

  • TabURL: The current URL of each open tab. This reveals what the user was actively looking at when Safari closed.
  • TabTitle: The page title provides context even when the URL is opaque (e.g., dynamically generated URLs or URLs with encoded parameters).
  • SelectedTabIndex: Identifies which tab was in focus in each window. The selected tab represents what the user was most recently viewing in that window.
  • IsPrivate: A value of true indicates a Private Browsing window. While Safari does not persist Private Browsing history, the session state may capture private window tab URLs if Safari was not cleanly closed.
  • WindowUUID / TabUUID: Unique identifiers for correlation across artifacts and backup snapshots.
  • isAppInitiated: Distinguishes between tabs opened by user action and tabs restored automatically by Safari's session restore feature. A value of true typically indicates the tab was part of a restored session rather than opened by the user in the current session.
  • LastVisitTime: When available, provides a timestamp for the last navigation in each tab.

Timestamps

The LastVisitTime field is stored as a standard property list <date> value in ISO 8601 format. Not all tabs may have this field populated.

The modification time of LastSession.plist itself indicates when Safari was last closed (or when the session state was last saved).

Analysis Notes

  • Active browsing snapshot: LastSession.plist captures the exact state of the browser at the moment it was closed. This is particularly valuable when the user was in the middle of a task -- open tabs in email, document editing, research, or communication services reveal current activity.
  • Multiple windows: Users may have multiple windows open, each with its own set of tabs. The window array preserves all windows. Examine each window separately as they may represent different tasks or contexts.
  • Private browsing detection: The IsPrivate flag on windows reveals that the user had Private Browsing windows open. While the flag only appears in session data (not persisted history), its presence is evidence that Private Browsing was in use.
  • Tab count as indicator: An unusually large number of tabs may indicate research activity. The specific tabs open provide context for the research topic.
  • Session restore artefact: When Safari restores a session after a crash or reboot, the isAppInitiated flag is set on restored tabs. This can help distinguish between tabs the user opened in the current session and those carried forward from a previous session.
  • Correlation with history: Cross-reference tab URLs with History.db to determine when each tab was first opened and how long it had been open.
  • Cloud tabs: If CloudTabs.db exists, it can reveal tabs open on the user's other Apple devices, providing a broader picture of cross-device browsing activity.

Version Differences

VersionChange
Safari 10-14 (macOS 10.12-10.15)Basic session state with windows and tabs
Safari 13+ (macOS 10.13+)RecentlyClosedTabs.plist introduced
Safari 15+ (macOS 11.0+)CloudTabs.db for iCloud tab sync
Safari 15+ (macOS 12.0+)SafariTabs.db for Tab Groups feature

The LastSession.plist format has remained stable, with minor additions to per-tab metadata in newer versions.

Tool Support

macfor

The browser.safari plugin parses LastSession.plist and emits two record types:

  • browser_session_window: Window-level records with fields window_index, window_uuid, is_private, selected_tab_index, tab_count, and source_file.
  • browser_session_tab: Tab-level records with fields window_index, tab_index, tab_uuid, url, title, last_visit_time, is_app_initiated, and source_file.

The raw plist file is also preserved in the evidence container.

Manual Analysis

# Convert to XML for inspection
plutil -convert xml1 -o - ~/Library/Safari/LastSession.plist

# Quick summary with Python
python3 -c "
import plistlib
with open('LastSession.plist', 'rb') as f:
    session = plistlib.load(f)
windows = session.get('SessionWindows', [])
print(f'Session version: {session.get(\"SessionVersion\", \"unknown\")}')
print(f'Windows: {len(windows)}')
for i, window in enumerate(windows):
    private = ' [PRIVATE]' if window.get('IsPrivate', False) else ''
    tabs = window.get('TabStates', [])
    selected = window.get('SelectedTabIndex', -1)
    print(f'\nWindow {i}{private} ({len(tabs)} tabs, selected: {selected})')
    for j, tab in enumerate(tabs):
        marker = ' <-- ACTIVE' if j == selected else ''
        url = tab.get('TabURL', 'about:blank')
        title = tab.get('TabTitle', '')
        print(f'  [{j}] {title[:60]}')
        print(f'       {url[:80]}{marker}')
"

References

Previous
Local Storage