Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
4ce0ec1
Fix accessibility violation: Add alt text to navbar logo image
huangkevin-apr Feb 4, 2026
8283010
chore: update mitreattack-python version
adpare Feb 12, 2026
6d31c17
Merge pull request #564 from huangkevin-apr/fix-a11y-aria-label
jondricek Feb 16, 2026
94fc971
refactor: enhance tactic handling in get_sub_matrices function
jondricek Feb 26, 2026
f8a8167
fix: handle exceptions during Excel file generation and log missing t…
jondricek Feb 26, 2026
0101351
fix: log error when no detected technique relationship is found for d…
jondricek Mar 9, 2026
8cd0a99
fix: improve error handling and logging for pelican command execution
jondricek Mar 9, 2026
feb5bd9
refactor: streamline redirection generation by consolidating file wri…
jondricek Mar 9, 2026
3bbda11
fix: remove unnecessary result handling in pelican command execution
jondricek Mar 9, 2026
53ea2d0
feat: add pre-staged Excel files for ATT&CK version 18.1 and update g…
jondricek Mar 12, 2026
2095e20
feat: add ATT&CK Advisory Council resources and member bios
jondricek Mar 17, 2026
e85382f
feat: add AGENTS.md for coding guidance and repository structure
jondricek Mar 17, 2026
3140886
fix: update ATT&CK Advisory Council announcement with hyperlink for c…
jondricek Mar 17, 2026
fdf7ac6
fix: re-order council members alphabetically
jondricek Mar 17, 2026
d9b1ba6
Merge remote-tracking branch 'origin/master' into develop
jondricek Apr 1, 2026
15ae7fc
fix: update technique title tag to enable searching for technique pages
adpare Apr 10, 2026
cf283c4
chore: add start and stop indexing for search
adpare Apr 10, 2026
7346fcc
chore: update stop index for search functionality
adpare Apr 10, 2026
beb9f5a
Merge pull request #567 from mitre-attack/fix-search-for-techniques
jondricek Apr 21, 2026
a5887b8
chore: remove empty advisory page
adpare Apr 21, 2026
e017166
fix: enhance error handling for analytics and detection strategies
jondricek Apr 22, 2026
e636f7c
fix: skip revoked or deprecated detection strategies in datacomponent…
jondricek Apr 23, 2026
880731c
fix: add redirect for ics
adpare Apr 23, 2026
a5f206c
feat: add pelican sitemap support
jondricek Apr 23, 2026
34d592e
fix: update redirection logic
adpare Apr 24, 2026
be05038
Merge pull request #568 from mitre-attack/ics-redirects
adpare Apr 24, 2026
8b9f0fc
fix: filter out deprecated and revoked tactics in markdown generation
jondricek Apr 28, 2026
65f1e97
feat: add ATT&CK Sightings redirect and remove static sightings page
jondricek Apr 28, 2026
f860f9a
Merge remote-tracking branch 'origin/master' into develop
jondricek Apr 28, 2026
d28afb3
fix: update website banner to reflect the release of ATT&CK v19
jondricek Apr 28, 2026
786db42
fix: correct subtechnique ID extraction in technique template
jondricek Apr 28, 2026
b85f333
fix: update AGENTS.md with improved guidance on Python environment an…
jondricek Apr 28, 2026
919e46b
feat: update October 2025 release notes, enhance search indexing, bum…
jondricek Apr 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .env.template
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
PELICAN_AUTHOR="MITRE"
PELICAN_SITENAME="ATT&CK"
PELICAN_SITEURL="https://attack.mitre.org"
PELICAN_TIMEZONE="America/New_York"
PELICAN_DEFAULT_LANG="en"
ATTACK_VERSION_ARCHIVES="attack-version-archives"
BANNER_ENABLED=True
BANNER_MESSAGE="This is a custom instance of the MITRE ATT&CK Website. The official website can be found at <a href='https://attack.mitre.org'>attack.mitre.org</a>."
STIX_LOCATION_ENTERPRISE="https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/enterprise-attack.json"
STIX_LOCATION_MOBILE="https://raw.githubusercontent.com/mitre/cti/master/mobile-attack/mobile-attack.json"
STIX_LOCATION_ICS="https://raw.githubusercontent.com/mitre/cti/master/ics-attack/ics-attack.json"
STIX_LOCATION_PRE="https://raw.githubusercontent.com/mitre/cti/master/pre-attack/pre-attack.json"
WORKBENCH_USER=""
WORKBENCH_API_KEY=""
GOOGLE_ANALYTICS=""
GOOGLE_SITE_VERIFICATION=""
INCLUDE_OSANO=""
1 change: 1 addition & 0 deletions .github/workflows/gh-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ jobs:
GOOGLE_ANALYTICS: ${{ secrets.GOOGLE_ANALYTICS }}
GOOGLE_SITE_VERIFICATION: ${{ secrets.GOOGLE_SITE_VERIFICATION }}
INCLUDE_OSANO: true
PELICAN_SITEURL: https://attack.mitre.org

