9 min read
Overviewβ
If you are building a front-end decentralized application (dApp), your site will need to connect to the chain with an endpoint node. You can think of your endpoint as an API key that allows you to connect to the chain. If you are using a front-end (e.g., a Candy Machine Mint Page or a Defi Application), you may be exposing your endpoint to the public. This means a malicious actor could exploit and use your private endpoint. This could run up your bill and cause other performance issues. In this guide, you will learn various strategies to protect your endpoint when using a front end:
Tactic | Ease/Complexity | Effectiveness | QuickNode Plan |
---|---|---|---|
Rotate Keys | π‘ Moderate | π’ High | All plans |
Dot Env with Backend Proxy | π’ Easy | βͺ Moderate | n/a |
Rate Limiting | π’ Easy | βͺ Moderate | All plans |
Domain Whitelisting | π‘ Moderate | βͺ Moderate | All plans |
JSON Web Tokens (JWT) | π΄ Complex | π’ High | All plans |
Endpoint Armor | π‘ Moderate | π’ High | Marketplace Add-on |
Rotate Keysβ
Rotating your keys is a simple yet effective method for protecting your endpoint. It involves regularly rotating your endpoint's private token to prevent unauthorized access. This means that even if your endpoint is exposed, it will only be vulnerable for a limited time. QuickNode allows you to rotate your keys directly from your QuickNode dashboard.
Just open your QuickNode Dashboard (https://dashboard.quicknode.com/) and select the endpoint you want to rotate keys for. Click the Security Tab and scroll to the "Authentication: Tokens" section. Here, you can add or delete new keys. New keys will be available immediately. Just copy the new key and use it in your application. You can delete old keys by clicking the ποΈ button next to the key you want to remove. Any previously compromised keys that have been removed are no longer valid.
Regularly rotating your keys can significantly reduce the risk of unauthorized access to your endpoint. For more information on how to rotate your keys, check out our Guide: How to Set Up Multi-Token Authentication on QuickNode.
- Pros: Simple, Secure
- Cons: Time-consuming (requires regular key rotation), Key Management
Dot Env and Backend Proxyβ
Dot Envβ
Dot Env (.env
) is a simple yet effective method for managing environment variables in your application. It involves using a .env
file to store configuration settings and sensitive information, such as API keys and database passwords. This approach centralizes configuration management, making it easier to update and maintain. Dot Env has several benefits:
- Security: Keeps sensitive data out of your codebase, reducing the risk of exposing it in version control systems.
- Flexibility: Allows different configurations for different environments (e.g., development, testing, production) without changing the code.
- Ease of Use: Simplifies managing environment-specific variables.
Backend Proxyβ
While Dot Env is effective for managing environment variables, variables stored in .env
files can be inadvertently exposed if the file is served to the client side. A backend proxy serves as an excellent solution to this problem. A backend proxy is a middleman between the client and server sides. It can handle requests requiring sensitive data, like your endpoint, without exposing them to the client. Here's an example of a backend proxy making a Solana getBalance
request:
const dotenv = require('dotenv');
dotenv.config();
const PRIVATE_ENDPOINT = process.env.PRIVATE_ENDPOINT;
const solanaWeb3 = require('@solana/web3.js');
const app = express();
app.get('/getBalance', async (req, res) => {
const connection = new solanaWeb3.Connection(
PRIVATE_ENDPOINT,
'confirmed',
);
const balance = await connection.getBalance(req.query.publicKey);
res.send(balance);
});
This approach has several benefits:
- Secure Data Handling: The backend proxy can securely handle requests and manage sensitive data, like API keys, without exposing them to the client side.
- Environment Variables: Store sensitive data in
.env
on the server and use the backend proxy to mediate interactions with external services. - Reduced Exposure Risk: This approach significantly reduces the risk of sensitive information exposure, as the data never reaches the front end.
Best Practicesβ
- Use Dot Env Server-Side: Store sensitive variables in
.env
server files, not client-side code. - Do not Commit
.env
Files: Ensure.env
files are not committed to public repositories (use.gitignore
). - Implement Backend Proxy: Use a backend proxy to handle requests that require sensitive data, ensuring this data is not exposed in the client-side application.
By combining Dot Env with a backend proxy, you can maintain the ease and security of environment variable management while safeguarding against the risks of client-side exposure.
- Pros: Adaptable, Scalable, Secure
- Cons: Codebase Complexity (additional server-side code) and Performance Overhead
Rate Limitingβ
Rate limiting is crucial to endpoint security, especially in web applications and APIs. It involves setting a maximum number of requests your endpoint can handle within a given time frame. Though this will not prevent others from accessing your endpoint, it will limit the number of requests they can make. This can help prevent abuse and overuse of resources, which can lead to performance issues and increased costs.
Setting Rate Limitsβ
QuickNode lets you set rate limits for any endpoints directly from your QuickNode dashboard. Go to your QuickNode Dashboard (https://dashboard.quicknode.com/) and select the endpoint you want to apply rate limits to. Click the Security Tab and scroll to the "Rate Limits" section. Here, you can apply limits to your endpoint regarding Requests per Second, Minute, or Day.
Select the rate limit type you want to apply, enter the limit, and click Add. Your rate limits will be applied immediately.
Method Rate Limitsβ
QuickNode also offers method-specific rate limits. These can be found on the same endpoint security page in the dashboard. Method rate limits allow you to set different limits for different API methods, providing more granular control over your endpoint's usage.
- Pros: Easy to implement/modify
- Cons: Could impact user experience if limits are too low, Does not prevent access to endpoint
Domain Whitelistingβ
Domain whitelisting (or referrer whitelisting) is a simple yet effective method for restricting access to your endpoint. It involves creating a list of approved domains that can access your endpoint. This can help prevent unauthorized access and abuse of your endpoint. QuickNode allows you to whitelist multiple referrers for any of your endpoints directly from your QuickNode dashboard.
Whitelisting Domainsβ
Go to your QuickNode Dashboard (https://dashboard.quicknode.com/) and select the endpoint you want to apply whitelists to. Click the Security Tab and scroll down to the "Referrer Whitelist" section. Here, you can add domains to your whitelist. Enter the domain you want to whitelist and click Add. Your whitelist will be applied immediately. You can easily delete a whitelisted domain by clicking the ποΈ button next to the domain you want to remove.
After it's saved, you can test your whitelist by making a request to your endpoint with a cURL script or from a domain that is not whitelisted. You should receive an UNAUTHORIZED
response.
For example, this request:
curl https://your-endpoint.solana-mainnet.quiknode.pro/123/ \
-X POST \
-H "Content-Type: application/json" \
--data '{"jsonrpc":"2.0","id":1, "method":"getBlock"}'
Should now return:
{
"error":"UNAUTHORIZED",
"instance":"your-endpoint",
"request-id":""
}
- Pros: Easy to implement/modify
- Cons: Limited effectiveness
For more information on how to whitelist domains, check out our Guide: How to setup referrer whitelist with QuickNode.
JSON Web Tokens (JWT)β
JSON Web Tokens (JWT) are a popular method for securing APIs. They are an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA. JWTs are commonly used for authentication and information exchange in web applications and APIs.
JWTs prevent unauthorized access by verifying the integrity of the information contained within the token. This is accomplished by signing a duration-limited token with a secret or a public/private key pair. Requests received without a token or with an invalid token (either because it has expired or was not signed with the correct secret) will be rejected.
Implementing JWTsβ
Here's a simple example of how to implement JWTs in your application (for a more detailed walkthrough, check out our Guide: How to Implement JWT Authorization with QuickNode):
- Key Generation: Generate a public/private key pair using RSA or ECDSA. Example:
const { generateKeyPairSync } = require('crypto');
var jwt = require('jsonwebtoken');
// Generate RSA keys
const { publicKey, privateKey } = generateKeyPairSync('rsa', {
modulusLength: 2048,
publicKeyEncoding: {
type: 'spki',
format: 'pem'
},
privateKeyEncoding: {
type: 'pkcs8',
format: 'pem',
}
});
- Define Key: Add your public key to your QuickNode dashboard (Security Tab).
- Token Generation: In your backend, generate a limited duration JWT using your private key (e.g., 60 seconds for handling a transaction request). Example:
const app = express();
const jwt = require("jsonwebtoken");
app.get('/get_token', (req, res) => { // endpoint to retrieve JWT
const privateKey = process.env;
var token = jwt.sign({}, privateKey, {
algorithm: 'RS256', // RSA signature with SHA-256
expiresIn: "60000" // 30 seconds
});
return res.json({ token: token }); // return an object containing the signed JWT
});
- Establish Connection: In your front-end, connect to your endpoint using the JWT. Example:
const { Connection } = require('@solana/web3.js');
async function makeRequest() {
const token = await fetch('/get_token'); // fetch JWT from backend
const connection = new Connection('https://example.solana-devnet.quiknode.pro/12345/', {
httpHeaders: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': `Bearer ${token.token}`
}
});
const block = await connection.getBlock();
// do something with the block
}
makeRequest();
- Token Verification: When we receive the request, we can verify the token using the public key you added to your QuickNode dashboard. This will ensure the token is valid and has not been tampered with.
Best Practicesβ
- Key Management: Securely manage and regularly rotate cryptographic keys.
- Token Expiration: Set appropriate token expiration times to reduce the risk of token misuse.
- Pros: Secure, Scalable, Adaptable
- Cons: Codebase Complexity (additional server-side code and key management)
Endpoint Armorβ
Endpoint Armor is a powerful add-on that provides an additional layer of security for your endpoint. Think of Endpoint Armor as an advanced rate limiter and firewall that can be configured to block requests based on a variety of factors, including:
- global limits,
- visitor limits,
- method-specific limits,
- method restrictions,
- parameter restrictions,
- contract restrictions
Using Endpoint Armorβ
Endpoint Armor is an add-on available through the QuickNode Marketplace. To add Endpoint Armor to your endpoint, go to your QuickNode Dashboard (https://dashboard.quicknode.com/) and select the endpoint you want to add Endpoint Armor to. Click the Add-ons Tab and scroll down to the "Endpoint Armor" section. Click Install. Your Endpoint Armor will be applied to your account immediately.
To use your Armor, you will need to do two things:
- Update your endpoint URL (Endpoint Armor uses a unique subdomain:
demo-endpoint.quiknode.pro
->demo-endpoint.secure.quiknode.pro
) - Define your Armor Rules. Here's an example implementation:
{
"methods": {
"getSlot": {
"reqPerHour": 1000,
"reqPerMinute": 100,
"reqPerSecond": 10,
"minBlockNumber": 24000000
}
},
"visitorRateLimits": {
"reqPerMinute": 10
}
}
The above example whitelists one method: getSlot
. It will allow 1,000 requests per hour, 100 per minute, and 10 per second (globally). It will also only allow requests for slots above 24,000,000. Finally, it will allow ten requests per minute from a single visitor to your website.
For more details on how to deploy Endpoint Armor, check out our Guide: How to Deploy Endpoint Armor.
- Pros: Secure, Scalable, Configurable
- Cons: Additional Cost, Endpoint is Visible (so it can be targeted within the limits of the Armor)
Wrap Upβ
Practicing good endpoint security on your front end is crucial for protecting your endpoint from unauthorized access and abuse. Implementing the strategies outlined in this guide can significantly reduce the risk of unauthorized access to your endpoint.
If you are stuck or have questions, drop them in our Discord. Stay up to date with the latest by following us on Twitter (@QuickNode) or our Telegram announcement channel.
We β€οΈ Feedback!
Let us know if you have any feedback or requests for new topics. We'd love to hear from you.