Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

STIX 2.1 Temporal Uncertainty Extension

A community extension for STIX 2.1 that adds temporal uncertainty support to objects and relationships.

Status: v1.0 — Community proposal. Implemented via the official STIX 2.1 Extension Definition mechanism.


Motivation

STIX 2.1 handles absolute timestamps well, but provides no native mechanism for expressing temporal uncertainty. In practice, CTI analysts often face situations where:

  • An event occurred within a time range, not at a precise moment ("between Jan 1 and Jan 5")
  • Multiple sources report different timestamps for the same event
  • A first_seen or start_time value is not available with certainty

This extension complements STIX native temporal fields without replacing them:

  • Native fields (first_seen, last_seen, start_time, stop_time) express certain information.
  • This extension is used when the information is uncertain.

The two never coexist on the same object for the same information.


Extension for Objects

Applicable to STIX objects that carry native temporal semantics: campaign, malware, threat-actor...

Extension Definition ID: extension-definition--97e3afda-ebea-400a-9cce-10fa1fb98b77

Structure

{
  "type": "malware",
  "extensions": {
    "extension-definition--97e3afda-ebea-400a-9cce-10fa1fb98b77": {
      "extension_type": "property-extension",
      "uncertainty_range": {
        "earliest": "2024-01-01T00:00:00Z",
        "latest": "2024-01-10T00:00:00Z",
        "most_probable": "2024-01-05T00:00:00Z"
      },
      "observations": [
        { "source": "firewall_log", "timestamp": "2024-01-03T00:00:00Z" },
        { "source": "analyst_report", "timestamp": "2024-01-08T00:00:00Z" }
      ]
    }
  }
}

Fields

Field Type Required Description
uncertainty_range object No* The synthesized uncertainty interval
uncertainty_range.earliest timestamp Yes (if present) Lower bound — RFC 3339 / UTC
uncertainty_range.latest timestamp Yes (if present) Upper bound — RFC 3339 / UTC
uncertainty_range.most_probable timestamp No Best estimate, set manually by the analyst
observations array No* Raw timestamps collected from sources
observations[].source string Yes Identifier of the source
observations[].timestamp timestamp Yes Timestamp reported by the source — RFC 3339 / UTC

*At least one of uncertainty_range or observations must be present.

Rules

  • If most_probable is absent, no automatic inference is made. The object is treated as temporally unresolved.
  • No confidence scores — CTI reports do not provide formally defined confidence values on timestamps.
  • No propagation of uncertainty to relationships — consistency is the implementer's responsibility.

Extension for Relationships

Applicable to STIX relationships with temporal duration: uses, targets, attributed-to...

Extension Definition ID: extension-definition--b19394bc-0293-4432-bf86-5338c02d227f

Structure

{
  "type": "relationship",
  "relationship_type": "uses",
  "extensions": {
    "extension-definition--b19394bc-0293-4432-bf86-5338c02d227f": {
      "extension_type": "property-extension",
      "start": {
        "uncertainty_range": {
          "earliest": "2024-01-01T00:00:00Z",
          "latest": "2024-01-10T00:00:00Z"
        }
      },
      "stop": null
    }
  }
}

Fields

Field Type Required Description
start object Yes Uncertainty block for the start of the relationship
stop object or null Yes Uncertainty block for the end — null if ongoing

Each start / stop block follows the same structure as the object extension (uncertainty_range + observations).

Rules

  • stop is always present, set to null when the relationship is ongoing or has no known end.
  • start_time / stop_time native fields and this extension never coexist on the same relationship.

Bundle Merge Rules

When merging two STIX bundles containing the same object (same id):

  • observations — union of both lists, deduplicated on (source, normalized timestamp)
  • earliest / latest — widened to min(earliest) / max(latest) across both bundles
  • most_probable — taken from the most recently modified bundle (modified field); inherited from the older bundle if the newer one does not have it

Python Package

Installation

pip install stix2 python-dateutil

Usage

import stix2
from temporal_uncertainty.extension import TemporalObjectUncertainty
from temporal_uncertainty.validator import validate_object, validate_relation
from temporal_uncertainty.merge import merge_objects, merge_relations

# Create a STIX object with temporal uncertainty
malware = stix2.Malware(
    name="ExampleMalware",
    malware_types=["trojan"],
    is_family=False,
    extensions={
        "extension-definition--97e3afda-ebea-400a-9cce-10fa1fb98b77": {
            "extension_type": "property-extension",
            "uncertainty_range": {
                "earliest": "2024-01-01T00:00:00Z",
                "latest": "2024-01-10T00:00:00Z"
            }
        }
    }
)

# Validate
validate_object(malware)

Repository Structure

stix2-temporal-uncertainty/
├── schemas/
│   ├── object_uncertainty.json      # JSON Schema for the object extension
│   ├── relation_uncertainty.json    # JSON Schema for the relation extension
│   └── common/
│       └── timestamp.json           # Shared RFC 3339 timestamp schema
├── extension-definition/
│   ├── extension-definition-objects.json
│   └── extension-definition-relations.json
├── examples/
│   ├── bundle_example.json          # Full CTI scenario
│   ├── bundle_simple.json           # Minimal bundle
│   └── minimal_example.json         # Single object and relation
├── python/
│   └── temporal_uncertainty/
│       ├── extension.py             # Extension registration (stix2)
│       ├── validator.py             # Business rule validation
│       └── merge.py                 # Bundle merge logic
└── spec/
    └── temporal-uncertainty.md      # Full specification

Future Work

  • Temporal uncertainty on punctual relationships (drops, exploits, downloads) — out of scope for v1.

Author

iliamsou — Community proposal, v1.0.

Licensed under Apache 2.0.

About

Adding temporal uncertainty to stix2 !

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages