Super Speedy Imports security review
Security › Super Speedy Imports
Security score 100/100 · Version 3.74.1 · Reviewed 6 November 2026 · Source fingerprint cb4f02e
Summary
We reviewed the security of Super Speedy Imports 3.68.4 on 3 November 2026, fixed everything the review found, and reviewed each set of fixes again until nothing remained. Version 3.74.1, reviewed on 6 November 2026, scores 100 out of 100. The reviews were carried out by an AI agent working through our written security checklist, and every confirmed finding was reproduced on a private test site before it was fixed and tested again afterwards, in both the paid and the Lite editions where the code ships in both.
What was found and fixed
SECURITY-001: field keys from an import configuration could reach a database query
- Severity: Critical. Points: 30.
- The problem: the key of an Advanced Custom Fields sub-field, stored in an import’s configuration, was written into a database query without being checked when the configuration was saved through MCP (AI agent) tools rather than the import screen. The dedicated Import Manager role, which does not have administrator rights, could use this to read data from the database.
- The fix: every way of saving a configuration now checks these keys, and they are checked again where the query is built. Fixed in 3.69.0.
SECURITY-002: supplier feed values that looked like PHP objects
- Severity: Critical. Points: 25.
- The problem: imports write post and term data in bulk with SQL, which skips the step WordPress normally uses to make sure text that looks like serialized PHP stays text. A feed value written in PHP’s object format was stored as is and turned into a PHP object when the product was read, which broke product pages.
- The fix: such values are stored as text, exactly as WordPress stores them, at every place feed values become post, term or custom-field data. Ordinary serialized lists still import as before. Fixed in 3.72.0, with two further cases closed by the follow-up reviews before release.
SECURITY-003: custom PHP functions and the site’s file-editing policy
- Severity: High. Points: 25.
- The problem: PHP written into individual column mappings could be saved by any administrator even when the site disables file editing, and on multisite a site administrator who is not a network super admin could save and run PHP.
- The fix: adding or changing custom PHP now needs the WordPress “edit plugins” permission, which WordPress itself withholds when file editing is disabled and gives only to super admins on multisite. PHP already saved on an import can still be saved again unchanged. Fixed in 3.69.0.
SECURITY-013: PHP in variation grouping options
- Severity: Critical. Points: 0 at the time it was found (it was found in the second review, after the first scoring).
- The problem: four variation options (grouping, parent title, parent SKU and parent match) can be set to run a PHP function. The checks added for SECURITY-003, and the rule that MCP tools never store PHP, did not look at these options.
- The fix: those options are treated as PHP everywhere: MCP tools and remote demo installs refuse them, and changing them needs the same “edit plugins” permission. Fixed in 3.70.0, with a gap found by the third review closed in 3.71.0.
SECURITY-004: background runs on multisite
- Severity: High. Points: 25.
- The problem: on a multisite network, background imports started from a sub-site ran without naming that sub-site, so they ran the main site’s import with the same number.
- The fix: every background process names the site it belongs to. Fixed in 3.69.0.
SECURITY-005: New Import file choice
- Severity: Medium. Points: 25.
- The problem: the New Import request accepted a full server path as the source file, and the row preview would then show the contents of that file.
- The fix: New Import accepts only files in the plugin’s import folder. Fixed in 3.69.0.
SECURITY-006: feed passwords on redirects
- Severity: Low. Points: 15.
- The problem: a username and password included in a feed URL were sent on to whichever server the feed’s host redirected to.
- The fix: they are dropped when a redirect leads to a different server; a same-server upgrade from http to https keeps them. Fixed in 3.69.0, refined in 3.70.0.
SECURITY-007: spreadsheet formulas in the error report
- Severity: Low. Points: 10.
- The problem: the import error report download did not neutralise cells that a spreadsheet would run as formulas, and the Lite edition did not include the escaping at all.
- The fix: every cell is escaped, in every edition. Fixed in 3.69.0.
SECURITY-008: direct-access guards
- Severity: Low. Points: 40 (two files).
- The problem: two PHP files could be requested directly, which on some server configurations showed the server’s file path.
- The fix: both files exit immediately when requested directly. Fixed in 3.69.0.
SECURITY-009: internal notes in the plugin files
- Severity: Low. Points: 15.
- The problem: two internal development notes were included in the paid plugin’s files.
- The fix: removed from the plugin. Fixed in 3.69.0.
SECURITY-012: import source files on hosts that do not block the folder
- Severity: Low. Points: 15.
- The problem: source files are kept in the uploads folder under their real names, because many customers replace them from the command line before re-running an import. The folder is protected for Apache and LiteSpeed, but nginx ignores that protection, so on an nginx host without its own rule a file could be downloaded by anyone who guessed its name.
- The fix: the Imports screen checks, from the administrator’s browser, whether the folder can be read from the web. If it can, it shows the server rule to add (nginx, Apache and LiteSpeed) and stores new uploads under unguessable names until the server is fixed, while showing the original names everywhere in the plugin. Hosts that block the folder keep real names. Fixed in 3.72.1.
What the review covered
| Area | Result | Evidence |
|---|---|---|
| Authentication, authorisation, object access and request forgery | Checked | Every admin request checks a nonce and a capability; there are no logged-out handlers; REST routes need administrator rights except the scheduled-import trigger, which needs a signed token; MCP tools are split into read, author and confirmed-run levels; custom PHP needs the “edit plugins” permission. |
| SQL injection | Checked | All 1,059 database calls classified; configuration values that reach queries are checked when saved and again where the query is built. |
| Cross-site scripting | Checked | All admin, email and download output escaped for its context, including the new folder notice and file-name labels. |
| Server-side request forgery, redirects and headers | Checked | Remote fetches use WordPress’s safe request functions, which refuse private and internal addresses; credentials are not forwarded across servers. |
| File upload and path traversal | Checked | Every upload and file choice is confined to the plugin’s import folder. |
| Remote code execution and unsafe deserialisation | Checked | Custom PHP only in the paid edition and only for users allowed to edit plugins; feed values cannot become PHP objects; all of the plugin’s own decoding refuses objects. |
| XML parsing | Checked | Document type declarations are refused and network access is disabled while parsing. |
| Secrets, privacy and data exposure | Checked | Nothing secret or personal in the paid or Lite release files. |
| Business logic and concurrency | Checked | Run locking, stop and fail handling, scheduled triggers and confirmations. |
| Dependencies and supply chain | Checked | Bundled libraries inventoried; no development packages ship. |
| JWT, GraphQL, server-side templates | Not applicable | None used. |
The reviews also re-ran the plugin’s own test suites, including on MySQL 8 and MariaDB, and the paid and Lite release packages were built and inspected.
Not scored
- The Import Manager role is designed to run imports on behalf of an AI agent or a person. Imports can create any kind of post, coupons included, with raw HTML, so the role should only be given to accounts you would trust like a shop manager with unfiltered HTML. This is documented in the plugin and the knowledge base.
- A few hardening items with no way for an attacker to reach them, such as an internal escaping helper that only ever receives already-cleaned file names.
- Repository-only housekeeping that never shipped in any release.
