PluginProbe
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services / 8.7.4
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services v8.7.4
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
chatbot / includes / class-wpbot-gc-download.php

class-wpbot-gc-download.php in WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services 8.7.4, at includes/class-wpbot-gc-download.php

170 lines 6.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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();
170