pentest-lyan-web-security-testing

v2026.09.24

Autonomous web penetration testing skill with threat modeling, JavaScript analysis, and multi-role verification

GitHub
安装命令
npx skhub add reason-machines/pentest-lyan-web-security-testing
Markdown
SKILL.md

Pentest-Lyan Web Security Testing

Skill by ara.so — Security Skills collection.

Pentest-Lyan is an autonomous web penetration testing framework that performs self-directed threat modeling across 12 dimensions, complete JavaScript analysis, and cross-role verification. It validates business impact (not just HTTP 200 responses), maintains state across sessions, and generates both technical Markdown and delivery-ready Word reports.

What It Does

  • Autonomous Threat Modeling: Identifies threats based on 12 thinking dimensions rather than fixed vulnerability checklists
  • Deep JavaScript Analysis: Reads and understands business logic, signing mechanisms, and frontend parameters before testing APIs
  • Business Impact Validation: Verifies database-layer changes, data access, and state transitions actually occur
  • Multi-Role Testing: Builds permission matrices and performs cross-role privilege escalation checks
  • Stateful Testing: Supports resume (--resume), multi-project isolation, and session pooling
  • Dual Report Formats: Markdown for technical details, Word for delivery; separates critical findings from configuration issues

Installation

Prerequisites

  1. Python 3.8+ with the project dependencies
  2. Playwright MCP Server (recommended for browser automation and session pooling)

Setup Steps

# Clone the repository
git clone https://github.com/HeaSec/Pentest-Lyan.git
cd Pentest-Lyan

# Install Python dependencies (if requirements.txt exists)
pip install -r requirements.txt

# Install as a Claude Code skill
# Copy the entire pentest-lyan/ directory to your Claude Code skills path
# Default locations:
#   - macOS/Linux: ~/.config/claude-code/skills/
#   - Windows: %APPDATA%\claude-code\skills\

cp -r . ~/.config/claude-code/skills/pentest-lyan/

Playwright MCP Setup (Optional but Recommended)

# Install Playwright MCP for browser automation
npm install -g @playwright/mcp-server

# Or add to your MCP configuration
# The skill will use curl if Playwright is unavailable

Project Structure

pentest-lyan/
├── SKILL.md              # Main orchestrator (3 phases, 9 exit conditions)
├── gates.md              # HARD GATE definitions (G1-G7)
├── schema.md             # Data schema index
├── references/           # Process documentation (read by agent as needed)
│   ├── discovery-guide.md
│   ├── attack-guide.md
│   ├── threat-modeling.md
│   ├── validation-guide.md
│   ├── cross-role-testing.md
│   ├── audit-guide.md
│   ├── report-template.md
│   ├── docx-template.md
│   └── post-delivery.md
├── schema/              # Field specification schemas (*.schema.json)
├── scripts/             # Utility scripts
│   └── render_docx.py
└── templates/           # Word document templates

Basic Usage

Starting a New Security Test

# Basic invocation
/pentest-lyan https://target.example.com

# Provide credentials (required for proper testing)
/pentest-lyan https://target.example.com
账号:
  - admin/Admin@123   (role_level: high_privilege)
  - user1/User@123    (role_level: standard)
  - user2/User@123    (role_level: standard)

Important: No need to declare authorization scope/timeframe — issuing the command implies authorization.

Multi-Project Management

# List all projects
/pentest-lyan --list

# Resume an existing project
/pentest-lyan --resume <project-id>

# Start with custom project ID
/pentest-lyan https://target.example.com --project custom-id

Default project-id is extracted from the hostname's first segment.

Testing Phases

Pentest-Lyan executes in three sequential phases:

Phase 1: Discovery

  • Deep JavaScript analysis (business logic, signing, parameters)
  • Complete API endpoint discovery
  • Session pool creation
  • Permission matrix generation

Phase 2: Attack

  • Feature-level testing pipeline
  • Dynamic sub-module discovery
  • Cross-role privilege verification
  • Business impact validation

