[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f794Uh-mkCWEYFPYJ5z-6ERiGxDXf9z8GSWBy_dZOv7w":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":11,"severity":12,"cvss_score":13,"cvss_vector":14,"vuln_type":15,"published_date":16,"updated_date":17,"references":18,"days_to_patch":20,"patch_diff_files":21,"patch_trac_url":9,"research_status":25,"research_verified":26,"research_rounds_completed":27,"research_plan":28,"research_summary":9,"research_vulnerable_code":9,"research_fix_diff":9,"research_exploit_outline":9,"research_model_used":29,"research_started_at":30,"research_completed_at":31,"research_error":9,"poc_status":9,"poc_video_id":9,"poc_summary":9,"poc_steps":9,"poc_tested_at":9,"poc_wp_version":9,"poc_php_version":9,"poc_playwright_script":9,"poc_exploit_code":9,"poc_has_trace":26,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":26,"source_links":32},"CVE-2026-7048","photo-gallery-by-10web-authenticated-contributor-sql-injection-via-orderby-shortcode-attribute","Photo Gallery by 10Web \u003C= 1.8.40 - Authenticated (Contributor+) SQL Injection via 'order_by' Shortcode Attribute","The Photo Gallery by 10Web – Mobile-Friendly Image Gallery plugin for WordPress is vulnerable to time-based blind SQL Injection via the 'order_by' parameter in all versions up to, and including, 1.8.40 due to insufficient escaping on the user supplied parameter and lack of sufficient preparation on the existing SQL query. This makes it possible for authenticated attackers, with contributor-level access and above, to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database. This is exploitable by embedding a malicious shortcode in a post or draft, allowing the injected SQL to execute when the shortcode is rendered.","photo-gallery",null,"\u003C=1.8.40","1.8.41","medium",6.5,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:H\u002FI:N\u002FA:N","Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')","2026-05-27 19:36:32","2026-05-28 07:43:43",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F27394b03-3604-4fb0-950f-e1f838cabb05?source=api-prod",1,[22,23,24],"framework\u002FWDWLibrary.php","photo-gallery.php","readme.txt","researched",false,3,"# Exploitation Research Plan: CVE-2026-7048 - Photo Gallery SQL Injection\n\n## 1. Vulnerability Summary\nThe **Photo Gallery by 10Web** plugin (\u003C= 1.8.40) is vulnerable to an authenticated time-based blind SQL Injection. The vulnerability exists because the plugin fails to properly sanitize and prepare the `order_by` attribute within the `[Best_Wordpress_Gallery]` shortcode before incorporating it into a database query. This allows an attacker with **Contributor** level access or higher to execute arbitrary SQL commands by embedding a malicious shortcode into a post or draft.\n\n## 2. Attack Vector Analysis\n*   **Endpoint**: Standard WordPress post\u002Fpage rendering (or `admin-ajax.php` if the shortcode triggers an AJAX load).\n*   **Vulnerable Attribute**: `order_by` inside the `Best_Wordpress_Gallery` shortcode.\n*   **Authentication**: Authenticated user with at least `Contributor` privileges (required to save\u002Fpreview posts containing shortcodes).\n*   **Preconditions**: \n    1.  The Photo Gallery plugin must be active.\n    2.  At least one Gallery must exist in the system (to ensure the SQL query that uses `order_by` is executed).\n\n## 3. Code Flow\n1.  **Registration**: `photo-gallery.php` registers the shortcode: \n    `add_shortcode('Best_Wordpress_Gallery', array($this, 'shortcode'));`\n2.  **Parsing**: When a post containing `[Best_Wordpress_Gallery order_by=\"...\"]` is rendered, WordPress calls the `shortcode()` method in the `BWG` class.\n3.  **Data Processing**: The `shortcode()` method extracts attributes. The `order_by` attribute is passed down to a \"Model\" or \"Controller\" responsible for fetching images from the database (likely using `WDWLibrary::get()` logic or direct attribute access).\n4.  **SQL Sink**: The value of `order_by` is concatenated into an `ORDER BY` clause of a `$wpdb->get_results()` call. Because `wpdb->prepare` cannot safely parameterize `ORDER BY` column names using `%s` (it adds single quotes, which breaks the column reference), the developer likely used direct string concatenation without whitelisting or sufficient escaping.\n\n## 4. Nonce Acquisition Strategy\nThis vulnerability is exploited via a shortcode embedded in a post.\n*   **Initial Rendering**: Viewing a published post or previewing a draft generally does **not** require a nonce for the initial shortcode execution.\n*   **AJAX Fallback**: If the gallery loads data via AJAX (specifically via the `bwg_frontend_data` action registered in `photo-gallery.php`), a nonce might be required.\n*   **Strategy**:\n    1.  Create a post with the shortcode using `wp-cli`.\n    2.  Navigate to the post URL.\n    3.  If the injection triggers on page load, no nonce is needed.\n    4.  If the injection occurs during an AJAX call, use `browser_eval` to extract the nonce from the localized script:\n        `browser_eval(\"window.bwg_objectsL10n?.bwg_nonce\")` (inferred based on plugin naming conventions, actual key to be verified by the agent in the page source).\n\n## 5. Exploitation Strategy\nThe agent will perform a time-based blind SQL injection using the `SLEEP()` function.\n\n1.  **Preparation**: Ensure a gallery exists to trigger the query.\n2.  **Payload Construction**:\n    The `order_by` parameter is injected into an `ORDER BY` clause. A subquery-based sleep is most reliable here.\n    *   **Payload**: `(SELECT 1 FROM (SELECT(SLEEP(5)))a)`\n3.  **Request Execution**:\n    *   Log in as a Contributor.\n    *   Create a draft post: `[Best_Wordpress_Gallery id=\"1\" order_by=\"(SELECT 1 FROM (SELECT(SLEEP(5)))a)\"]`.\n    *   Request the preview URL of that post using the `http_request` tool.\n    *   Measure the response time.\n4.  **Data Extraction (Proof of Concept)**:\n    To prove data exfiltration, check the first character of the database version:\n    *   **Payload**: `(CASE WHEN (SUBSTRING(version(),1,1)='8') THEN id ELSE (SELECT 1 FROM (SELECT(SLEEP(5)))a) END)`\n\n## 6. Test Data Setup\n1.  **User Creation**: Create a contributor user.\n    `wp user create attacker attacker@example.com --role=contributor --user_pass=password`\n2.  **Gallery Creation**: Use `wp-cli` or `wp eval` to ensure a gallery exists in the `{prefix}bwg_gallery` table.\n    ```bash\n    wp eval 'global $wpdb; $wpdb->insert($wpdb->prefix . \"bwg_gallery\", [\"name\" => \"Test Gallery\", \"slug\" => \"test-gallery\", \"published\" => 1]);'\n    ```\n3.  **Post Creation**: Create a post with the shortcode.\n    `wp post create --post_type=post --post_status=publish --post_author=$(wp user get attacker --format=ids) --post_content='[Best_Wordpress_Gallery id=\"1\" order_by=\"id\"]' --post_title='Gallery Page'`\n\n## 7. Expected Results\n*   **Normal Request**: A request to the post with `order_by=\"id\"` should return in \u003C 1 second.\n*   **Malicious Request**: A request with the `SLEEP(5)` payload should take approximately 5 seconds (or a multiple thereof, depending on how many times the query executes for the gallery view).\n*   **HTTP Status**: 200 OK (The SQL error is suppressed or the sleep executes before the response is sent).\n\n## 8. Verification Steps\nAfter the `http_request` confirms the time delay:\n1.  Verify the database state was not corrupted (though this is a `SELECT` injection).\n2.  Check the WordPress `debug.log` (if enabled) for any SQL syntax errors that might provide clues to the query structure:\n    `tail -n 20 \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fdebug.log`\n\n## 9. Alternative Approaches\nIf the shortcode rendering does not immediately trigger the sleep:\n1.  **AJAX Endpoint**: Targeted exploitation of the `wp_ajax_bwg_frontend_data` or `wp_ajax_nopriv_bwg_frontend_data` actions.\n    *   **Action**: `bwg_frontend_data`\n    *   **Parameters**: `action=bwg_frontend_data&order_by=(SELECT...SLEEP(5))&nonce=[extracted_nonce]`\n2.  **Boolean-Based**: If the gallery sorting changes visibly based on the `order_by` logic (e.g., using `IF(1=1, id, name)`), use boolean-based exfiltration.\n3.  **IDOR Combination**: If `id=\"1\"` does not exist, iterate through `id` values until a valid gallery triggers the query.","gemini-3-flash-preview","2026-06-04 16:38:22","2026-06-04 16:38:58",{"type":33,"vulnerable_version":34,"fixed_version":11,"vulnerable_browse":35,"vulnerable_zip":36,"fixed_browse":37,"fixed_zip":38,"all_tags":39},"plugin","1.8.40","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fphoto-gallery\u002Ftags\u002F1.8.40","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fphoto-gallery.1.8.40.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fphoto-gallery\u002Ftags\u002F1.8.41","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fphoto-gallery.1.8.41.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fphoto-gallery\u002Ftags"]