Closed taowang1993 closed 1 week ago
I found a similar open issue: Embedding Chatbot Will Expose URL, which was last updated on August 27, 2024 [1].
To prevent technical users from inspecting the code and finding the URL when embedding a chatbot with an iframe, you can obfuscate the URL and use server-side validation to ensure that only authorized users can access the chatbot. Here is a basic approach to achieve this:
Here is an example of how you can modify the existing code to include these steps:
You can use a function to encode the URL or generate a token that will be validated on the server.
async function getObfuscatedUrl(token, inputs) {
const params = new URLSearchParams(inputs);
const baseUrl = `https://${config.isDev ? "dev." : ""}udify.app`;
const url = `${baseUrl}/chatbot/${token}?${params}`;
// Encode the URL
const encodedUrl = btoa(url);
return encodedUrl;
}
embedChatbot
function to use the obfuscated URLasync function embedChatbot() {
if (!config || !config.token) {
console.error(`${configKey} is empty or token is not provided`);
return;
}
const inputs = await getCompressedInputsFromConfig();
const obfuscatedUrl = await getObfuscatedUrl(config.token, inputs);
// Use the obfuscated URL
const iframeUrl = `https://your-server.com/validate?url=${obfuscatedUrl}`;
function createIframe() {
const iframe = document.createElement("iframe");
iframe.allow = "fullscreen;microphone";
iframe.title = "dify chatbot bubble window";
iframe.id = iframeId;
iframe.src = iframeUrl;
iframe.style.cssText = `
border: none; position: fixed; flex-direction: column; justify-content: space-between;
box-shadow: rgba(150, 150, 150, 0.2) 0px 10px 30px 0px, rgba(150, 150, 150, 0.2) 0px 0px 0px 1px;
bottom: 5rem; right: 1rem; width: 24rem; max-width: calc(100vw - 2rem); height: 40rem;
max-height: calc(100vh - 6rem); border-radius: 0.75rem; display: flex; z-index: 2147483647;
overflow: hidden; left: unset; background-color: #F3F4F6;
`;
document.body.appendChild(iframe);
}
createButton();
}
On your server, you should have an endpoint that validates the obfuscated URL and returns the actual URL if the user is authorized.
from flask import Flask, request, jsonify
import base64
app = Flask(__name__)
@app.route('/validate', methods=['GET'])
def validate():
obfuscated_url = request.args.get('url')
if not obfuscated_url:
return jsonify({"error": "Invalid request"}), 400
# Decode the URL
decoded_url = base64.b64decode(obfuscated_url).decode('utf-8')
# Perform your validation logic here
if user_is_authorized():
return jsonify({"url": decoded_url})
else:
return jsonify({"error": "Unauthorized"}), 403
def user_is_authorized():
# Implement your authorization logic here
return True
if __name__ == '__main__':
app.run()
Additionally, you can use the Dify platform's built-in capabilities to manage the embedding of chatbots securely. Dify provides various embedding options such as iframe, scripts, and Chrome plugins, which can be customized and secured as needed. Here is an example of how you can use Dify's embedding options:
const OPTION_MAP = {
iframe: {
getContent: (url: string, token: string) =>
`<iframe
src="${url}/chatbot/${token}"
style="width: 100%; height: 100%; min-height: 700px"
frameborder="0"
allow="microphone">
</iframe>`,
},
scripts: {
getContent: (url: string, token: string, primaryColor: string, isTestEnv?: boolean) =>
`<script>
window.difyChatbotConfig = {
token: '${token}'${isTestEnv
? `,
isDev: true`
: ''}${IS_CE_EDITION
? `,
baseUrl: '${url}'`
: ''}
}
</script>
<script
src="${url}/embed.min.js"
id="${token}"
defer>
</script>
<style>
#dify-chatbot-bubble-button {
background-color: ${primaryColor} !important;
}
</style>`,
},
chromePlugin: {
getContent: (url: string, token: string) => `ChatBot URL: ${url}/chatbot/${token}`,
},
}
By following these steps and leveraging Dify's features, you can help prevent technical users from easily inspecting the code and finding the URL, thus avoiding bypassing the paywall [2][3].
To continue talking to Dosu, mention @dosu.
This is an expected behavior.
Is it possible to configure CORS to only allow my own domain to embed the chatbot?
If others find out my chatbot url, they can embed it on their website and consume my tokens.
This is an expected behavior.
Is this going to be fixed in near future? I don't want others embed my chatbot.
It will probably not be "fixed" as it's not "broken". That's how iframe works, not an issue with Dify.
If you want to protect your chatbot, I suggest one of 2 ways:
window.difyChatbotConfig
. Then inside your bot, before calling any LLM you must always call an API to check if the key is valid.Either way, you must pick some kind of complexity. I'd recommend the first.
Flowise has this secure approach of embedding chatbot.
<flowise-fullchatbot></flowise-fullchatbot>
<script type="module">
import Chatbot from "https://cdn.jsdelivr.net/npm/flowise-embed/dist/web.js"
Chatbot.init({
chatflowid: "f5adc8af-d9e3-4735-af79-886f237",
apiHost: "https://taowang1993-flowise.hf.space",
})
</script>
Then, you can set up Allowed Domains for embedding your chatbot. So, only your website can embed your chatbot.
I wish Dify has this as well. I would love to make contributions, but I am not very technical.
Self Checks
Dify version
0.7.2
Cloud or Self Hosted
Cloud
Steps to reproduce
If I embed this chatbot, technical users can just inspect the code and find the url. Then, they can bypass paywall and use the chatbot. How to prevent this?
✔️ Expected Behavior
No response
❌ Actual Behavior
No response