Phase 3: Audit

  • Schema validation
  • Completeness auditing
  • System-level checks
  • Report generation (Markdown + Word)

Account Requirements (G1 Gate)

The G1 gate checks account availability but does not block testing:

  • ≥2 accounts: Normal flow, full cross-role testing
  • 0-1 accounts: Degraded mode, limited privilege testing; if registration page found, report prompts user to register additional accounts

role_level must be explicitly declared by the user (not inferred from username):

  • high_privilege: Admin, superuser, manager
  • standard: Regular user
  • limited: Guest, read-only

Working with State Files

Pentest-Lyan maintains state in pentest-data/<project-id>/:

pentest-data/
└── <project-id>/
    ├── state.json           # Main state (phase, coverage, findings)
    ├── index.json           # Project metadata
    ├── pages/              # Discovered pages/APIs
    ├── sessions/           # Session data (contains credentials)
    ├── modules/            # Feature module state
    └── coverage/           # Coverage tracking

State File Example

{
  "project_id": "example-com",
  "phase": "discovery",
  "target": "https://example.com",
  "accounts": [
    {
      "username": "admin",
      "password": "REDACTED",
      "role_level": "high_privilege"
    }
  ],
  "discovered_endpoints": [],
  "findings": [],
  "coverage": {}
}

Security Warning: pentest-data/ contains plaintext credentials. Add to .gitignore:

# Add to .gitignore
echo "pentest-data/" >> .gitignore
echo "pentest-report/" >> .gitignore

Threat Modeling Dimensions

Pentest-Lyan uses 12 autonomous threat dimensions:

  1. Authentication: Session, token, multi-factor bypasses
  2. Authorization: Horizontal/vertical privilege escalation, IDOR
  3. Input Validation: Injection, XSS, path traversal
  4. Business Logic: Workflow bypasses, race conditions
  5. Data Exposure: Sensitive data leaks, information disclosure
  6. Session Management: Fixation, hijacking, timeout issues
  7. Cryptography: Weak algorithms, improper key management
  8. Configuration: Default credentials, unnecessary services
  9. API Security: Rate limiting, parameter tampering
  10. File Handling: Upload bypasses, arbitrary file operations
  11. Error Handling: Stack traces, verbose errors
  12. Third-Party: Dependency vulnerabilities, external service abuse

Code Examples

Extending Validation Logic (Python)

# Example: Custom validator for business impact
# File: custom_validators.py

import requests
import json

def validate_discount_manipulation(session, endpoint, payload):
    """
    Verify that discount manipulation actually affects the database.
    Returns True if vulnerability is confirmed.
    """
    # Apply discount
    resp = session.post(
        endpoint,
        json=payload,
        headers={"Content-Type": "application/json"}
    )
    
    if resp.status_code != 200:
        return False
    
    # Retrieve order to confirm database change
    order_id = resp.json().get("order_id")
    verify_resp = session.get(f"/api/orders/{order_id}")
    
    if verify_resp.status_code == 200:
        order_data = verify_resp.json()
        expected_price = payload.get("discounted_price")
        actual_price = order_data.get("total_price")
        
        # Confirm business impact
        return actual_price == expected_price
    
    return False

# Use in validation-guide.md workflow

Reading JavaScript for Signing Logic

# Example: Extracting signing mechanism from JS
# The agent performs this during discovery phase

import re
import requests

def extract_signing_function(js_url):
    """
    Download and parse JavaScript to find signing functions.
    """
    resp = requests.get(js_url)
    js_content = resp.text
    
    # Look for common signing patterns
    signing_patterns = [
        r'function\s+sign\([^)]*\)\s*{([^}]+)}',
        r'const\s+sign\s*=\s*\([^)]*\)\s*=>\s*{([^}]+)}',
        r'\.sign\s*=\s*function\([^)]*\)\s*{([^}]+)}'
    ]
    
    for pattern in signing_patterns:
        matches = re.findall(pattern, js_content)
        if matches:
            return {
                "signing_function": matches[0],
                "algorithm": detect_algorithm(matches[0])
            }
    
    return None

