WP Manifestindependent plugin directory
manifest / i18n / multilingual-tools

Multilingual Tools WP Registry grade D+. High-severity findings · 4 findingsWP RegistryHigh-severity findings · 4 findingsOpen the reportD+ #3 in Languages & Localization

Set of tools related to WPML plugin bundle. Created with tendency to ease WPML compatibility testing process.

★ 40stars
171kcomposer installs
2.3.2latest · 2mo ago

Install

Download source zip No release zip yet

This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/onthegosystems/multilingual-tools/archive/refs/heads/master.zip

On Packagist as otgs/multilingual-tools:

composer require otgs/multilingual-tools
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

Multilingual Tools are set of tools related to WPML plugin bundle. Created with tendency to ease multilingual testing process, and help out WordPress developers who applied to GoGlobal Program.

Key features

  • Auto generate strings for translations
  • Add language information to post duplicate
  • Generate WPML config file ( wpml-config.xml )
  • Assist with Custom Fields translation preferences

Requirements

For this plugin to work you will need:

  • WPML Multilingual CMS
  • WPML String Translation

All plugins can be downloaded from WPML.org

Contribute

If you spot any bug or have idea for useful feature feel free to contribute via GitHub.

Releases

17 releases.

Tag
Published
2.3.2 latest
Aug 7, 2026 2mo ago
Mar 4, 2026 7mo ago
Oct 16, 2025 1 year ago
Jun 7, 2024 2 years ago
Mar 26, 2024 2 years ago
Oct 13, 2023 3 years ago
Nov 26, 2020 5 years ago
Mar 31, 2020 6 years ago
Sep 17, 2019 7 years ago
Mar 28, 2018 8 years ago
Mar 2, 2018 8 years ago
Feb 15, 2018 8 years ago
Jul 10, 2017 9 years ago
Mar 15, 2017 9 years ago
Feb 1, 2017 9 years ago
Jan 18, 2017 9 years ago
Dec 27, 2016 9 years ago

These releases are tags only. The author does not attach a packaged zip, so there are no download counts to report.

D+ grade

Security

Multilingual Tools 2.3.2 · audited by WP Registry

High-severity findings.

3 high 1 medium
Audited release
2.3.2
Findings
4
Worst severity
high
Content hash
43f64cc3875624b7cdf655a9…

Findings

  • high Stored XSS via unsanitized custom-field sample values on the CF helper screen

    xss_stored

    The Custom Field Settings Helper (admin.php?page=cf-translations, manage_options) loads one sample meta_value per public (non-underscore) meta_key and prints it inside <code> with no escaping. Custom field values are not passed through kses on save, so an Author (or anyone who can write public post meta via the Custom Fields panel or REST) can store <script> or an event-handler payload under a key such as evil_field. When an administrator later opens this helper — the page exists specifically to review those fields — the sample column executes in wp-admin. get_custom_fields() only excludes underscore-prefixed and a small prefix denylist (acfml, attribute_pa, wpml, wpform), so ordinary public keys are in scope. Distinct from Finding 1: the write path is post meta, not wpml_ctt_settings.

    menus/settings/custom-fields-translation.php:56-71

    Recommendation

    Echo sample values with esc_html() (and esc_attr if moved into attributes). Do not print raw post meta into admin HTML. Optionally restrict the helper to keys the current user could not have written, but escaping is the actual fix.

  • high Stored XSS in the Elementor config-generator meta box via raw _elementor_data dump

    xss_stored

    When Elementor is active, MLTools_Elementor_Config_Generator adds a meta box on every post type that has non-empty _elementor_data. The 'RAW value from _elementor_data (JSON)' and print_r debug sections echo $section['content'] into a <textarea> with no esc_textarea. The missing-widgets XML is also htmlspecialchars_decode()'d before echo, which restores a </textarea> sequence SimpleXML would have encoded. _elementor_data is post meta (not kses'd as post_content), so an Author with Elementor can put </textarea><script>…</script> in a widget text field or a crafted widgetType. An administrator who later edits that post (classic pending-review / 'edit this page' flow) loads the meta box and executes the script in wp-admin. The meta box is registered with add_meta_box and no extra capability, so it appears for anyone who can edit the post.

    inc/class-mltools-elementor-config-generator.php:225-272

    Recommendation

    Escape every debug dump with esc_textarea() (or htmlspecialchars with ENT_QUOTES) and do not htmlspecialchars_decode XML before placing it in HTML. Consider limiting the meta box to manage_options; this is a developer inspection UI, not an author-facing editor control.

  • high Reflected XSS in admin settings forms via unescaped REQUEST_URI

    xss_reflected

    Three settings forms set action to echo $_SERVER['REQUEST_URI'] with no escaping. Those templates are loaded only for manage_options users, but WordPress does not apply wp_magic_quotes() to REQUEST_URI, and extra query args do not change get_current_screen()->id. An administrator who opens admin.php?page=mt-settings&x="><script>…</script> (or the same on the duplicate-strings / shortcode-helper forms which share the pattern) reflects the payload into the form action attribute and executes it in wp-admin. $_SERVER['REQUEST_URI'] is attacker-controlled via the request line.

    menus/settings/auto-translate-strings.php:15-16

    Recommendation

    Use action="" or esc_url( admin_url( 'admin.php?page=mt-settings' ) ). Never echo REQUEST_URI into HTML. Same fix on auto-translate-duplicate.php and shortcode-helper.php.

  • medium Shortcode debug output echoes captured attribute values without escaping

    xss_stored

    When an administrator has enabled Shortcode Helper debug (nonce-protected, so not Finding 1), mltools_shortcode_helper_add_hooks() attaches shutdown printers for every logged-in user on the front end. mltools_shortcode_helper_unregistered_print_captured_values() echoes shortcode $tag and $attr_value into HTML with no escaping; the same values are printed on the Shortcode Helper admin table. Captured attributes come from do_shortcode_tag / shortcode_atts on real page content and are stored in _mltools_shortcode_helper_captured_values. A Contributor who publishes a shortcode whose attribute contains <script> (or breaks out of the <span>) XSS's every logged-in visitor while debug is on, and any admin who opens Settings → Shortcode Helper. This is the plugin's intended debug mode, but the sink is still an unescaped HTML echo of user-controlled content.

    inc/wpml-compatibility-test-tools.functions.php:462-478

    Recommendation

    Escape $tag, $attr_name, and $attr_value with esc_html() in both the front-end shutdown printer and menus/settings/shortcode-helper.php. Restrict debug HTML to manage_options users, not is_user_logged_in().

WP Registry hashes the installable build and reports on that exact bytes-for-bytes copy. Embargoed findings are withheld until they are disclosed, so a clean verdict means nothing public is outstanding. WP Manifest does not audit code itself.