- name: Cleanup build
run: rm -rf attack-version-archives
Expand Down
199 changes: 199 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
# AGENTS.md

This file is guidance for coding agents working in `attack-website`.

## Scope

- Applies to the repository root.
- There was no existing `AGENTS.md` to preserve.
- No Cursor rules were found in `.cursor/rules/` or `.cursorrules`.
- No Copilot instructions were found in `.github/copilot-instructions.md`.
- Primary human docs are `DEVELOPMENT.md`, `README.md`, `test/README.md`, and `CONTRIBUTING.md`.

## Repo Shape

- Root Python build system generates the static site via `update-attack.py`.
- `attack-search/` is a separate Node/CommonJS project for the search bundle.
- Search source and tests live in `attack-search/src/` and `attack-search/__tests__/`.
- `attack-style/` is a separate Node/Sass project for CSS output.
- SCSS entrypoints are `attack-style/style-attack.scss` and `attack-style/style-user.scss`.
- `attack-theme/` contains Jinja templates, static assets, and legacy browser JS.
- Theme templates and static assets live in `attack-theme/templates/` and `attack-theme/static/`.
- `modules/` contains Python modules that generate ATT&CK site content.
- `test/` provides an Nginx Docker environment for validating the built site.

## Environment Expectations

- Python 3 is required for the main build.
- When managing a local Python environment, prefer `uv` with a virtual environment at `.venv` in the git repository root.
- Node.js and npm are required for `attack-search/` and `attack-style/`.
- Docker is the preferred way to validate the final static output in an Nginx-like environment.
- CI currently uses Python `3.13` and Node `18.x` in `.github/workflows/gh-pages.yml`.
- Prefer CI versions when reproducing CI behavior; Docker and development docs may reference older base images.
- Production-like builds may depend on environment variables from `.github/workflows/gh-pages.yml`, including `GOOGLE_ANALYTICS`, `GOOGLE_SITE_VERIFICATION`, `INCLUDE_OSANO`, and `PELICAN_SITEURL`.

## High-Value Commands

Run commands from the repo root unless a subdirectory is called out.

### Install

- Preferred Python env: `uv venv .venv`
- Python deps: `uv pip install -r requirements.txt`
- Search deps: `cd attack-search && npm ci`
- Style deps: `cd attack-style && npm ci`
- Prefer `npm ci` over `npm install`; do not update lockfiles unless dependency changes are part of the task.

### Build

- Main website build: `uv run python update-attack.py --attack-brand --extras --no-test-exitstatus`
- Search bundle: `cd attack-search && npm run build`
- Search dev bundle: `cd attack-search && npm run build:dev`
- Copy built search bundle into site output: `cd attack-search && npm run copy`
- Style build: `cd attack-style && npm run build`
- Style build + copy into theme static assets: `cd attack-style && npm run build-copy`

### Local Validation

- Full local site validation follows `DEVELOPMENT.md` and `test/README.md`.
- Build site output first, then serve `output/` through the Docker test image.
- Test container build: `cd test && docker build -t attack-website-test .`
- Test container run: `cd test && docker run -p 80:80 -v $(pwd)/../output:/workspace attack-website-test`
- Helper script: `cd test && ./run_test.sh`

### Lint And Format

- Python lint (configured, not wired into CI): `ruff check .`
- Python lint autofix: `ruff check --fix .`
- Python format: `ruff format .`
- Search lint: `cd attack-search && npm run lint`
- Search lint autofix: `cd attack-search && npm run lint:fix`
- Style lint: `cd attack-style && npm run lint`

