mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-16 07:53:18 +03:00
Initial commit - 611 cybersecurity skills across all subdomains
This commit is contained in:
@@ -0,0 +1,184 @@
|
||||
---
|
||||
name: testing-mobile-api-authentication
|
||||
description: >
|
||||
Tests authentication and authorization mechanisms in mobile application APIs to identify
|
||||
broken authentication, insecure token management, session fixation, privilege escalation,
|
||||
and IDOR vulnerabilities. Use when performing API security assessments against mobile app
|
||||
backends, testing JWT implementations, evaluating OAuth flows, or assessing session management.
|
||||
Activates for requests involving mobile API auth testing, token security assessment, OAuth
|
||||
mobile flow testing, or API authorization bypass.
|
||||
domain: cybersecurity
|
||||
subdomain: mobile-security
|
||||
author: mahipal
|
||||
tags: [mobile-security, android, ios, api-security, authentication, penetration-testing]
|
||||
version: 1.0.0
|
||||
license: MIT
|
||||
---
|
||||
# Testing Mobile API Authentication
|
||||
|
||||
## When to Use
|
||||
|
||||
Use this skill when:
|
||||
- Assessing mobile app backend API authentication during penetration tests
|
||||
- Testing JWT token implementation for common vulnerabilities (none algorithm, weak signing)
|
||||
- Evaluating OAuth 2.0 / OIDC flows in mobile applications for redirect, PKCE, and scope issues
|
||||
- Testing for broken object-level authorization (BOLA/IDOR) in API endpoints
|
||||
|
||||
**Do not use** this skill against production APIs without explicit authorization and rate-limiting awareness.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Burp Suite or mitmproxy configured as mobile device proxy
|
||||
- SSL pinning bypassed on target application (if implemented)
|
||||
- Valid test account credentials for the target application
|
||||
- Postman or curl for API request crafting
|
||||
- jwt.io or PyJWT for JWT analysis and manipulation
|
||||
|
||||
## Workflow
|
||||
|
||||
### Step 1: Map Authentication Endpoints
|
||||
|
||||
Intercept mobile app traffic to identify authentication-related endpoints:
|
||||
|
||||
```
|
||||
POST /api/v1/auth/login - Initial authentication
|
||||
POST /api/v1/auth/register - Account registration
|
||||
POST /api/v1/auth/refresh - Token refresh
|
||||
POST /api/v1/auth/logout - Session termination
|
||||
POST /api/v1/auth/forgot-password - Password reset
|
||||
POST /api/v1/auth/verify-otp - OTP verification
|
||||
GET /api/v1/auth/me - Authenticated user profile
|
||||
```
|
||||
|
||||
### Step 2: Analyze Token Format and Security
|
||||
|
||||
**JWT Analysis:**
|
||||
```bash
|
||||
# Decode JWT without verification
|
||||
echo "eyJhbGciOiJIUzI1NiIs..." | cut -d. -f2 | base64 -d 2>/dev/null
|
||||
|
||||
# Check for common JWT vulnerabilities:
|
||||
# 1. None algorithm attack
|
||||
# Change header to: {"alg":"none","typ":"JWT"}
|
||||
# Remove signature: header.payload.
|
||||
|
||||
# 2. Algorithm confusion (RS256 to HS256)
|
||||
# If server uses RS256, try HS256 with public key as secret
|
||||
|
||||
# 3. Weak signing key
|
||||
# Use hashcat or jwt-cracker to brute-force HMAC secret
|
||||
hashcat -m 16500 jwt.txt wordlist.txt
|
||||
|
||||
# 4. Expiration bypass
|
||||
# Modify "exp" claim to future timestamp
|
||||
```
|
||||
|
||||
**Opaque Token Analysis:**
|
||||
```
|
||||
- Test token length and entropy
|
||||
- Check if tokens are sequential/predictable
|
||||
- Test token reuse after logout
|
||||
- Verify token invalidation on password change
|
||||
```
|
||||
|
||||
### Step 3: Test Authentication Bypass
|
||||
|
||||
```bash
|
||||
# Test missing authentication
|
||||
curl -X GET https://api.target.com/api/v1/users/profile
|
||||
|
||||
# Test with empty/null token
|
||||
curl -X GET https://api.target.com/api/v1/users/profile \
|
||||
-H "Authorization: Bearer "
|
||||
|
||||
curl -X GET https://api.target.com/api/v1/users/profile \
|
||||
-H "Authorization: Bearer null"
|
||||
|
||||
# Test with expired token (should fail)
|
||||
curl -X GET https://api.target.com/api/v1/users/profile \
|
||||
-H "Authorization: Bearer <expired_token>"
|
||||
|
||||
# Test token from different user
|
||||
curl -X GET https://api.target.com/api/v1/users/123/profile \
|
||||
-H "Authorization: Bearer <user_456_token>"
|
||||
```
|
||||
|
||||
### Step 4: Test IDOR / Broken Object-Level Authorization
|
||||
|
||||
```bash
|
||||
# Change user ID in request path
|
||||
curl -X GET https://api.target.com/api/v1/users/123/orders \
|
||||
-H "Authorization: Bearer <user_456_token>"
|
||||
|
||||
# Change object ID in request body
|
||||
curl -X PUT https://api.target.com/api/v1/orders/789 \
|
||||
-H "Authorization: Bearer <user_456_token>" \
|
||||
-d '{"status": "cancelled"}'
|
||||
|
||||
# Test horizontal privilege escalation
|
||||
# Access admin endpoints with regular user token
|
||||
curl -X GET https://api.target.com/api/v1/admin/users \
|
||||
-H "Authorization: Bearer <regular_user_token>"
|
||||
```
|
||||
|
||||
### Step 5: Test Session Management
|
||||
|
||||
```bash
|
||||
# Test concurrent sessions
|
||||
# Login from multiple devices simultaneously - should both remain valid?
|
||||
|
||||
# Test session invalidation after logout
|
||||
TOKEN=$(curl -s -X POST https://api.target.com/api/v1/auth/login \
|
||||
-d '{"email":"test@test.com","password":"pass"}' | jq -r '.token')
|
||||
|
||||
# Logout
|
||||
curl -X POST https://api.target.com/api/v1/auth/logout \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
|
||||
# Try using the same token (should fail)
|
||||
curl -X GET https://api.target.com/api/v1/users/me \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
|
||||
# Test session invalidation after password change
|
||||
# Token obtained before password change should be invalidated
|
||||
```
|
||||
|
||||
### Step 6: Test OAuth 2.0 / OIDC Mobile Flows
|
||||
|
||||
```bash
|
||||
# Test for authorization code interception
|
||||
# Check if PKCE (Proof Key for Code Exchange) is enforced
|
||||
# Test with missing code_verifier parameter
|
||||
|
||||
# Test redirect URI manipulation
|
||||
# Try custom scheme hijacking: myapp://callback
|
||||
# Test with modified redirect_uri parameter
|
||||
|
||||
# Test scope escalation
|
||||
# Request higher privileges than granted
|
||||
```
|
||||
|
||||
## Key Concepts
|
||||
|
||||
| Term | Definition |
|
||||
|------|-----------|
|
||||
| **BOLA/IDOR** | Broken Object Level Authorization - accessing resources by changing identifiers without server-side authorization checks |
|
||||
| **JWT** | JSON Web Token - self-contained authentication token with header, payload, and signature components |
|
||||
| **PKCE** | Proof Key for Code Exchange - OAuth 2.0 extension preventing authorization code interception in mobile apps |
|
||||
| **Token Refresh** | Mechanism for obtaining new access tokens using long-lived refresh tokens without re-authentication |
|
||||
| **Session Fixation** | Attack where adversary sets a known session ID before victim authenticates, then hijacks the session |
|
||||
|
||||
## Tools & Systems
|
||||
|
||||
- **Burp Suite**: HTTP proxy for intercepting and modifying authentication requests
|
||||
- **jwt_tool**: Python tool for testing JWT vulnerabilities (none algorithm, key confusion, claim manipulation)
|
||||
- **Postman**: API testing client for crafting authentication requests
|
||||
- **hashcat**: Password/JWT secret cracking tool for testing HMAC signing key strength
|
||||
- **Autorize**: Burp Suite extension for automated authorization testing
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
- **Rate limiting masks issues**: API may rate-limit test requests. Use delays between requests and test from the tester's authorized perspective first.
|
||||
- **Token in URL**: Some mobile APIs pass tokens in URL query parameters, exposing them in server logs and browser history. Flag as finding even if authorization works correctly.
|
||||
- **Refresh token rotation**: Some APIs rotate refresh tokens on each use. If your test invalidates the refresh token, you may lock out your test account.
|
||||
- **Mobile-specific OAuth**: Mobile apps use custom URI schemes for OAuth redirects, which can be intercepted by malicious apps registered for the same scheme.
|
||||
@@ -0,0 +1,32 @@
|
||||
# Mobile API Authentication Test Report
|
||||
|
||||
## Target
|
||||
| Field | Value |
|
||||
|-------|-------|
|
||||
| API Base URL | [URL] |
|
||||
| Application | [APP_NAME] |
|
||||
| Token Type | [JWT/OAuth/Opaque] |
|
||||
| Test Date | [DATE] |
|
||||
|
||||
## JWT/Token Analysis
|
||||
| Check | Result | Severity |
|
||||
|-------|--------|----------|
|
||||
| Algorithm | [ALG] | [SEVERITY] |
|
||||
| Expiration | [DURATION] | [SEVERITY] |
|
||||
| Sensitive Claims | [YES/NO] | [SEVERITY] |
|
||||
| Signing Key Strength | [WEAK/STRONG] | [SEVERITY] |
|
||||
|
||||
## Authentication Tests
|
||||
| Test | Endpoint | Result | Severity |
|
||||
|------|----------|--------|----------|
|
||||
| Missing Auth | [ENDPOINT] | [PASS/FAIL] | [SEVERITY] |
|
||||
| Expired Token | [ENDPOINT] | [PASS/FAIL] | [SEVERITY] |
|
||||
| Empty Token | [ENDPOINT] | [PASS/FAIL] | [SEVERITY] |
|
||||
|
||||
## Authorization Tests (IDOR)
|
||||
| Endpoint | Own ID | Other ID | Accessible | Severity |
|
||||
|----------|--------|----------|-----------|----------|
|
||||
| [ENDPOINT] | [ID] | [ID] | [YES/NO] | [SEVERITY] |
|
||||
|
||||
## Recommendations
|
||||
1. [RECOMMENDATION]
|
||||
@@ -0,0 +1,35 @@
|
||||
# Standards Reference: Mobile API Authentication Testing
|
||||
|
||||
## OWASP Mobile Top 10 2024
|
||||
|
||||
| OWASP ID | Risk | Testing Focus |
|
||||
|----------|------|---------------|
|
||||
| M1 | Improper Credential Usage | Hardcoded API keys, credential transmission |
|
||||
| M3 | Insecure Authentication/Authorization | Auth bypass, IDOR, privilege escalation |
|
||||
|
||||
## OWASP API Security Top 10 2023
|
||||
|
||||
| API Risk | Test Case |
|
||||
|----------|-----------|
|
||||
| API1: Broken Object Level Authorization | Modify object IDs, test cross-user access |
|
||||
| API2: Broken Authentication | JWT vulnerabilities, token replay, session management |
|
||||
| API3: Broken Object Property Level Auth | Mass assignment, property-level access |
|
||||
| API5: Broken Function Level Authorization | Admin endpoint access with user tokens |
|
||||
|
||||
## OWASP MASVS v2.0 - MASVS-AUTH
|
||||
|
||||
| Control | Test Method |
|
||||
|---------|-------------|
|
||||
| MASVS-AUTH-1 | Verify authentication enforcement on all sensitive endpoints |
|
||||
| MASVS-AUTH-2 | Test token generation, validation, and revocation |
|
||||
| MASVS-AUTH-3 | Assess multi-factor authentication implementation |
|
||||
|
||||
## CWE Mappings
|
||||
|
||||
| CWE | Title | Test |
|
||||
|-----|-------|------|
|
||||
| CWE-287 | Improper Authentication | Missing auth on endpoints |
|
||||
| CWE-639 | Authorization Bypass Through User-Controlled Key | IDOR testing |
|
||||
| CWE-798 | Hardcoded Credentials | API key in APK/IPA |
|
||||
| CWE-613 | Insufficient Session Expiration | Token lifetime testing |
|
||||
| CWE-384 | Session Fixation | Pre-auth token reuse |
|
||||
@@ -0,0 +1,28 @@
|
||||
# Workflows: Mobile API Authentication Testing
|
||||
|
||||
## Workflow 1: Authentication Assessment
|
||||
|
||||
```
|
||||
[Intercept traffic] --> [Map auth endpoints] --> [Analyze token format]
|
||||
|
|
||||
+-------------+-------------+
|
||||
| | |
|
||||
[JWT analysis] [OAuth flow] [Session mgmt]
|
||||
[None alg] [PKCE check] [Expiration]
|
||||
[Key brute] [Redirect URI] [Logout invalidation]
|
||||
| | |
|
||||
+-------------+-------------+
|
||||
|
|
||||
[IDOR testing]
|
||||
[Privilege escalation]
|
||||
[Report findings]
|
||||
```
|
||||
|
||||
## Decision Matrix: Token Vulnerability Testing
|
||||
|
||||
| Token Type | Primary Tests | Tools |
|
||||
|-----------|--------------|-------|
|
||||
| JWT (HS256) | Key brute force, none algorithm, claim manipulation | jwt_tool, hashcat |
|
||||
| JWT (RS256) | Algorithm confusion, public key retrieval, key ID manipulation | jwt_tool |
|
||||
| Opaque | Entropy analysis, predictability, server-side invalidation | Burp Sequencer |
|
||||
| OAuth Bearer | Scope escalation, redirect URI manipulation, PKCE enforcement | Burp, Postman |
|
||||
@@ -0,0 +1,242 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Mobile API Authentication Tester
|
||||
|
||||
Tests common authentication vulnerabilities in mobile API endpoints including
|
||||
JWT analysis, IDOR detection, and session management assessment.
|
||||
|
||||
Usage:
|
||||
python process.py --base-url https://api.target.com --token <JWT> [--output report.json]
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import base64
|
||||
import json
|
||||
import sys
|
||||
import time
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
try:
|
||||
import requests
|
||||
requests.packages.urllib3.disable_warnings()
|
||||
except ImportError:
|
||||
print("ERROR: 'requests' required. Install: pip install requests")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
class MobileAPIAuthTester:
|
||||
"""Tests mobile API authentication and authorization."""
|
||||
|
||||
def __init__(self, base_url: str, token: str):
|
||||
self.base_url = base_url.rstrip("/")
|
||||
self.token = token
|
||||
self.findings = []
|
||||
self.session = requests.Session()
|
||||
self.session.verify = False
|
||||
self.session.headers.update({
|
||||
"Authorization": f"Bearer {token}",
|
||||
"User-Agent": "MobileSecurityTester/1.0",
|
||||
})
|
||||
|
||||
def analyze_jwt(self) -> dict:
|
||||
"""Analyze JWT token structure and identify vulnerabilities."""
|
||||
parts = self.token.split(".")
|
||||
if len(parts) != 3:
|
||||
return {"is_jwt": False, "format": "opaque_or_invalid"}
|
||||
|
||||
try:
|
||||
# Decode header
|
||||
header_padded = parts[0] + "=" * (4 - len(parts[0]) % 4)
|
||||
header = json.loads(base64.urlsafe_b64decode(header_padded))
|
||||
|
||||
# Decode payload
|
||||
payload_padded = parts[1] + "=" * (4 - len(parts[1]) % 4)
|
||||
payload = json.loads(base64.urlsafe_b64decode(payload_padded))
|
||||
|
||||
issues = []
|
||||
|
||||
# Check algorithm
|
||||
alg = header.get("alg", "unknown")
|
||||
if alg.lower() == "none":
|
||||
issues.append({"issue": "none_algorithm", "severity": "CRITICAL"})
|
||||
elif alg.lower() in ("hs256", "hs384", "hs512"):
|
||||
issues.append({"issue": "hmac_algorithm_key_brute_forceable", "severity": "MEDIUM"})
|
||||
|
||||
# Check expiration
|
||||
exp = payload.get("exp")
|
||||
if not exp:
|
||||
issues.append({"issue": "no_expiration_claim", "severity": "HIGH"})
|
||||
elif exp < time.time():
|
||||
issues.append({"issue": "token_already_expired", "severity": "INFO"})
|
||||
elif exp - time.time() > 86400 * 7:
|
||||
issues.append({"issue": "excessive_token_lifetime", "severity": "MEDIUM",
|
||||
"details": f"Expires in {(exp - time.time()) / 86400:.0f} days"})
|
||||
|
||||
# Check for sensitive data in payload
|
||||
sensitive_keys = ["password", "secret", "ssn", "credit_card"]
|
||||
for key in payload:
|
||||
if any(s in key.lower() for s in sensitive_keys):
|
||||
issues.append({"issue": f"sensitive_data_in_jwt: {key}", "severity": "HIGH"})
|
||||
|
||||
# Check missing claims
|
||||
if "iss" not in payload:
|
||||
issues.append({"issue": "missing_issuer_claim", "severity": "LOW"})
|
||||
if "iat" not in payload:
|
||||
issues.append({"issue": "missing_issued_at_claim", "severity": "LOW"})
|
||||
|
||||
finding = {
|
||||
"check": "jwt_analysis",
|
||||
"is_jwt": True,
|
||||
"algorithm": alg,
|
||||
"claims": list(payload.keys()),
|
||||
"issues": issues,
|
||||
"severity": "HIGH" if any(i["severity"] in ("CRITICAL", "HIGH") for i in issues) else "MEDIUM",
|
||||
}
|
||||
self.findings.append(finding)
|
||||
return finding
|
||||
|
||||
except Exception as e:
|
||||
return {"is_jwt": True, "error": str(e)}
|
||||
|
||||
def test_missing_auth(self, endpoints: list) -> list:
|
||||
"""Test endpoints without authentication."""
|
||||
results = []
|
||||
for endpoint in endpoints:
|
||||
url = f"{self.base_url}{endpoint}"
|
||||
try:
|
||||
resp = requests.get(url, verify=False, timeout=10,
|
||||
headers={"User-Agent": "MobileSecurityTester/1.0"})
|
||||
if resp.status_code != 401 and resp.status_code != 403:
|
||||
result = {
|
||||
"endpoint": endpoint,
|
||||
"status": resp.status_code,
|
||||
"issue": "accessible_without_auth",
|
||||
"severity": "CRITICAL",
|
||||
}
|
||||
results.append(result)
|
||||
except requests.RequestException:
|
||||
pass
|
||||
time.sleep(0.5) # Rate limiting
|
||||
|
||||
if results:
|
||||
self.findings.append({
|
||||
"check": "missing_authentication",
|
||||
"owasp_api": "API2",
|
||||
"endpoints_tested": len(endpoints),
|
||||
"unprotected": len(results),
|
||||
"details": results,
|
||||
"severity": "CRITICAL",
|
||||
})
|
||||
return results
|
||||
|
||||
def test_expired_token(self) -> dict:
|
||||
"""Test if expired tokens are accepted."""
|
||||
# Create a JWT with expired timestamp (modifying payload)
|
||||
parts = self.token.split(".")
|
||||
if len(parts) != 3:
|
||||
return {"check": "expired_token", "skipped": True}
|
||||
|
||||
try:
|
||||
payload_padded = parts[1] + "=" * (4 - len(parts[1]) % 4)
|
||||
payload = json.loads(base64.urlsafe_b64decode(payload_padded))
|
||||
|
||||
if "exp" in payload and payload["exp"] < time.time():
|
||||
# Token is already expired, test if it still works
|
||||
resp = self.session.get(f"{self.base_url}/api/v1/users/me", timeout=10)
|
||||
accepted = resp.status_code == 200
|
||||
|
||||
finding = {
|
||||
"check": "expired_token_acceptance",
|
||||
"token_expired": True,
|
||||
"still_accepted": accepted,
|
||||
"severity": "CRITICAL" if accepted else "PASS",
|
||||
}
|
||||
self.findings.append(finding)
|
||||
return finding
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return {"check": "expired_token", "skipped": True, "reason": "token_not_expired"}
|
||||
|
||||
def test_idor(self, endpoint_template: str, valid_id: str, other_ids: list) -> list:
|
||||
"""Test for IDOR by substituting object IDs."""
|
||||
results = []
|
||||
for other_id in other_ids:
|
||||
url = f"{self.base_url}{endpoint_template.replace('{id}', other_id)}"
|
||||
try:
|
||||
resp = self.session.get(url, timeout=10)
|
||||
if resp.status_code == 200:
|
||||
results.append({
|
||||
"endpoint": url,
|
||||
"original_id": valid_id,
|
||||
"tested_id": other_id,
|
||||
"accessible": True,
|
||||
"severity": "CRITICAL",
|
||||
})
|
||||
except requests.RequestException:
|
||||
pass
|
||||
time.sleep(0.5)
|
||||
|
||||
if results:
|
||||
self.findings.append({
|
||||
"check": "idor",
|
||||
"owasp_api": "API1",
|
||||
"vulnerable_endpoints": len(results),
|
||||
"details": results,
|
||||
"severity": "CRITICAL",
|
||||
})
|
||||
return results
|
||||
|
||||
def generate_report(self) -> dict:
|
||||
"""Generate authentication test report."""
|
||||
severity_counts = {}
|
||||
for f in self.findings:
|
||||
sev = f.get("severity", "INFO")
|
||||
severity_counts[sev] = severity_counts.get(sev, 0) + 1
|
||||
|
||||
return {
|
||||
"assessment": {
|
||||
"target": self.base_url,
|
||||
"type": "Mobile API Authentication Testing",
|
||||
"date": datetime.now().isoformat(),
|
||||
},
|
||||
"summary": {
|
||||
"total_checks": len(self.findings),
|
||||
"severity_breakdown": severity_counts,
|
||||
},
|
||||
"findings": self.findings,
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Mobile API Authentication Tester")
|
||||
parser.add_argument("--base-url", required=True, help="API base URL")
|
||||
parser.add_argument("--token", required=True, help="Bearer token (JWT or opaque)")
|
||||
parser.add_argument("--output", default="auth_test.json", help="Output report")
|
||||
parser.add_argument("--endpoints", nargs="*", default=[
|
||||
"/api/v1/users/me", "/api/v1/users", "/api/v1/admin",
|
||||
], help="Endpoints to test")
|
||||
args = parser.parse_args()
|
||||
|
||||
tester = MobileAPIAuthTester(args.base_url, args.token)
|
||||
|
||||
print("[*] Analyzing token...")
|
||||
tester.analyze_jwt()
|
||||
|
||||
print("[*] Testing missing authentication...")
|
||||
tester.test_missing_auth(args.endpoints)
|
||||
|
||||
print("[*] Testing expired token acceptance...")
|
||||
tester.test_expired_token()
|
||||
|
||||
report = tester.generate_report()
|
||||
with open(args.output, "w") as f:
|
||||
json.dump(report, f, indent=2)
|
||||
|
||||
print(f"[+] Report saved: {args.output}")
|
||||
print(f"[*] Findings: {report['summary']['severity_breakdown']}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user