A comprehensive JavaScript/TypeScript library for parsing, validating, and generating XARF v4.0.0 (eXtended Abuse Reporting Format) reports.
- Parser: Parse and validate XARF reports from JSON
- Generator: Create XARF-compliant reports programmatically
- Validator: Comprehensive validation with detailed error reporting
- TypeScript Support: Full type definitions for all XARF structures
- Backward Compatibility: Automatic v3 to v4 conversion with deprecation warnings
- All Categories: Support for all 7 XARF categories
- Messaging
- Connection
- Content
- Infrastructure
- Copyright
- Vulnerability
- Reputation
npm install xarfimport { XARFParser } from 'xarf';
const parser = new XARFParser();
const report = parser.parse({
xarf_version: '4.0.0',
report_id: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
timestamp: '2024-01-15T10:30:00Z',
reporter: {
org: 'Security Team',
contact: 'abuse@example.com',
domain: 'example.com'
},
sender: {
org: 'Security Team',
contact: 'abuse@example.com',
domain: 'example.com'
},
source_identifier: '192.0.2.100',
category: 'connection',
type: 'ddos',
evidence_source: 'honeypot',
destination_ip: '203.0.113.10',
protocol: 'tcp'
});
console.log(report.category); // 'connection'import { XARFGenerator } from 'xarf';
const generator = new XARFGenerator();
const report = generator.generateReport({
category: 'messaging',
type: 'spam', // Using XARF spec field name
source_identifier: '192.0.2.100', // snake_case matches XARF spec
reporter: {
org: 'Example Security',
contact: 'abuse@example.com',
domain: 'example.com'
},
sender: {
org: 'Example Security',
contact: 'abuse@example.com',
domain: 'example.com'
},
evidence_source: 'automated_scan', // snake_case matches XARF spec
description: 'Spam email detected from source',
tags: ['spam', 'email'],
// Category-specific fields can be passed directly (union types)
protocol: 'smtp',
smtp_from: 'spammer@evil.example.com'
});
console.log(JSON.stringify(report, null, 2));import { XARFValidator } from 'xarf';
const validator = new XARFValidator();
const result = validator.validate(report);
if (result.valid) {
console.log('Report is valid');
} else {
console.log('Validation errors:', result.errors);
console.log('Warnings:', result.warnings);
}Parse and validate XARF reports from JSON.
const parser = new XARFParser(strict?: boolean);strict: Iftrue, throw exceptions on validation errors. Iffalse, collect errors for retrieval.
parse(jsonData: string | object): XARFReport- Parse a XARF reportvalidate(jsonData: string | object): boolean- Validate without parsinggetErrors(): string[]- Get validation errors from last operation
Generate XARF-compliant reports programmatically.
const generator = new XARFGenerator();generateReport(options: GeneratorOptions): XARFReport- Create a complete reportgenerateUUID(): string- Generate a UUID for report IDgenerateTimestamp(): string- Generate an ISO 8601 timestampgenerateHash(data: string | Buffer, algorithm?: string): string- Hash dataaddEvidence(contentType: string, description: string, payload: string | Buffer): XARFEvidence- Create evidence with hashgenerateRandomEvidence(category: XARFCategory, description?: string): XARFEvidence- Generate sample evidencegenerateSampleReport(category: XARFCategory, reportType: string, includeEvidence?: boolean, includeOptional?: boolean): XARFReport- Generate test report
The GeneratorOptions interface for generateReport() supports both snake_case (XARF spec, preferred) and camelCase (backward compatibility).
Union Types: Category-specific fields can be passed directly without using additionalFields:
// Messaging report with direct fields
const messagingReport = generator.generateReport({
category: 'messaging',
type: 'spam',
source_identifier: '192.0.2.100',
reporter: { org: '...', contact: '...', domain: '...' },
sender: { org: '...', contact: '...', domain: '...' },
evidence_source: 'spamtrap',
// Messaging-specific fields directly on options
protocol: 'smtp',
smtp_from: 'spammer@evil.example.com',
subject: 'You won!'
});
// Connection report with direct fields
const connectionReport = generator.generateReport({
category: 'connection',
type: 'ddos',
source_identifier: '192.0.2.100',
reporter: { org: '...', contact: '...', domain: '...' },
sender: { org: '...', contact: '...', domain: '...' },
evidence_source: 'honeypot',
// Connection-specific fields directly on options
destination_ip: '203.0.113.10',
protocol: 'tcp',
destination_port: 80
});Base Options (all categories):
{
category: XARFCategory; // Required: Report category
type?: string; // Report type (e.g., 'spam', 'ddos')
reportType?: string; // Backward compatibility alias
source_identifier?: string; // Required: Source IP or identifier
sourceIdentifier?: string; // Backward compatibility alias
reporter: ContactInfo; // Required: Reporter information
sender: ContactInfo; // Required: Sender information
evidence_source?: EvidenceSource; // Evidence source
evidenceSource?: EvidenceSource; // Backward compatibility alias
description?: string; // Human-readable description
evidence?: XARFEvidence[]; // Evidence items
confidence?: number; // Confidence score (0.0 to 1.0)
tags?: string[]; // Tags for categorization
additionalFields?: Record<string, unknown>; // Additional fields (legacy approach)
}Note: The library accepts both naming conventions but generates reports using snake_case as per the XARF specification.
Comprehensive validation with detailed error and warning reporting.
const validator = new XARFValidator();validate(report: XARFReport, strict?: boolean, showMissingOptional?: boolean): ValidationResult- Validate a report
Parameters:
report- The XARF report to validatestrict- Iftrue, throwXARFValidationErroron validation failures (default:false)showMissingOptional- Iftrue, include info about missing optional fields (default:false)
Returns:
{
valid: boolean;
errors: Array<{ field: string; message: string; value?: unknown }>;
warnings: Array<{ field: string; message: string; value?: unknown }>;
info?: Array<{ field: string; message: string }>; // Only when showMissingOptional=true
}The validator automatically warns about unknown fields in reports:
const report = {
// ... valid fields ...
unknownField: 'value' // Will trigger a warning
};
const result = validator.validate(report);
// result.warnings will include: "Unknown field 'unknownField' is not defined in the XARF schema"In strict mode, unknown fields are treated as errors.
Use showMissingOptional to discover which optional fields you could add:
const result = validator.validate(report, false, true);
if (result.info) {
result.info.forEach(({ field, message }) => {
console.log(`${field}: ${message}`);
// e.g., "description: OPTIONAL - Human-readable description of the abuse"
// e.g., "confidence: RECOMMENDED - Confidence score between 0.0 and 1.0"
});
}Access schema-derived validation rules programmatically:
import { schemaRegistry } from 'xarf';
// Get all valid categories
const categories = schemaRegistry.getCategories();
// Set { 'messaging', 'connection', 'content', ... }
// Get valid types for a category
const types = schemaRegistry.getTypesForCategory('connection');
// Set { 'ddos', 'port_scan', 'login_attack', ... }
// Check if a category/type combination is valid
schemaRegistry.isValidType('connection', 'ddos'); // true
// Get valid evidence sources
const sources = schemaRegistry.getEvidenceSources();
// Set { 'honeypot', 'spamtrap', 'user_report', ... }
// Get field metadata including descriptions
const metadata = schemaRegistry.getFieldMetadata('confidence');
// { description: '...', required: false, recommended: true, ... }spam,phishing,social_engineering,bulk_messaging
ddos,port_scan,login_attack,ip_spoofing,compromised,botnet,malicious_traffic, and more
phishing_site,malware_distribution,defacement,spamvertised,web_hack, and more
botnet,compromised_server
infringement,dmca,trademark,p2p, and more
cve,misconfiguration,open_service
blocklist,threat_intelligence
const report = generator.generateReport({
category: 'connection',
type: 'ddos',
source_identifier: '192.0.2.100',
reporter: {
org: 'Security Operations',
contact: 'abuse@example.com',
domain: 'example.com'
},
sender: {
org: 'Security Operations',
contact: 'abuse@example.com',
domain: 'example.com'
},
evidence_source: 'honeypot',
// Category-specific fields directly (union types)
destination_ip: '203.0.113.10',
protocol: 'tcp',
destination_port: 80,
attack_type: 'syn_flood',
confidence: 0.95
});const report = generator.generateReport({
category: 'content',
type: 'phishing',
source_identifier: '192.0.2.100',
reporter: {
org: 'Phishing Response Team',
contact: 'abuse@example.com',
domain: 'example.com'
},
sender: {
org: 'Phishing Response Team',
contact: 'abuse@example.com',
domain: 'example.com'
},
evidence_source: 'user_report',
// Category-specific fields directly (union types)
url: 'http://phishing.example.com',
content_type: 'text/html',
description: 'Phishing site mimicking banking portal',
tags: ['phishing', 'banking', 'credential-theft']
});const report = generator.generateReport({
category: 'messaging',
type: 'spam',
source_identifier: '192.0.2.100',
reporter: {
org: 'Example Security',
contact: 'abuse@example.com',
domain: 'example.com'
},
sender: {
org: 'Example Security',
contact: 'abuse@example.com',
domain: 'example.com'
},
evidence_source: 'spamtrap',
// Category-specific fields directly (union types)
protocol: 'smtp',
smtp_from: 'spammer@evil.example.com',
smtp_to: 'victim@example.com',
subject: 'You won the lottery!',
message_id: '<123456@evil.example.com>'
});Full TypeScript definitions are included:
import type {
XARFReport,
ConnectionReport,
MessagingReport,
XARFCategory,
ReporterType
} from 'xarf';
const report: ConnectionReport = {
// TypeScript will enforce correct structure
};# Run tests
npm test
# Run tests with coverage
npm run test:coverage
# Run tests in watch mode
npm run test:watch# Build TypeScript to JavaScript
npm run build
# Type check without building
npm run typecheckThis library validates against the official xarf-spec JSON schemas. Schemas are automatically fetched from the xarf-spec repository on npm install.
# Check if a newer version of xarf-spec is available
npm run check-schema-updates
# Show all available releases
npm run check-schema-updates -- --allExample output:
[xarf] Checking for schema updates...
Configured version: v4.1.0
Installed version: v4.1.0
Latest release: v4.1.0 (Dec 18, 2025)
✅ You are using the latest version.
To update to a newer version of the XARF specification:
-
Edit
package.jsonand update the version:"xarfSpec": { "version": "v4.2.0" }
-
Run npm install to fetch the new schemas:
npm install
# Re-fetch schemas from xarf-spec (useful if schemas are missing)
npm run fetch-schemas# Run ESLint
npm run lint
# Fix linting issues
npm run lint:fix
# Check Prettier formatting
npm run format:check
# Format code
npm run formatContributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Run linting and formatting
- Submit a pull request
MIT License - see LICENSE file for details
This library automatically detects and converts XARF v3 format reports to v4:
import { XARFParser } from 'xarf';
const parser = new XARFParser();
// v3 format report
const v3Report = {
Version: '3',
ReporterInfo: {
ReporterOrg: 'Security Team',
ReporterOrgEmail: 'abuse@example.com'
},
Report: {
ReportType: 'Spam',
Date: '2024-01-15T10:00:00Z',
SourceIp: '192.0.2.100',
Protocol: 'smtp',
SmtpMailFromAddress: 'spammer@evil.example'
}
};
// Automatically converted to v4 format
const report = parser.parse(v3Report);
console.log(report.xarf_version); // '4.0.0'
console.log(report.category); // 'messaging'
console.log(report.type); // 'spam'
console.log(report._internal?.legacy_version); // '3'
// Get deprecation warnings
const warnings = parser.getWarnings();
console.log(warnings); // Contains deprecation noticeThe parser automatically detects v3 reports by checking for the Version field:
import { isXARFv3 } from 'xarf';
if (isXARFv3(jsonData)) {
console.log('This is a legacy v3 report');
}You can also manually convert v3 reports:
import { convertV3toV4, getV3DeprecationWarning } from 'xarf';
const warnings: string[] = [];
const v4Report = convertV3toV4(v3Report, warnings);
console.log(getV3DeprecationWarning());
// "DEPRECATION WARNING: XARF v3 format detected..."The following v3 report types are automatically mapped to v4 categories:
| v3 ReportType | v4 Category | v4 Type |
|---|---|---|
| Spam | messaging | spam |
| Login-Attack | connection | login_attack |
| Port-Scan | connection | port_scan |
| DDoS | connection | ddos |
| Phishing | content | phishing |
| Malware | content | malware |
| Botnet | infrastructure | botnet |
| Copyright | copyright | copyright |
Unknown v3 report types are mapped to category content with type unclassified.
Current version: 1.0.0 XARF Specification: 4.1.0 (from xarf-spec)
Production release with full support for all 7 XARF categories: messaging, connection, content, infrastructure, copyright, vulnerability, and reputation.
Schema Updates: Schemas are fetched from the official xarf-spec repository. Run npm run check-schema-updates to check for new versions.
v3 Compatibility: Full backward compatibility with XARF v3 format with automatic conversion and deprecation warnings.