In one sentence
STIX is the standard JSON format for describing threat intelligence — indicators, malware, attack patterns and how they relate — and TAXII is the HTTPS protocol for publishing and pulling STIX between organisations and tools.
Why it matters
Threat intelligence used to arrive as PDFs and spreadsheets, retyped by hand into each firewall and SIEM. STIX makes an indicator machine-readable and self-describing — the value, the pattern to match, when it is valid, who said so and how confident they are — and TAXII moves it automatically: your platform polls a partner's collection every hour and the blocklist updates itself. Every major threat-intelligence platform (MISP, OpenCTI, ThreatConnect, Anomali), the commercial feeds and the sector ISACs speak it; ATT&CK itself is published as a STIX bundle.
For a small team the payoff is simpler: an IOC list exported as STIX imports cleanly into whatever the next tool or the next partner uses, with stable identifiers so the same indicator is not duplicated on every exchange.
How it is structured
STIX 2.1 is JSON. Everything is an object with a type, a spec_version, an id of the form type--UUID, and created/modified timestamps. The main kinds:
- Domain objects (SDOs):
indicator,malware,attack-pattern(ATT&CK techniques),threat-actor,intrusion-set,campaign,tool,vulnerability,report,note,identity. - Relationship objects (SROs):
relationship(indicator indicates malware, intrusion-set uses attack-pattern) andsighting. - Cyber-observable objects (SCOs): the raw things —
ipv4-addr,domain-name,url,filewith hashes,email-addr. - Marking definitions: TLP, attached via
object_marking_refs. - A bundle is just a container:
{"type":"bundle","id":"bundle--…","objects":[…]}.
An indicator carries a pattern in the STIX pattern language — [domain-name:value = 'evil-cdn.example'], [file:hashes.'SHA-256' = '9f86…'], [ipv4-addr:value = '203.0.113.66'] — plus valid_from, optional valid_until, indicator_types (malicious-activity, anomalous-activity…) and confidence. Because ids are UUIDs, two parties emitting the same indicator with random ids create duplicates; the fix is deterministic UUIDv5 ids derived from the pattern, which is what the STIX-generating tools on this site do.
TAXII 2.1 is a small HTTPS API: a server exposes API roots, each with collections; clients GET …/collections/{id}/objects/?added_after=… to pull and POST to push, with content type application/taxii+json. Authentication is whatever the server chooses (usually HTTP basic or a token). It says nothing about the content beyond "STIX objects".
Try it yourself hands-on
You finished a phishing investigation with four indicators in a text file and the partner asks for "STIX, TLP:AMBER, so we can load it into MISP".
- Paste the list into the STIX 2.1 Formatter:
It refangs the URL, types each line, picks the right pattern (login-portal-example.com hxxps://login-portal-example[.]com/auth 203.0.113.66 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08domain-name,url,ipv4-addr,file:hashes.'SHA-256') and lets you set the TLP marking and anidentityfor your organisation ascreated_by_ref. - Look at one indicator in the output. Its id is a UUIDv5 of the pattern: run the same domain through the tool tomorrow and you get the same
indicator--…id, so MISP dedupes it against the copy you sent last month. The bundle id is random, as it should be. - Deliver the bundle. If the partner runs a TAXII server, this file is exactly the body of a
POSTto their collection; if they use MISP's import, the same file uploads as a STIX 2.1 event. - Case with more context than a flat list — which hosts you saw the indicators on, which incident they belong to? Build it in the IOC Pivoting Tool and export STIX from there: the export includes the relationships, not just the indicators. Either way, run the human-readable version through the IOC Defanger before it goes into the covering e-mail.
Common misreadings
- STIX 1 and STIX 2 are different formats. STIX 1.x was XML and is dead; "supports STIX" without a version usually means 2.0 or 2.1, and they are not identical (2.1 added
malware-analysis,grouping,note, and madespec_versionmandatory on every object). - A bundle is not a report. It has no author, no title, no narrative; use a
reportobject inside it for that. - Custom properties are allowed but not free.
x_myorg_…fields are legal;x-mytypeobjects that strict validators reject are not, and tools such as MISP will drop them.