PluginProbe
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services / 8.8.0
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services v8.8.0
8.8.0 8.7.9 8.7.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 All 536 releases
← All changes | includes/class-wpbot-gc-download.php +169 -167 8.6.8 → 8.8.0 View file →
@@ -1,167 +1,169 @@
1 -<?php
2 -if ( ! defined( 'ABSPATH' ) ) {
3 - exit;
4 -}
5 -
6 -class WPBotGCDownload
7 -{
8 - private $download_url = 'https://github.com/qcloud/gc/raw/master/wpbotgc.zip';
9 - private $filename = 'wpbotgc.zip';
10 -
11 - public function __construct() {
12 - add_action( 'wp_ajax_qcld_wp_chatbot_gc_client_download', array( $this, 'downloadgc' ) );
13 - add_action( 'wp_ajax_qcld_wp_chatbot_gc_client_extract', array( $this, 'extractgc' ) );
14 - }
15 -
16 - /**
17 - * Initialise WP_Filesystem and return the global instance.
18 - */
19 - private function get_filesystem() {
20 - global $wp_filesystem;
21 - if ( empty( $wp_filesystem ) ) {
22 - require_once ABSPATH . 'wp-admin/includes/file.php';
23 - WP_Filesystem();
24 - }
25 - return $wp_filesystem;
26 - }
27 -
28 - /**
29 - * Create a directory using WP_Filesystem.
30 - */
31 - public function create_folder( $gcdirectory ) {
32 - $fs = $this->get_filesystem();
33 - if ( ! $fs->is_dir( $gcdirectory ) ) {
34 - return $fs->mkdir( $gcdirectory, FS_CHMOD_DIR );
35 - }
36 - return true;
37 - }
38 -
39 - /**
40 - * Create a blank index.php guard file using WP_Filesystem.
41 - */
42 - public function create_file( $filename ) {
43 - $fs = $this->get_filesystem();
44 - if ( $fs->exists( $filename ) ) {
45 - return true;
46 - }
47 - return $fs->put_contents( $filename, '<?php //silence is golden', FS_CHMOD_FILE );
48 - }
49 -
50 - public function downloadgc() {
51 - if ( ! current_user_can( 'manage_options' ) ) {
52 - wp_send_json( array( 'success' => false, 'msg' => esc_html__( 'Unauthorized access', 'chatbot' ) ) );
53 - wp_die();
54 - }
55 -
56 - $nonce = sanitize_text_field( wp_unslash( $_POST['nonce'] ?? '' ) );
57 - if ( ! wp_verify_nonce( $nonce, 'wp_chatbot' ) ) {
58 - wp_send_json( array( 'success' => false, 'msg' => esc_html__( 'Failed in Security check', 'chatbot' ) ) );
59 - wp_die();
60 - }
61 -
62 - $fs = $this->get_filesystem();
63 - $gcdirectory = QCLD_wpCHATBOT_GC_DIRNAME;
64 -
65 - if ( ! $fs->is_dir( $gcdirectory ) ) {
66 - $this->create_folder( $gcdirectory );
67 - }
68 -
69 - if ( ! $fs->exists( $gcdirectory . '/index.php' ) ) {
70 - $this->create_file( $gcdirectory . '/index.php' );
71 - }
72 -
73 - if ( ! $fs->is_dir( $gcdirectory ) ) {
74 - wp_send_json( array( 'status' => 'error', 'content' => esc_html__( 'Server does not allow creating files and folders.', 'chatbot' ) ) );
75 - wp_die();
76 - }
77 -
78 - $zip_file = $gcdirectory . '/' . $this->filename;
79 -
80 - $remote_response = wp_remote_get( $this->download_url, array(
81 - 'timeout' => 60,
82 - 'stream' => true,
83 - 'filename' => $zip_file,
84 - ) );
85 -
86 - if ( is_wp_error( $remote_response ) ) {
87 - wp_send_json( array( 'status' => 'error', 'content' => esc_html( $remote_response->get_error_message() ) ) );
88 - wp_die();
89 - }
90 -
91 - $http_code = wp_remote_retrieve_response_code( $remote_response );
92 - if ( 200 !== $http_code ) {
93 - wp_send_json( array( 'status' => 'error', 'content' => esc_html__( 'Remote server returned an unexpected response.', 'chatbot' ) ) );
94 - wp_die();
95 - }
96 -
97 - wp_send_json( array( 'status' => 'success', 'content' => esc_html__( 'File downloaded successfully.', 'chatbot' ) ) );
98 - wp_die();
99 - }
100 -
101 - public function extractgc() {
102 - if ( ! current_user_can( 'manage_options' ) ) {
103 - wp_send_json( array( 'success' => false, 'msg' => esc_html__( 'Unauthorized access', 'chatbot' ) ) );
104 - wp_die();
105 - }
106 -
107 - $nonce = sanitize_text_field( wp_unslash( $_POST['nonce'] ?? '' ) );
108 - if ( ! wp_verify_nonce( $nonce, 'wp_chatbot' ) ) {
109 - wp_send_json( array( 'success' => false, 'msg' => esc_html__( 'Failed in Security check', 'chatbot' ) ) );
110 - wp_die();
111 - }
112 -
113 - $fs = $this->get_filesystem();
114 - $gcdirectory = QCLD_wpCHATBOT_GC_DIRNAME;
115 - $gcfilename = $gcdirectory . '/' . $this->filename;
116 -
117 - // Verify the zip exists before attempting to open it.
118 - if ( ! $fs->exists( $gcfilename ) ) {
119 - wp_send_json( array( 'status' => 'error', 'content' => esc_html__( 'File not found.', 'chatbot' ) ) );
120 - wp_die();
121 - }
122 -
123 - $zip = new ZipArchive();
124 - if ( true !== $zip->open( $gcfilename ) ) {
125 - wp_send_json( array( 'status' => 'error', 'content' => esc_html__( 'Could not open zip archive.', 'chatbot' ) ) );
126 - wp_die();
127 - }
128 -
129 - // Validate every entry: block path traversal and absolute paths.
130 - $real_dest = realpath( $gcdirectory );
131 - for ( $i = 0; $i < $zip->numFiles; $i++ ) {
132 - $stat = $zip->statIndex( $i );
133 - $entry = $stat['name'];
134 -
135 - if (
136 - strpos( $entry, '../' ) !== false ||
137 - strpos( $entry, '..' . DIRECTORY_SEPARATOR ) !== false ||
138 - '/' === substr( $entry, 0, 1 )
139 - ) {
140 - $zip->close();
141 - $fs->delete( $gcfilename );
142 - wp_send_json( array( 'status' => 'error', 'content' => esc_html__( 'Invalid zip structure — path traversal detected.', 'chatbot' ) ) );
143 - wp_die();
144 - }
145 -
146 - // Ensure resolved path stays within the destination directory.
147 - $resolved = realpath( $real_dest . DIRECTORY_SEPARATOR . $entry );
148 - if ( $resolved !== false && strpos( $resolved, $real_dest ) !== 0 ) {
149 - $zip->close();
150 - $fs->delete( $gcfilename );
151 - wp_send_json( array( 'status' => 'error', 'content' => esc_html__( 'Invalid zip structure — entry escapes destination.', 'chatbot' ) ) );
152 - wp_die();
153 - }
154 - }
155 -
156 - $zip->extractTo( $gcdirectory );
157 - $zip->close();
158 -
159 - // Remove the zip after successful extraction.
160 - $fs->delete( $gcfilename );
161 -
162 - wp_send_json( array( 'status' => 'success', 'content' => esc_html__( 'Files extracted successfully.', 'chatbot' ) ) );
163 - wp_die();
164 - }
165 -}
166 -
167 -new WPBotGCDownload();
1 +<?php
2 +if ( ! defined( 'ABSPATH' ) ) {
3 + exit;
4 +}
5 +
6 +class WPBotGCDownload
7 +{
8 + private $filename = 'wpbotgc.zip';
9 +
10 + /**
11 + * Path to the bundled Google Client zip inside the plugin.
12 + *
13 + * @return string
14 + */
15 + private function get_bundled_zip_path() {
16 + return plugin_dir_path( __FILE__ ) . 'assets/' . $this->filename;
17 + }
18 +
19 + public function __construct() {
20 + add_action( 'wp_ajax_qcld_wp_chatbot_gc_client_download', array( $this, 'downloadgc' ) );
21 + add_action( 'wp_ajax_qcld_wp_chatbot_gc_client_extract', array( $this, 'extractgc' ) );
22 + }
23 +
24 + /**
25 + * Initialise WP_Filesystem and return the global instance.
26 + */
27 + private function get_filesystem() {
28 + global $wp_filesystem;
29 + if ( empty( $wp_filesystem ) ) {
30 + require_once ABSPATH . 'wp-admin/includes/file.php';
31 + WP_Filesystem();
32 + }
33 + return $wp_filesystem;
34 + }
35 +
36 + /**
37 + * Create a directory using WP_Filesystem.
38 + */
39 + public function create_folder( $gcdirectory ) {
40 + $fs = $this->get_filesystem();
41 + if ( ! $fs->is_dir( $gcdirectory ) ) {
42 + return $fs->mkdir( $gcdirectory, FS_CHMOD_DIR );
43 + }
44 + return true;
45 + }
46 +
47 + /**
48 + * Create a blank index.php guard file using WP_Filesystem.
49 + */
50 + public function create_file( $filename ) {
51 + $fs = $this->get_filesystem();
52 + if ( $fs->exists( $filename ) ) {
53 + return true;
54 + }
55 + return $fs->put_contents( $filename, '<?php //silence is golden', FS_CHMOD_FILE );
56 + }
57 +
58 + public function downloadgc() {
59 + if ( ! current_user_can( 'manage_options' ) ) {
60 + wp_send_json( array( 'success' => false, 'msg' => esc_html__( 'Unauthorized access', 'chatbot' ) ) );
61 + wp_die();
62 + }
63 +
64 + $nonce = sanitize_text_field( wp_unslash( $_POST['nonce'] ?? '' ) );
65 + if ( ! wp_verify_nonce( $nonce, 'wp_chatbot' ) ) {
66 + wp_send_json( array( 'success' => false, 'msg' => esc_html__( 'Failed in Security check', 'chatbot' ) ) );
67 + wp_die();
68 + }
69 +
70 + $fs = $this->get_filesystem();
71 + $gcdirectory = QCLD_wpCHATBOT_GC_DIRNAME;
72 +
73 + if ( ! $fs->is_dir( $gcdirectory ) ) {
74 + $this->create_folder( $gcdirectory );
75 + }
76 +
77 + if ( ! $fs->exists( $gcdirectory . '/index.php' ) ) {
78 + $this->create_file( $gcdirectory . '/index.php' );
79 + }
80 +
81 + if ( ! $fs->is_dir( $gcdirectory ) ) {
82 + wp_send_json( array( 'status' => 'error', 'content' => esc_html__( 'Server does not allow creating files and folders.', 'chatbot' ) ) );
83 + wp_die();
84 + }
85 +
86 + $zip_file = $gcdirectory . '/' . $this->filename;
87 + $bundled = $this->get_bundled_zip_path();
88 +
89 + if ( ! $fs->exists( $bundled ) ) {
90 + wp_send_json( array( 'status' => 'error', 'content' => esc_html__( 'Bundled Google Client package not found. Please install it manually using the instructions above.', 'chatbot' ) ) );
91 + wp_die();
92 + }
93 +
94 + if ( ! $fs->copy( $bundled, $zip_file, true, FS_CHMOD_FILE ) ) {
95 + wp_send_json( array( 'status' => 'error', 'content' => esc_html__( 'Could not copy the Google Client package.', 'chatbot' ) ) );
96 + wp_die();
97 + }
98 +
99 + wp_send_json( array( 'status' => 'success', 'content' => esc_html__( 'File downloaded successfully.', 'chatbot' ) ) );
100 + wp_die();
101 + }
102 +
103 + public function extractgc() {
104 + if ( ! current_user_can( 'manage_options' ) ) {
105 + wp_send_json( array( 'success' => false, 'msg' => esc_html__( 'Unauthorized access', 'chatbot' ) ) );
106 + wp_die();
107 + }
108 +
109 + $nonce = sanitize_text_field( wp_unslash( $_POST['nonce'] ?? '' ) );
110 + if ( ! wp_verify_nonce( $nonce, 'wp_chatbot' ) ) {
111 + wp_send_json( array( 'success' => false, 'msg' => esc_html__( 'Failed in Security check', 'chatbot' ) ) );
112 + wp_die();
113 + }
114 +
115 + $fs = $this->get_filesystem();
116 + $gcdirectory = QCLD_wpCHATBOT_GC_DIRNAME;
117 + $gcfilename = $gcdirectory . '/' . $this->filename;
118 +
119 + // Verify the zip exists before attempting to open it.
120 + if ( ! $fs->exists( $gcfilename ) ) {
121 + wp_send_json( array( 'status' => 'error', 'content' => esc_html__( 'File not found.', 'chatbot' ) ) );
122 + wp_die();
123 + }
124 +
125 + $zip = new ZipArchive();
126 + if ( true !== $zip->open( $gcfilename ) ) {
127 + wp_send_json( array( 'status' => 'error', 'content' => esc_html__( 'Could not open zip archive.', 'chatbot' ) ) );
128 + wp_die();
129 + }
130 +
131 + // Validate every entry: block path traversal and absolute paths.
132 + $real_dest = realpath( $gcdirectory );
133 + for ( $i = 0; $i < $zip->numFiles; $i++ ) {
134 + $stat = $zip->statIndex( $i );
135 + $entry = $stat['name'];
136 +
137 + if (
138 + strpos( $entry, '../' ) !== false ||
139 + strpos( $entry, '..' . DIRECTORY_SEPARATOR ) !== false ||
140 + '/' === substr( $entry, 0, 1 )
141 + ) {
142 + $zip->close();
143 + $fs->delete( $gcfilename );
144 + wp_send_json( array( 'status' => 'error', 'content' => esc_html__( 'Invalid zip structure — path traversal detected.', 'chatbot' ) ) );
145 + wp_die();
146 + }
147 +
148 + // Ensure resolved path stays within the destination directory.
149 + $resolved = realpath( $real_dest . DIRECTORY_SEPARATOR . $entry );
150 + if ( $resolved !== false && strpos( $resolved, $real_dest ) !== 0 ) {
151 + $zip->close();
152 + $fs->delete( $gcfilename );
153 + wp_send_json( array( 'status' => 'error', 'content' => esc_html__( 'Invalid zip structure — entry escapes destination.', 'chatbot' ) ) );
154 + wp_die();
155 + }
156 + }
157 +
158 + $zip->extractTo( $gcdirectory );
159 + $zip->close();
160 +
161 + // Remove the zip after successful extraction.
162 + $fs->delete( $gcfilename );
163 +
164 + wp_send_json( array( 'status' => 'success', 'content' => esc_html__( 'Files extracted successfully.', 'chatbot' ) ) );
165 + wp_die();
166 + }
167 +}
168 +
169 +new WPBotGCDownload();