Security
Security considerations and best practices for using Shade402 in production.
Wallet Security
Private Key Storage
Never store private keys in code or version control:
// BAD: Hardcoded private key
const wallet = Keypair.fromSecretKey(
Buffer.from('hardcoded-secret-key', 'base64')
);
// GOOD: Load from environment variable
const wallet = Keypair.fromSecretKey(
Buffer.from(process.env.WALLET_SECRET_KEY!, 'base64')
);
// GOOD: Use key management service
const wallet = await loadWalletFromAWSSecretsManager();Key Rotation
Regularly rotate wallet keys:
Generate new key pair
Update environment variables
Update configuration
Test with small amounts
Monitor old wallet for unexpected activity
Key Access Control
Limit access to wallet private keys:
Use environment variables (not committed to git)
Use secret management services (AWS Secrets Manager, HashiCorp Vault)
Implement access controls and audit logging
Use separate wallets for different environments
Payment Verification
On-chain Verification
Always enable on-chain verification in production:
initX402({
// ... other config ...
autoVerify: true, // Enable in production
});On-chain verification:
Confirms transaction exists on blockchain
Verifies transaction signature
Checks transaction status
Prevents replay attacks
Payment Expiration
Set appropriate expiration times:
paymentRequired({
expiresIn: 300, // 5 minutes - short for sensitive operations
// or
expiresIn: 3600, // 1 hour - longer for batch operations
});Consider:
Shorter expiration for high-value resources
Longer expiration for user-initiated flows
Balance security with user experience
Amount Validation
Always validate payment amounts:
// Server-side validation
if (parseFloat(authorization.actualAmount) < parseFloat(requiredAmount)) {
return res.status(403).json({ error: 'Insufficient payment' });
}Resource Encryption
Enable Encryption
Use resource encryption for sensitive resources:
import { generateKeyPair } from '@shade402/core';
const { publicKey, privateKey } = generateKeyPair();
initX402({
// ... other config ...
encryptionPublicKey: publicKey,
encryptionPrivateKey: privateKey,
});Encryption prevents:
Payment request replay attacks
Resource path exposure
Unauthorized access to payment requests
Key Management
Store encryption keys securely:
Use separate keys for different environments
Rotate keys periodically
Use key management services
Never expose private keys
URL Validation
Client-side Validation
The client validates URLs to prevent SSRF attacks:
Only allows
http://andhttps://schemesBlocks localhost and private IPs (unless
allowLocalis enabled)Validates URL format
For local development only:
const client = new X402Client(wallet, rpcUrl, undefined, true); // allowLocalNever use allowLocal in production.
Server-side Validation
Validate all incoming URLs and parameters:
function validateUrl(url: string): boolean {
try {
const parsed = new URL(url);
// Only allow specific domains
const allowedDomains = ['api.example.com'];
return allowedDomains.includes(parsed.hostname);
} catch {
return false;
}
}Error Handling
Don't Expose Sensitive Information
// BAD: Exposes internal details
catch (error) {
res.status(500).json({ error: error.message, stack: error.stack });
}
// GOOD: Generic error messages
catch (error) {
console.error('Internal error:', error);
res.status(500).json({ error: 'Internal server error' });
}Rate Limiting
Implement rate limiting for payment-protected endpoints:
import rateLimit from 'express-rate-limit';
const paymentLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 10, // 10 requests per window
});
app.get('/api/premium-data',
paymentLimiter,
paymentRequired({ amount: '0.01' }),
handler
);Transaction Security
Transaction Signing
Always verify transaction signatures:
// Server verifies signature
const isValid = await processor.verifyPayment(
paymentRequest,
authorization
);
if (!isValid) {
return res.status(403).json({ error: 'Invalid payment' });
}Transaction Monitoring
Monitor transactions for suspicious activity:
Track payment amounts and frequencies
Alert on unusual patterns
Log all payment transactions
Review failed payment attempts
Network Security
RPC Endpoint Security
Use secure RPC endpoints:
// Use HTTPS
const rpcUrl = 'https://api.mainnet-beta.solana.com';
// Or use authenticated RPC provider
const rpcUrl = process.env.HELIUS_RPC_URL; // Includes API keyNetwork Validation
Validate network configuration:
const allowedNetworks = ['solana-mainnet', 'solana-devnet'];
if (!allowedNetworks.includes(network)) {
throw new Error('Invalid network');
}Best Practices Summary
Never commit private keys to version control
Use environment variables or key management services
Enable on-chain verification in production
Set appropriate expiration times for payment requests
Validate all payment data before processing
Enable resource encryption for sensitive resources
Implement rate limiting for payment endpoints
Monitor transactions for suspicious activity
Use secure RPC endpoints with HTTPS
Log payment transactions for audit purposes
Handle errors securely without exposing sensitive information
Regularly rotate keys and update dependencies
Test security measures before production deployment
Keep dependencies updated for security patches
Security Checklist
Before deploying to production:
Reporting Security Issues
If you discover a security vulnerability:
Do not open a public issue
Email [email protected]
Include details of the vulnerability
Wait for confirmation before disclosing
Next Steps
Review Best Practices
Check out Troubleshooting
See Examples for secure implementations
Last updated
