# Pentesting Checklist Platform

> Interactive security assessment checklist covering 23 platforms with 1,000+ checks for pentesting, bug bounty, and security audits

- Skill: `aradotso-security-skills/pentesting-checklist-platform` (Agent Skill)
- Install (CLI): `npx skillmds@latest add aradotso-security-skills/pentesting-checklist-platform`
- Raw SKILL.md: https://api.skillmd.com/api/skills/aradotso-security-skills/pentesting-checklist-platform/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: aradotso (https://skillmd.com/u/aradotso-security-skills)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/aradotso-security-skills/pentesting-checklist-platform

---


# 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];
        const checkNotes = notes[key]?.content || '';
        
        const row = [
          platform.name,
          category.name,
          tech.name,
          `"${check.title}"`,
          check.severity,
          checkState?.status || 'unchecked',
          `"${checkNotes.replace(/"/g, '""')}"`,
          `"${check.tags.join('; ')}"`,
          `"${(check.tools || []).join('; ')}"`
        ];
        
        csv += row.join(',') + '\n';
      });
    });
  });
  
  return csv;
}
```

## Import Functionality

```typescript
function importFromJSON(jsonString: string): void {
  try {
    const importData: ExportData = JSON.parse(jsonString);
    
    // Validate version compatibility
    if (importData.version !== '1.0') {
      throw new Error('Unsupported export version');
    }
    
    const currentState = JSON.parse(localStorage.getItem(STORAGE_KEYS.CHECKLIST_STATE) || '{}');
    const currentNotes = JSON.parse(localStorage.getItem(STORAGE_KEYS.USER_NOTES) || '{}');
    
    // Merge imported data
    Object.entries(importData.platforms).forEach(([platformId, platformData]) => {
      Object.entries(platformData.checks).forEach(([checkId, checkData]) => {
        const key = checkId; // Full key already in format
        
        currentState[key] = {
          status: checkData.status,
          timestamp: checkData.timestamp
        };
        
        if (checkData.notes) {
          currentNotes[key] = {
            checkId,
            content: checkData.notes,
            timestamp: checkData.timestamp
          };
        }
      });
    });
    
    localStorage.setItem(STORAGE_KEYS.CHECKLIST_STATE, JSON.stringify(currentState));
    localStorage.setItem(STORAGE_KEYS.USER_NOTES, JSON.stringify(currentNotes));
    
    console.log('Import successful');
  } catch (error) {
    console.error('Import failed:', error);
    throw error;
  }
}
```

## Common Workflows

### Starting a New Assessment

```typescript
// 1. Navigate to platform
function startWebAssessment() {
  window.location.href = '/web';
}

// 2. Expand all categories for overview
function expandAllCategories() {
  const collapsed = new Set();
  localStorage.setItem(STORAGE_KEYS.COLLAPSED_SECTIONS, JSON.stringify([...collapsed]));
}

// 3. Filter by severity for prioritization
function filterBySeverity(minSeverity: 'critical' | 'high' | 'medium' | 'low') {
  const severityLevels = ['critical', 'high', 'medium', 'low', 'info'];
  const minIndex = severityLevels.indexOf(minSeverity);
  // Apply filter in UI to show only checks >= minSeverity
}
```

### Recording Findings

```typescript
interface Finding {
  checkId: string;
  vulnerability: string;
  impact: string;
  steps: string[];
  payload?: string;
  evidence: string[];
  remediation: string;
}

function recordFinding(
  platformId: string,
  categoryId: string,
  techId: string,
  checkId: string,
  finding: Finding
): void {
  // Mark as Open
  updateCheckStatus(platformId, categoryId, techId, checkId, 'open');
  
  // Save detailed notes
  const noteContent = `
**Vulnerability:** ${finding.vulnerability}

**Impact:** ${finding.impact}

**Steps to Reproduce:**
${finding.steps.map((step, i) => `${i + 1}. ${step}`).join('\n')}

${finding.payload ? `**Payload:**\n\`\`\`\n${finding.payload}\n\`\`\`` : ''}

**Evidence:**
${finding.evidence.map(e => `- ${e}`).join('\n')}

**Remediation:**
${finding.remediation}
  `.trim();
  
  saveCheckNote(platformId, categoryId, techId, checkId, noteContent);
}
```

### Filtering Open Findings

