How to Handle Special Characters in Database Passwords with the Dify DB Query Plugin

The Dify DB Query plugin handles special characters in database passwords by URL-encoding them using urllib.parse.quote_plus before constructing the database connection string.

The junjiem/dify-plugin-tools-dbquery repository provides secure database query capabilities for Dify workflows. When connecting to databases that require passwords containing reserved URL characters—such as @, :, /, or spaces—the plugin automatically encodes these values to prevent connection string parsing errors.

Why Special Characters in Passwords Break Database Connections

Database connection URLs follow the standard URI format: driver://username:password@host:port/database. When a password contains characters that serve as delimiters or have special meaning in URLs, the parser misinterprets the connection string structure.

Common problematic characters include:

  • @ (used to separate credentials from host)
  • : (used to separate username from password)
  • / (used to separate host from database name)
  • (space) and + (plus sign)

Without proper encoding, a password like p@ss:w0rd causes the connection parser to treat w0rd as the hostname rather than part of the password.

How the Dify Plugin Handles Special Characters in Database Passwords

The plugin implements a robust encoding strategy within its database utility class to ensure password integrity across all supported database types.

The URL Encoding Strategy

The plugin utilizes Python's standard library function urllib.parse.quote_plus to encode passwords before inserting them into the connection DSN. This function:

  • Replaces special characters with their percent-encoded equivalents (e.g., @ becomes %40)
  • Converts spaces to + signs (as per application/x-www-form-urlencoded specification)
  • Ensures the resulting string is safe for URL parsing

Implementation in db_util.py

The encoding logic resides in the DbUtil class, specifically within the connection string construction method. In db_query_pre_auth/tools/db_util.py, the implementation processes the password as follows:

from urllib import parse

class DbUtil:
    def get_engine(self):
        # URL-encode the password to handle special characters

        parsed_password = parse.quote_plus(self.password)
        
        # Construct the connection string with encoded credentials

        url = f"{self.get_driver_name()}://{self.username}:{parsed_password}@{self.host}:{self.port}/{self.db_name}"
        
        return create_engine(url)

This pattern appears at lines 55-57 in the pre-authentication version of the utility file. The same implementation exists in the standard plugin version at db_query/tools/db_util.py, ensuring consistent behavior across both authentication modes.

Practical Code Examples

Connecting with a Complex Password

When configuring the plugin with a password containing multiple special characters, the encoding happens automatically:

from db_query_pre_auth.tools.db_util import DbUtil

# Password containing @, :, /, space, and +

complex_password = "p@ss:w0rd/ with+chars"

util = DbUtil(
    driver_name="postgresql+psycopg2",
    username="admin",
    password=complex_password,
    host="db.production.local",
    port=5432,
    db_name="analytics"
)

# The engine receives a properly encoded URL:

# postgresql+psycopg2://admin:p%40ss%3Aw0rd%2F+with%2Bchars@db.production.local:5432/analytics

engine = util.get_engine()

Query Execution with Special Character Passwords

The SqlQueryTool class automatically invokes the encoding when establishing connections:

from db_query.tools.sql_query import SqlQueryTool

tool = SqlQueryTool()
result = tool.run(
    db_type="mysql",
    db_host="mysql.internal",
    db_port=3306,
    db_name="users",
    db_username="app_user",
    db_password="my#P@ss!2024",  # Contains #, @, and !

    sql="SELECT COUNT(*) FROM active_users;"
)

In both examples, the password my#P@ss!2024 is automatically converted to my%23P%40ss%212024 before the connection attempt, preventing URL parsing errors while preserving the original password value for authentication.

Summary

  • The Dify DB Query plugin automatically handles special characters in database passwords by URL-encoding them using urllib.parse.quote_plus.
  • The encoding logic is implemented in the DbUtil class within db_query_pre_auth/tools/db_util.py and db_query/tools/db_util.py.
  • This approach safely encodes reserved URL characters—including @, :, /, spaces, and +—preventing connection string parsing errors.
  • Developers using the plugin do not need to manually encode passwords; the plugin handles this transparently during connection string construction.

Frequently Asked Questions

What special characters in passwords does the Dify plugin handle?

The plugin handles all characters that have special meaning in URLs, including @ (separator between credentials and host), : (separator between username and password), / (path separator), spaces, + signs, # (fragment identifier), and percent signs. The quote_plus function converts these to their percent-encoded equivalents (e.g., %40 for @).

Does URL-encoding passwords affect database authentication performance?

No, encoding occurs only once during the connection string construction phase before the SQLAlchemy engine is created. The encoding process is computationally trivial and adds negligible overhead compared to the network round-trip and database authentication handshake. Once encoded, the connection string is cached for the engine's lifetime.

Is URL-encoding sufficient for securing database passwords in the plugin?

URL-encoding ensures syntactic correctness of the connection string but does not constitute encryption or security hardening. The plugin stores passwords in memory as instance variables of the DbUtil class during execution. For production deployments, ensure that Dify's secret management or environment variable injection is used to pass passwords to the plugin, rather than hardcoding them in workflow configurations.

What happens if a password contains Unicode characters or emojis?

The quote_plus function handles Unicode characters by first encoding them to UTF-8 bytes, then percent-encoding each byte. For example, an emoji like 🔐 becomes %F0%9F%94%90. This ensures compatibility with database drivers that expect percent-encoded UTF-8 sequences in connection URLs. Both PostgreSQL and MySQL drivers supported by the plugin correctly decode these sequences during connection establishment.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →