Back to the catalog

Android Security Analyzer

MCP server for static security analysis of Android source code

Open source Repository Open in the app JSON README (API)

About

MCP server for static security analysis of Android source code

Details

Kind
MCP servers
Topic
No topic detected
Publisher
ako2345
Origin
official
Category
ferramentas
Transport
http
Version
1.0.0
Stars
2
Last push
2026-03-14T22:06:00Z
Repository state
ativo
Language
TypeScript
Added
2026-08-29 03:02:24
Updated
2026-08-29 03:02:24
Origin id
io.github.ako2345/android-security-analyzer

README

# Android Security Analyzer

MCP server for static security analysis of Android application source code. Runs on Cloudflare Workers as a remote MCP server over Streamable HTTP.

## What it does

Analyzes Android project source files — **without building the project** — and returns a structured security report. The analysis covers:

- **Manifest analysis** — exported components, dangerous permissions, cleartext traffic, debug flags, backup settings, SDK versions
- **Gradle/build config** — release build misconfigurations, outdated SDKs, suspicious dependencies, hardcoded secrets
- **Source code (Java/Kotlin)** — insecure WebView, SSL/TLS bypass, weak crypto, SQL injection patterns, process execution, insecure file storage, PendingIntent issues
- **XML configuration** — network security config weaknesses, overly broad file provider paths
- **Secret scanning** — API keys, tokens, passwords, private keys, cloud credentials, high-entropy strings

All analysis is regex/pattern-based and runs natively in the Workers runtime with no external tools, Java, or Android SDK required.

## Architecture

```
POST /mcp ──► McpServer (JSON-RPC 2.0) ──► Tool Router
                                              │
              ┌───────────────────────────────┘
              ▼
         Orchestrator
              │
    ┌─────────┼─────────┬─────────────┬──────────────┐
    ▼         ▼         ▼             ▼              ▼
 Manifest  Gradle   Source Code   XML Config    Secret
 Analyzer  Analyzer  Analyzer     Analyzer     Scanner
    │         │         │             │              │
    └─────────┴─────────┴─────────────┴──────────────┘
              │
              ▼
     Scoring + Deduplication ──► AnalysisReport
```

**Key design decisions:**
- Stateless — no sessions, no Durable Objects
- Minimal MCP JSON-RPC 2.0 implementation (no heavy SDK dependencies)
- Data-driven rule engine with extensible rule registry
- Independent analyzers with unified Finding type
- Lightweight XML parsing via `fast-xml-parser`
- Input validation via `zod`
- Bundle size: ~66KB gzipped

## MCP Tools

| Tool | Description |
|------|-------------|
| `analyze_android_project` | Full security analysis of project files |
| `list_android_security_checks` | List all implemented security rules |
| `explain_finding` | Detailed explanation of a specific rule |
| `health` | Server status and rule engine stats |

## Install

**Hosted server (recommended for Cline / MCP clients):** no local install needed. The server runs at:

`https://android-security-analyzer.ako-labs.workers.dev/mcp`