def detect_algorithm(func_body):
    """Detect crypto algorithm from function body."""
    if 'md5' in func_body.lower():
        return 'md5'
    elif 'sha256' in func_body.lower():
        return 'sha256'
    elif 'hmac' in func_body.lower():
        return 'hmac'
    return 'unknown'

Permission Matrix Generation

# Example: Building permission matrix for cross-role testing
# File: permission_matrix.py

def build_permission_matrix(endpoints, sessions):
    """
    Test each endpoint with each role to build permission matrix.
    Returns matrix of {endpoint: {role: accessible}}.
    """
    matrix = {}
    
    for endpoint in endpoints:
        matrix[endpoint["path"]] = {}
        
        for session_info in sessions:
            role = session_info["role_level"]
            session = session_info["session"]
            
            # Test access
            resp = session.get(
                endpoint["url"],
                allow_redirects=False
            )
            
            # Determine if accessible
            accessible = resp.status_code in [200, 201, 204]
            matrix[endpoint["path"]][role] = {
                "accessible": accessible,
                "status_code": resp.status_code
            }
    
    return matrix

# Example matrix output:
# {
#   "/api/admin/users": {
#     "high_privilege": {"accessible": True, "status_code": 200},
#     "standard": {"accessible": False, "status_code": 403}
#   },
#   "/api/profile": {
#     "high_privilege": {"accessible": True, "status_code": 200},
#     "standard": {"accessible": True, "status_code": 200}
#   }
# }

Cross-Role Privilege Testing

# Example: Test privilege escalation using permission matrix
# File: cross_role_test.py

def test_privilege_escalation(matrix, sessions):
    """
    Use permission matrix to find privilege escalation vulnerabilities.
    """
    findings = []
    
    for endpoint, roles in matrix.items():
        # Find endpoints accessible to high_privilege but not standard
        if (roles.get("high_privilege", {}).get("accessible") and
            not roles.get("standard", {}).get("accessible")):
            
            # Test with standard user using high_privilege user's ID
            standard_session = get_session_by_role(sessions, "standard")
            high_priv_user_id = get_user_id_by_role(sessions, "high_privilege")
            
            # Attempt access with victim ID (not hardcoded)
            test_url = endpoint.replace("{user_id}", str(high_priv_user_id))
            resp = standard_session.get(test_url)
            
            if resp.status_code in [200, 201]:
                findings.append({
                    "type": "privilege_escalation",
                    "endpoint": endpoint,
                    "description": f"Standard user can access high_privilege endpoint",
                    "evidence": {
                        "url": test_url,
                        "status": resp.status_code,
                        "attacker_role": "standard",
                        "victim_role": "high_privilege"
                    }
                })
    
    return findings

Report Generation

Markdown Report

Generated automatically at end of audit phase:

# Reports are written to:
pentest-report/<project-id>_<timestamp>.md

Structure:

  • Executive Summary
  • Findings (Critical → High → Medium → Low)
  • Coverage Analysis (answers: input surface, behavior surface, depth)
  • Appendix (configuration issues, not_vulnerable with unruled_out)

Word Report

# scripts/render_docx.py
import sys
from docx import Document
from docx.shared import Inches, Pt, RGBColor

def render_docx(markdown_path, output_path, template_path=None):
    """
    Convert Markdown report to Word document.
    
    Args:
        markdown_path: Path to .md report
        output_path: Path for output .docx
        template_path: Optional custom template
    """
    doc = Document(template_path) if template_path else Document()
    
    with open(markdown_path, 'r', encoding='utf-8') as f:
        content = f.read()
    
    # Parse markdown and apply styles
    sections = parse_markdown(content)
    
    for section in sections:
        if section['type'] == 'heading1':
            doc.add_heading(section['text'], level=1)
        elif section['type'] == 'finding':
            add_finding_block(doc, section['data'])
        elif section['type'] == 'code':
            add_code_block(doc, section['text'])
    
    doc.save(output_path)