### Tests

- Search tests: `cd attack-search && npm test`
- Single Jest test file: `cd attack-search && npm test -- __tests__/search-service.test.js`
- Alternate single Jest file: `cd attack-search && npx jest __tests__/search-service.test.js`
- Main Python-driven site tests run through the build script, not `pytest`.
- Run specific site test categories: `uv run python update-attack.py -m tests -t size`
- Multiple site test categories: `uv run python update-attack.py -m tests -t links external_links citations`

### Important Command Notes

- There is no root `package.json`, `Makefile`, or single universal test runner.
- CI clearly builds the site and search bundle, but does not currently enforce Jest, ESLint, Stylelint, Ruff, or type checks.
- For Python-side testing, the narrowest supported scope is a named category (`size`, `links`, `external_links`, `citations`), not an individual test file.
- Preferred production-like validation is Nginx via Docker, not Pelican's built-in dev server.
- Pelican's built-in development server does not match production Nginx routing behavior.

## Source Of Truth

- Follow existing file-local conventions before applying generic preferences.
- Treat `pyproject.toml`, `attack-search/.eslintrc`, and `attack-style/.stylelintrc.json` as authoritative style configs.
- Treat `DEVELOPMENT.md` and `.github/workflows/gh-pages.yml` as authoritative for build workflow.
- In templates, respect comments that mark generated files or source-of-truth files.
- Example: `attack-theme/templates/general/base-template.html` explicitly says to edit `base-template.html`, not generated `base.html`.

## Generated And Volatile Outputs

- Do not edit `output/` as source; regenerate it through the build pipeline.
- Avoid direct edits to `attack-search/dist/` and `attack-style/dist/` unless the task explicitly targets generated artifacts.
- Avoid direct edits to copied assets in `attack-theme/static/` when a source file in `attack-style/` or another generator owns the output.
- Preserve generated-file comments and edit the named source template or source asset instead.

## Python Style

- Use 4-space indentation.
- Match Ruff formatting and the configured 120-character line length.
- Keep imports grouped as standard library, third-party, then local imports.
- Use Ruff when reorganizing imports.
- Prefer `snake_case` for variables, functions, and module names.
- Reserve `UPPER_CASE` for constants or config-like values.
- Keep modules function-oriented and simple; the codebase uses few classes outside JS.
- Type hints are not a dominant convention here; do not introduce a large typing layer unless the touched area already uses it.
- Python type hints are desired to be added over time.
- Python docstrings should follow NumPy conventions.

## Python Error Handling

- Raise explicit argument validation errors when input is invalid.
- Preserve existing CLI behavior in `update-attack.py`; it is the operational entry point.
- Avoid silent failures in build code unless the surrounding module already degrades intentionally.
- When editing build logic, prefer predictable failures with useful messages over hidden fallbacks.

## JavaScript Style

- In `attack-search/`, use CommonJS (`require`, `module.exports`) unless the file already uses something else.
- Keep local imports consistent with surrounding code; many files include `.js` extensions intentionally for webpack resolution.
- Prefer single quotes in `attack-search/` unless the local file already differs.
- Semicolons are the norm in `attack-search/`; keep them.
- Use `camelCase` for variables and functions, `PascalCase` for classes.
- Modern JS features are acceptable in `attack-search/` (async/await, private methods, optional chaining, nullish coalescing).
- Favor small, explicit DOM interactions over framework-style abstractions; this repo is not React-based.
- In legacy `attack-theme/static/scripts/`, preserve the file's existing style rather than forcing `attack-search/` conventions into older code.
- Preserve browser compatibility assumptions in legacy theme scripts; avoid modernizing syntax there unless the build path transpiles it.

## JavaScript Error Handling And Testing

- For async startup flows, follow the existing `try/catch` and `.catch()` patterns.
- Log actionable errors with `console.error` or `console.debug` where the surrounding code already does so.
- Prefer graceful UI degradation for browser capability issues instead of crashing the page.
- Jest tests live in `attack-search/__tests__/` and usually use `describe`, `test` or `it`, mocked globals, and fixture files.
- When adding tests, follow the existing jsdom/jQuery mocking style rather than introducing a new browser test stack.

## Templates, HTML, And Content Generation