```typescript
function getOpenFindings(platform: Platform): Array<{
  check: Check;
  category: string;
  technology: string;
  notes: string;
}> {
  const openFindings: Array<any> = [];
  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}`;
        
        if (state[key]?.status === 'open') {
          openFindings.push({
            check,
            category: category.name,
            technology: tech.name,
            notes: notes[key]?.content || ''
          });
        }
      });
    });
  });
  
  return openFindings;
}
```

## Platform-Specific Patterns

### Web Application Assessment

```typescript
const webAppChecks = {
  authentication: [
    'Test for username enumeration',
    'Check password policy enforcement',
    'Verify session timeout settings',
    'Test for account lockout mechanisms'
  ],
  authorization: [
    'Test horizontal privilege escalation',
    'Test vertical privilege escalation',
    'Check for IDOR vulnerabilities',
    'Verify API endpoint authorization'
  ],
  injection: [
    'Test for SQL injection',
    'Check for XSS vulnerabilities',
    'Test for command injection',
    'Verify template injection protections'
  ]
};
```

### API Security Assessment

```typescript
const apiSecurityChecks = {
  authentication: [
    'Test broken object level authorization (BOLA)',
    'Verify broken user authentication',
    'Check for excessive data exposure',
    'Test resource consumption limits'
  ],
  authorization: [
    'Test broken function level authorization',
    'Verify mass assignment protections',
    'Check security misconfiguration',
    'Test for SSRF vulnerabilities'
  ]
};
```

### Cloud Security Assessment

```typescript
const cloudSecurityChecks = {
  iam: [
    'Review IAM policies for overprivileged roles',
    'Check for unused access keys',
    'Verify MFA enforcement',
    'Test for privilege escalation paths'
  ],
  storage: [
    'Check for publicly accessible S3 buckets',
    'Verify encryption at rest',
    'Test bucket policy configurations',
    'Check for sensitive data exposure'
  ],
  compute: [
    'Test instance metadata SSRF',
    'Verify security group configurations',
    'Check for exposed management interfaces',
    'Test network segmentation'
  ]
};
```

## Troubleshooting

### Data Persistence Issues

```typescript
// Check if localStorage is available
function isLocalStorageAvailable(): boolean {
  try {
    const test = '__localStorage_test__';
    localStorage.setItem(test, test);
    localStorage.removeItem(test);
    return true;
  } catch (e) {
    return false;
  }
}

// Clear corrupted data
function resetChecklistData(): void {
  if (confirm('This will clear all assessment data. Continue?')) {
    localStorage.removeItem(STORAGE_KEYS.CHECKLIST_STATE);
    localStorage.removeItem(STORAGE_KEYS.USER_NOTES);
    localStorage.removeItem(STORAGE_KEYS.PROGRESS);
    localStorage.removeItem(STORAGE_KEYS.COLLAPSED_SECTIONS);
    window.location.reload();
  }
}

// Backup before clearing
function backupBeforeReset(): void {
  const backup = {
    state: localStorage.getItem(STORAGE_KEYS.CHECKLIST_STATE),
    notes: localStorage.getItem(STORAGE_KEYS.USER_NOTES),
    progress: localStorage.getItem(STORAGE_KEYS.PROGRESS)
  };
  
  const blob = new Blob([JSON.stringify(backup, null, 2)], { type: 'application/json' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = `checklist-backup-${Date.now()}.json`;
  a.click();
}
```

### Search Performance

```typescript
// Debounced search for better performance
function createDebouncedSearch(delay = 300) {
  let timeoutId: number;
  
  return function(query: string, callback: (results: SearchResult[]) => void) {
    clearTimeout(timeoutId);
    
    timeoutId = setTimeout(() => {
      const results = performSearch(query, getAllPlatforms());
      callback(results);
    }, delay);
  };
}

const debouncedSearch = createDebouncedSearch();
```

### Export Size Limitations

```typescript
// For large assessments, export per platform
function exportPlatformIndividually(platformId: string): void {
  const platform = getPlatformById(platformId);
  const markdown = exportToMarkdown(platform);
  
  const blob = new Blob([markdown], { type: 'text/markdown' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = `${platformId}-assessment-${Date.now()}.md`;
  a.click();
  URL.revokeObjectURL(url);
}
```

## Best Practices

1. **Regular Backups**: Export your assessment data regularly, especially before major changes
2. **Structured Notes**: Use consistent formatting in notes for easier report generation
3. **Severity Filtering**: Start with Critical/High severity checks, then work down
4. **Progress Tracking**: Mark checks as N/A when not applicable to keep accurate progress metrics
5. **Evidence Recording**: Include timestamps, URLs, and request/response data in notes
6. **Export Early**: Don't wait until the end — export incremental findings
7. **Browser Compatibility**: Recommended browsers are Chrome, Firefox, or Edge (modern versions)

## Integration Patterns

### Custom Automation Scripts

```typescript
// Example: Automated check status update from external tool
function updateFromBurpSuite(findings: Array<{url: string, issue: string}>): void {
  findings.forEach(finding => {
    // Map Burp issues to checklist items
    const checkMapping = mapBurpIssueToCheck(finding.issue);
    if (checkMapping) {
      updateCheckStatus(
        checkMapping.platformId,
        checkMapping.categoryId,
        checkMapping.techId,
        checkMapping.checkId,
        'open'
      );
      
      saveCheckNote(
        checkMapping.platformId,
        checkMapping.categoryId,
        checkMapping.techId,
        checkMapping.checkId,
        `Found by Burp Suite at ${finding.url}: ${finding.issue}`
      );
    }
  });
}
```

This skill provides comprehensive coverage of the PentestingChecklist platform for AI agents to assist developers and security professionals in conducting structured security assessments.

