WordPress, along with most other content management systems, uses a database to store state. State is the things the content management system knows about, including the content and its organization, and user data. There are many different types of database, but WordPress uses one of the most popular open source SQL-based databases, MySQL.
SQL is a language used to build the databases tables, to put data in them, and to get data out. It looks like this:
INSERT INTO TABLE VALUES (13, 'Phoenix', 'AZ', 33, 112);
You can think of the current state of a database as the totality of every SQL query it has run. In fact, when you backup an SQL database, that’s what you get: a dump of the SQL required to transform a new and empty database into the backed-up database (plus some other data).
As you can imagine, it’s important to make sure only authenticated people and programs are allowed to make queries to a WordPress site’s database. If an attacker can send SQL to the database, they can delete, create, or modify data — and that data is WordPress’s view of its world.
For example, we want only a few trusted people to have admin permissions on our WordPress site. We tell WordPress who those people are and WordPress puts their details in the database. If an unauthorized person can tell the database, via an SQL query, to create a new admin user with a password of their choosing, they can take over the site.
Of course, there are many safeguards in place to stop this happening. The database will ignore requests from unauthorized sources. But the content management system needs to be able to make changes to the database.
WordPress stands between the user and the database. Authorized users interact with WordPress, and WordPress sends information to the the database. Users never send requests direct to the database.
However, sometimes developers make mistakes. Imagine a developer creates an input box on a WordPress site so that users can enter their email, which is sent to the database to be stored. The only thing the input box should allow to be sent to the database is a valid email address. But a malicious user might try to use the input box to send something different, like an SQL query.
The vast majority of the time, input like that is rejected by validation in the browser, and made safe by escaping and sanitization. If the attacker is very lucky, the developer may have made a mistake, allowing the SQL to be sent directly to the database, which is definitely not something we want to happen.
SQL injection vulnerabilities are rare, but serious. From the perspective of the average WordPress user, the best way to avoid SQL injection attacks is to only install themes and plugins from trusted sources, and ensure that the WordPress site and its plugins are regularly updated — updating will fix any SQL injection vulnerabilities that have been discovered and reported to WordPress and plugin developers.