| name | ai-security-trainer-2026 |
| description | Browser-based cybersecurity education platform with guided lessons, quizzes, gamified progression, and adaptive learning scenarios for information security practice. |
| triggers | ["set up ai security trainer platform","configure cybersecurity learning environment","create security training lessons and quizzes","implement gamified security education","build interactive security training scenarios","customize ai security trainer features","deploy security education platform","integrate security learning progress tracking"] |
AI Security Trainer v2026 Skill
Skill by ara.so — Security Skills collection.
Overview
AI Security Trainer v2026 is a browser-based cybersecurity education platform that provides interactive security training through guided lessons, quizzes, gamified progression, and adaptive learning scenarios. The platform is built with HTML/JavaScript frontend and Flask backend, offering features like XP systems, badges, leaderboards, skills mapping, and user profile management.
Installation
Local Setup
git clone https://github.com/dylanhwiireed3200/ai-security-trainer-2026.git
cd ai-security-trainer-2026
pip install -r requirements.txt
python app.py
flask run
Docker Deployment
docker build -t ai-security-trainer:2026 .
docker run -d -p 5000:5000 \
-v $(pwd)/data:/app/data \
--name security-trainer \
ai-security-trainer:2026
Project Structure
ai-security-trainer-2026/
├── app.py # Flask application entry point
├── static/
│ ├── css/ # Styling (dark theme)
│ ├── js/ # Frontend logic
│ └── images/ # Assets and avatars
├── templates/
│ ├── index.html # Main interface
│ ├── lessons.html # Lesson content
│ ├── dashboard.html # User progress
│ └── skills.html # Skills map
├── data/ # User data and progress storage
├── lessons/ # Lesson content files
├── Dockerfile
└── requirements.txt
Core Concepts
User Progression System
The platform tracks learning through:
- XP (Experience Points): Earned by completing lessons and quizzes
- Levels: Automatic progression based on accumulated XP
- Badges: Achievement milestones for completing challenges
- Leaderboard: Competitive ranking system
Lesson Structure
Lessons follow a structured format with:
- Learning objectives
- Interactive content
- Embedded quizzes
- Practical scenarios
- Progress checkpoints
Key Features Implementation
Creating Custom Lessons
const Lesson = {
id: "sql-injection-basics",
title: "SQL Injection Fundamentals",
category: "web-security",
difficulty: "intermediate",
xpReward: 150,
content: [
{
type: "text",
content: "SQL injection allows attackers to manipulate database queries..."
},
{
type: "code",
language: "sql",
content: "SELECT * FROM users WHERE username = '' OR '1'='1' --"
},
{
type: "quiz",
question: "What does the SQL comment operator '--' do?",
options: [
"Starts a multi-line comment",
"Comments out the rest of the query",
"Ends the SQL statement",
"Escapes special characters"
],
correctAnswer: 1
}
],
scenario: {
type: "interactive",
description: "Identify vulnerable SQL code",
challenge: "Find the SQL injection vulnerability in the following code",
solution: "The user input is directly concatenated into the query"
}
};
function () {
(, {
: ,
: {
: ,
:
},
: .(lesson)
})
.( response.())
.( {
.(, data.);
});
}
User Profile Management
class UserProfile {
constructor() {
this.userId = localStorage.getItem('userId');
this.profile = null;
}
async loadProfile() {
const response = await fetch(`/api/users/${this.userId}/profile`);
this.profile = await response.json();
return this.profile;
}
async updateAvatar(avatarFile) {
const formData = new FormData();
formData.append('avatar', avatarFile);
const response = await fetch(`/api/users/${this.userId}/avatar`, {
method: 'POST',
body: formData
});
return await response.json();
}
async getProgress() {
response = ();
response.();
}
() {
.(.(xp / ));
}
}
profile = ();
profile.();
.();
Quiz System Implementation
class QuizEngine {
constructor(lessonId) {
this.lessonId = lessonId;
this.currentQuestion = 0;
this.score = 0;
this.answers = [];
}
async loadQuiz() {
const response = await fetch(`/api/lessons/${this.lessonId}/quiz`);
this.quiz = await response.json();
return this.quiz;
}
submitAnswer(questionIndex, answerIndex) {
const question = this.quiz.questions[questionIndex];
const isCorrect = answerIndex === question.correctAnswer;
this.answers.push({
questionIndex,
answerIndex,
isCorrect,
timestamp: Date.now()
});
if (isCorrect) {
this.score += question. || ;
}
{
isCorrect,
: question.,
: question.
};
}
() {
result = {
: .,
: .,
: ...,
: .,
: ().()
};
response = (, {
: ,
: { : },
: .(result)
});
response.();
}
}
Skills Map Tracking
class SkillsMap {
constructor() {
this.skills = {
'web-security': ['XSS', 'SQL Injection', 'CSRF', 'SSRF'],
'network-security': ['Packet Analysis', 'Firewall Rules', 'VPN'],
'cryptography': ['Symmetric', 'Asymmetric', 'Hashing', 'PKI'],
'incident-response': ['Detection', 'Analysis', 'Containment', 'Recovery']
};
}
async getUserSkills(userId) {
const response = await fetch(`/api/users/${userId}/skills`);
return await response.json();
}
calculateSkillProgress(category, completedLessons) {
const totalSkills = this.skills[category].length;
const masteredSkills = completedLessons.filter(
lesson => lesson.category === category && lesson.score >= 80
).;
{
category,
: totalSkills,
: masteredSkills,
: (masteredSkills / totalSkills) *
};
}
() {
categories = .(.);
skillsData = categories.(
.(cat, userProgress)
);
skillsData;
}
}
Flask Backend Implementation
Main Application Setup
from flask import Flask, render_template, request, jsonify, session
from flask_cors import CORS
import json
import os
from datetime import datetime
app = Flask(__name__)
app.secret_key = os.environ.get('SECRET_KEY', 'dev-secret-key')
CORS(app)
app.config['UPLOAD_FOLDER'] = 'static/uploads/avatars'
app.config['MAX_CONTENT_LENGTH'] = 2 * 1024 * 1024
app.config['DATA_FOLDER'] = 'data'
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
os.makedirs(app.config['DATA_FOLDER'], exist_ok=True)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/api/lessons', methods=['GET', 'POST'])
def lessons():
if request.method == 'GET':
lessons_file = os.path.join(app.config['DATA_FOLDER'], 'lessons.json')
with open(lessons_file, 'r') as f:
lessons = json.load(f)
jsonify(lessons)
request.method == :
lesson_data = request.json
lesson_data[] = generate_lesson_id()
lesson_data[] = datetime.utcnow().isoformat()
lessons_file = os.path.join(app.config[], )
(lessons_file, ) f:
lessons = json.load(f)
lessons.append(lesson_data)
f.seek()
json.dump(lessons, f, indent=)
jsonify({: lesson_data[]}),
():
progress_file = os.path.join(app.config[], )
request.method == :
os.path.exists(progress_file):
(progress_file, ) f:
jsonify(json.load(f))
jsonify({: , : , : [], : []})
request.method == :
progress_data = request.json
(progress_file, ) f:
json.dump(progress_data, f, indent=)
jsonify({: })
():
quiz_data = request.json
user_id = session.get()
xp_earned = calculate_xp(quiz_data[], quiz_data[])
progress_file = os.path.join(app.config[], )
(progress_file, ) f:
progress = json.load(f)
progress[] += xp_earned
progress[].append({
: quiz_data[],
: quiz_data[],
: quiz_data[]
})
new_level = calculate_level(progress[])
new_level > progress.get(, ):
progress[] = new_level
progress[].append({
: ,
: new_level,
: datetime.utcnow().isoformat()
})
f.seek()
json.dump(progress, f, indent=)
jsonify({
: xp_earned,
: progress[],
: progress[],
: new_level > progress.get(, )
})
():
percentage = (score / total) *
base_xp =
(base_xp * (percentage / ))
():
math
math.floor(math.sqrt(xp / ))
():
uuid
(uuid.uuid4())[:]
__name__ == :
app.run(debug=, host=, port=)
Adaptive Learning Engine
import json
from datetime import datetime, timedelta
class AdaptiveLearningEngine:
def __init__(self, user_id):
self.user_id = user_id
self.user_progress = self.load_progress()
def load_progress(self):
try:
with open(f'data/user_{self.user_id}_progress.json', 'r') as f:
return json.load(f)
except FileNotFoundError:
return {'completedLessons': [], 'weakAreas': [], 'strengths': []}
def analyze_performance(self):
"""Analyze user performance to identify strengths and weaknesses"""
lessons = self.user_progress.get('completedLessons', [])
category_scores = {}
for lesson in lessons:
category = lesson.get('category', 'general')
if category not in category_scores:
category_scores[category] = []
category_scores[category].append(lesson['score'])
weak_areas = []
strengths = []
for category, scores category_scores.items():
avg_score = (scores) / (scores)
avg_score < :
weak_areas.append({
: category,
: avg_score,
: (scores)
})
avg_score > :
strengths.append({
: category,
: avg_score,
: (scores)
})
{: weak_areas, : strengths}
():
analysis = .analyze_performance()
completed_ids = [l[] l .user_progress.get(, [])]
recommendations = []
weak analysis[]:
related_lessons = [
l l available_lessons
l[] == weak[]
l[] completed_ids
l.get() [, ]
]
recommendations.extend(related_lessons[:])
strength analysis[]:
advanced_lessons = [
l l available_lessons
l[] == strength[]
l[] completed_ids
l.get() ==
]
recommendations.extend(advanced_lessons[:])
remaining = [l l available_lessons l[] completed_ids]
recommendations.extend(remaining[: - (recommendations)])
recommendations[:]
():
user_score >= :
user_score < :
:
Configuration
Environment Variables
SECRET_KEY=your-secret-key-here
DATABASE_URL=sqlite:///data/security_trainer.db
UPLOAD_FOLDER=static/uploads/avatars
MAX_CONTENT_LENGTH=2097152
FLASK_ENV=production
FLASK_DEBUG=False
Docker Configuration
# Dockerfile
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
RUN mkdir -p data static/uploads/avatars
EXPOSE 5000
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "4", "app:app"]
version: '3.8'
services:
web:
build: .
ports:
- "5000:5000"
environment:
- SECRET_KEY=${SECRET_KEY}
- FLASK_ENV=production
volumes:
- ./data:/app/data
- ./static/uploads:/app/static/uploads
restart: unless-stopped
Common Patterns
Creating Interactive Scenarios
class SecurityScenario {
constructor(scenarioConfig) {
this.config = scenarioConfig;
this.state = { phase: 0, score: 0, actions: [] };
}
async loadScenario() {
const response = await fetch(`/api/scenarios/${this.config.id}`);
this.scenario = await response.json();
this.renderPhase(0);
}
renderPhase(phaseIndex) {
const phase = this.scenario.phases[phaseIndex];
document.getElementById('scenario-description').textContent = phase.description;
const actionsContainer = document.getElementById('scenario-actions');
actionsContainer.innerHTML = '';
phase..( {
button = .();
button. = action.;
button. = .(index);
actionsContainer.(button);
});
}
() {
phase = ..[..];
action = phase.[actionIndex];
...({
: ..,
: actionIndex,
: .()
});
(action.) {
.. += ;
.(, );
} (action.) {
.. += ;
.(, );
} {
.(, );
}
(.. < ... - ) {
..++;
.(..);
} {
.();
}
}
() {
result = (, {
: ,
: { : },
: .({
: ..,
: ..,
: ..
})
});
data = result.();
.(data);
}
() {
feedback = .();
feedback. = ;
feedback. = message;
.().(feedback);
}
() {
.(). = ;
.(). = ;
}
}
Leaderboard System
from datetime import datetime, timedelta
import json
import os
class Leaderboard:
def __init__(self, data_folder='data'):
self.data_folder = data_folder
self.leaderboard_file = os.path.join(data_folder, 'leaderboard.json')
def get_global_leaderboard(self, limit=10):
"""Get top users by total XP"""
users = self._load_all_users()
sorted_users = sorted(users, key=lambda x: x['xp'], reverse=True)
return sorted_users[:limit]
def get_weekly_leaderboard(self, limit=10):
"""Get top users by XP earned this week"""
users = self._load_all_users()
week_ago = datetime.now() - timedelta(days=7)
weekly_scores = []
for user in users:
weekly_xp = sum(
lesson['xpEarned'] for lesson in user.get('completedLessons', [])
if datetime.fromisoformat(lesson['completedAt']) > week_ago
)
if weekly_xp > 0:
weekly_scores.append({
: user[],
: user[],
: weekly_xp,
: user.get()
})
(weekly_scores, key= x: x[], reverse=)[:limit]
():
leaderboard = .get_global_leaderboard(limit=)
index, user (leaderboard, ):
user[] == user_id:
{
: index,
: user[],
: user[],
: (leaderboard)
}
():
users = []
filename os.listdir(.data_folder):
filename.startswith() filename.endswith():
(os.path.join(.data_folder, filename), ) f:
user_data = json.load(f)
user_id = filename.replace(, ).replace(, )
user_data[] = user_id
users.append(user_data)
users
Troubleshooting
Flask Not Starting
python --version
pip install -r requirements.txt
lsof -i :5000
netstat -ano | findstr :5000
export FLASK_DEBUG=1
flask run
Data Not Persisting
import os
data_folder = 'data'
if not os.path.exists(data_folder):
os.makedirs(data_folder, exist_ok=True)
print(f"Created {data_folder}")
test_file = os.path.join(data_folder, 'test.txt')
try:
with open(test_file, 'w') as f:
f.write('test')
os.remove(test_file)
print("Write permissions OK")
except PermissionError:
print("Permission denied - check folder permissions")
Avatar Upload Issues
from werkzeug.utils import secure_filename
import imghdr
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/api/users/<user_id>/avatar', methods=['POST'])
def upload_avatar(user_id):
if 'avatar' not in request.files:
return jsonify({'error': 'No file provided'}), 400
file = request.files['avatar']
if file.filename == '':
return jsonify({'error': 'No file selected'}), 400
if not allowed_file(file.filename):
return jsonify({'error': 'Invalid file type'}), 400
file_bytes = file.read()
if imghdr.what(None, h=file_bytes) [, , , ]:
jsonify({: }),
file.seek()
filename = secure_filename()
filepath = os.path.join(app.config[], filename)
file.save(filepath)
jsonify({
: ,
:
})
Quiz Score Not Updating
async function submitQuizAndUpdate() {
try {
const quizEngine = new QuizEngine('lesson-123');
const result = await quizEngine.completeQuiz();
if (!result.xpEarned) {
console.error('XP not returned from server');
return;
}
updateProgressBar(result.totalXp);
displayLevelUp(result.level, result.leveledUp);
const profile = new UserProfile();
await profile.loadProfile();
} catch (error) {
console.error('Quiz submission failed:', error);
alert('Failed to save quiz results. Please try again.');
}
}
Best Practices
- Always validate user input on both client and server side
- Use environment variables for sensitive configuration
- Implement proper error handling for all API calls
- Store user data securely with appropriate file permissions
- Regularly backup the data folder
- Test quiz and lesson content before deployment
- Monitor XP calculations to prevent gaming the system
- Use transaction-like operations when updating user progress
- Implement rate limiting to prevent abuse
- Log important events for debugging and analytics