{"id":274352,"date":"2026-04-06T18:17:02","date_gmt":"2026-04-06T18:17:02","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/smstunnel\/"},"modified":"2026-07-08T18:15:04","modified_gmt":"2026-07-08T18:15:04","slug":"smstunnel","status":"publish","type":"plugin","link":"https:\/\/lmo.wordpress.org\/plugins\/smstunnel\/","author":23084331,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.9","stable_tag":"1.0.9","tested":"6.9.4","requires":"5.0","requires_php":"7.4","requires_plugins":null,"header_name":"SMSTunnel","header_author":"SMSTunnel.io","header_description":"SMS gateway using your own phone. Provides API integration, settings, and SMS-based Two-Factor Authentication for WordPress login.","assets_banners_color":"","last_updated":"2026-07-08 18:15:04","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/smstunnel.io\/plugins\/smstunnel","header_author_uri":"https:\/\/smstunnel.io","rating":2,"author_block_rating":0,"active_installs":0,"downloads":266,"num_ratings":1,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","changelog"],"tags":{"1.0.6":{"tag":"1.0.6","author":"nicunarcisbodea","date":"2026-04-06 18:23:41"},"1.0.9":{"tag":"1.0.9","author":"nicunarcisbodea","date":"2026-07-08 18:15:04"}},"upgrade_notice":{"1.0.2":"<p>Security update - removed external QR services, fixed XSS vulnerabilities, improved script enqueueing.<\/p>","1.0.1":"<p>Security update with improved input sanitization and output escaping.<\/p>"},"ratings":{"1":0,"2":1,"3":0,"4":0,"5":0},"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3500086,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3500086,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256},"icon.svg":{"filename":"icon.svg","revision":3500086,"resolution":false,"location":"assets","locale":false}},"assets_banners":[],"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.6","1.0.9"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3509584,"resolution":"1","location":"assets","locale":"","width":1739,"height":1728},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3509584,"resolution":"2","location":"assets","locale":"","width":1971,"height":1827},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3509584,"resolution":"3","location":"assets","locale":"","width":1209,"height":1096},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3509584,"resolution":"4","location":"assets","locale":"","width":2730,"height":1721}},"screenshots":{"1":"Connect SMSTunnel to your account using multiple sign-in methods - API key, Google, or Facebook - right from the plugin settings page","2":"Advanced settings panel featuring Two-Factor Authentication for WordPress login, interface language selection, end-to-end encryption toggle, and one-click connection testing","3":"Send a test SMS directly from the admin panel to verify your configuration works end-to-end","4":"Quick Setup wizard - scan the QR code with the SMSTunnel mobile app to pair your WordPress site in seconds"}},"plugin_section":[],"plugin_tags":[9211,1890,4906,711,1909],"plugin_category":[41],"plugin_contributors":[259570,229162],"plugin_business_model":[],"class_list":["post-274352","plugin","type-plugin","status-publish","hentry","plugin_tags-2fa","plugin_tags-gateway","plugin_tags-notifications","plugin_tags-sms","plugin_tags-two-factor-authentication","plugin_category-communication","plugin_contributors-narcisbodea","plugin_contributors-nicunarcisbodea","plugin_committers-nicunarcisbodea"],"banners":[],"icons":{"svg":"https:\/\/ps.w.org\/smstunnel\/assets\/icon.svg?rev=3500086","icon":"https:\/\/ps.w.org\/smstunnel\/assets\/icon.svg?rev=3500086","icon_2x":false,"generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/smstunnel\/assets\/screenshot-1.png?rev=3509584","caption":"Connect SMSTunnel to your account using multiple sign-in methods - API key, Google, or Facebook - right from the plugin settings page"},{"src":"https:\/\/ps.w.org\/smstunnel\/assets\/screenshot-2.png?rev=3509584","caption":"Advanced settings panel featuring Two-Factor Authentication for WordPress login, interface language selection, end-to-end encryption toggle, and one-click connection testing"},{"src":"https:\/\/ps.w.org\/smstunnel\/assets\/screenshot-3.png?rev=3509584","caption":"Send a test SMS directly from the admin panel to verify your configuration works end-to-end"},{"src":"https:\/\/ps.w.org\/smstunnel\/assets\/screenshot-4.png?rev=3509584","caption":"Quick Setup wizard - scan the QR code with the SMSTunnel mobile app to pair your WordPress site in seconds"}],"raw_content":"<!--section=description-->\n<p>SMSTunnel transforms your Android phone into a powerful SMS gateway for WordPress.<\/p>\n\n<h4>Key Features<\/h4>\n\n<ul>\n<li>Use Your Own Phone - No third-party SMS gateway costs<\/li>\n<li>Two-Factor Authentication - Secure WordPress login with SMS 2FA<\/li>\n<li>End-to-End Encryption - Messages encrypted with RSA keys<\/li>\n<li>Quick Setup - Scan QR code from the mobile app<\/li>\n<\/ul>\n\n<h3>Emergency 2FA recovery<\/h3>\n\n<p>When SMS 2FA is required and the \"server fallback\" option is OFF (the secure default), a total SMS outage would lock every admin out of wp-login - and the fallback option can only be changed while logged in. To recover, edit wp-config.php over FTP\/SSH (or use WP-CLI) and add this line above the \"That's all, stop editing\" comment:<\/p>\n\n<pre><code>define('SMSTUNNEL_2FA_EMERGENCY_BYPASS', true);\n<\/code><\/pre>\n\n<p>While this constant is true, admins can log in without entering a 2FA code. Every use is recorded in the PHP error log. Remove the line as soon as SMS delivery is restored. Advanced users can instead hook the 'smstunnel_2fa_emergency_bypass' filter and return true.<\/p>\n\n<h3>External Services<\/h3>\n\n<p>This plugin connects to external services to provide certain functionality. Below are the details of each service:<\/p>\n\n<h4>SMSTunnel API<\/h4>\n\n<ul>\n<li><strong>Purpose<\/strong>: Core service that enables the plugin to communicate with the SMSTunnel mobile app for sending SMS messages from your phone<\/li>\n<li><strong>When data is sent<\/strong>: During Quick Setup (when pairing via QR code), when sending SMS messages, and when verifying API connections<\/li>\n<li><strong>Data sent<\/strong>:\n\n<ul>\n<li>During setup: Site URL, site token (random identifier), admin email (for account creation)<\/li>\n<li>When sending SMS: Phone number, message content (encrypted if E2E is enabled), API key for authentication<\/li>\n<\/ul><\/li>\n<li><strong>Service provider<\/strong>: SMSTunnel.io (NARBOWEB SRL)<\/li>\n<li><strong>Privacy Policy<\/strong>: https:\/\/smstunnel.io\/privacy<\/li>\n<li><strong>Terms of Service<\/strong>: https:\/\/smstunnel.io\/terms<\/li>\n<\/ul>\n\n<h4>SMSTunnel Authentication<\/h4>\n\n<ul>\n<li><strong>Purpose<\/strong>: Optional sign-in via Google, Facebook, or email to link your SMSTunnel account with WordPress<\/li>\n<li><strong>When data is sent<\/strong>: Only when the admin uses the \"Connect with Google\/Facebook\/Email\" options on the plugin settings page<\/li>\n<li><strong>Data sent<\/strong>:\n\n<ul>\n<li>Google\/Facebook: Redirects to smstunnel.io\/auth\/google or smstunnel.io\/auth\/facebook with a callback URL and CSRF state token<\/li>\n<li>Email login: Email and password sent to smstunnel.io\/api\/v1\/auth\/login<\/li>\n<li>After authentication: Fetches user profile from smstunnel.io\/auth\/me and creates an API key via smstunnel.io\/api\/v1\/api-keys<\/li>\n<\/ul><\/li>\n<li><strong>Service provider<\/strong>: SMSTunnel.io (NARBOWEB SRL)<\/li>\n<li><strong>Privacy Policy<\/strong>: https:\/\/smstunnel.io\/privacy<\/li>\n<li><strong>Terms of Service<\/strong>: https:\/\/smstunnel.io\/terms<\/li>\n<\/ul>\n\n<p><strong>Note<\/strong>: QR codes are generated locally using an embedded JavaScript library (qrcode.min.js). No external QR code generation services are used. All SMS messages are sent through your own Android phone - the SMSTunnel server only acts as a relay to connect WordPress with your phone.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin to \/wp-content\/plugins\/<\/li>\n<li>Activate the plugin<\/li>\n<li>Install the SMSTunnel app on your Android phone from https:\/\/smstunnel.io\/integrations\/android-app<\/li>\n<li>Go to SMSTunnel &gt; Quick Setup and scan the QR code with the app<\/li>\n<\/ol>\n\n<!--section=changelog-->\n<h4>1.0.9<\/h4>\n\n<ul>\n<li>Security: Added an emergency break-glass bypass for 2FA so admins are not permanently locked out of wp-login during a total SMS outage (fail-closed fallback). Enable by adding define('SMSTUNNEL_2FA_EMERGENCY_BYPASS', true); to wp-config.php (see \"Emergency 2FA recovery\" in Installation), then remove it once access is restored. Every activation is written to the PHP error log.<\/li>\n<li>Fix: API validation errors returned by the server as an array (NestJS class-validator) are now flattened to a readable string instead of storing the literal \"Array\" (PHP 8 \"Array to string conversion\").<\/li>\n<li>Fix: The read endpoints (connection test, usage, message status, received messages) now handle HTTP 429 rate-limit responses consistently with the send endpoints.<\/li>\n<li>Fix: The login 2FA code request is now idempotent - reloading the login page reuses the existing code instead of resending an SMS and burning a rate-limit slot.<\/li>\n<li>Fix: Uninstall now also removes the locally generated RSA key pair (smstunnel_public_key, smstunnel_private_key) so no key material is left orphaned.<\/li>\n<\/ul>\n\n<h4>1.0.8<\/h4>\n\n<ul>\n<li>Added: Optional hybrid end-to-end encryption (v2) using AES-256-GCM for the message payload plus RSA-OAEP for the AES key, removing the ~245 byte size limit of legacy RSA encryption for long SMS messages<\/li>\n<li>Added: \"Use hybrid encryption (v2)\" toggle in End-to-End Encryption settings (default OFF; requires an up-to-date SMSTunnel app that advertises v2 support)<\/li>\n<li>Added: Pairing now stores the device's advertised E2E version so the encryptor only uses v2 for capable devices; falls back to v1 otherwise<\/li>\n<li>Compatibility: When the hybrid toggle is OFF (default), encryption behaviour is unchanged (RSA PKCS#1 v1.5), so existing paired devices keep working<\/li>\n<\/ul>\n\n<h4>1.0.7<\/h4>\n\n<ul>\n<li>Security: Added rate limiting to public (nopriv) 2FA SMS endpoints to prevent SMS bombing (3 codes \/ 15 min per IP on login, 60s cooldown + 5\/hour on phone-setup verification)<\/li>\n<li>Security: Added brute-force lockout on 2FA code verification (max 5 wrong attempts, then the code is invalidated) and switched to constant-time comparison (hash_equals)<\/li>\n<li>Security: 2FA server fallback (\"login without 2FA when SMS unavailable\") now defaults to OFF to avoid fail-open authentication<\/li>\n<li>Security: Client IP detection now relies solely on REMOTE_ADDR (validated) and no longer trusts spoofable proxy headers<\/li>\n<li>Security: REST \/setup-callback site token now compared in constant time (hash_equals)<\/li>\n<li>Security: Hardened admin-settings.js E2E pairing UI to use .text() for dynamic\/i18n values (DOM XSS)<\/li>\n<li>Security: Added rate-limit (HTTP 429) handling for the SMS API client<\/li>\n<li>Security: Strict in_array() comparisons for role checks<\/li>\n<li>Fix: Synchronized uninstall cleanup with the option keys actually used by the plugin<\/li>\n<li>Added: Shared recipient validation helpers (smstunnel_validate_e164, smstunnel_is_premium_number, smstunnel_sanitize_recipient) for satellite form plugins<\/li>\n<\/ul>\n\n<h4>1.0.6<\/h4>\n\n<ul>\n<li>Security: Added nonce validation (check_ajax_referer) to all nopriv AJAX endpoints including 2FA login and phone setup<\/li>\n<li>Security: Fixed DOM XSS in quick-setup.js, social-login.js, and admin-settings.js - all server\/URL data now uses .text() instead of .html()<\/li>\n<li>Security: Escaped all remaining unescaped outputs in SMS history table<\/li>\n<li>Security: API key verification now uses X-API-Key header and configurable server URL (consistent with rest of plugin)<\/li>\n<li>Fix: Corrected AJAX action name mismatch for API key verification<\/li>\n<li>Documentation: Added SMSTunnel Authentication section to External Services (auth endpoints)<\/li>\n<\/ul>\n\n<h4>1.0.5<\/h4>\n\n<ul>\n<li>Security: Moved all inline JavaScript to external files using wp_enqueue_script and wp_localize_script<\/li>\n<li>Security: Added OAuth state parameter validation to prevent CSRF attacks on OAuth callback<\/li>\n<li>Security: REST API \/setup-callback now validates site_token in permission_callback instead of callback body<\/li>\n<li>Security: Removed all wp_add_inline_script calls - all scripts now in external .js files<\/li>\n<li>Code: Added $request parameter to all REST API permission_callback methods for PHP 8+ compatibility<\/li>\n<\/ul>\n\n<h4>1.0.4<\/h4>\n\n<ul>\n<li>Documentation: Updated External Services section with complete service documentation<\/li>\n<\/ul>\n\n<h4>1.0.3<\/h4>\n\n<ul>\n<li>Security: Replaced __return_true with documented custom permission_callback methods<\/li>\n<\/ul>\n\n<h4>1.0.2<\/h4>\n\n<ul>\n<li>Security: Replaced inline scripts with wp_add_inline_script for proper enqueueing<\/li>\n<li>Security: Fixed XSS vulnerabilities by using textContent instead of innerHTML for server responses<\/li>\n<li>Security: Removed external QR code generation services (Google Charts, QR Server API) - all QR codes now generated locally<\/li>\n<li>Security: Improved escaping for all JavaScript strings using esc_js()<\/li>\n<li>Documentation: Updated External Services section to accurately reflect service usage<\/li>\n<\/ul>\n\n<h4>1.0.1<\/h4>\n\n<ul>\n<li>Security: Added sanitization callbacks for all settings<\/li>\n<li>Security: Fixed escape output for translatable strings<\/li>\n<li>Security: Database queries now use prepared statements<\/li>\n<li>Security: Changed wp_redirect to wp_safe_redirect<\/li>\n<li>Security: Changed mt_rand to wp_rand<\/li>\n<li>Compatibility: Tested up to WordPress 6.7.1<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release<\/li>\n<\/ul>","raw_excerpt":"Send SMS messages directly from WordPress using your own Android phone as the SMS gateway.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/274352","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=274352"}],"author":[{"embeddable":true,"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/nicunarcisbodea"}],"wp:attachment":[{"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=274352"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=274352"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=274352"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=274352"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=274352"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=274352"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}