- Jinja templates typically place `set` statements and imports at the top.
- Preserve existing macro usage patterns instead of inlining repeated HTML.
- Do not edit generated artifacts if the template comments point to a source template.
- Keep ATT&CK branding, banner, and version placeholders intact unless the task is explicitly about site configuration.
- Be careful with path handling and generated `index.html` semantics; many helpers normalize trailing slashes.

## SCSS And Styling

- `attack-style/` uses Sass modules with `@use`, not legacy `@import`.
- Preserve the layered structure: `abstracts/`, `base/`, `layout/`, `components/`.
- Import order matters because variables/functions are dependencies for later files.
- Use lowercase, hyphenated naming for classes and partial filenames.
- Reuse existing Sass variables, maps, and helper functions instead of hardcoding colors or spacing.
- Lint with Stylelint when editing SCSS.

## Naming And File Hygiene

- Keep filenames and identifiers consistent with the surrounding subsystem.
- Prefer focused changes over opportunistic refactors.
- Avoid renaming public paths, generated content paths, or ATT&CK URL structures unless required.
- Preserve comments that explain generation behavior, browser compatibility, or build caveats.

## Do Not

- Do not treat generated output as canonical source.
- Do not change ATT&CK URL structures, permalink behavior, or `index.html` generation casually.
- Do not convert `attack-search/` from CommonJS to ESM unless the task explicitly requires it.
- Do not add frontend frameworks for small browser interactions.
- Do not assume Pelican's development server is sufficient for routing-sensitive validation.

## Agent Workflow Expectations

- Before editing, identify which subsystem you are in: root Python build, `attack-search/`, `attack-style/`, `attack-theme/`, or `modules/`.
- Run the narrowest relevant validation for the files you touched.
- If you changed `attack-search/`, run relevant Jest tests and/or `cd attack-search && npm run lint`.
- If you changed SCSS, run `cd attack-style && npm run lint` and usually `cd attack-style && npm run build`.
- If you changed root build or content-generation code, run at least the relevant `update-attack.py` build or targeted test category.
- If your change affects rendered output or routing, validate with the Docker Nginx test environment when practical.
- For template, routing, or generated-output behavior changes, run the site build and prefer Docker/Nginx validation when practical.

## Git And Contribution Notes

- Pull requests should target the `develop` branch per `CONTRIBUTING.md`.
- The PR template expects a reviewer and a `CHANGELOG.md` update when appropriate.
- `pyproject.toml` configures Towncrier for `CHANGELOG.md`; prefer the repository's release-note fragment workflow when one is present instead of hand-editing generated changelog sections.
- Do not assume `master` is the integration branch just because GitHub Pages deploys from it.
- Use Conventional Commit style git messages.

## When Unsure

- Read the nearest config file and a nearby edited file before making stylistic changes.
- Prefer matching existing conventions over introducing new tools or patterns.
- Keep builds reproducible, paths stable, and generated output compatible with the current pipeline.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Website Changelog

## v4.4.2 (2026-04-28)

### Features

