PluginProbe
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services / 8.3.8
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services v8.3.8
8.7.7 8.7.6 8.7.5 8.7.4 8.7.3 8.7.2 8.7.1 8.7.0 8.6.9 8.6.8 8.6.7 8.6.6 8.6.5 8.6.4 8.6.2 8.6.1 8.6.0 8.5.9 8.5.8 8.5.7 8.5.6 8.5.5 8.5.4 8.5.3 8.5.2 All 533 releases
← All changes | functions.php +19 -209 8.7.68.3.8 View file →
@@ -58,62 +58,8 @@
58 58 });
59 59 </script>
60 60 <?php
61 61 }
62 -/**
63 - * Extract a YouTube video ID from common URL formats.
64 - *
65 - * @param string $url YouTube watch, embed, short, or youtu.be URL.
66 - * @return string Video ID or empty string.
67 - */
68 -if ( ! function_exists( 'qcld_wpbot_extract_youtube_id' ) ) {
69 - function qcld_wpbot_extract_youtube_id( $url ) {
70 - $url = trim( (string) $url );
71 - if ( $url === '' ) {
72 - return '';
73 - }
74 -
75 - if ( preg_match( '/(?:youtube\.com\/(?:embed\/|shorts\/|live\/|watch\?(?:.*&)?v=)|youtu\.be\/)([A-Za-z0-9_-]{11})/', $url, $matches ) ) {
76 - return $matches[1];
77 - }
78 -
79 - $path = (string) wp_parse_url( $url, PHP_URL_PATH );
80 - $base = basename( $path );
81 - if ( preg_match( '/^[A-Za-z0-9_-]{11}$/', $base ) ) {
82 - return $base;
83 - }
84 -
85 - return '';
86 - }
87 -}
88 -if ( ! function_exists( 'qcld_wpbot_youtube_icon_embed_src' ) ) {
89 - function qcld_wpbot_youtube_icon_embed_src( $url ) {
90 - $video_id = qcld_wpbot_extract_youtube_id( $url );
91 - if ( $video_id === '' ) {
92 - return '';
93 - }
94 -
95 - return add_query_arg(
96 - array(
97 - 'autoplay' => '1',
98 - 'mute' => '1',
99 - 'loop' => '1',
100 - 'playlist' => $video_id,
101 - 'controls' => '0',
102 - 'showinfo' => '0',
103 - 'rel' => '0',
104 - 'fs' => '0',
105 - 'iv_load_policy' => '3',
106 - 'cc_load_policy' => '0',
107 - 'disablekb' => '1',
108 - 'playsinline' => '1',
109 - 'modestbranding' => '1',
110 - 'color' => 'white',
111 - ),
112 - 'https://www.youtube.com/embed/' . rawurlencode( $video_id )
113 - );
114 - }
115 -}
116 62 function wp_chatbot_load_footer_html(){
117 63 if ( get_option('disable_wp_chatbot') != 1 && wp_chatbot_load_controlling() === true) {
118 64
119 65 ?>
@@ -119,9 +65,9 @@
119 65 ?>
120 66 <style>
121 67 <?php if(get_option('wp_chatbot_custom_css')!="") {
122 68
123 - echo wp_strip_all_tags( get_option('wp_chatbot_custom_css') );// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
69 + echo wp_strip_all_tags( get_option('wp_chatbot_custom_css') );
124 70 }
125 71 ?>
126 72 </style>
127 73
@@ -133,27 +79,10 @@
133 79 }
134 80 ?>
135 81 <style>
136 82 .wp-chatbot-container {
137 - background-color: #eceef3 !important;
138 83 background-image: url(<?php echo esc_url($qcld_wb_chatbot_board_bg_path); ?>) !important;
139 - background-size: cover !important;
140 - background-position: center !important;
141 - background-repeat: no-repeat !important;
142 84 }
143 - .wp-chatbot-template-01 #wp-chatbot-board-container,
144 - .wp-chatbot-template-01 .wp-chatbot-board-container {
145 - background-color: #eceef3 !important;
146 - background-image: none !important;
147 - }
148 - .wp-chatbot-template-01 #wp-chatbot-board-container::before,
149 - .wp-chatbot-template-01 .wp-chatbot-board-container::before {
150 - background-color: #eceef3 !important;
151 - background-image: url(<?php echo esc_url($qcld_wb_chatbot_board_bg_path); ?>) !important;
152 - background-size: cover !important;
153 - background-position: center !important;
154 - background-repeat: no-repeat !important;
155 - }
156 85 </style>
157 86 <?php }
158 87 $wp_chatbot_enable_rtl = "";
159 88 if (get_option('enable_wp_chatbot_rtl') == '1') {
@@ -251,72 +180,14 @@
251 180 $wp_chatbot_custom_icon_path = QCLD_wpCHATBOT_IMG_URL . get_option('wp_chatbot_icon');
252 181 } else {
253 182 $wp_chatbot_custom_icon_path = QCLD_wpCHATBOT_IMG_URL . 'custom.png';
254 183 }
255 - $_wpbot_icon_video = get_option('wp_chatbot_icon_video', '');
256 - $_wpbot_video_is_youtube = ( strpos( $_wpbot_icon_video, 'youtube.com' ) !== false || strpos( $_wpbot_icon_video, 'youtu.be' ) !== false );
257 - $_wpbot_youtube_embed_src = $_wpbot_video_is_youtube ? qcld_wpbot_youtube_icon_embed_src( $_wpbot_icon_video ) : '';
258 - $_wpbot_video_delay_ms = absint( get_option( 'wp_chatbot_icon_video_delay', 0 ) ) * 1000;
259 -
260 - $wp_chatbot_ball_is_youtube = ($_wpbot_icon_video !== '' && (strpos($_wpbot_icon_video, 'youtube.com') !== false || strpos($_wpbot_icon_video, 'youtu.be') !== false));
261 - $wp_chatbot_ball_is_video = ($_wpbot_icon_video !== '' && !$wp_chatbot_ball_is_youtube);
262 - $wp_chatbot_ball_has_video = ($wp_chatbot_ball_is_youtube || $wp_chatbot_ball_is_video);
263 184 ?>
264 185 <img src="<?php echo esc_url($wp_chatbot_custom_icon_path); ?>"
265 - alt="wpChatIcon" qcld_agent="<?php echo esc_url($wp_chatbot_custom_icon_path); ?>"
266 - id="wp-chatbot-ball-icon-img"
267 - <?php if ($wp_chatbot_ball_has_video) { echo 'style="display:none;"'; } ?> >
268 - <?php if ( $_wpbot_icon_video !== '' ) : ?>
269 - <?php if ( $_wpbot_video_is_youtube && $_wpbot_youtube_embed_src !== '' ) : ?>
270 - <iframe class="wpbot-icon-video" src="<?php echo $_wpbot_video_delay_ms > 0 ? 'about:blank' : esc_url( $_wpbot_youtube_embed_src ); ?>" data-wpbot-yt-src="<?php echo esc_url( $_wpbot_youtube_embed_src ); ?>" frameborder="0" allow="autoplay; fullscreen; encrypted-media; picture-in-picture"></iframe>
271 - <?php elseif ( ! $_wpbot_video_is_youtube ) : ?>
272 - <video class="wpbot-icon-video" src="<?php echo esc_url( $_wpbot_icon_video ); ?>" autoplay muted loop playsinline preload="auto"></video>
273 - <?php endif; ?>
274 - <?php endif; ?>
186 + alt="wpChatIcon" qcld_agent="<?php echo esc_url($wp_chatbot_custom_icon_path); ?>" >
187 +
275 188 </div>
276 -
277 189 </div>
278 - <?php
279 - if ( $_wpbot_icon_video !== '' ) :
280 - ?>
281 - <script>
282 - (function(){
283 - var wpbotDelay = <?php echo (int) $_wpbot_video_delay_ms; ?>;
284 - function wpbotForcePlay(){
285 - var v = document.querySelector('#wp-chatbot-ball video.wpbot-icon-video');
286 - if( v ){
287 - v.muted = true;
288 - v.volume = 0;
289 - v.loop = true;
290 - var tries = 0, maxTries = 30;
291 - var timer = setInterval(function(){
292 - tries++;
293 - v.play().then(function(){ clearInterval(timer); }).catch(function(){});
294 - if( tries >= maxTries ) clearInterval(timer);
295 - }, 300);
296 - }
297 - var yt = document.querySelector('#wp-chatbot-ball iframe.wpbot-icon-video');
298 - if( yt ){
299 - var ytSrc = yt.getAttribute('data-wpbot-yt-src');
300 - if( ytSrc && ( !yt.getAttribute('src') || yt.getAttribute('src') === 'about:blank' || yt.getAttribute('src').indexOf('autoplay=1') === -1 ) ){
301 - yt.setAttribute('src', ytSrc);
302 - }
303 - }
304 - }
305 - function wpbotDelayedPlay(){
306 - setTimeout(wpbotForcePlay, wpbotDelay);
307 - }
308 - if( document.readyState === 'loading' ){
309 - document.addEventListener('DOMContentLoaded', wpbotDelayedPlay);
310 - } else {
311 - wpbotDelayedPlay();
312 - }
313 - window.addEventListener('load', function(){
314 - setTimeout(wpbotForcePlay, wpbotDelay);
315 - });
316 - })();
317 - </script>
318 - <?php endif; ?>
319 190 <?php
320 191 $fb_app_id = get_option('qlcd_wp_chatbot_fb_app_id');
321 192 $fb_page_id = get_option('qlcd_wp_chatbot_fb_page_id');
322 193 $fb_mgs_color = get_option('qlcd_wp_chatbot_fb_color') != '' ? get_option('qlcd_wp_chatbot_fb_color') : '#0084ff';
@@ -1721,9 +1592,9 @@
1721 1592
1722 1593 if(class_exists('Qcformbuilder_Forms_Admin')){
1723 1594
1724 1595
1725 - $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM ". $wpdb->prefix."wfb_forms WHERE type= %s",'primary')); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
1596 + $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM ". $wpdb->prefix."wfb_forms WHERE type= %s",'primary')); //DB Call OK, No Caching OK
1726 1597
1727 1598 if(!empty($results)){
1728 1599
1729 1600 foreach($results as $result){
@@ -1876,12 +1747,9 @@
1876 1747 }
1877 1748 }
1878 1749
1879 1750 function qcld_choose_random($array){
1880 - if (is_array($array) && !empty($array)) {
1881 - return $array[array_rand($array)];
1882 - }
1883 - return $array;
1751 + return $array[array_rand($array)];
1884 1752 }
1885 1753
1886 1754 //User session count
1887 1755 add_action('wp_ajax_qcld_wb_chatbot_session_count', 'qcld_wb_chatbot_session_count');
@@ -1894,22 +1762,22 @@
1894 1762 $tableuser = $wpdb->prefix.'wpbot_sessions';
1895 1763 $response = array();
1896 1764
1897 1765
1898 - $session_exists = $wpdb->get_row($wpdb->prepare("select * from {$tableuser} where 1 and id = %d",1)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
1766 + $session_exists = $wpdb->get_row($wpdb->prepare("select * from $tableuser where 1 and id = %d",1)); //DB Call OK, No Caching OK
1899 1767
1900 1768 if(empty($session_exists)){
1901 - $wpdb->insert( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
1769 + $wpdb->insert(
1902 1770 $tableuser,
1903 1771 array(
1904 1772 'session' => 1,
1905 1773 )
1906 - );
1774 + ); //DB Call OK, No Caching OK
1907 1775 }else{
1908 1776
1909 1777 $session_id = $session_exists->id;
1910 1778
1911 - $wpdb->update( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
1779 + $wpdb->update(
1912 1780 $tableuser,
1913 1781 array(
1914 1782 'session'=>($session_exists->session+1),
1915 1783 ),
@@ -1917,9 +1785,9 @@
1917 1785 array(
1918 1786 '%d',
1919 1787 ),
1920 1788 array('%d')
1921 - );
1789 + ); //DB Call OK, No Caching OK
1922 1790
1923 1791 }
1924 1792
1925 1793 wp_send_json($response);
@@ -1927,9 +1795,9 @@
1927 1795
1928 1796 /* WPBot Chat History Addon check */
1929 1797 function qcld_wpbot_is_active_chat_history(){
1930 1798
1931 - if(function_exists('qcwp_chat_session_menu_fnc') || function_exists('qcwp_chat_session_menu_fnc_free') || function_exists( 'qcpdcs_chat_session_menu_fnc' ) ){
1799 + if(function_exists('qcwp_chat_session_menu_fnc') || function_exists( 'qcpdcs_chat_session_menu_fnc' ) ){
1932 1800 return 1;
1933 1801 }else{
1934 1802 return 0;
1935 1803 }
@@ -1935,68 +1803,15 @@
1935 1803 }
1936 1804
1937 1805 }
1938 1806
1939 -/**
1940 - * Safely sanitize chatbot conversation input.
1941 - *
1942 - * SECURITY FIX (CVE WPBot Stored XSS ≤ 8.6.9):
1943 - * The previous order was: wp_kses() → html_entity_decode() → htmlspecialchars().
1944 - * An attacker could submit entity-encoded payloads (&lt;img onerror=...&gt;) that
1945 - * bypassed wp_kses (which saw inert text), were then decoded back into live markup
1946 - * by html_entity_decode(), and survived into storage and the admin UI.
1947 - *
1948 - * Correct order: html_entity_decode() FIRST → wp_kses() → htmlspecialchars().
1949 - * wp_kses() now sees the real decoded markup and strips forbidden tags/attributes.
1950 - *
1951 - * @param string $data Raw conversation string (already wp_unslash'd by caller).
1952 - * @return string Sanitized, entity-encoded string safe for DB storage.
1953 - */
1954 1807 function qcld_wpbot_input_validation( $data ) {
1955 - // 1. Decode any entity-encoded HTML so wp_kses sees the real markup.
1956 - $data = html_entity_decode( $data, ENT_QUOTES | ENT_HTML5, 'UTF-8' );
1957 - $data = trim( $data );
1958 - $data = stripslashes( $data );
1959 - // 2. Sanitize with a strict allowlist — NOW operating on decoded markup.
1960 - $data = wp_kses( $data, wpbot_get_safe_conversation_tags() );
1961 - // 3. Re-encode for safe DB storage; admin.js decodes for rendering.
1962 - $data = htmlspecialchars( $data, ENT_QUOTES | ENT_HTML5, 'UTF-8' );
1808 + $data = html_entity_decode($data);
1809 + $data = trim($data);
1810 + $data = stripslashes($data);
1811 + $data = htmlspecialchars($data);
1963 1812 return $data;
1964 1813 }
1965 -
1966 -/**
1967 - * Returns the strict HTML allowlist for chatbot conversation content.
1968 - *
1969 - * Critically: no event-handler attributes (onerror, onclick, onload, etc.) are
1970 - * allowed — wp_kses strips any attribute not explicitly listed here.
1971 - * 'img' is intentionally omitted; bot responses that include images should use
1972 - * safe URLs only and can be re-added with only 'src', 'alt', 'class' if needed.
1973 - *
1974 - * @return array<string, array<string, bool>>
1975 - */
1976 -function wpbot_get_safe_conversation_tags() {
1977 - return array(
1978 - 'ul' => array( 'class' => true ),
1979 - 'ol' => array( 'class' => true ),
1980 - 'li' => array( 'class' => true, 'id' => true ),
1981 - 'div' => array( 'class' => true, 'id' => true ),
1982 - 'span' => array( 'class' => true, 'id' => true ),
1983 - 'p' => array( 'class' => true ),
1984 - 'br' => array(),
1985 - 'strong' => array(),
1986 - 'em' => array(),
1987 - 'b' => array(),
1988 - 'i' => array(),
1989 - 'a' => array(
1990 - 'href' => true,
1991 - 'target' => true,
1992 - 'rel' => true,
1993 - 'class' => true,
1994 - ),
1995 - // 'img' intentionally excluded — prevents onerror/onload injection.
1996 - // Add back with only 'src','alt','class' if bot image responses are needed.
1997 - );
1998 -}
1999 1814 add_action('wp_ajax_qcld_small_talk_import', 'qcld_small_talk_import');
2000 1815 function qcld_small_talk_import(){
2001 1816 if ( ! current_user_can( 'manage_options' ) ) {
2002 1817 wp_die();
@@ -2008,10 +1823,9 @@
2008 1823 $csvFile = file(QCLD_wpCHATBOT_PLUGIN_DIR_PATH . 'small_talk.csv');
2009 1824
2010 1825 foreach ($csvFile as $line) {
2011 1826 $line = str_getcsv($line, ',', '"');
2012 - $wpdb->insert( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
2013 - $table, array(
1827 + $wpdb->insert($table, array(
2014 1828 'query' => $line[0],
2015 1829 'keyword' => $line[1],
2016 1830 'response' => $line[2],
2017 1831 'category'=> $line[3],
@@ -2016,17 +1830,16 @@
2016 1830 'response' => $line[2],
2017 1831 'category'=> $line[3],
2018 1832 'intent'=> '',
2019 1833 //'lang'=> 'en_US',
2020 - ));
1834 + )); //DB Call OK, No Caching OK
2021 1835 }
2022 1836
2023 1837 $table2 = $wpdb->prefix.'wpbot_response_category';
2024 1838
2025 - $wpdb->insert( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
2026 - $table2, array(
1839 + $wpdb->insert($table2, array(
2027 1840 'name' => 'smalltalk',
2028 - ));
1841 + )); //DB Call OK, No Caching OK
2029 1842
2030 1843 update_option( 'qcld_small_talk_imported', 'yes' );
2031 1844
2032 1845 }
@@ -2074,7 +1887,4 @@
2074 1887
2075 1888 }
2076 1889 }
2077 1890 }
2078 -
2079 -// AI Actions Chat Preview
2080 -