Payment security engine for Stripe and Razorpay workflows
Project description
Shrike — Payment Security Scanner
593 rules. Stripe, Razorpay, PayPal. One command.
Find idempotency bugs, webhook signature bypasses, float currency errors, leaked keys, and hundreds of other payment-specific vulnerabilities before they cost you money.
Why Shrike?
Generic SAST tools know nothing about payment APIs. They miss the bugs that actually cost money:
| What they miss | What Shrike catches |
|---|---|
amount: 19.99 passed as float |
CUR001 — Float currency causes rounding chargebacks |
| No idempotency key on PaymentIntent.create | IDP001 — Duplicate charges on network retry |
constructEvent() without raw body |
WHK003 — Webhook signature always fails |
sk_live_ in client-side bundle |
SEC001 — Secret key exposed to browsers |
| Redirect-only checkout with no webhook | CHK002 — Fulfillment never fires on bank delays |
Shrike has 593 rules across 39 categories covering Stripe, Razorpay, PayPal, PCI-DSS compliance, and cross-provider architecture patterns. Each finding includes a risk score, financial exposure estimate, and a concrete fix.
Install
pip install shrike-scanner
Requires Python 3.10+. No external services needed — all scanning is local.
Quick Start
# Activate your license
shrike activate <YOUR_LICENSE_KEY>
# Scan a project
shrike audit .
# Scan with financial exposure estimates
shrike audit . --mrr 50000
# Output SARIF for GitHub Security tab
shrike audit . --format sarif --output results.sarif
# Scan a public GitHub repo directly
shrike github https://github.com/stripe-samples/accept-a-payment
Example Output
╔═╗╦ ╦╦═╗╦╦╔═╔═╗ vMAX
╚═╗╠═╣╠╦╝║╠╩╗║╣ 593 Rules · Payment Security Scanner
╚═╝╩ ╩╩╚═╩╩ ╩╚═╝ shrike.pro/cli
Scanning: ./src Rules: 593
[✗] SEC001 · CRITICAL [CERTAIN] Stripe Secret Key Exposed
Location: src/api/stripe.ts:14
Category: Secrets CWE-798
Snippet: const stripe = new Stripe("sk_live_51H...")
Risk: Live secret key in source — full account access if leaked
Exposure: UNLIMITED — account compromise possible
Fix: Move to environment variable: process.env.STRIPE_SECRET_KEY
[!] IDP001 · HIGH [LIKELY] Missing Idempotency Key
Location: src/api/checkout.ts:47
Category: Idempotency CWE-834
Snippet: await stripe.paymentIntents.create({ amount, currency })
Risk: Network retries can create duplicate charges
Exposure: $500–$10,000 / month
Fix: Add idempotencyKey: `pi_${orderId}` to the create() call
╭──────────────────────────────────╮
│ AUDIT SUMMARY │
├────────────────────────┬─────────┤
│ Target │ ./src │
│ Files Scanned │ 47 │
│ Duration │ 340ms │
│ ──────────────────────── ──────── │
│ CRITICAL │ 1 │
│ HIGH │ 3 │
│ MEDIUM │ 5 │
│ LOW │ 2 │
│ ──────────────────────── ──────── │
│ TOTAL │ 11 │
│ Risk Score │ 58/100 │
│ Est. Monthly Exposure │ ~$4,200 │
╰────────────────────────┴─────────╯
GitHub Action
Add Shrike to your CI pipeline — findings appear in the GitHub Security tab via SARIF.
# .github/workflows/shrike.yml
name: Payment Security
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: NANIEXISTS/shrike@v1
with:
shrike_token: ${{ secrets.SHRIKE_TOKEN }}
fail_on: HIGH # block merges on HIGH+ findings
engine: 5 # max depth (1=fast, 5=thorough)
Action Inputs
| Input | Default | Description |
|---|---|---|
shrike_token |
(required) | License key — set as repository secret |
target |
. |
Directory or file to scan |
fail_on |
HIGH |
Minimum severity to fail the build (CRITICAL, HIGH, MEDIUM, LOW, NONE) |
engine |
5 |
Scan depth (1 = fast regex, 5 = full taint analysis) |
upload_sarif |
true |
Upload results to GitHub Security tab |
mrr |
— | Monthly revenue (USD) for exposure estimates |
Action Outputs
| Output | Description |
|---|---|
sarif_path |
Path to generated SARIF file |
findings_json |
Path to full JSON findings |
risk_score |
Numeric risk score (0–100) |
CLI Reference
shrike audit <TARGET> Scan a codebase for payment vulnerabilities
shrike github <URL> Clone + scan a public GitHub repo
shrike analyze <FILE> Forensic analysis of a webhook payload
shrike watch <LOG> Live-monitor webhook logs
shrike rules List all detection rules
shrike activate <KEY> Activate license
shrike license status Check license status
shrike license deactivate Free a device seat
shrike config set <K> <V> Set AI/config options
shrike config show Show current configuration
Key Flags
--format terminal | json | html | pdf | sarif | all
--output Output file stem (or "-" to pipe JSON/SARIF to stdout)
--mrr Monthly revenue for exposure calculation
--fail-on Exit code 1 if findings at this severity or above
--engine Scan depth: 1 (regex) → 3 (taint) → 5 (cross-file + LLM)
--workers Parallel scan workers (default: all CPUs)
--baseline Path to baseline JSON — report only new findings
Docker
docker run --rm -v $(pwd):/src ghcr.io/naniexists/shrike:latest audit /src
Output Formats
| Format | Use Case |
|---|---|
terminal |
Human-readable CLI output |
json |
Machine-readable, CI integration, baseline diffing |
sarif |
GitHub Security tab, VS Code SARIF Viewer |
html |
Shareable report with risk scores |
pdf |
Stakeholder/compliance reporting (requires pip install shrike-scanner[pdf]) |
Rule Categories
| Provider | Categories |
|---|---|
| Stripe | Secrets, Idempotency, Webhooks, Payments, Subscriptions, Connect, Currency, Checkout, Refunds, Customers, SCA |
| Razorpay | Secrets, Webhooks, Payments, Subscriptions, UPI, RazorpayX |
| PayPal | Secrets, Webhooks, Payments, Config, Subscriptions |
| Compliance | PCI-DSS, RBI, EU PSD2 |
| Cross-Provider | Architecture, Logging, Race Conditions, Frontend, Infrastructure, Error Handling |
| Frameworks | Next.js, Express, Django, Flask, Rails, Laravel, Go, Slim |
AI-Powered Fixes
With an API key, Shrike generates context-aware patches for critical findings:
shrike config set openai_api_key sk-...
shrike audit . --ai-patches
Supports OpenAI, Anthropic, and Google Gemini. Code snippets are sent to the LLM — you'll be prompted for consent.
Architecture
shrike audit .
│
├── File Discovery ──→ language detection, .shrikeignore, size limits
├── Relevance Filter ──→ payment-signal matching (skip non-payment files)
├── L1: Regex Rules ──→ 593 pattern rules with context windows
├── L3: Taint Analysis ──→ AST-based data flow (tree-sitter)
├── L4: LLM Filtering ──→ false-positive suppression via AI
├── Deduplication ──→ two-tier: exact + LOW/INFO rollup
├── Cross-File Suppression ──→ e.g., CHK002 if webhook handler exists
└── Report Generation ──→ terminal, JSON, HTML, PDF, SARIF
License
Business Source License 1.1 — free for non-production use and education. Commercial/production use requires a license from shrike.pro.
Changes to Apache 2.0 four years after each release.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file shrike_scanner-1.0.0.tar.gz.
File metadata
- Download URL: shrike_scanner-1.0.0.tar.gz
- Upload date:
- Size: 185.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
71e9422c9c1e9c6a0afcef6f845b8531aad0d7d8d3f6bc7cdce33c558348304f
|
|
| MD5 |
6c910c11494271293c9f52a1d95b3ed9
|
|
| BLAKE2b-256 |
f4554427f3674484f82922e22b3c993b72cbb70dd2698557e60697dca4fd40e8
|
File details
Details for the file shrike_scanner-1.0.0-py3-none-any.whl.
File metadata
- Download URL: shrike_scanner-1.0.0-py3-none-any.whl
- Upload date:
- Size: 196.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
783ec159abfa88a09feab411e10d5bddd90d7819f94e70e57c9582eab5939c57
|
|
| MD5 |
d1ddf4001f2673a5d2dd21558a6471d0
|
|
| BLAKE2b-256 |
e2da4e4b4330d61a6a9ce4f46eb8a1652f68b27e442aed8d30942de3b6b12618
|