# Usage:
# python scripts/render_docx.py pentest-report/example-com_2026.md output.docx

Configuration

Environment Variables

# Optional: Custom data directory
export PENTEST_DATA_DIR="/secure/location/pentest-data"

# Optional: Report output directory
export PENTEST_REPORT_DIR="/reports"

# Optional: Playwright MCP endpoint
export PLAYWRIGHT_MCP_URL="http://localhost:3000"

# Optional: Rate limiting (requests per second)
export PENTEST_RATE_LIMIT="5"

# Optional: Timeout for requests (seconds)
export PENTEST_TIMEOUT="30"

Custom Gate Configuration

Edit gates.md to adjust gate thresholds:

# G1: Account Gate
Threshold: ≥2 accounts (degraded mode if fewer)

# G2: JavaScript Coverage Gate
Threshold: ≥80% of main bundles analyzed

# G3: Endpoint Discovery Gate
Threshold: ≥5 unique endpoints or complete sitemap

Common Patterns

Pattern 1: Testing with Multiple Accounts

# The framework automatically manages session pools
# You provide credentials at invocation:

/pentest-lyan https://api.example.com
Accounts:
  - admin@example.com/SecurePass123! (role_level: high_privilege)
  - user@example.com/UserPass456! (role_level: standard)
  - guest@example.com/GuestPass789! (role_level: limited)

Pattern 2: Resuming After Interruption

# List projects to find ID
/pentest-lyan --list

# Output:
# example-com | Phase: attack | Findings: 3 | Status: in_progress

# Resume
/pentest-lyan --resume example-com

Pattern 3: Custom Threat Module

Create a custom module in references/custom-threats/:

# custom-payment-logic.md

## Threat: Payment Amount Manipulation

**Coverage Questions:**
- Input surface: price, quantity, discount_code, currency
- Behavior surface: calculate_total, apply_discount, process_payment
- Depth: Database transaction verification, audit log check

**Test Steps:**
1. Capture legitimate payment request
2. Modify `amount` parameter to $0.01
3. Replay request
4. Verify database: SELECT amount FROM orders WHERE order_id = ?
5. Check audit logs for amount mismatch

**Validation:**
- Status 200 alone is NOT sufficient
- Must confirm database shows manipulated amount
- Must confirm payment gateway charged manipulated amount

Troubleshooting

Issue: "No endpoints discovered"

Cause: JavaScript not fully analyzed or SPA routing not detected.

Solution:

# Check if JS bundles were downloaded
ls pentest-data/<project-id>/pages/

# Verify Playwright MCP is running
curl http://localhost:3000/health

# Force re-discovery
rm pentest-data/<project-id>/state.json
/pentest-lyan --resume <project-id>

Issue: "G1 gate: insufficient accounts"

Cause: Fewer than 2 accounts provided.

Solution: This is a soft gate — testing continues in degraded mode.

  • Provide additional accounts and re-run
  • Or continue and register accounts manually if prompted in report

Issue: "Validation failed: status 200 but no business impact"

Cause: Response is 200 but database/state unchanged.

Solution: This is correct behavior (not a bug).

  • Pentest-Lyan requires verification of actual state change
  • Check validation-guide.md for proper validation steps
  • Customize validators if needed (see Code Examples above)

Issue: Session expires during testing

Cause: Long-running tests exceed session timeout.

Solution:

# Pentest-Lyan auto-refreshes sessions
# If custom session handling needed, extend:

# File: custom_session_refresh.py
def refresh_session(session_info):
    """Re-authenticate if session expired."""
    login_resp = requests.post(
        f"{session_info['base_url']}/api/login",
        json={
            "username": session_info["username"],
            "password": session_info["password"]
        }
    )
    return login_resp.cookies.get("session_token")

Issue: Report missing findings

Cause: Findings not properly recorded in state.json.

Solution:

# Validate state file structure
python -c "
import json
with open('pentest-data/<project-id>/state.json') as f:
    state = json.load(f)
    print(f'Findings: {len(state.get(\"findings\", []))}')
"

# Check findings schema
cat schema/findings.schema.json

Issue: Word report rendering fails

Cause: Missing python-docx or template corruption.

Solution:

# Install dependencies
pip install python-docx

# Re-render with default template
python scripts/render_docx.py \
  pentest-report/<project-id>.md \
  output.docx

# Or specify custom template
python scripts/render_docx.py \
  pentest-report/<project-id>.md \
  output.docx \
  --template templates/custom-template.docx

Security Best Practices

  1. Credential Management:

    • Never commit pentest-data/ to version control
    • Use environment variables for sensitive config
    • Follow post-delivery cleanup (see references/post-delivery.md)
  2. Authorization:

    • Only test systems you have explicit permission to test
    • Issuing /pentest-lyan <target> implies authorization
  3. Data Handling:

    • Encrypt pentest-data/ and pentest-report/ after testing
    • Clear sessions after delivery: rm -rf pentest-data/<project-id>/sessions/
  4. Rate Limiting:

    • Set PENTEST_RATE_LIMIT to avoid overwhelming targets
    • Default: 5 req/s (configurable)

Advanced Usage

Custom Validation Pipeline

# File: advanced_validation.py

from typing import Dict, Any, List

def extended_validation_pipeline(finding: Dict[str, Any]) -> bool:
    """
    Extended validation requiring multiple confirmation steps.
    """
    validators = [
        validate_http_response,
        validate_database_state,
        validate_audit_log,
        validate_side_effects
    ]
    
    results = []
    for validator in validators:
        result = validator(finding)
        results.append(result)
        
        # Log validation step
        log_validation_step(
            finding_id=finding['id'],
            validator=validator.__name__,
            result=result
        )
    
    # All validators must pass
    return all(results)

def validate_database_state(finding: Dict[str, Any]) -> bool:
    """Verify database reflects the exploit."""
    # Implementation specific to finding type
    pass

def validate_audit_log(finding: Dict[str, Any]) -> bool:
    """Check if suspicious activity was logged."""
    # Absence of logging may itself be a finding
    pass

def validate_side_effects(finding: Dict[str, Any]) -> bool:
    """Verify no unintended side effects occurred."""
    pass

Integration with CI/CD

# .github/workflows/security-test.yml
name: Automated Security Testing

on:
  schedule:
    - cron: '0 2 * * 0'  # Weekly on Sunday 2 AM

jobs:
  pentest:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.10'
      
      - name: Install Pentest-Lyan
        run: |
          git clone https://github.com/HeaSec/Pentest-Lyan.git
          cd Pentest-Lyan
          pip install -r requirements.txt
      
      - name: Run Security Test
        env:
          TEST_ADMIN_USER: ${{ secrets.TEST_ADMIN_USER }}
          TEST_ADMIN_PASS: ${{ secrets.TEST_ADMIN_PASS }}
          TEST_USER_USER: ${{ secrets.TEST_USER_USER }}
          TEST_USER_PASS: ${{ secrets.TEST_USER_PASS }}
        run: |
          /pentest-lyan https://staging.example.com \
            --account "$TEST_ADMIN_USER/$TEST_ADMIN_PASS (role_level: high_privilege)" \
            --account "$TEST_USER_USER/$TEST_USER_PASS (role_level: standard)"
      
      - name: Upload Report
        uses: actions/upload-artifact@v3
        with:
          name: security-report
          path: pentest-report/*.md

Additional Resources


License: MIT
Repository: https://github.com/HeaSec/Pentest-Lyan
Issues: https://github.com/HeaSec/Pentest-Lyan/issues

发现
标签

此技能尚未发布标签。

版本
最新版本元数据

版本

v2026.09.24

发布时间

2026年9月24日

分类

未分类

许可证

NOASSERTION

源路径

skills/pentest-lyan-web-security-testing

默认分支

main

最新提交

304c245

Tree SHA

010f47d