DefinitionsWordPressWhat is the WordPress Database (wp_options, wp_posts)?
WordPress

What is the WordPress Database (wp_options, wp_posts)?

The WordPress database is a MySQL or MariaDB relational database that stores all site content, settings, user data, and plugin configurations in a structured set of tables, with wp_options and wp_posts being two of the most critical and security-sensitive tables.

WPSentry TeamMarch 9, 20265 min read
Table of Contents 5 sections

What is the WordPress Database?

The WordPress database is the central data store for every WordPress installation, holding all site content, configuration settings, user accounts, plugin data, and metadata in a structured relational database. WordPress uses MySQL or MariaDB as its database engine, organising data across a default set of twelve core tables. Each table serves a specific purpose: wp_posts stores all content (posts, pages, custom post types, revisions, and menu items), wp_options stores site-wide configuration settings, wp_users and wp_usermeta store user account information and metadata, and wp_comments and wp_commentmeta store comment data.

The database is the single point of truth for a WordPress site. Every page load involves multiple database queries to retrieve content, settings, and user information. The connection credentials are stored in wp-config.php, and WordPress communicates with the database through the $wpdb global object, which provides an abstraction layer for constructing and executing SQL queries. Because the database contains everything from administrator credentials to private content to payment information stored by e-commerce plugins, it is the highest-value target in any WordPress installation.

The wp_options Table

The wp_options table is a key-value store that holds virtually all WordPress configuration settings, from the site URL and admin email address to active plugins, theme settings, and widget configurations. It is also heavily used by plugins to store their own settings, license keys, API credentials, and cached data. The table has a simple structure with four columns: option_id, option_name, option_value, and autoload. Options marked with autoload = yes are loaded into memory on every page request, making them available without additional database queries.

From a security perspective, wp_options is extremely sensitive. It contains the siteurl and home options that define the site's URLs; an attacker who modifies these can redirect the entire site to a malicious domain. The active_plugins option controls which plugins are loaded; modifying this value can activate malicious plugins or deactivate security plugins. User roles and capabilities are serialised and stored in wp_options, so direct database manipulation can grant administrative privileges to any user. The admin_email option controls where password reset emails are sent, making it a target for account takeover attacks.

The wp_posts Table

The wp_posts table is the most versatile table in the WordPress database, storing not just blog posts but all content types including pages, attachments, revisions, navigation menu items, and any custom post types registered by plugins. Each row represents a content object with fields for the title, content body, excerpt, author, publication date, status (published, draft, pending, private), type, and various other metadata. The post_content field can contain HTML, shortcodes, and serialised block data (for the Gutenberg editor), making it both powerful and potentially dangerous.

The security implications of the wp_posts table centre on content injection and data exposure. If an attacker gains write access to this table, they can inject malicious JavaScript, iframe elements, or redirect scripts into any page or post on the site, potentially affecting every visitor. The table also stores private and draft content that should not be publicly accessible, as well as revision history that may contain sensitive information that was later edited out. Plugins that store sensitive data in custom post types (such as e-commerce orders, form submissions, or customer records) make the wp_posts table an even more attractive target for data exfiltration.

Database Security Threats

SQL injection remains the most critical database security threat for WordPress sites. This attack occurs when user input is incorporated into a SQL query without proper sanitisation or parameterisation, allowing an attacker to manipulate the query structure and execute arbitrary SQL commands. A successful SQL injection attack can read any data in the database (including user passwords and private content), modify data (such as creating admin accounts or injecting malicious content), delete data (destroying posts, settings, or entire tables), or in some configurations, read or write files on the server's file system.

Database credential theft is another significant threat. If an attacker obtains the database username and password from wp-config.php (through a file inclusion vulnerability, server misconfiguration, or exposed backup), they can connect directly to the database and bypass all WordPress application-level security measures. On shared hosting environments, databases from different sites may be accessible to the same MySQL user if the hosting provider has not implemented proper isolation. Unencrypted database connections between the web server and database server can also be intercepted on untrusted networks, exposing both credentials and data in transit.

Database Security Best Practices

The most important database security practice is using $wpdb->prepare() for every database query that incorporates external data. This function implements parameterised queries that separate the SQL structure from the data, making SQL injection impossible regardless of the input. Developers should never concatenate variables directly into SQL strings, even if they believe the data has been previously sanitised. WordPress's database abstraction layer provides safe methods for all common operations: $wpdb->insert(), $wpdb->update(), $wpdb->delete(), and $wpdb->get_results() with prepared statements.

At the infrastructure level, the database user configured in wp-config.php should have only the minimum privileges required by WordPress: SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX, and DROP. Administrative privileges like GRANT, FILE, and SUPER should never be assigned to the WordPress database user. Changing the default table prefix from wp_ to a custom value adds a layer of obscurity that disrupts automated SQL injection scripts targeting default table names. Regular database backups (stored securely off-server) ensure recovery capability in the event of data corruption, ransomware, or accidental deletion. Enabling database encryption at rest and in transit (using MySQL's SSL/TLS options) protects data from physical theft and network interception respectively.

FAQ

Frequently Asked Questions

The wp_options table is a key-value store that holds all WordPress configuration settings, active plugin lists, theme settings, widget configurations, and plugin-specific data. It is loaded on every page request and is critical to site operation.

Always use $wpdb->prepare() for queries that include external data. Never concatenate variables directly into SQL strings. Use WordPress's built-in methods like $wpdb->insert() and $wpdb->update() which handle parameterisation automatically.

Yes. Changing the default wp_ prefix to a custom value disrupts automated SQL injection scripts that target default table names. While not a substitute for proper security measures, it adds an additional layer of obscurity.

Tags

Related Definitions