anastasis
v1.3.0
Published
High-performance JavaScript file crawler and endpoint discovery tool for bug bounty and security research
Maintainers
Readme
Anastasis
A high-performance JavaScript endpoint discovery tool for security researchers and bug bounty hunters. Anastasis combines passive reconnaissance with advanced AST-based parsing to extract API endpoints, parameters, and validation schemas from JavaScript files.
The name comes from the Greek word for "resurrection" or "restoration", reflecting the tool's ability to reconstruct application structure from minified and fragmented JavaScript artifacts.
What It Does
Anastasis discovers API endpoints by:
- Aggregating JavaScript files from 15+ passive sources (Wayback Machine, CommonCrawl, URLScan, etc.)
- Parsing JavaScript using a hybrid tree-sitter/Acorn AST system
- Following webpack chunks and reconstructing sourcemaps
- Extracting parameters with types, constraints, and validation schemas
- Tracking authentication patterns and conditional routing
Key Features
Hybrid Parser System
The tool uses a three-tier fallback parser that guarantees 100% parsing success:
- Tree-sitter (fastest, for well-formed code)
- Acorn (robust, handles minified code)
- Acorn-loose (error-tolerant, accepts malformed syntax)
This approach ensures no JavaScript file fails to parse, regardless of minification or syntax errors.
Advanced Endpoint Extraction
- Supports 15+ HTTP libraries (fetch, axios, jQuery, superagent, got, ky, undici, etc.)
- Resolves template literals and dynamic URL construction
- Evaluates obfuscation patterns (atob(), String.fromCharCode(), array.join())
- Tracks class properties and constructor assignments (this.baseURL)
- Extracts GraphQL queries and mutations from client code
- Filters React internals, Tailwind classes, and common false positives
Parameter Extraction
- Recursive extraction of nested objects (up to 3 levels with dot notation)
- Validation framework integration (Joi, Zod, Yup, class-validator)
- TypeScript interface and type analysis
- Automatic type inference (email, UUID, URL, datetime patterns)
- Constraint extraction (min/max, length, regex, enum values)
- Multi-source confidence scoring
Sourcemap Reconstruction
- Fetches external sourcemaps and extracts inline ones
- Maps minified positions back to original source locations
- Enriches endpoints with original file paths, line numbers, and function names
- Validates mapping accuracy and adjusts confidence scores
Security Analysis
- Cross-file authentication tracking
- Detects Base64-encoded auth headers
- Tracks configured HTTP clients (axios.create(), fetch wrappers)
- Identifies auth wrapper functions (authFetch, authenticatedRequest)
- Conditional routing analysis (feature flags, role-based endpoints)
Installation
Quick Setup
git clone https://github.com/0xazanul/Anastasis.git
cd Anastasis
./install.shPrerequisites
- Node.js 18-22 LTS (v22 recommended, v24+ not supported)
- Python 3.x (for native module compilation)
- macOS: Xcode Command Line Tools (
xcode-select --install) - Linux:
sudo apt-get install build-essential python3 - Windows: Visual Studio Build Tools 2022 or WSL2
Manual Installation
git clone https://github.com/0xazanul/Anastasis.git
cd Anastasis
npm install
npm run buildSee the Installation section below for platform-specific troubleshooting.
Complete Usage Guide
Input Mode Flags
These flags determine what target to scan. Use exactly one of these:
-u, --url <domain>
Scan a domain using passive reconnaissance sources.
# Basic domain scan
npm run scan -- -u example.com
# With protocol (http or https)
npm run scan -- -u https://api.example.com
# Subdomain scanning
npm run scan -- -u app.example.comWhat it does:
- Queries 8+ passive sources (Wayback, URLScan, CommonCrawl, etc.)
- Discovers historical and current JavaScript files
- Follows webpack chunks and sourcemaps
- Optionally probes for API documentation
Use when: You want comprehensive passive reconnaissance on a domain.
-js, --js-url <url>
Parse a single JavaScript file directly from URL.
# Parse single JS file
npm run scan -- -js https://example.com/static/app.bundle.js
# With parameter extraction
npm run scan -- -js https://example.com/main.js --params -o json
# Minified production bundle
npm run scan -- -js https://cdn.example.com/build/main.dd68a024.jsWhat it does:
- Downloads and parses the specified JavaScript file
- Extracts endpoints and parameters
- Attempts sourcemap reconstruction if available
- No passive source queries
Use when: You have a specific JavaScript file URL to analyze.
-fs, --local <path>
Scan local JavaScript file(s) from filesystem.
# Single file
npm run scan -- -fs ./downloaded/app.js
# Entire directory (recursive)
npm run scan -- -fs ./js-files/
# With full analysis
npm run scan -- -fs ./bundle.js --params --build-schemas -o jsonWhat it does:
- Reads file(s) from local filesystem
- Parses all .js files in directory (recursive)
- Works offline (no network requests)
- Fastest scanning mode
Use when: You have downloaded JavaScript files or want offline analysis.
-f, --file <path>
Process multiple domains from a file.
# Batch process domains
npm run scan -- -f targets.txt
# With JSON output
npm run scan -- -f domains.txt -o json --save results.jsonFile format (one domain per line):
example.com
api.example.com
app.example.comWhat it does:
- Reads domains from text file
- Processes each domain sequentially
- Combines results in output
Use when: You need to scan multiple domains in batch.
Discovery Control Flags
Control what gets discovered and how:
-b, --browser
Enable headless browser crawler for dynamic content.
# Discover dynamically loaded JavaScript
npm run scan -- -u example.com --browser
# Browser + API discovery
npm run scan -- -u app.example.com --browser --paramsWhat it does:
- Launches headless Chromium browser
- Intercepts network requests
- Discovers dynamically loaded JS files
- Captures lazy-loaded chunks
Use when: Target uses heavy client-side rendering or dynamic imports.
Note: Slower than passive sources, use when passive discovery is insufficient.
--no-api
Skip API documentation discovery.
# Only parse JavaScript files
npm run scan -- -u example.com --no-api
# Fast JS-only scan
npm run scan -- -u example.com --no-api -c 20What it does:
- Skips probing for Swagger, GraphQL, WADL, etc.
- Only extracts endpoints from JavaScript files
- Faster scanning
Use when: You only want JS-extracted endpoints, not API documentation.
--api-only, --skip-js
Only probe for API documentation, skip JavaScript parsing.
# API documentation only
npm run scan -- -u api.example.com --api-only
# Fast API check
npm run scan -- -u example.com --api-only -o jsonWhat it does:
- Probes 50+ common API doc paths
- Checks for Swagger, OpenAPI, GraphQL introspection
- Skips JavaScript file discovery and parsing
- Very fast
Use when: You only want API documentation endpoints.
--fast
Fast mode: API discovery only with high concurrency.
# Quick API check
npm run scan -- -u example.com --fast
# Batch fast scan
npm run scan -- -f targets.txt --fastWhat it does:
- Equivalent to
--api-only -c 20 - Probes API docs with high concurrency
- Fastest scanning mode
Use when: You need quick results and only care about API documentation.
Parameter Extraction Flags
Control parameter extraction depth and detail:
--params
Extract path, query, and body parameters.
# Basic parameter extraction (inline in list format)
npm run scan -- -u example.com --params
# Parameters with JSON output
npm run scan -- -u example.com --params -o jsonWhat it does:
- Extracts parameters from HTTP request bodies
- Infers types (string, number, email, uuid, etc.)
- Extracts constraints from validation schemas
- Calculates confidence scores
- Shows inline in list format:
POST /api/users ← body:[email,password]
Use when: You need parameter information for fuzzing or testing.
--build-schemas
Build nested body schemas for complex objects.
# Full nested schema extraction
npm run scan -- -u example.com --params --build-schemas -o json
# Local file with schemas
npm run scan -- -fs app.js --params --build-schemas -o jsonWhat it does:
- Recursively extracts nested objects (up to 3 levels)
- Creates dot notation:
profile.address.city - Builds full object schemas with types
- Higher accuracy for complex payloads
Use when: APIs use complex nested objects in request bodies.
Note: Requires --params flag. Adds 5-7% performance overhead.
-v, --verbose
Show detailed parameter information.
# Verbose parameter output
npm run scan -- -u example.com --params --verbose -o json
# Full detail with schemas
npm run scan -- -u example.com --params --verbose --build-schemas -o jsonWhat it does:
- Shows parameter sources (tree-sitter, validation-framework, etc.)
- Includes example values when available
- Shows per-parameter confidence scores
- Displays extraction method details
Use when: You need to understand where parameter information came from.
Note: Only affects JSON output format.
--show-headers
Include HTTP headers as parameters.
# Include header parameters
npm run scan -- -u example.com --params --show-headers -o jsonWhat it does:
- Extracts headers from HTTP client configurations
- Shows headers in unified ParamSpec format
- Distinguishes static vs dynamic headers
- Includes auth headers
Use when: You need header information for request reconstruction.
Output Control Flags
Control output format and destination:
-o, --output <format>
Set output format: list, json, tree, or full.
List Format (default):
npm run scan -- -u example.com -o listOutput:
GET /api/v1/users
POST /api/v1/users
GET /api/v1/users/{id}JSON Format:
npm run scan -- -u example.com -o jsonOutput:
[
{
"method": "GET",
"path": "/api/v1/users",
"source": "js",
"confidence": 0.95
}
]Tree Format:
npm run scan -- -u example.com -o treeOutput:
/api
└── /v1
└── /users
├── GET
└── POSTFull Format:
npm run scan -- -u example.com -o fullOutput: Includes all metadata, sources, confidence scores, and analysis details.
Use cases:
list: Human-readable, pipe to other toolsjson: Automation, further processingtree: Visual inspection, documentationfull: Debugging, detailed analysis
--save <file>, -s <file>
Save output to file.
# Save JSON to file
npm run scan -- -u example.com -o json --save results.json
# Save with parameters
npm run scan -- -u example.com --params -o json --save endpoints.json
# Batch scan to file
npm run scan -- -f domains.txt -o json --save all-endpoints.jsonWhat it does:
- Writes output to specified file
- Creates file if it doesn't exist
- Overwrites existing file
Use when: You need to save results for later analysis or processing.
Performance & Control Flags
Optimize scanning speed and control execution:
-c, --concurrency <n>
Set number of concurrent requests.
# Higher concurrency (faster, more aggressive)
npm run scan -- -u example.com -c 20
# Lower concurrency (slower, more polite)
npm run scan -- -u example.com -c 5
# Maximum speed
npm run scan -- -u example.com -c 50 --no-apiDefault: 10
What it does:
- Controls parallel HTTP requests
- Higher = faster but more aggressive
- Lower = slower but more polite
Recommendations:
- Small targets: 5-10
- Medium targets: 10-20
- Large targets: 20-50
- Bug bounty: 5-15 (be polite)
- Own infrastructure: 30-50
-d, --debug
Enable debug mode with detailed logging.
# Debug output
npm run scan -- -u example.com -d
# Debug with local file
npm run scan -- -fs app.js -dWhat it does:
- Shows detailed processing information
- Logs parser strategy used (tree-sitter, acorn, acorn-loose)
- Displays constant propagation details
- Shows why endpoints were filtered
- Logs HTTP request/response details
Use when: Troubleshooting parsing issues or understanding extraction logic.
-h, --help
Display help information.
npm run scan -- --helpWhat it does:
- Shows all available flags
- Displays usage examples
- Lists supported sources and features
Common Usage Patterns
Basic Reconnaissance
# Standard bug bounty scan
npm run scan -- -u target.com
# With parameters
npm run scan -- -u target.com --params -o jsonDeep Analysis
# Full extraction with all features
npm run scan -- -u example.com \
--params \
--build-schemas \
--verbose \
--show-headers \
--browser \
-o json \
--save full-analysis.jsonFast Checking
# Quick API documentation check
npm run scan -- -u api.example.com --fast
# Fast JS-only scan
npm run scan -- -u example.com --no-api -c 30Offline Analysis
# Analyze downloaded files
npm run scan -- -fs ./downloaded-js/ \
--params \
--build-schemas \
-o json \
--save offline-results.jsonBatch Processing
# Process multiple domains
npm run scan -- -f targets.txt \
--params \
-o json \
--save batch-results.json \
-c 15Specific File Analysis
# Deep dive on single file
npm run scan -- -js https://target.com/app.js \
--params \
--verbose \
--build-schemas \
-o json \
-dFlag Compatibility Matrix
| Flag | Compatible With | Incompatible With |
|------|----------------|-------------------|
| --params | All output formats, --build-schemas, --verbose | None |
| --build-schemas | --params (required) | None |
| --verbose | --params, -o json | -o list/tree/full |
| --show-headers | --params | None |
| --no-api | -u, -f | --api-only, --fast |
| --api-only | -u, -f | --no-api, --browser, -fs, -js |
| --fast | -u, -f | --no-api, --browser, -fs, -js |
| --browser | -u | --api-only, --fast, -fs, -js |
| -o json | All flags | None |
| --save | All flags | None |
Performance Impact
| Flag | Performance Impact | Notes |
|------|-------------------|-------|
| --params | +10-15% time | Worth it for parameter data |
| --build-schemas | +5-7% time | Requires --params |
| --verbose | Negligible | Output formatting only |
| --browser | +30-60s | Launches headless browser |
| -c 20 | 2x faster | Double default concurrency |
| -c 50 | 3-4x faster | Use on own infrastructure |
| --fast | 5-10x faster | API docs only |
| --no-api | -20% time | Skips API probing |
Benchmark Results
Performance metrics from real-world testing:
Parse Performance
| File Size | Lines | Endpoints | Parse Time | Throughput | |-----------|-------|-----------|------------|------------| | 20 lines | 20 | 7 | 0.49s | 14 eps/s | | 33 KB | 1,156 | 117 | 0.58s | 202 eps/s | | 100 KB | ~3,500 | ~350 | 1.8s | 194 eps/s | | 500 KB | ~15,000 | ~1,400 | 8.2s | 171 eps/s |
Feature Accuracy
| Feature | Detection Rate | Notes | |---------|---------------|-------| | fetch() calls | 100% | Direct and wrapped calls | | axios methods | 100% | All methods (get, post, put, etc.) | | Template literals | 95% | Requires constant propagation | | Class properties | 90% | this.baseURL patterns | | atob() decoding | 100% | Base64 URL detection | | Nested parameters | 85% | Up to 3 levels deep |
Comparison with Other Tools
| Tool | Endpoints Found | Parse Time | False Positives | Parameter Extraction | |------|----------------|------------|-----------------|---------------------| | Anastasis | 117 | 0.58s | Low | Full (typed) | | jsluice | 89 | 0.31s | Medium | Basic | | LinkFinder | 43 | 2.14s | High | None | | Katana | N/A | N/A | N/A | Basic |
Tested on a 33KB minified production file with 168 actual HTTP calls.
Parser Strategy Distribution
On 100 random production JavaScript files:
| Parser | Success Rate | Avg Time | |--------|-------------|----------| | Tree-sitter | 42% | 0.18s | | Acorn | 51% | 0.24s | | Acorn-loose | 7% | 0.31s |
The hybrid system ensures 100% parsing success across all files.
Output Examples
List Format
GET /api/v1/users
POST /api/v1/auth/login
GET /api/v1/users/{id}
DELETE /api/v1/users/{id}
POST /graphql
POST /graphql#mutation/CreateUser
POST /graphql#query/GetUser
GET /v2/products/{id}List Format with Parameters
POST /api/users ← body:[email,password,profile,profile.firstName,profile.age]
PATCH /api/users/{userId}/profile ← path:[userId] body:[displayName,bio]
GET /api/search ← query:[q,limit,offset,sortBy]
POST /api/orders ← body:[items,shipping.address.street,payment.method]JSON Format with Full Specifications
{
"requestSpecs": [
{
"path": "/api/users",
"method": "POST",
"bodyParams": [
{
"name": "email",
"type": "email",
"required": true,
"confidence": 0.95,
"sources": ["tree-sitter", "validation-framework", "name-heuristic"],
"example": "[email protected]",
"constraints": {
"format": "email"
}
},
{
"name": "password",
"type": "string",
"required": true,
"confidence": 0.95,
"constraints": {
"minLength": 8,
"maxLength": 100
}
},
{
"name": "age",
"type": "number",
"required": false,
"confidence": 0.85,
"constraints": {
"min": 18,
"max": 120
}
}
],
"confidence": 0.92
}
]
}Architecture
src/
├── scan.ts # CLI entry point
├── core/
│ ├── discovery-orchestrator.ts # Coordinates discovery sources
│ ├── http-client.ts # HTTP with connection pooling
│ ├── chunk-crawler.ts # Webpack/Vite chunk following
│ └── endpoint-discovery.ts # API documentation probing
├── parsers/
│ ├── parser-strategies.ts # Hybrid parser fallback system
│ ├── tree-sitter-parser.ts # Primary AST extraction
│ ├── ast-normalizer.ts # Acorn to tree-sitter normalization
│ ├── expression-evaluator.ts # atob(), fromCharCode(), join()
│ ├── constant-propagator.ts # 4-pass variable tracking
│ ├── param-extractor.ts # Parameter extraction
│ ├── validation-framework-analyzer.ts # Joi/Zod/Yup schemas
│ ├── typescript-type-analyzer.ts # Interface analysis
│ └── sourcemap-enricher.ts # Sourcemap reconstruction
└── sources/
├── wayback.ts # Wayback Machine integration
├── commoncrawl.ts # CommonCrawl queries
├── urlscan.ts # URLScan API
└── ... # 15+ sources totalHow It Works
1. Discovery Phase
The tool queries multiple passive sources in parallel:
- Wayback Machine (with pagination)
- CommonCrawl (recent indexes)
- URLScan (historical scans)
- AlienVault OTX
- GAU aggregator
- JSMon, SubJS, and others
JavaScript URLs are deduplicated and filtered to remove static assets.
2. Content Fetching
Files are fetched using a connection-pooled HTTP client with:
- Automatic retry on failure
- Concurrent requests (configurable limit)
- LRU caching to avoid refetching
- Sourcemap detection and retrieval
3. Parsing
The hybrid parser tries strategies in order:
- Tree-sitter (fast, strict)
- Acorn (robust, standards-compliant)
- Acorn-loose (error-tolerant)
Acorn ASTs are normalized to tree-sitter format for unified processing.
4. Extraction
The parser walks the AST to find:
- Function calls (fetch, axios, $.ajax, etc.)
- HTTP methods from call signatures
- URL arguments (strings, template literals, expressions)
- Dynamic constructions (concatenation, obfuscation)
Expression evaluator plugins handle:
- Base64 decoding (atob)
- Character code conversion (String.fromCharCode)
- Array concatenation (array.join)
Constant propagator tracks variables across:
- Variable declarations
- Object properties
- Class constructor assignments
- Import/export statements
5. Parameter Extraction
When --params is enabled:
- Finds HTTP request bodies in call arguments
- Recursively extracts nested object properties
- Analyzes validation schemas (Joi, Zod, Yup)
- Parses TypeScript interfaces and types
- Infers types from patterns and constraints
- Assigns confidence scores based on sources
6. Enrichment
If sourcemaps are available:
- Maps minified positions to original sources
- Adds file paths, line numbers, function names
- Validates mapping accuracy
- Adjusts confidence scores
Authentication and conditional analysis:
- Tracks auth headers and tokens
- Identifies auth wrapper functions
- Detects role-based routing
- Flags feature flags and lazy loading
Data Sources
Passive JS Discovery
| Source | Description | Rate Limits | |--------|-------------|-------------| | Wayback Machine | Historical JavaScript files | None | | GAU | GetAllUrls aggregator | None | | AlienVault OTX | Open Threat Exchange | API key optional | | URLScan | Historical scan data | 100/day free | | JSMon | JavaScript monitoring | Requires login | | CommonCrawl | Web crawl indexes | None | | SubJS | Subdomain JS enumeration | None | | Browser Crawler | Headless browser | Active (requires --browser) |
API Discovery Probes
| Type | Example Paths | |------|---------------| | Swagger/OpenAPI | /swagger.json, /api-docs, /openapi.json | | GraphQL | /graphql, /gql (with introspection) | | WADL | /application.wadl, /?_wadl | | WSDL | ?wsdl, /ws/*.wsdl | | Manifests | /_next/build-manifest.json | | Well-Known | /.well-known/openapi.json |
Use Cases
Bug Bounty Hunting
- Find hidden endpoints not linked in the UI
- Discover deprecated or legacy endpoints
- Extract historical endpoints from old JavaScript versions
- Identify internal or admin API routes
- Extract parameter validation for fuzzing targets
Security Research
- Map the complete attack surface
- Find endpoints for fuzzing and testing
- Extract GraphQL schemas and operations
- Identify authentication patterns
- Analyze client-side validation logic
API Documentation Recovery
- Reverse-engineer undocumented APIs
- Extract parameter types and constraints
- Reconstruct TypeScript interfaces
- Generate API documentation from code
Offline Analysis
- Parse downloaded JavaScript without network access
- Analyze mobile app JavaScript bundles
- Review code from previous assessments
- Archive API specifications
Development
# Development mode (with tsx watch)
npm run dev -- -u example.com
# Build TypeScript
npm run build
# Type checking
npm run lint
# Run tests
npm test
# Run tests in watch mode
npm run test:watchTesting
The project includes comprehensive test coverage:
# Run all tests
npm test
# Run with coverage
npm run test:coverage
# Run specific categories
npm run test:unit # Unit tests
npm run test:integration # Integration tests
npm run test:e2e # End-to-end testsTest Coverage
| Category | Tests | Description | |----------|-------|-------------| | Unit | 520+ | Parser components, utilities, extractors | | Integration | 17 | Full pipeline, framework parsers | | End-to-end | 19 | Complete workflows, performance |
All tests run on Node.js 18, 20, and 22 in CI.
Performance Characteristics
Typical Scan Times
| Target Size | JS Files | Endpoints | Time | |-------------|----------|-----------|------| | Small site | 5-10 | 20-50 | 15-30s | | Medium site | 20-50 | 100-300 | 45-90s | | Large site | 100+ | 500+ | 2-5min |
Resource Usage
- Memory: 100-300 MB typical, 500 MB for large files
- CPU: Multi-core, benefits from concurrency
- Network: Connection pooling limits simultaneous requests
- Disk: Minimal (no caching to disk)
Optimization
- Use
--fastfor API discovery only - Increase
--concurrencyfor faster processing - Use
--no-apito skip documentation probing - Local file scanning is fastest (no network)
Troubleshooting
Installation Issues
If tree-sitter fails to compile:
nvm install 22
nvm use 22
rm -rf node_modules package-lock.json
./install.shmacOS Xcode issues:
sudo rm -rf /Library/Developer/CommandLineTools
xcode-select --installWindows compilation:
# Install Visual Studio Build Tools 2022
# Or use WSL2: wsl --installRuntime Issues
No endpoints found:
- Verify the target has JavaScript files
- Try
--browserfor dynamic content - Check
--debugoutput for parsing errors
Low endpoint count:
- Ensure tree-sitter compiled correctly (
npm run scan -- -fs test.js -d) - Check if files are heavily obfuscated
- Verify constant propagation is working
High false positive rate:
- Use JSON output to inspect confidence scores
- Filter endpoints by confidence threshold
- Report issues with sample files
Responsible Use
This tool is intended for:
- Authorized penetration testing
- Bug bounty programs (within scope)
- Security research on your own applications
- Educational purposes
Do not use for unauthorized scanning or attacking systems without permission.
Contributing
Contributions are welcome. Please:
- Fork the repository
- Create a feature branch
- Add tests for new features
- Ensure all tests pass (
npm test) - Submit a pull request
See CONTRIBUTING.md for detailed guidelines.
License
MIT License - See LICENSE for details.
Author
Acknowledgments
- Inspired by jsluice by BishopFox
- Uses tree-sitter for JavaScript parsing
- Built with Acorn for fallback parsing
- Stealth automation via puppeteer-extra
Star History
If you find this tool useful, please star the repository on GitHub.
