PluginProbe
Booktics – Appointment Booking Calendar for Service Businesses / 1.0.27
Booktics – Appointment Booking Calendar for Service Businesses v1.0.27
1.0.29 1.0.28 1.0.27 1.0.26 1.0.25 1.0.24 1.0.23 1.0.22 1.0.21 1.0.20 1.0.19 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.17 1.0.18 1.0.2 1.0.3 All 31 releases
← All changes | base/abstracts/booktics-database.php +40 -6 1.0.2 → 1.0.27 View file →
@@ -31,8 +31,33 @@
31 31 $this->db = $wpdb;
32 32 }
33 33
34 34 /**
35 + * Validate a SQL identifier (column name) against a strict allow-list.
36 + *
37 + * Only plain identifiers ([A-Za-z0-9_]) are permitted. Since column names
38 + * cannot be parameterized by wpdb::prepare(), any value used as a column
39 + * name must be validated here to prevent SQL injection when the array keys
40 + * originate from user-controlled request bodies.
41 + *
42 + * @param string $identifier
43 + *
44 + * @return string The validated identifier, wrapped in backticks.
45 + *
46 + * @throws RuntimeException When the identifier is not a plain column name.
47 + */
48 + private function sanitize_identifier( string $identifier ): string {
49 + if ( ! preg_match( '/^[a-zA-Z0-9_]+$/', $identifier ) ) {
50 + throw new RuntimeException(
51 + /* translators: %s: column name. */
52 + sprintf( esc_html__( 'Invalid database column identifier: %s', 'booktics' ), esc_html( $identifier ) )
53 + );
54 + }
55 +
56 + return "`{$identifier}`";
57 + }
58 +
59 + /**
35 60 * Begin database transaction
36 61 *
37 62 * @return void
38 63 */
@@ -71,9 +96,9 @@
71 96 $conditions = array();
72 97 $values = array();
73 98
74 99 foreach ( $where as $key => $value ) {
75 - $conditions[] = "$key = %s";
100 + $conditions[] = $this->sanitize_identifier( $key ) . ' = %s';
76 101 $values[] = $value;
77 102 }
78 103
79 104 $condition_string = implode( ' AND ', $conditions );
@@ -106,8 +131,9 @@
106 131 }
107 132
108 133 $table = booktics_get_table_name( $table );
109 134 $columns = array_keys( $records[0] );
135 + $safe_columns = array_map( array( $this, 'sanitize_identifier' ), $columns );
110 136 $placeholders = array_fill( 0, count( $columns ), '%s' );
111 137 $placeholder_string = '(' . implode( ',', $placeholders ) . ')';
112 138
113 139 $values = array();
@@ -119,9 +145,9 @@
119 145 $values[] = $record[ $column ] ?? '';
120 146 }
121 147 }
122 148
123 - $column_string = implode( ',', $columns );
149 + $column_string = implode( ',', $safe_columns );
124 150 $placeholders_string = implode( ',', $placeholders_groups );
125 151
126 152 $sql = "INSERT INTO $table ($column_string) VALUES $placeholders_string";
127 153
@@ -145,9 +171,17 @@
145 171 * @return array
146 172 */
147 173 public function select( string $table, array $where = array(), array $columns = array( '*' ) ) {
148 174 $table = booktics_get_table_name( $table );
149 - $columns_s = implode( ', ', $columns );
175 + $columns_s = implode(
176 + ', ',
177 + array_map(
178 + function ( $column ) {
179 + return '*' === $column ? '*' : $this->sanitize_identifier( $column );
180 + },
181 + $columns
182 + )
183 + );
150 184 $sql = "SELECT $columns_s FROM $table";
151 185
152 186 $values = array();
153 187 if ( ! empty( $where ) ) {
@@ -153,9 +187,9 @@
153 187 if ( ! empty( $where ) ) {
154 188 $conditions = array();
155 189
156 190 foreach ( $where as $key => $value ) {
157 - $conditions[] = "$key = %s";
191 + $conditions[] = $this->sanitize_identifier( $key ) . ' = %s';
158 192 $values[] = $value;
159 193 }
160 194
161 195 $condition_string = implode( ' AND ', $conditions );
@@ -201,14 +235,14 @@
201 235 $where_conditions = array();
202 236 $values = array();
203 237
204 238 foreach ( $data as $key => $value ) {
205 - $set_values[] = "$key = %s";
239 + $set_values[] = $this->sanitize_identifier( $key ) . ' = %s';
206 240 $values[] = $value;
207 241 }
208 242
209 243 foreach ( $where as $key => $value ) {
210 - $where_conditions[] = "$key = %s";
244 + $where_conditions[] = $this->sanitize_identifier( $key ) . ' = %s';
211 245 $values[] = $value;
212 246 }
213 247
214 248 $set_string = implode( ', ', $set_values );