Back to skill

Security audit

Paytm Integration Skill

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to be a genuine Paytm integration guide, but its sample backends could expose real merchant payment authority if deployed without added access controls.

Install only if you treat the included servers as demos or harden them before real use. Before using live Paytm credentials, add authentication, authorization, ownership checks, rate limits, request-size limits, strict CORS, callback URL allowlists, minimal response fields, and clear privacy/notification notices for customer contact data.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/backend-node/server.js:69
Finding

Unauthenticated Merchant Operations and Transaction Data Access

Content
View full analysis
{ const { amount, custId, mobile, email, orderId } = req.body ?? {}; return initiateTransaction({ amount, custId, mobile, email, orderId, serverBaseUrl: requestBase(req) }); })); app.post("/paytm/create-subscription", withIdempotency(async (req) => { return createSubscription({ ...(req.body ?? {}), serverBaseUrl: requestBase(req) }); })); app.post("/paytm/create-link", withIdempotency(async (req) => { return createPaymentLink({ ...(req.body ?? {}), serverBaseUrl: requestBase(req) }); })); app.post("/paytm/create-qr", withIdempotency(async (req) => { return createDynamicQr({ ...(req.body ?? {}) }); })); app.post("/paytm/link-transactions", async (req, res) => { try { const out = await fetchLinkTransactions({ ...(req.body ?? {}) }); res.json(out); } catch (e) { res.status(Number(e?.httpStatus) || 500).json(payloadFromError(e)); } }); ``` ```javascript app.post("/paytm/order-status", async (req, res) => { try { const orderId = req.body?.orderId; if (!orderId) return res.status(400).json({ error: true, message: "orderId required" }); const json = await fetchOrderStatus({ orderId }); res.type("application/json").send(json); } catch (e) { res.status(500).json({ error: true, message: e?.message || String(e) }); } }); ``` ### Technical Analysis These endpoints perform privileged operations using the backend's Paytm merchant key. However, none of the route handlers authenticate ...[truncated 2484 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/backend-node/server.js:25
Finding

Attacker-Controlled Callback URL in Merchant-Signed Paytm Requests

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/backend-spring/src/main/java/com/paytm/demo/PaytmBackendApplication.java:21
Finding

Wildcard CORS Enables Cross-Origin Invocation of Sensitive Spring Endpoints

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (50)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description is narrowly focused on Paytm payment gateway integration and troubleshooting. The supplied code does not reference Paytm, payment gateways, checksums, transactions, callbacks, SDKs, or any Paytm endpoints. Instead, it implements a generic in-process idempotency cache for backend create endpoints, including TTL-based storage and extraction of an idempotency key from headers/body. This is a materially different primary purpose, not merely a supporting detail of Paytm integration, so it is a clear description-behavior mismatch.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/troubleshooting.md (reported line 153)May include surrounding context.

Extract the corp root cert, then point your runtime at it. TLS verification stays ON.

macOS - export from System keychain:

bash
mkdir -p ./certs
security find-certificate -a -p /Library/Keychains/System.keychain > ./certs/corp-proxy-ca.crt

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/troubleshooting.md (reported line 156)May include surrounding context.

Extract the corp root cert, then point your runtime at it. TLS verification stays ON.

macOS - export from System keychain:

bash
mkdir -p ./certs
security find-certificate -a -p /Library/Keychains/System.keychain > ./certs/corp-proxy-ca.crt

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/troubleshooting.md (reported line 159)May include surrounding context.

Extract the corp root cert, then point your runtime at it. TLS verification stays ON.

macOS - export from System keychain:

bash
mkdir -p ./certs
security find-certificate -a -p /Library/Keychains/System.keychain > ./certs/corp-proxy-ca.crt

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/troubleshooting.md (reported line 156)May include surrounding context.

macOS - export from System keychain:

bash
mkdir -p ./certs
security find-certificate -a -p /Library/Keychains/System.keychain > ./certs/corp-proxy-ca.crt
# Or just the corp root if you know its CN:
security find-certificate -a -c "YourCorpName Root CA" -p \
  /Library/Keychains/System.keychain > ./certs/corp-proxy-ca.crt

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/troubleshooting.md (reported line 159)May include surrounding context.

macOS - export from System keychain:

bash
mkdir -p ./certs
security find-certificate -a -p /Library/Keychains/System.keychain > ./certs/corp-proxy-ca.crt
# Or just the corp root if you know its CN:
security find-certificate -a -c "YourCorpName Root CA" -p \
  /Library/Keychains/System.keychain > ./certs/corp-proxy-ca.crt

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
85% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 54)May include surrounding context.

OR

bash
mkdir -p ~/.claude/skills
git clone https://github.com/paytm/paytm-integration-skills.git ~/.claude/skills/paytm-integration

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · README.md (reported line 54)May include surrounding context.

OR

bash
mkdir -p ~/.claude/skills
git clone https://github.com/paytm/paytm-integration-skills.git ~/.claude/skills/paytm-integration

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

At L233 the document says recurring debit, status, edit, and cancel operations are out of scope for the skill. But at L506 it describes references/subscriptions.md as covering 'charge/edit/cancel', which directly contradicts that earlier scope statement and could cause the skill to provide guidance for actions it said it would not handle.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The markdown imposes strict natural-language constraints such as 'must be exclusively displayed' and 'must use only the following vocabulary' for all user-facing copy and chat replies. This is an organizational language-policy restriction that is not presented as user choice or clearly justified as a region/compliance-specific requirement, so it fits the policy-violation category.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This skill description instructs users to send customer name, email, phone number, and customer ID to Paytm-hosted APIs and to trigger SMS/email dispatch, but it does not warn that personally identifiable information is being transmitted to a third party. Under the markdown-file criteria, behaviors affecting user privacy should be disclosed clearly to the operator.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The document gives conflicting reconciliation guidance: one section says orderId lets you reconcile via /v3/order/status, while later sections explicitly say Payment Links should be reconciled via /link/fetchTransaction. In a payment integration skill, contradictory instructions can cause developers to validate the wrong transaction surface, miss multi-payer link activity, or incorrectly mark payments as unpaid/paid, creating fulfillment and accounting errors.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The documentation describes resending payment-link notifications to customer mobile numbers and email addresses, which can directly affect user privacy and communications. Although the section explains API mechanics, it lacks a clear warning that invoking it will contact customers through Paytm channels.

Content

No source excerpt is available for this finding.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · references/troubleshooting.md (reported line 244)May include surrounding context.

md
### What NOT to do

- **Do not** set `NODE_TLS_REJECT_UNAUTHORIZED=0` or `rejectUnauthorized: false` with real production merchant credentials. It disables verification for *every* outbound HTTPS call in the process - any host on-path can read your `MERCHANT_KEY`.
- **Do not** set `verify=False` (Python `requests`) or trust-all `SSLContext` (Java) in prod for the same reason.
- **Do not** commit the extracted CA bundle to a public repo - it's not secret, but it leaks your employer's name and proxy vendor.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · references/troubleshooting.md (reported line 245)May include surrounding context.

md
### What NOT to do

- **Do not** set `NODE_TLS_REJECT_UNAUTHORIZED=0` or `rejectUnauthorized: false` with real production merchant credentials. It disables verification for *every* outbound HTTPS call in the process - any host on-path can read your `MERCHANT_KEY`.
- **Do not** set `verify=False` (Python `requests`) or trust-all `SSLContext` (Java) in prod for the same reason.
- **Do not** commit the extracted CA bundle to a public repo - it's not secret, but it leaks your employer's name and proxy vendor.

### Quick triage

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The code builds a request containing customer identifiers, mobile numbers, and email addresses and sends it to the Paytm API via fetch. While comments describe the technical purpose, there is no confirmation prompt, user-facing log/message, or other disclosure in this file warning that personal data will be transmitted to an external payment provider.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The handler stores the full parsed webhook payload in eventLog, and the comments describe this as audit persistence. Although the file documents the behavior for developers, there is no user-facing disclosure, confirmation, or warning in this code about retaining payment-related webhook contents, which may include user or transaction data transmitted over the network.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
80% confidence
Finding

This markdown file instructs users to set PAYTM_MERCHANT_KEY and exposes demo flows for creating orders, subscriptions, payment links, and QR codes, but it provides no caution about keeping credentials private or avoiding unintended real transactions. For a skill description that affects payment operations and sensitive configuration, some user-facing warning about secret handling and transaction impact is expected.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/backend-python/payment_link_service.py (reported line 130)May include surrounding context.

python
"timestamp": str(int(datetime.now(timezone.utc).timestamp())),
    }

    r = requests.post(cfg["link_create_url"], json={"head": head, "body": body},
                      headers={"Content-Type": "application/json"}, timeout=15)
    text = r.text
    if not r.ok:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The create_payment_link function sends customerContact fields, callbackUrl, orderId, and amount to an external Paytm endpoint via requests.post. While the module docstring explains API mechanics, there is no user-facing warning, confirmation, logging, or explicit disclosure in this file that personal/contact data is transmitted off-system.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/backend-python/payment_link_service.py (reported line 197)May include surrounding context.

python
signature = PaytmChecksum.generateSignature(json.dumps(body), cfg["merchant_key"])
    head = {"tokenType": "AES", "signature": signature}

    r = requests.post(
        cfg["link_fetch_transaction_url"],
        json={"head": head, "body": body},
        headers={"Content-Type": "application/json"},

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/backend-python/paytm_service.py (reported line 89)May include surrounding context.

python
payload = {"body": body, "head": {"signature": signature}}

    url = f"{cfg['initiate_transaction_url']}?mid={cfg['mid']}&orderId={order_id}"
    r = requests.post(url, json=payload, headers={"Content-Type": "application/json"}, timeout=15)
    text = r.text
    if not r.ok:
        raise _upstream("INITIATE_HTTP_ERROR", f"initiateTransaction failed (HTTP {r.status_code})", order_id, text)

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/backend-python/subscription_service.py (reported line 135)May include surrounding context.

python
payload = {"body": body, "head": {"signature": signature}}

    url = f"{cfg['initiate_transaction_url']}?mid={cfg['mid']}&orderId={order_id}"
    r = requests.post(url, json=payload, headers={"Content-Type": "application/json"}, timeout=15)
    text = r.text
    if not r.ok:
        raise _upstream("INITIATE_HTTP_ERROR", f"initiateTransaction failed (HTTP {r.status_code})", order_id, text)

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/backend-python/paytm_service.py (reported line 116)May include surrounding context.

python
body = {"mid": cfg["mid"], "orderId": order_id}
    signature = PaytmChecksum.generateSignature(json.dumps(body), cfg["merchant_key"])
    payload = {"body": body, "head": {"signature": signature}}
    r = requests.post(cfg["order_status_url"], json=payload,
                      headers={"Content-Type": "application/json"}, timeout=15)
    if not r.ok:
        raise PaytmError("STATUS_HTTP_ERROR", f"order status HTTP {r.status_code} - {r.text}",

Static analysis

No suspicious patterns detected.