* Add filters for website search
* Release ATT&CK content version 19.0.
See detailed changes [here](https://github.com/mitre/cti/releases/tag/ATT%26CK-v19.0).

## v4.4.1 (2025-11-13)

### Features
Expand Down
2 changes: 1 addition & 1 deletion LICENSE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright 2025 The MITRE Corporation
Copyright 2026 The MITRE Corporation

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion NOTICE.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright 2015-2025 The MITRE Corporation
Copyright 2015-2026 The MITRE Corporation

Approved for Public Release; Distribution Unlimited. Case Number 19-3504.

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ STIX is designed to improve many different capabilities, such as collaborative t

## Notice

Copyright 2015-2025 The MITRE Corporation
Copyright 2015-2026 The MITRE Corporation

Approved for Public Release; Distribution Unlimited. Case Number 19-3504.

Expand Down
22 changes: 18 additions & 4 deletions attack-search/__tests__/attack-index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,22 @@ describe('AttackIndex', () => {
expect(results).toEqual(expectedResult);
});

test('Searches two-character content terms', async () => {
const data = {
id: 1,
title: 'Spearphishing Link',
content: 'By using a QR code, the URL may not be exposed',
};

await attackIndex.add(data);

const results = await attackIndex.search('qr', ['content'], 5, 0);

expect(results).toEqual([{field: 'content', result: [1]}]);
});

test('Bulk add documents to FlexSearch', async () => {
attackIndex.addBulk(data);
await attackIndex.addBulk(data);

// Search the title index for "The"
const results = await attackIndex.search('The', ['title']);
Expand All @@ -77,7 +91,7 @@ describe('AttackIndex', () => {
});

test('Paginate FlexSearch responses', async () => {
attackIndex.addBulk(data);
await attackIndex.addBulk(data);

/**
* limit, offset --> [ paginatedSearchResults ]
Expand Down Expand Up @@ -121,9 +135,9 @@ describe('AttackIndex', () => {

test('Resolve search results', async () => {
// Index the data
attackIndex.addBulk(data);
await attackIndex.addBulk(data);

const results = await attackIndex.search('of', ['title','content'], 10, 0);
const results = await attackIndex.search('learning', ['title','content'], 10, 0);

/**
* results: [
Expand Down
30 changes: 30 additions & 0 deletions attack-search/__tests__/mock-index.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,81 @@
{
"id": 1,
"title": "Introduction to Machine Learning",
"path": "/resources/machine-learning/index.html",
"pageType": "resources",
"domains": [],
"content": "Machine learning is a subfield of artificial intelligence that allows machines to learn from data and improve over time without being explicitly programmed."
},
{
"id": 2,
"title": "The Benefits of Regular Exercise",
"path": "/resources/exercise/index.html",
"pageType": "resources",
"domains": [],
"content": "Regular exercise has been shown to have numerous physical and mental health benefits, including reducing the risk of chronic diseases, improving mood, and boosting energy levels."
},
{
"id": 3,
"title": "The History of the Internet",
"path": "/resources/internet-history/index.html",
"pageType": "resources",
"domains": [],
"content": "The internet was created in the 1960s as a way for researchers to share information. Over the years, it has grown to become a global network connecting billions of people and devices around the world."
},
{
"id": 4,
"title": "The Importance of Sleep",
"path": "/resources/sleep/index.html",
"pageType": "resources",
"domains": [],
"content": "Sleep is essential for maintaining physical and mental health. It helps to restore the body and mind, regulate mood and appetite, and improve memory and cognitive function."
},
{
"id": 5,
"title": "The Art of Photography",
"path": "/resources/photography/index.html",
"pageType": "resources",
"domains": [],
"content": "Photography is the art and science of capturing light and creating images that communicate a message or convey a feeling. It requires technical skill, creativity, and an eye for detail."
},
{
"id": 6,
"title": "The Basics of Investing",
"path": "/resources/investing/index.html",
"pageType": "resources",
"domains": [],
"content": "Investing is the process of allocating resources, usually money, with the expectation of generating a profit or achieving a specific goal. It involves assessing risk, researching opportunities, and making informed decisions."
},
{
"id": 7,
"title": "The Science of Climate Change",
"path": "/resources/climate-change/index.html",
"pageType": "resources",
"domains": [],
"content": "Climate change is a global phenomenon caused by increasing levels of greenhouse gases in the atmosphere. It is a complex and multifaceted issue that requires action on multiple fronts to mitigate its impact."
},
{
"id": 8,
"title": "The Benefits of Meditation",
"path": "/resources/meditation/index.html",
"pageType": "resources",
"domains": [],
"content": "Meditation is a practice that involves training the mind to focus and calm the body. It has been shown to reduce stress, improve mental clarity and concentration, and promote feelings of peace and well-being."
},
{
"id": 9,
"title": "The Rise of Social Media",
"path": "/resources/social-media/index.html",
"pageType": "resources",
"domains": [],
"content": "Social media platforms like Facebook, Twitter, and Instagram have revolutionized the way people communicate and share information. They have also raised concerns about privacy, online harassment, and the spread of misinformation."
},
{
"id": 10,
"title": "The Benefits of a Healthy Diet",
"path": "/resources/diet/index.html",
"pageType": "resources",
"domains": [],
"content": "Eating a healthy, balanced diet is essential for maintaining optimal physical and mental health. It can help to prevent chronic diseases, boost energy levels, and improve mood and cognitive function."
}
]
Loading
Loading