Add this URL to your MCP client configuration (see [Connecting from an MCP client](#connecting-from-an-mcp-client) below).

**Local development:**

```bash
npm install
```

## Development

```bash
npm run dev
```

This starts a local Wrangler dev server. The MCP endpoint is available at `http://localhost:8787/mcp`.

## Deploy

```bash
npm run deploy
```

Deploys to Cloudflare Workers. Requires `wrangler` authentication (`npx wrangler login`).

## Testing

```bash
npm test              # Run all tests
npm run test:watch    # Watch mode
npm run typecheck     # TypeScript type checking
```

## Local MCP Testing

### Initialize the connection

Unix:
```bash
curl -X POST http://localhost:8787/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'
```

Windows (PowerShell):
```powershell
(Invoke-WebRequest -Method Post -Uri "http://localhost:8787/mcp" -ContentType "application/json" -Body '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' -UseBasicParsing).Content
```

### List available tools

Unix:
```bash
curl -X POST http://localhost:8787/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
```

Windows (PowerShell): ответ приходит в `result.tools`; чтобы увидеть список как JSON, используйте сырой ответ:
```powershell
(Invoke-WebRequest -Method Post -Uri "http://localhost:8787/mcp" -ContentType "application/json" -Body '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' -UseBasicParsing).Content
```
Либо через объект: `(Invoke-RestMethod ...).result.tools | ConvertTo-Json -Depth 5`

### Check health

Unix:
```bash
curl -X POST http://localhost:8787/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"health","arguments":{}}}'
```

Windows (PowerShell):
```powershell
(Invoke-WebRequest -Method Post -Uri "http://localhost:8787/mcp" -ContentType "application/json" -Body '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"health","arguments":{}}}' -UseBasicParsing).Content
```

### Run analysis (minimal example)

Unix:
```bash
curl -X POST http://localhost:8787/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 4,
    "method": "tools/call",
    "params": {
      "name": "analyze_android_project",
      "arguments": {
        "projectName": "TestApp",
        "files": [
          {
            "path": "app/src/main/AndroidManifest.xml",
            "content": "<manifest><application android:debuggable=\"true\" android:allowBackup=\"true\"></application></manifest>"
          }
        ]
      }
    }
  }'
```

Windows (PowerShell):
```powershell
$body = @{
  jsonrpc = "2.0"
  id = 4
  method = "tools/call"
  params = @{
    name = "analyze_android_project"
    arguments = @{
      projectName = "TestApp"
      files = @(
        @{
          path = "app/src/main/AndroidManifest.xml"
          content = "<manifest><application android:debuggable=`"true`" android:allowBackup=`"true`"></application></manifest>"
        }
      )
    }
  }
} | ConvertTo-Json -Depth 10
(Invoke-WebRequest -Method Post -Uri "http://localhost:8787/mcp" -ContentType "application/json" -Body $body -UseBasicParsing).Content
```

### Connecting from an MCP client

Add to your MCP client configuration:

```json
{
  "mcpServers": {
    "android-security-analyzer": {
      "url": "http://localhost:8787/mcp"
    }
  }
}
```

For production (hosted):

```json
{
  "mcpServers": {
    "android-security-analyzer": {
      "url": "https://android-security-analyzer.ako-labs.workers.dev/mcp"
    }
  }
}
```

## Security Rules

The analyzer implements 53 security rules across 5 categories:

| Category | Prefix | Rules | Examples |
|----------|--------|-------|----------|
| Manifest | MAN-* | 17 | debuggable, allowBackup, exported components, permissions |
| Gradle | GRD-* | 9 | release config, SDK versions, dependencies, secrets |
| Source | SRC-* | 17 | WebView, SSL/TLS, crypto, injection, file storage |
| XML Config | XML-* | 4 | network security config, file provider paths |
| Secret | SEC-* | 7 | API keys, tokens, passwords, cloud credentials |

Each finding includes:
- Stable rule ID
- Severity (critical/high/medium/low/info) and confidence (high/medium/low)
- File path and line number (when determinable)
- Evidence snippet
- CWE and OWASP Mobile Top 10 mappings
- Actionable recommendation

## Scoring

Risk score (0-100) is computed from finding severities:
- Critical: 9 points
- High: 6 points
- Medium: 3 points
- Low: 1 point
- Info: 0 points

The raw sum is normalized against an expected maximum of 50 points.

## Limitations

- **Not a SAST replacement** — pattern/regex-based heuristics, not full AST/dataflow analysis
- **No build required** — analyzes raw source, so build-time transforms are not visible
- **False positives possible** — especially for secret scanning and some code patterns
- **Workers constraints** — 128MB memory limit, CPU time limits, no filesystem access
- **No APK/AAB analysis** — source code only
- **No inter-procedural analysis** — patterns are matched per-file, not across call graphs

## Project Structure

```
src/
├── index.ts                          # Worker entry point
├── server/
│   ├── mcp.ts                        # MCP JSON-RPC 2.0 handler
│   └── tools/                        # MCP tool implementations
│       ├── analyzeAndroidProject.ts
│       ├── listAndroidSecurityChecks.ts
│       ├── explainFinding.ts
│       └── health.ts
├── core/
│   ├── types.ts                      # TypeScript types & Zod schemas
│   ├── scoring.ts                    # Risk score computation
│   ├── registry.ts                   # Rule registry
│   └── orchestrator.ts              # Analysis orchestrator
├── analyzers/
│   ├── manifestAnalyzer.ts
│   ├── gradleAnalyzer.ts
│   ├── sourceAnalyzer.ts
│   ├── xmlConfigAnalyzer.ts
│   └── secretScanner.ts
├── parsers/
│   ├── xml.ts                        # XML parser wrapper
│   ├── gradle.ts                     # Gradle file parser
│   ├── source.ts                     # Source code pattern matcher
│   └── files.ts                      # File classifier
├── rules/
│   ├── manifestRules.ts
│   ├── gradleRules.ts
│   ├── sourceRules.ts
│   ├── xmlRules.ts
│   └── secretRules.ts
├── mappings/
│   ├── cwe.ts                        # CWE descriptions
│   └── owaspMobile.ts               # OWASP Mobile Top 10
└── utils/
    ├── lines.ts                      # Line number utilities
    ├── paths.ts                      # Path classification
    └── text.ts                       # Text utilities
test/
├── fixtures/                         # Sample Android project files
├── unit/                             # Unit tests per module
└── integration/                      # Full analysis integration tests
```

## Adding New Rules

1. Define the rule in the appropriate file under `src/rules/`
2. Add detection logic in the corresponding analyzer under `src/analyzers/`
3. Add CWE mapping in `src/mappings/cwe.ts` if needed
4. Add a test case
5. The rule is automatically registered via `src/core/registry.ts`

## License

MIT

More