Plugin Directory

Changeset 3449367


Ignore:
Timestamp:
01/29/2026 08:45:37 AM (2 months ago)
Author:
pechenki
Message:

fix js XSS

Location:
telsender/trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • telsender/trunk/clasess/TelsenderCore.php

    r3059503 r3449367  
    1818{
    1919
    20     public $version = '1.14.13';
     20    public $version = '1.14.14';
    2121
    2222    /**
     
    8080
    8181
     82
    8283    }
    8384
     
    111112    public function tscfwc_setting_page()
    112113    {
     114
     115
    113116        load_plugin_textdomain('telsender', false, TELSENDER_DIR_NAME . '/languages/');
    114117        wp_enqueue_style('multi-select',TELSENDER_DIR_URL . 'css/multiselect.css',false,$this->version);
    115118        wp_enqueue_script('multi-select.',TELSENDER_DIR_URL . 'js/multiselect.js');
    116         wp_enqueue_script('ajax', TELSENDER_DIR_URL . 'js/ajax.js',false,false,$this->version);
     119        wp_enqueue_script('ajax-telsender', TELSENDER_DIR_URL . 'js/ajax.js',false,$this->version);
    117120        wp_enqueue_style('telsender-css', TELSENDER_DIR_URL . 'css/telsender.css',false,$this->version);
     121
     122
     123        wp_localize_script('ajax-telsender', 'tscfwc_params', [
     124            'nonce' => wp_create_nonce('tscfwc_form_nonce')
     125        ]);
     126
    118127
    119128        if (isset($_POST['curssent'])) {
     
    374383    public function tscfwc_form_ajax_reqest()
    375384    {
    376         check_ajax_referer('true_security','security');
     385        check_ajax_referer('tscfwc_form_nonce', '_wpnonce');
    377386
    378387
  • telsender/trunk/index.php

    r3205024 r3449367  
    22/**
    33 * @package HOT
    4  * @version 1.14.5
     4 * @version 1.14.15
    55 */
    66/*
     
    88Description: Плагін відправляє заявки з форм у телеграм канал
    99Author: Pechenki
    10 Version: 1.14.14
     10Version: 1.14.15
    1111Author URI: https://coder.org.ua/dev/wordpress/telsender
    1212*/
  • telsender/trunk/js/ajax.js

    r3029269 r3449367  
    1 /*telegramSender ajax*/
    2 
    3 jQuery(document).ready(function () {
    4     $ = jQuery
    5 
    6     function animation() {
    7         $('#telsetingven').html('Load...');
    8 
     1jQuery(document).ready(function ($) {
     2    // Функція анімації для кнопки
     3    function setButtonState(btn, text, isDisabled = false) {
     4        $(btn).text(text).prop('disabled', isDisabled);
    95    }
    106
    11     $('body').on("click", "#telsetingven", function () {
    12 
    13 
    14         const dats = $("#formsetinvendor").serialize();
     7    // AJAX збереження налаштувань
     8    $('body').on("click", "#telsetingven", function (e) {
     9        e.preventDefault();
     10        const $btn = $(this);
     11        const formData = $("#formsetinvendor").serialize();
    1512
    1613        $.ajax({
    1714            type: 'POST',
    1815            url: ajaxurl,
    19             data: 'action=tscfwc_form_reqest&' + dats,
    20             beforeSend: animation,
    21             success: function (data) {
    22                 $('#telsetingven').html('Saved');
    23 
    24 
     16            // Додаємо nonce для безпеки (має бути локалізований у PHP через wp_localize_script)
     17            data: 'action=tscfwc_form_reqest&_wpnonce=' + (window.tscfwc_params?.nonce || '') + '&' + formData,
     18            beforeSend: () => setButtonState($btn, 'Завантаження...', true),
     19            success: function (response) {
     20                setButtonState($btn, 'Збережено', false);
     21                setTimeout(() => setButtonState($btn, 'Зберегти'), 2000);
    2522            },
    26             error: function (xhr, str) {
    27                 alert('Помилка : ' + xhr.responseCode);
     23            error: function (xhr) {
     24                setButtonState($btn, 'Помилка', false);
     25                alert('Помилка : ' + xhr.status);
    2826            }
    2927        });
    3028    });
    3129
    32     $("input[value='no']").bind("click", function () {
    33         $('radioinput').css('display', 'none');
    34     });
    35 
    36     /*--------------------*/
    37     $("#sendKey").change(function () {
    38 
    39         if ($("#sendKey").is(":checked")) {
    40             $('.radioinputdefaul').hide();
    41             $('.con-def').hide();
    42             $('.radioinputkey').show();
    43             $('.con-key').show();
    44         } else {
    45             $('.con-def').show();
    46             $('.radioinputdefaul').show();
    47             $('.radioinputkey').hide();
    48             $('.con-key').hide();
    49         }
    50         /*--------------------*/
    51     });
    52     if ($("#sendKey").is(":checked")) {
    53         $('.radioinputdefaul').hide();
    54         $('.con-def').hide();
    55         $('.radioinputkey').show();
    56         $('.con-key').show();
    57     } else {
    58         $('.con-def').show();
    59         $('.radioinputdefaul').show();
    60         $('.radioinputkey').hide();
    61         $('.con-key').hide();
     30    // Перемикач відображення полів
     31    function toggleKeyVisibility() {
     32        const isChecked = $("#sendKey").is(":checked");
     33        $('.radioinputdefaul, .con-def').toggle(!isChecked);
     34        $('.radioinputkey, .con-key').toggle(isChecked);
    6235    }
    6336
    64     $("#selinfo,#wpforms_list").multiSelect({
    65         selectableHeader: "<div class=\'custom-header\'>All form</div>",
    66         selectionHeader: "<div class=\'custom-header\'>Send to telegram</div>"
     37    $("#sendKey").on("change", toggleKeyVisibility);
     38    toggleKeyVisibility(); // Запуск при завантаженні
    6739
    68     });
     40    // Ініціалізація плагінів (якщо вони підключені)
     41    if ($.fn.multiSelect) {
     42        $("#selinfo, #wpforms_list").multiSelect({
     43            selectableHeader: "<div class='custom-header'>Усі форми</div>",
     44            selectionHeader: "<div class='custom-header'>Відправляти в Telegram</div>"
     45        });
     46    }
    6947
    70     $('#tscfwc_status').selectize({
    71         plugins: ['remove_button'],
    72         delimiter: ',',
    73         persist: false,
    74         create: function (input) {
    75             return {
    76                 value: input,
    77                 text: input
    78             }
    79         }
    80     });
     48    if ($.fn.selectize) {
     49        $('#tscfwc_status').selectize({
     50            plugins: ['remove_button'],
     51            delimiter: ',',
     52            persist: false,
     53            create: (input) => ({ value: input, text: input })
     54        });
     55    }
    8156});
    8257
    83 
    84 
    85 let tokenstr = document.querySelector('#getUpdates');
    86 if (tokenstr){
    87     const token =  document.querySelector('[name="tscfwc_setting_token"]').value ?? '';
    88 
    89     let newurl = tokenstr.outerHTML.replaceAll('{token}',token)
    90 
    91     tokenstr.innerHTML = newurl
    92 
    93 }
    94 
    95 function telsenderInfo(){
    96     const token =  document.querySelector('[name="tscfwc_setting_token"]')?.value;
    97     const url  = `https://api.telegram.org/bot${token}/getUpdates`
    98     telsenderTestSend()
    99     fetch(url).then(res=>{
    100         res.json().then(response=>{
    101             telsenderOut(response)
    102         })
    103     })
     58/**
     59 * Оновлення посилання на getUpdates (БЕЗПЕЧНО)
     60 */
     61const tokenContainer = document.querySelector('#getUpdates');
     62if (tokenContainer) {
     63    const tokenInput = document.querySelector('[name="tscfwc_setting_token"]');
     64    if (tokenInput && tokenInput.value) {
     65        const originalHref = tokenContainer.getAttribute('href') || tokenContainer.textContent;
     66        // Оновлюємо атрибут href, а не весь HTML
     67        const secureUrl = originalHref.replace('{token}', encodeURIComponent(tokenInput.value));
     68        tokenContainer.href = secureUrl;
     69        tokenContainer.textContent = secureUrl; // Відображаємо текст посилання безпечно
     70    }
    10471}
    10572
    10673/**
    107  *
    108  * @param response
     74 * Отримання інформації про чати з Telegram
    10975 */
    110 function telsenderOut(response){
    111     let resultHtml =  document.querySelector('.result-tested')
    112     if (response.ok){
    113         let data = []
     76function telsenderInfo() {
     77    const tokenField = document.querySelector('[name="tscfwc_setting_token"]');
     78    if (!tokenField || !tokenField.value) {
     79        alert("Будь ласка, введіть токен бота");
     80        return;
     81    }
    11482
    115         response.result.forEach(res=>{
    116             if (res.my_chat_member){
    117                 data.push({
    118                     id:res.my_chat_member.chat.id,
    119                     name:res.my_chat_member.chat.title
    120                 })
    121             }
    122             if (res.message){
    123                 data.push({
    124                     id:res.message.from.id,
    125                     name:res.message.from.username
    126                 })
    127             }
     83    const token = tokenField.value;
     84    const url = `https://api.telegram.org/bot${token}/getUpdates`;
    12885
    129         })
    130         data = data.filter((v,i,a)=>a.findIndex(t=>(t.id === v.id))===i)
     86    // Візуальна індикація завантаження
     87    const resultContainer = document.querySelector('.result-tested');
     88    resultContainer.textContent = "Отримання даних...";
    13189
    132        let resultHtml =  document.querySelector('.result-tested')
    133         let html = ''
     90    telsenderTestSend(); // Викликаємо тестове повідомлення
    13491
    135         data.forEach(el=>{
    136             html +=`${el.name} :  <b >${el.id}</b> <span class="id-chat-list" title="Inset to form" onclick="insertId(${el.id})">&#10063</span> <br/>`
     92    fetch(url)
     93        .then(res => res.json())
     94        .then(response => telsenderOut(response))
     95        .catch(err => {
     96            resultContainer.textContent = "Помилка запиту: " + err.message;
     97        });
     98}
    13799
    138         })
    139         resultHtml.innerHTML = html
     100/**
     101 * Безпечний вивід списку чатів
     102 */
     103function telsenderOut(response) {
     104    const resultContainer = document.querySelector('.result-tested');
     105    resultContainer.innerHTML = ''; // Очищення контейнера
    140106
    141     }else{
    142         resultHtml.innerHTML = response.description
     107    if (!response.ok) {
     108        resultContainer.textContent = "Telegram API Error: " + (response.description || "Unknown");
     109        return;
     110    }
     111
     112    let data = [];
     113    response.result.forEach(res => {
     114        if (res.my_chat_member) {
     115            data.push({ id: res.my_chat_member.chat.id, name: res.my_chat_member.chat.title || "Чат без назви" });
     116        }
     117        if (res.message) {
     118            const user = res.message.from;
     119            data.push({ id: user.id, name: user.username || `${user.first_name || ''} ${user.last_name || ''}`.trim() || "Користувач" });
     120        }
     121    });
     122
     123    // Унікалізація
     124    data = data.filter((v, i, a) => a.findIndex(t => t.id === v.id) === i);
     125
     126    if (data.length === 0) {
     127        resultContainer.textContent = "Чати не знайдені. Напишіть щось боту першим.";
     128        return;
     129    }
     130
     131    data.forEach(el => {
     132        const div = document.createElement('div');
     133        div.className = 'chat-item-row';
     134        div.style.padding = '5px 0';
     135
     136        const nameSpan = document.createElement('span');
     137        nameSpan.textContent = `${el.name} : `; // Текст імені захищено
     138
     139        const boldId = document.createElement('b');
     140        boldId.textContent = el.id;
     141
     142        const actionIcon = document.createElement('span');
     143        actionIcon.className = 'id-chat-list';
     144        actionIcon.style.cursor = 'pointer';
     145        actionIcon.style.marginLeft = '10px';
     146        actionIcon.title = 'Вставити ID у форму';
     147        actionIcon.innerHTML = ' &#10063;';
     148        actionIcon.addEventListener('click', () => insertId(el.id));
     149
     150        div.append(nameSpan, boldId, actionIcon, document.createElement('br'));
     151        resultContainer.appendChild(div);
     152    });
     153}
     154
     155function insertId(id) {
     156    const idInput = document.querySelector('[name="tscfwc_setting_chatid"]');
     157    if (idInput) {
     158        idInput.value = id;
     159        // Додамо візуальний ефект успіху
     160        idInput.style.backgroundColor = '#e1f5fe';
     161        setTimeout(() => idInput.style.backgroundColor = '', 500);
    143162    }
    144163}
    145164
    146 function insertId(id){
    147     document.querySelector('[name="tscfwc_setting_chatid"]').value = id
     165/**
     166 * Надсилання тестового повідомлення
     167 */
     168function telsenderTestSend() {
     169    const token = document.querySelector('[name="tscfwc_setting_token"]')?.value;
     170    const chatid = document.querySelector('[name="tscfwc_setting_chatid"]')?.value;
     171
     172    if (!token || !chatid) return;
     173
     174    // Використання URLSearchParams для безпечного кодування параметрів
     175    const params = new URLSearchParams({
     176        chat_id: chatid,
     177        text: "Тестове повідомлення: Бот працює! 🙃"
     178    });
     179
     180    fetch(`https://api.telegram.org/bot${token}/sendMessage?${params.toString()}`)
     181        .then(res => res.json())
     182        .catch(console.error);
    148183}
    149 
    150 /**
    151  *
    152  */
    153 function telsenderTestSend(){
    154 
    155     const token =  document.querySelector('[name="tscfwc_setting_token"]').value
    156     const chatid =  document.querySelector('[name="tscfwc_setting_chatid"]').value
    157     const url  = `https://api.telegram.org/bot${token}/sendMessage?text=Is works 🙃 &chat_id=${chatid}`
    158     fetch(url).then(res=>{
    159         res.json().then(response=>{
    160 
    161         })
    162     })
    163 
    164 }
  • telsender/trunk/readme.md

    r3029269 r3449367  
    22Contributors: pechenki
    33Tags: telegram, Сontact form 7 to telegram, ninja forms, telegram ninja forms, Сontact form 7, wooccommerce to telegram, Wpforms to telegram, wpforms to telegram
    4 Requires at least: 4.8
    5 Requires PHP: 5.6
    6 Tested up to: 6.4
    7 Stable tag: 1.14.12
     4Requires at least: 5.8
     5Requires PHP: 7.4
     6Tested up to: 6.9
     7Stable tag: 1.14.15
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    5050== Changelog ==
    5151
     52= 1.14.15 =
     53 - fix XSS js
    5254= 1.14.12 =
    5355
Note: See TracChangeset for help on using the changeset viewer.