- name
- pentesting-checklist-platform
- description
- Interactive security assessment checklist covering 23 platforms with 1,000+ checks for pentesting, bug bounty, and security audits
- triggers
- ["how do I use the pentesting checklist tool","show me security assessment checklist platforms","help me track penetration testing progress","how to export pentesting findings","search security checks across platforms","use m14r41 pentesting checklist","organize security assessment workflow","track vulnerability assessment progress"]
# PentestingChecklist Platform Skill
> Skill by [ara.so](https://ara.so) — Security Skills collection.
## Overview
PentestingChecklist is a comprehensive, interactive security assessment tool that provides structured checklists across 23 platforms including Web, API, Mobile, Cloud, Active Directory, Kubernetes, LLM, and more. Built with TypeScript and React, it runs entirely client-side with no backend, storing all data in localStorage for privacy.
**Key Features:**
- 1,000+ security checks across 23 platforms
- Hierarchical organization (Platform → Category → Technology → Check)
- Progress tracking and status management (Open/Closed/N/A)
- Per-check notes and evidence recording
- Severity filtering (Critical to Info)
- Global search across all content
- Export to Markdown, CSV, Excel, JSON
- Import/export for assessment continuity
**Live Tool:** https://checklist.m14r41.in/
## Installation & Setup
### Local Development
```bash
# Clone the repository
git clone https://github.com/m14r41/PentestingChecklist.git
cd PentestingChecklist
# Install dependencies
npm install
# Start development server
npm run dev
# Build for production
npm run build
# Preview production build
npm run preview
```
### Using the Hosted Version
No installation required — navigate to https://checklist.m14r41.in/ in your browser. All data persists in browser localStorage.
## Architecture & Code Structure
### Key TypeScript Interfaces
```typescript
// Core data structures
interface Check {
id: string;
title: string;
description: string;
severity: 'critical' | 'high' | 'medium' | 'low' | 'info';
tags: string[];
tools?: string[];
references?: string[];
status?: 'open' | 'closed' | 'na';
notes?: string;
}
interface Technology {
id: string;
name: string;
checks: Check[];
}
interface Category {
id: string;
name: string;
technologies: Technology[];
}
interface Platform {
id: string;
name: string;
description: string;
categories: Category[];
}
// Progress tracking
interface AssessmentProgress {
platformId: string;
totalChecks: number;
completedChecks: number;
percentage: number;
statusBreakdown: {
open: number;
closed: number;
na: number;
unchecked: number;
};
}
```
### LocalStorage Schema
```typescript
// Storage keys used by the application
const STORAGE_KEYS = {
CHECKLIST_STATE: 'pentesting-checklist-state',
USER_NOTES: 'pentesting-checklist-notes',
PROGRESS: 'pentesting-checklist-progress',
COLLAPSED_SECTIONS: 'pentesting-checklist-collapsed'
};
// Example: Reading stored progress
function loadProgress(): Map<string, AssessmentProgress> {
const stored = localStorage.getItem(STORAGE_KEYS.PROGRESS);
return stored ? new Map(JSON.parse(stored)) : new Map();
}
// Example: Saving check status
function updateCheckStatus(
platformId: string,
categoryId: string,
techId: string,
checkId: string,
status: 'open' | 'closed' | 'na'
): void {
const key = `${platformId}.${categoryId}.${techId}.${checkId}`;
const state = JSON.parse(localStorage.getItem(STORAGE_KEYS.CHECKLIST_STATE) || '{}');
state[key] = { ...state[key], status };
localStorage.setItem(STORAGE_KEYS.CHECKLIST_STATE, JSON.stringify(state));
}
```
## Using the Checklist
### Navigation Patterns
```typescript
// Platform URLs follow the pattern
const platformUrls = {
allPlatforms: '/checklist',
web: '/web',
api: '/api',
mobile: '/mobile',
cloud: '/cloud',
activeDirectory: '/active-directory',
kubernetes: '/kubernetes',
llm: '/llm-security',
mcp: '/mcp-security'
// ... 23 platforms total
};
// Accessing specific platform data
function navigateToPlatform(platformId: string) {
window.location.href = `/${platformId}`;
}
```
### Search Functionality
The global search (⌘K / Ctrl+K) searches across:
- Platform names
- Category names
- Technology names
- Check titles and descriptions
- Tags
- Tools
- References
```typescript
// Search implementation pattern
interface SearchResult {
type: 'platform' | 'category' | 'technology' | 'check';
platformId: string;
categoryId?: string;
technologyId?: string;
checkId?: string;
title: string;
description?: string;
path: string;
}
function performSearch(query: string, platforms: Platform[]): SearchResult[] {
const results: SearchResult[] = [];
const lowerQuery = query.toLowerCase();
platforms.forEach(platform => {
platform.categories.forEach(category => {
category.technologies.forEach(tech => {
tech.checks.forEach(check => {
if (
check.title.toLowerCase().includes(lowerQuery) ||
check.description.toLowerCase().includes(lowerQuery) ||
check.tags.some(tag => tag.toLowerCase().includes(lowerQuery))
) {
results.push({
type: 'check',
platformId: platform.id,
categoryId: category.id,
technologyId: tech.id,
checkId: check.id,
title: check.title,
description: check.description,
path: `/${platform.id}#${check.id}`
});
}
});
});
});
});
return results;
}
```
## Working with Assessment Data
### Adding Notes to Checks
```typescript
// Note storage structure
interface CheckNote {
checkId: string;
content: string;
timestamp: number;
findings?: string[];
screenshots?: string[];
}
function saveCheckNote(
platformId: string,
categoryId: string,
techId: string,
checkId: string,
note: string
): void {
const key = `${platformId}.${categoryId}.${techId}.${checkId}`;
const notes = JSON.parse(localStorage.getItem(STORAGE_KEYS.USER_NOTES) || '{}');
notes[key] = {
checkId,
content: note,
timestamp: Date.now(),
findings: []
};
localStorage.setItem(STORAGE_KEYS.USER_NOTES, JSON.stringify(notes));
}
function getCheckNote(checkKey: string): CheckNote | null {
const notes = JSON.parse(localStorage.getItem(STORAGE_KEYS.USER_NOTES) || '{}');
return notes[checkKey] || null;
}
```
### Progress Calculation
```typescript
function calculatePlatformProgress(platform: Platform): AssessmentProgress {
let totalChecks = 0;
let completedChecks = 0;
const statusBreakdown = { open: 0, closed: 0, na: 0, unchecked: 0 };
const state = JSON.parse(localStorage.getItem(STORAGE_KEYS.CHECKLIST_STATE) || '{}');
platform.categories.forEach(category => {
category.technologies.forEach(tech => {
tech.checks.forEach(check => {
totalChecks++;
const key = `${platform.id}.${category.id}.${tech.id}.${check.id}`;
const checkState = state[key];
if (checkState?.status) {
completedChecks++;
statusBreakdown[checkState.status]++;
} else {
statusBreakdown.unchecked++;
}
});
});
});
return {
platformId: platform.id,
totalChecks,
completedChecks,
percentage: Math.round((completedChecks / totalChecks) * 100),
statusBreakdown
};
}
```
## Export Functionality
### Export to JSON
```typescript
interface ExportData {
version: string;
exportDate: string;
platforms: {
[platformId: string]: {
checks: {
[checkId: string]: {
status: 'open' | 'closed' | 'na';
notes: string;
timestamp: number;
};
};
};
};
}
function exportToJSON(): string {
const state = JSON.parse(localStorage.getItem(STORAGE_KEYS.CHECKLIST_STATE) || '{}');
const notes = JSON.parse(localStorage.getItem(STORAGE_KEYS.USER_NOTES) || '{}');
const exportData: ExportData = {
version: '1.0',
exportDate: new Date().toISOString(),
platforms: {}
};
// Merge state and notes
Object.keys(state).forEach(key => {
const [platformId, categoryId, techId, checkId] = key.split('.');
if (!exportData.platforms[platformId]) {
exportData.platforms[platformId] = { checks: {} };
}
exportData.platforms[platformId].checks[checkId] = {
status: state[key].status,
notes: notes[key]?.content || '',
timestamp: notes[key]?.timestamp || Date.now()
};
});
return JSON.stringify(exportData, null, 2);
}
```
### Export to Markdown
```typescript
function exportToMarkdown(platform: Platform, includeOnlyOpen = false): string {
let markdown = `# ${platform.name} Security Assessment\n\n`;
markdown += `**Export Date:** ${new Date().toLocaleDateString()}\n\n`;
const state = JSON.parse(localStorage.getItem(STORAGE_KEYS.CHECKLIST_STATE) || '{}');
const notes = JSON.parse(localStorage.getItem(STORAGE_KEYS.USER_NOTES) || '{}');
platform.categories.forEach(category => {
markdown += `## ${category.name}\n\n`;
category.technologies.forEach(tech => {
markdown += `### ${tech.name}\n\n`;
tech.checks.forEach(check => {
const key = `${platform.id}.${category.id}.${tech.id}.${check.id}`;
const checkState = state[key];
if (includeOnlyOpen && checkState?.status !== 'open') {
return;
}
markdown += `#### ${check.title}\n\n`;
markdown += `**Severity:** ${check.severity.toUpperCase()}\n\n`;
markdown += `**Status:** ${checkState?.status || 'Unchecked'}\n\n`;
markdown += `**Description:** ${check.description}\n\n`;
if (notes[key]?.content) {
markdown += `**Notes:**\n\n${notes[key].content}\n\n`;
}
if (check.tools && check.tools.length > 0) {
markdown += `**Tools:** ${check.tools.join(', ')}\n\n`;
}
markdown += '---\n\n';
});
});
});
return markdown;
}
```
### Export to CSV
```typescript
function exportToCSV(platform: Platform): string {
const headers = [
'Platform',
'Category',
'Technology',
'Check',
'Severity',
'Status',
'Notes',
'Tags',
'Tools'
];
let csv = headers.join(',') + '\n';
const state = JSON.parse(localStorage.getItem(STORAGE_KEYS.CHECKLIST_STATE) || '{}');
const notes = JSON.parse(localStorage.getItem(STORAGE_KEYS.USER_NOTES) || '{}');
platform.categories.forEach(category => {
category.technologies.forEach(tech => {
tech.checks.forEach(check => {
const key = `${platform.id}.${category.id}.${tech.id}.${check.id}`;
const checkState = state[key];
GitHubで見る