Cyber threat intelligence reporting is an essential part of modern cybersecurity strategies. Building an app that not only collects threat data but also analyzes, correlates, and presents it in a digestible format can help organizations preempt and respond to potential security breaches. The application you are about to build serves multiple purposes. It collects threat data (either through manual submission or API integrations), performs preliminary analysis, and allows analysts or security teams to view comprehensive reports.
In this document, we detail the necessary code and structure to build a basic yet extendable Cyber Threat Intelligence (CTI) reporting application using Python’s Flask web framework for the backend and SQLite as the database engine. This guide is designed to provide you with a robust foundation on which you can build more advanced features such as integration with external threat intelligence feeds, advanced data visualizations, and machine learning-based analytics.
The application is structured into three major components:
The app’s primary input comes from the submission of threat reports by users or integration with external threat feeds using APIs. For a basic demonstration, we use HTML forms to facilitate user submissions. In production, you might expand this component to interface with open-source tools or commercial APIs such as MISP, OpenCTI, or Recorded Future.
On the backend, threat data can be processed to extract valuable insights. In our example, we keep the analysis straightforward by storing data and ordering reports by time. However, with the right modules, you can incorporate algorithms for pattern recognition, threat correlation, and even machine learning methods to assess threat severity.
A critical part of the CTI app is displaying the results in an actionable and visually appealing interface. We rely on Flask’s template system leveraging HTML and CSS along with Bootstrap to quickly create a responsive and user-friendly front-end. Additional visualizations can be added later using libraries such as D3.js or Chart.js for more interactive reporting.
To get started, ensure that you have Python 3 installed. Install Flask using pip from the command line:
# Install Flask
pip install Flask
SQLite typically comes with Python. Set up a virtual environment if desired to keep dependencies isolated:
python3 -m venv venv
source venv/bin/activate # On Windows, use venv\Scripts\activate
pip install Flask
We utilize SQLite for our initial design. Create a database file and a table called "threat_reports" to store report data. The following code snippet sets up your database:
# Create database and threat_reports table using SQLite3
import sqlite3
# Connect to SQLite database; if it doesn't exist, it will be created
conn = sqlite3.connect('threat_intelligence.db')
# Create a cursor object to interact with the DB
cursor = conn.cursor()
# Create the threat_reports table if not exists
cursor.execute('''
CREATE TABLE IF NOT EXISTS threat_reports (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
description TEXT NOT NULL,
severity TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
# Commit changes and close the connection
conn.commit()
conn.close()
The Flask app will be responsible for serving HTML templates, processing form data, and interacting with the database. Save the following code as app.py in your working directory:
from flask import Flask, request, render_template, redirect, url_for, flash
import sqlite3
import os
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key' # Change in production environments
DATABASE = 'threat_intelligence.db'
def get_db_connection():
conn = sqlite3.connect(DATABASE)
conn.row_factory = sqlite3.Row # Enable column name access
return conn
def init_db():
"""Initialize the database if it does not exist."""
if not os.path.exists(DATABASE):
conn = get_db_connection()
conn.execute('''
CREATE TABLE IF NOT EXISTS threat_reports (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
description TEXT NOT NULL,
severity TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
conn.commit()
conn.close()
@app.route('/')
def index():
# Display all threat reports sorted by submission time in descending order
conn = get_db_connection()
reports = conn.execute('SELECT * FROM threat_reports ORDER BY created_at DESC').fetchall()
conn.close()
return render_template('index.html', reports=reports)
@app.route('/submit', methods=['GET', 'POST'])
def submit():
if request.method == 'POST':
title = request.form.get('title')
description = request.form.get('description')
severity = request.form.get('severity')
# Basic validation to ensure no empty fields are submitted
if not title or not description or not severity:
flash('All fields are required.', 'error')
return redirect(url_for('submit'))
# Insert the new report into the database
conn = get_db_connection()
conn.execute(
'INSERT INTO threat_reports (title, description, severity) VALUES (?, ?, ?)',
(title, description, severity)
)
conn.commit()
conn.close()
flash('Report submitted successfully!', 'success')
return redirect(url_for('index'))
return render_template('submit.html')
@app.route('/report/<int:report_id>')
def report_detail(report_id):
conn = get_db_connection()
report = conn.execute('SELECT * FROM threat_reports WHERE id = ?', (report_id,)).fetchone()
conn.close()
if report is None:
flash('Report not found', 'error')
return redirect(url_for('index'))
return render_template('report_detail.html', report=report)
if __name__ == '__main__':
init_db() # Initialize the DB if needed and then run the app
app.run(debug=True)
Create a folder named templates in your project directory and add the following HTML files for rendering the web interface.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CTI Reporting App</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
<style>
body { padding-top: 20px; }
</style>
</head>
<body>
<div class="container">
<nav class="navbar navbar-expand-lg navbar-light bg-light mb-3">
<span style="opacity: 0.2">CTI Reporting App</span>
<div class="collapse navbar-collapse">
<ul class="navbar-nav mr-auto">
<li class="nav-item"><span style="opacity: 0.2">Home</span></li>
<li class="nav-item"><span style="opacity: 0.2">Submit Report</span></li>
</ul>
</div>
</nav>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ category }} alert-dismissible fade show">
{{ message }}
<button type="button" class="close" data-dismiss="alert">×</button>
</div>
{% endfor %}
{% endif %}
{% endwith %}
{% block content %}{% endblock %}
</div>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
{% extends 'base.html' %}
{% block content %}
<h2>Cyber Threat Reports</h2>
{% if reports %}
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Title</th>
<th>Severity</th>
<th>Submitted At</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{% for report in reports %}
<tr>
<td>{{ report.id }}</td>
<td>{{ report.title }}</td>
<td>{{ report.severity }}</td>
<td>{{ report.created_at }}</td>
<td><span style="opacity: 0.2">View</span></td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>No reports available. <span style="opacity: 0.2">Submit a new report.</span></p>
{% endif %}
{% endblock %}
{% extends 'base.html' %}
{% block content %}
<h2>Submit Cyber Threat Report</h2>
<form method="post" action="{{ url_for('submit') }}">
<div class="form-group">
<label for="title">Report Title</label>
<input type="text" class="form-control" id="title" name="title" placeholder="E.g.: Phishing attack at corporate level" required>
</div>
<div class="form-group">
<label for="description">Report Description</label>
<textarea class="form-control" id="description" name="description" rows="5" placeholder="Describe the incident in detail..." required></textarea>
</div>
<div class="form-group">
<label for="severity">Threat Severity</label>
<select class="form-control" id="severity" name="severity" required>
<option value="">Select Severity</option>
<option value="Low">Low</option>
<option value="Medium">Medium</option>
<option value="High">High</option>
<option value="Critical">Critical</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Submit Report</button>
</form>
{% endblock %}
{% extends 'base.html' %}
{% block content %}
<h2>Report Details</h2>
<div class="card">
<div class="card-header">
<h4>{{ report.title }}</h4>
</div>
<div class="card-body">
<p><strong>Severity:</strong> {{ report.severity }}</p>
<p><strong>Description:</strong></p>
<p>{{ report.description }}</p>
<p><small class="text-muted">Submitted at: {{ report.created_at }}</small></p>
<span style="opacity: 0.2">Back to Reports</span>
</div>
</div>
{% endblock %}
The provided example serves only as a template for your initial setup. To create a production-ready CTI reporting application, consider implementing the following enhancements:
Integrate additional APIs from reputable threat intelligence providers. Your code can fetch data from platforms that deliver real-time threat updates, thus automating data ingestion.
Develop algorithms to analyze and correlate threat indicators. Incorporate machine learning models that can recognize emerging patterns and alert analysts to sophisticated threats.
Improve your application's reporting capabilities using visualization libraries such as D3.js or Chart.js. Create dynamic and interactive graphs that provide insights into trends, threat actors, and incident timelines.
As the application evolves, prioritize security practices. Implement user authentication and authorization, add input validation, and secure endpoints against common vulnerabilities such as SQL injection and cross-site scripting (XSS).
If the application grows, consider transitioning from SQLite to a more robust database system like PostgreSQL or MySQL. Also, adopt application blueprints and modularize the code to facilitate maintenance and future expansions.
For sophisticated cyber threat intelligence (CTI) projects, integration with established platforms such as MISP or OpenCTI is highly recommended. These platforms offer rich APIs and tools that greatly enhance threat data collection and sharing capabilities.
A practical approach includes:
Component | Description | Technologies |
---|---|---|
Data Collection | Ingest data from external CTI feeds, APIs, and manual submissions. | REST APIs, Python Requests, MISP/OpenCTI |
Data Processing | Analyze incoming data to extract patterns, correlate events, and classify threats. | Python, Pandas, scikit-learn, custom ML algorithms |
Data Presentation | Visualize the intelligence reports with interactive dashboards and detailed views for each incident. | Flask, Bootstrap, D3.js/Chart.js |
Additionally, staying updated with STIX2 standards for threat intelligence sharing can facilitate data integration with other cybersecurity platforms. Adhering to these standards ensures that your CTI data is interoperable with other systems.
Once your application is set up, it is crucial to test various components to ensure robust performance. Here are a few testing strategies:
Write tests for individual functions such as data insertion, retrieval from the database, and form validation. Tools like pytest can be useful for this purpose.
Test how different parts of your application interact – for instance, simulate a user submitting a threat report and confirm that it appears on the index page.
Have end-users (e.g., cybersecurity analysts) test the functionality to reflect realistic use cases. Gather feedback to improve user experience and functionality.
Before moving to production, consider these deployment steps:
Replace the development server with a production-ready web server such as Gunicorn or uWSGI, set proper environment variables, and hide debug messages.
For scaling up, move from SQLite to a more robust database solution, applying database migrations to ensure data integrity.
Secure the application using HTTPS. Tools like Let's Encrypt can help manage SSL certificates.
Implement monitoring solutions, logging mechanisms, and periodic audits to catch and resolve issues quickly.
In this guide, we have designed a cyber threat intelligence reporting application that is modular, secure, and expandable. Starting with a simple Flask app, SQLite for data storage, and essential HTML templates, you now have a foundation on which you can build more robust functionalities such as real-time threat data integrations, advanced threat correlation and machine learning analyses, and interactive dashboards for threat visualization.
The strategic steps outlined incorporate best practices for coding, testing, and deployment while ensuring that the user interface remains intuitive and responsive. As you expand this proof-of-concept to meet enterprise-level demands, consider integrating comprehensive security measures and scalable architectures. This iterative development approach will help facilitate timely updates as cyber threats evolve, keeping your CTI reporting application at the forefront of cybersecurity solutions.