WP GDPR Compliance - Version 1.4.3

Version Description

Release date: November 7th, 2018 * Security fix: Removed base64_decode() function. * Security fix: Correctly escape input in $wpdb->prepare() function. * Security fix: Only allow modifying WordPress options used by the plugin and by the user capabilities.

Download this release

Release Info

Developer donnyoexman
Plugin Icon 128x128 WP GDPR Compliance
Version 1.4.3
Comparing to
See all releases

Code changes from version 1.4.2 to 1.4.3

Includes/AccessRequest.php CHANGED
@@ -19,6 +19,8 @@ class AccessRequest {
19
  private $sessionId = '';
20
  /** @var string */
21
  private $ipAddress = '';
 
 
22
  /** @var int */
23
  private $expired = 0;
24
  /** @var string */
@@ -43,10 +45,10 @@ class AccessRequest {
43
  public function getByEmailAddressAndSessionId($emailAddress = '', $sessionId = '') {
44
  global $wpdb;
45
  $query = "SELECT * FROM `" . self::getDatabaseTableName() . "`";
46
- $query .= " WHERE `email_address` = '%s'";
47
- $query .= " AND `session_id` = '%s'";
48
  $query .= " AND `expired` = '0'";
49
- $query .= " AND `site_id` = '%d'";
50
  $row = $wpdb->get_row($wpdb->prepare($query, $emailAddress, $sessionId, get_current_blog_id()));
51
  if ($row !== null) {
52
  return new self($row->ID);
@@ -54,6 +56,23 @@ class AccessRequest {
54
  return false;
55
  }
56
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  /**
58
  * @param array $filters
59
  * @return int
@@ -62,7 +81,7 @@ class AccessRequest {
62
  global $wpdb;
63
  $query = "SELECT COUNT(`ID`) FROM `" . self::getDatabaseTableName() . "` WHERE 1";
64
  $query .= Helper::getQueryByFilters($filters);
65
- $query .= sprintf(" AND `site_id` = '%d'", get_current_blog_id());
66
  $result = $wpdb->get_var($query);
67
  if ($result !== null) {
68
  return absint($result);
@@ -81,7 +100,7 @@ class AccessRequest {
81
  $output = array();
82
  $query = "SELECT * FROM `" . self::getDatabaseTableName() . "` WHERE 1";
83
  $query .= Helper::getQueryByFilters($filters);
84
- $query .= sprintf(" AND `site_id` = '%d'", get_current_blog_id());
85
  $query .= " ORDER BY `date_created` DESC";
86
  if (!empty($limit)) {
87
  $query .= " LIMIT $offset, $limit";
@@ -106,13 +125,14 @@ class AccessRequest {
106
  $this->setEmailAddress($row->email_address);
107
  $this->setSessionId($row->session_id);
108
  $this->setIpAddress($row->ip_address);
 
109
  $this->setExpired($row->expired);
110
  $this->setDateCreated($row->date_created);
111
  }
112
 
113
  public function load() {
114
  global $wpdb;
115
- $query = "SELECT * FROM `" . self::getDatabaseTableName() . "` WHERE `ID` = '%d'";
116
  $row = $wpdb->get_row($wpdb->prepare($query, $this->getId()));
117
  if ($row !== null) {
118
  $this->loadByRow($row);
@@ -127,7 +147,7 @@ class AccessRequest {
127
  global $wpdb;
128
  $row = $wpdb->get_row(
129
  $wpdb->prepare(
130
- "SELECT * FROM `" . self::getDatabaseTableName() . "` WHERE `ID` = '%d'",
131
  intval($id)
132
  )
133
  );
@@ -142,9 +162,9 @@ class AccessRequest {
142
  public function existsByEmailAddress($emailAddress = '', $nonExpiredOnly = false) {
143
  global $wpdb;
144
  $query = "SELECT * FROM `" . self::getDatabaseTableName() . "`";
145
- $query .= " WHERE `email_address` = '%s'";
146
- $query .= " AND `site_id` = '%d'";
147
- if ($nonExpiredOnly) {
148
  $query .= " AND `expired` = '0'";
149
  }
150
  $row = $wpdb->get_row($wpdb->prepare($query, $emailAddress, get_current_blog_id()));
@@ -173,10 +193,11 @@ class AccessRequest {
173
  'email_address' => $this->getEmailAddress(),
174
  'session_id' => $this->getSessionId(),
175
  'ip_address' => $this->getIpAddress(),
 
176
  'expired' => $this->getExpired(),
177
  'date_created' => date_i18n('Y-m-d H:i:s'),
178
  ),
179
- array('%d', '%s', '%s', '%s', '%d', '%s')
180
  );
181
  if ($result !== false) {
182
  $this->setId($wpdb->insert_id);
@@ -266,6 +287,20 @@ class AccessRequest {
266
  $this->ipAddress = $ipAddress;
267
  }
268
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269
  /**
270
  * @return int
271
  */
19
  private $sessionId = '';
20
  /** @var string */
21
  private $ipAddress = '';
22
+ /** @var string */
23
+ private $token = '';
24
  /** @var int */
25
  private $expired = 0;
26
  /** @var string */
45
  public function getByEmailAddressAndSessionId($emailAddress = '', $sessionId = '') {
46
  global $wpdb;
47
  $query = "SELECT * FROM `" . self::getDatabaseTableName() . "`";
48
+ $query .= " WHERE `email_address` = %s";
49
+ $query .= " AND `session_id` = %s";
50
  $query .= " AND `expired` = '0'";
51
+ $query .= " AND `site_id` = %d";
52
  $row = $wpdb->get_row($wpdb->prepare($query, $emailAddress, $sessionId, get_current_blog_id()));
53
  if ($row !== null) {
54
  return new self($row->ID);
56
  return false;
57
  }
58
 
59
+ /**
60
+ * @param string $token
61
+ * @return bool|AccessRequest
62
+ */
63
+ public function getByToken($token = '') {
64
+ global $wpdb;
65
+ $query = "SELECT * FROM `" . self::getDatabaseTableName() . "`";
66
+ $query .= " WHERE `token` = %s";
67
+ $query .= " AND `expired` = '0'";
68
+ $query .= " AND `site_id` = %d";
69
+ $row = $wpdb->get_row($wpdb->prepare($query, $token, get_current_blog_id()));
70
+ if ($row !== null) {
71
+ return new self($row->ID);
72
+ }
73
+ return false;
74
+ }
75
+
76
  /**
77
  * @param array $filters
78
  * @return int
81
  global $wpdb;
82
  $query = "SELECT COUNT(`ID`) FROM `" . self::getDatabaseTableName() . "` WHERE 1";
83
  $query .= Helper::getQueryByFilters($filters);
84
+ $query .= sprintf(" AND `site_id` = %d", get_current_blog_id());
85
  $result = $wpdb->get_var($query);
86
  if ($result !== null) {
87
  return absint($result);
100
  $output = array();
101
  $query = "SELECT * FROM `" . self::getDatabaseTableName() . "` WHERE 1";
102
  $query .= Helper::getQueryByFilters($filters);
103
+ $query .= sprintf(" AND `site_id` = %d", get_current_blog_id());
104
  $query .= " ORDER BY `date_created` DESC";
105
  if (!empty($limit)) {
106
  $query .= " LIMIT $offset, $limit";
125
  $this->setEmailAddress($row->email_address);
126
  $this->setSessionId($row->session_id);
127
  $this->setIpAddress($row->ip_address);
128
+ $this->setToken($row->token);
129
  $this->setExpired($row->expired);
130
  $this->setDateCreated($row->date_created);
131
  }
132
 
133
  public function load() {
134
  global $wpdb;
135
+ $query = "SELECT * FROM `" . self::getDatabaseTableName() . "` WHERE `ID` = %d";
136
  $row = $wpdb->get_row($wpdb->prepare($query, $this->getId()));
137
  if ($row !== null) {
138
  $this->loadByRow($row);
147
  global $wpdb;
148
  $row = $wpdb->get_row(
149
  $wpdb->prepare(
150
+ "SELECT * FROM `" . self::getDatabaseTableName() . "` WHERE `ID` = %d",
151
  intval($id)
152
  )
153
  );
162
  public function existsByEmailAddress($emailAddress = '', $nonExpiredOnly = false) {
163
  global $wpdb;
164
  $query = "SELECT * FROM `" . self::getDatabaseTableName() . "`";
165
+ $query .= " WHERE `email_address` = %s";
166
+ $query .= " AND `site_id` = %d";
167
+ if ($nonExpiredOnly === true) {
168
  $query .= " AND `expired` = '0'";
169
  }
170
  $row = $wpdb->get_row($wpdb->prepare($query, $emailAddress, get_current_blog_id()));
193
  'email_address' => $this->getEmailAddress(),
194
  'session_id' => $this->getSessionId(),
195
  'ip_address' => $this->getIpAddress(),
196
+ 'token' => $this->getToken(),
197
  'expired' => $this->getExpired(),
198
  'date_created' => date_i18n('Y-m-d H:i:s'),
199
  ),
200
+ array('%d', '%s', '%s', '%s', '%s', '%d', '%s')
201
  );
202
  if ($result !== false) {
203
  $this->setId($wpdb->insert_id);
287
  $this->ipAddress = $ipAddress;
288
  }
289
 
290
+ /**
291
+ * @return string
292
+ */
293
+ public function getToken() {
294
+ return $this->token;
295
+ }
296
+
297
+ /**
298
+ * @param string $token
299
+ */
300
+ public function setToken($token) {
301
+ $this->token = $token;
302
+ }
303
+
304
  /**
305
  * @return int
306
  */
Includes/Ajax.php CHANGED
@@ -10,6 +10,74 @@ class Ajax {
10
  /** @var null */
11
  private static $instance = null;
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  public function processAction() {
14
  check_ajax_referer('wpgdprc', 'security');
15
 
@@ -33,44 +101,6 @@ class Ajax {
33
 
34
  if (empty($output['error'])) {
35
  switch ($type) {
36
- case 'save_setting' :
37
- $option = (isset($data['option']) && is_string($data['option'])) ? esc_html($data['option']) : false;
38
- $value = (isset($data['value'])) ? self::sanitizeValue($data['value']) : false;
39
- $enabled = (isset($data['enabled'])) ? filter_var($data['enabled'], FILTER_VALIDATE_BOOLEAN) : false;
40
- $append = (isset($data['append'])) ? filter_var($data['append'], FILTER_VALIDATE_BOOLEAN) : false;
41
-
42
- if (!$option) {
43
- $output['error'] = __('Missing option name.', WP_GDPR_C_SLUG);
44
- }
45
-
46
- if (!isset($data['value'])) {
47
- $output['error'] = __('Missing value.', WP_GDPR_C_SLUG);
48
- }
49
-
50
- // Let's do this!
51
- if (empty($output['error'])) {
52
- if ($append) {
53
- $values = (array)get_option($option, array());
54
- if ($enabled) {
55
- if (!in_array($value, $values)) {
56
- $values[] = $value;
57
- }
58
- } else {
59
- $index = array_search($value, $values);
60
- if ($index !== false) {
61
- unset($values[$index]);
62
- }
63
- }
64
- $value = $values;
65
- } else {
66
- if (isset($data['enabled'])) {
67
- $value = $enabled;
68
- }
69
- }
70
- update_option($option, $value);
71
- do_action($option, $value);
72
- }
73
- break;
74
  case 'access_request' :
75
  if (Helper::isEnabled('enable_access_request', 'settings')) {
76
  $emailAddress = (isset($data['email']) && is_email($data['email'])) ? $data['email'] : false;
@@ -92,6 +122,7 @@ class Ajax {
92
  $request->setEmailAddress($emailAddress);
93
  $request->setSessionId(SessionHelper::getSessionId());
94
  $request->setIpAddress(Helper::getClientIpAddress());
 
95
  $request->setExpired(0);
96
  $id = $request->save();
97
  if ($id !== false) {
@@ -101,10 +132,7 @@ class Ajax {
101
  '<a target="_blank" href="%s">%s</a>',
102
  add_query_arg(
103
  array(
104
- 'wpgdprc' => base64_encode(serialize(array(
105
- 'email' => $request->getEmailAddress(),
106
- 'sId' => $request->getSessionId()
107
- )))
108
  ),
109
  get_permalink($page)
110
  ),
@@ -159,13 +187,13 @@ class Ajax {
159
  break;
160
  case 'delete_request' :
161
  if (Helper::isEnabled('enable_access_request', 'settings')) {
162
- $session = (isset($data['session'])) ? esc_html($data['session']) : '';
163
  $settings = (isset($data['settings']) && is_array($data['settings'])) ? $data['settings'] : array();
164
  $type = (isset($settings['type']) && in_array($settings['type'], Data::getPossibleDataTypes())) ? $settings['type'] : '';
165
  $value = (isset($data['value']) && is_numeric($data['value'])) ? (int)$data['value'] : 0;
166
 
167
- if (empty($session)) {
168
- $output['error'] = __('Missing session.', WP_GDPR_C_SLUG);
169
  }
170
 
171
  if (empty($type)) {
@@ -178,8 +206,7 @@ class Ajax {
178
 
179
  // Let's do this!
180
  if (empty($output['error'])) {
181
- $accessRequest = unserialize(base64_decode($session));
182
- $accessRequest = (!empty($accessRequest)) ? AccessRequest::getInstance()->getByEmailAddressAndSessionId($accessRequest['email'], $accessRequest['sId']) : false;
183
  if ($accessRequest !== false) {
184
  if (
185
  SessionHelper::checkSession($accessRequest->getSessionId()) &&
10
  /** @var null */
11
  private static $instance = null;
12
 
13
+ public function processSettings() {
14
+ check_ajax_referer('wpgdprc', 'security');
15
+
16
+ $output = array(
17
+ 'message' => '',
18
+ 'error' => '',
19
+ );
20
+ $data = (isset($_POST['data']) && (is_array($_POST['data']) || is_string($_POST['data']))) ? $_POST['data'] : false;
21
+ if (is_string($data)) {
22
+ $data = json_decode(stripslashes($data), true);
23
+ }
24
+
25
+ if (!$data) {
26
+ $output['error'] = __('Missing data.', WP_GDPR_C_SLUG);
27
+ }
28
+
29
+ if (empty($output['error'])) {
30
+ $option = (isset($data['option']) && is_string($data['option'])) ? esc_html($data['option']) : false;
31
+ $value = (isset($data['value'])) ? self::sanitizeValue($data['value']) : false;
32
+ $enabled = (isset($data['enabled'])) ? filter_var($data['enabled'], FILTER_VALIDATE_BOOLEAN) : false;
33
+ $append = (isset($data['append'])) ? filter_var($data['append'], FILTER_VALIDATE_BOOLEAN) : false;
34
+
35
+ if (!$option) {
36
+ $output['error'] = __('Missing option name.', WP_GDPR_C_SLUG);
37
+ }
38
+
39
+ if (!current_user_can('manage_options')) {
40
+ $output['error'] = __('You\'re not allowed to manage settings.', WP_GDPR_C_SLUG);
41
+ }
42
+
43
+ if (!in_array($option, Helper::getAvailableOptions())) {
44
+ $output['error'] = __('You\'re not allowed to manage this setting.', WP_GDPR_C_SLUG);
45
+ }
46
+
47
+ if (!isset($data['value'])) {
48
+ $output['error'] = __('Missing value.', WP_GDPR_C_SLUG);
49
+ }
50
+
51
+ // Let's do this!
52
+ if (empty($output['error'])) {
53
+ if ($append) {
54
+ $values = (array)get_option($option, array());
55
+ if ($enabled) {
56
+ if (!in_array($value, $values)) {
57
+ $values[] = $value;
58
+ }
59
+ } else {
60
+ $index = array_search($value, $values);
61
+ if ($index !== false) {
62
+ unset($values[$index]);
63
+ }
64
+ }
65
+ $value = $values;
66
+ } else {
67
+ if (isset($data['enabled'])) {
68
+ $value = $enabled;
69
+ }
70
+ }
71
+ update_option($option, $value);
72
+ do_action($option, $value);
73
+ }
74
+ }
75
+
76
+ header('Content-type: application/json');
77
+ echo json_encode($output);
78
+ die();
79
+ }
80
+
81
  public function processAction() {
82
  check_ajax_referer('wpgdprc', 'security');
83
 
101
 
102
  if (empty($output['error'])) {
103
  switch ($type) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  case 'access_request' :
105
  if (Helper::isEnabled('enable_access_request', 'settings')) {
106
  $emailAddress = (isset($data['email']) && is_email($data['email'])) ? $data['email'] : false;
122
  $request->setEmailAddress($emailAddress);
123
  $request->setSessionId(SessionHelper::getSessionId());
124
  $request->setIpAddress(Helper::getClientIpAddress());
125
+ $request->setToken(substr(md5(openssl_random_pseudo_bytes(20)), -32));
126
  $request->setExpired(0);
127
  $id = $request->save();
128
  if ($id !== false) {
132
  '<a target="_blank" href="%s">%s</a>',
133
  add_query_arg(
134
  array(
135
+ 'wpgdprc' => urlencode($request->getToken())
 
 
 
136
  ),
137
  get_permalink($page)
138
  ),
187
  break;
188
  case 'delete_request' :
189
  if (Helper::isEnabled('enable_access_request', 'settings')) {
190
+ $token = (isset($data['token'])) ? esc_html(urldecode($data['token'])) : false;
191
  $settings = (isset($data['settings']) && is_array($data['settings'])) ? $data['settings'] : array();
192
  $type = (isset($settings['type']) && in_array($settings['type'], Data::getPossibleDataTypes())) ? $settings['type'] : '';
193
  $value = (isset($data['value']) && is_numeric($data['value'])) ? (int)$data['value'] : 0;
194
 
195
+ if (empty($token)) {
196
+ $output['error'] = __('Missing token.', WP_GDPR_C_SLUG);
197
  }
198
 
199
  if (empty($type)) {
206
 
207
  // Let's do this!
208
  if (empty($output['error'])) {
209
+ $accessRequest = ($token !== false) ? AccessRequest::getInstance()->getByToken($token) : false;
 
210
  if ($accessRequest !== false) {
211
  if (
212
  SessionHelper::checkSession($accessRequest->getSessionId()) &&
Includes/Consent.php CHANGED
@@ -169,7 +169,7 @@ class Consent {
169
 
170
  public function load() {
171
  global $wpdb;
172
- $query = "SELECT * FROM `" . self::getDatabaseTableName() . "` WHERE `ID` = '%d'";
173
  $row = $wpdb->get_row($wpdb->prepare($query, $this->getId()));
174
  if ($row !== null) {
175
  $this->loadByRow($row);
@@ -184,7 +184,7 @@ class Consent {
184
  global $wpdb;
185
  $row = $wpdb->get_row(
186
  $wpdb->prepare(
187
- "SELECT * FROM `" . self::getDatabaseTableName() . "` WHERE `ID` = '%d'",
188
  intval($id)
189
  )
190
  );
169
 
170
  public function load() {
171
  global $wpdb;
172
+ $query = "SELECT * FROM `" . self::getDatabaseTableName() . "` WHERE `ID` = %d";
173
  $row = $wpdb->get_row($wpdb->prepare($query, $this->getId()));
174
  if ($row !== null) {
175
  $this->loadByRow($row);
184
  global $wpdb;
185
  $row = $wpdb->get_row(
186
  $wpdb->prepare(
187
+ "SELECT * FROM `" . self::getDatabaseTableName() . "` WHERE `ID` = %d",
188
  intval($id)
189
  )
190
  );
Includes/Data.php CHANGED
@@ -190,7 +190,7 @@ class Data {
190
  public function getUsers() {
191
  global $wpdb;
192
  $output = array();
193
- $query = "SELECT * FROM `" . $wpdb->users . "` WHERE `user_email` = '%s'";
194
  $results = $wpdb->get_results($wpdb->prepare($query, $this->getEmailAddress()));
195
  if ($results !== null) {
196
  foreach ($results as $row) {
@@ -207,7 +207,7 @@ class Data {
207
  public function getComments() {
208
  global $wpdb;
209
  $output = array();
210
- $query = "SELECT * FROM " . $wpdb->comments . " WHERE `comment_author_email` = '%s'";
211
  $results = $wpdb->get_results($wpdb->prepare($query, $this->getEmailAddress()));
212
  if ($results !== null) {
213
  foreach ($results as $row) {
@@ -225,7 +225,7 @@ class Data {
225
  public function getWooCommerceOrders() {
226
  global $wpdb;
227
  $output = array();
228
- $query = "SELECT * FROM " . $wpdb->postmeta . " WHERE `meta_key` = '_billing_email' AND `meta_value` = '%s'";
229
  $results = $wpdb->get_results($wpdb->prepare($query, $this->getEmailAddress()));
230
  if ($results !== null) {
231
  foreach ($results as $row) {
190
  public function getUsers() {
191
  global $wpdb;
192
  $output = array();
193
+ $query = "SELECT * FROM `" . $wpdb->users . "` WHERE `user_email` = %s";
194
  $results = $wpdb->get_results($wpdb->prepare($query, $this->getEmailAddress()));
195
  if ($results !== null) {
196
  foreach ($results as $row) {
207
  public function getComments() {
208
  global $wpdb;
209
  $output = array();
210
+ $query = "SELECT * FROM " . $wpdb->comments . " WHERE `comment_author_email` = %s";
211
  $results = $wpdb->get_results($wpdb->prepare($query, $this->getEmailAddress()));
212
  if ($results !== null) {
213
  foreach ($results as $row) {
225
  public function getWooCommerceOrders() {
226
  global $wpdb;
227
  $output = array();
228
+ $query = "SELECT * FROM " . $wpdb->postmeta . " WHERE `meta_key` = '_billing_email' AND `meta_value` = %s";
229
  $results = $wpdb->get_results($wpdb->prepare($query, $this->getEmailAddress()));
230
  if ($results !== null) {
231
  foreach ($results as $row) {
Includes/Data/Comment.php CHANGED
@@ -37,7 +37,7 @@ class Comment {
37
 
38
  public function load() {
39
  global $wpdb;
40
- $query = "SELECT * FROM `" . $wpdb->users . "` WHERE `ID` = '%d'";
41
  $row = $wpdb->get_row($wpdb->prepare($query, $this->getId()));
42
  if ($row !== null) {
43
  $this->loadByRow($row);
37
 
38
  public function load() {
39
  global $wpdb;
40
+ $query = "SELECT * FROM `" . $wpdb->users . "` WHERE `ID` = %d";
41
  $row = $wpdb->get_row($wpdb->prepare($query, $this->getId()));
42
  if ($row !== null) {
43
  $this->loadByRow($row);
Includes/Data/User.php CHANGED
@@ -38,7 +38,7 @@ class User {
38
 
39
  public function load() {
40
  global $wpdb;
41
- $query = "SELECT * FROM `" . $wpdb->users . "` WHERE `ID` = '%d'";
42
  $row = $wpdb->get_row($wpdb->prepare($query, $this->getId()));
43
  if ($row !== null) {
44
  $this->loadByRow($row);
@@ -68,7 +68,7 @@ class User {
68
  public function getMetaDataByUserId($userId = 0) {
69
  global $wpdb;
70
  $output = array();
71
- $query = "SELECT * FROM `" . $wpdb->usermeta . "` WHERE `user_id` = '%d'";
72
  $results = $wpdb->get_results($wpdb->prepare($query, $userId));
73
  if ($results !== null) {
74
  foreach ($results as $row) {
38
 
39
  public function load() {
40
  global $wpdb;
41
+ $query = "SELECT * FROM `" . $wpdb->users . "` WHERE `ID` = %d";
42
  $row = $wpdb->get_row($wpdb->prepare($query, $this->getId()));
43
  if ($row !== null) {
44
  $this->loadByRow($row);
68
  public function getMetaDataByUserId($userId = 0) {
69
  global $wpdb;
70
  $output = array();
71
+ $query = "SELECT * FROM `" . $wpdb->usermeta . "` WHERE `user_id` = %d";
72
  $results = $wpdb->get_results($wpdb->prepare($query, $userId));
73
  if ($results !== null) {
74
  foreach ($results as $row) {
Includes/DeleteRequest.php CHANGED
@@ -48,10 +48,10 @@ class DeleteRequest {
48
  public function getByTypeAndDataIdAndAccessRequestId($type = '', $dataId = 0, $accessRequestId = 0) {
49
  global $wpdb;
50
  $query = "SELECT `ID` FROM `" . self::getDatabaseTableName() . "`";
51
- $query .= " WHERE `type` = '%s'";
52
- $query .= " AND `data_id` = '%d'";
53
- $query .= " AND `access_request_id` = '%d'";
54
- $query .= " AND `site_id` = '%d'";
55
  $result = $wpdb->get_row($wpdb->prepare($query, $type, $dataId, $accessRequestId, get_current_blog_id()));
56
  if ($result !== null) {
57
  return new self($result->ID);
@@ -66,9 +66,9 @@ class DeleteRequest {
66
  public function getAmountByAccessRequestId($accessRequestId = 0) {
67
  global $wpdb;
68
  $query = "SELECT COUNT(`ID`) FROM `" . self::getDatabaseTableName() . "`";
69
- $query .= " WHERE `access_request_id` = '%d'";
70
  $query .= " AND `processed` = '0'";
71
- $query .= " AND `site_id` = '%d'";
72
  $result = $wpdb->get_var($wpdb->prepare($query, intval($accessRequestId), get_current_blog_id()));
73
  if ($result !== null) {
74
  return absint($result);
@@ -136,7 +136,7 @@ class DeleteRequest {
136
 
137
  public function load() {
138
  global $wpdb;
139
- $query = "SELECT * FROM `" . self::getDatabaseTableName() . "` WHERE `ID` = '%d'";
140
  $row = $wpdb->get_row($wpdb->prepare($query, $this->getId()));
141
  if ($row !== null) {
142
  $this->loadByRow($row);
@@ -151,7 +151,7 @@ class DeleteRequest {
151
  global $wpdb;
152
  $row = $wpdb->get_row(
153
  $wpdb->prepare(
154
- "SELECT * FROM `" . self::getDatabaseTableName() . "` WHERE `ID` = '%d'",
155
  intval($id)
156
  )
157
  );
48
  public function getByTypeAndDataIdAndAccessRequestId($type = '', $dataId = 0, $accessRequestId = 0) {
49
  global $wpdb;
50
  $query = "SELECT `ID` FROM `" . self::getDatabaseTableName() . "`";
51
+ $query .= " WHERE `type` = %s";
52
+ $query .= " AND `data_id` = %d";
53
+ $query .= " AND `access_request_id` = %d";
54
+ $query .= " AND `site_id` = %d";
55
  $result = $wpdb->get_row($wpdb->prepare($query, $type, $dataId, $accessRequestId, get_current_blog_id()));
56
  if ($result !== null) {
57
  return new self($result->ID);
66
  public function getAmountByAccessRequestId($accessRequestId = 0) {
67
  global $wpdb;
68
  $query = "SELECT COUNT(`ID`) FROM `" . self::getDatabaseTableName() . "`";
69
+ $query .= " WHERE `access_request_id` = %d";
70
  $query .= " AND `processed` = '0'";
71
+ $query .= " AND `site_id` = %d";
72
  $result = $wpdb->get_var($wpdb->prepare($query, intval($accessRequestId), get_current_blog_id()));
73
  if ($result !== null) {
74
  return absint($result);
136
 
137
  public function load() {
138
  global $wpdb;
139
+ $query = "SELECT * FROM `" . self::getDatabaseTableName() . "` WHERE `ID` = %d";
140
  $row = $wpdb->get_row($wpdb->prepare($query, $this->getId()));
141
  if ($row !== null) {
142
  $this->loadByRow($row);
151
  global $wpdb;
152
  $row = $wpdb->get_row(
153
  $wpdb->prepare(
154
+ "SELECT * FROM `" . self::getDatabaseTableName() . "` WHERE `ID` = %d",
155
  intval($id)
156
  )
157
  );
Includes/Helper.php CHANGED
@@ -485,6 +485,57 @@ class Helper {
485
  return $output;
486
  }
487
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
488
  /**
489
  * @return bool|\WP_Post
490
  */
485
  return $output;
486
  }
487
 
488
+ /**
489
+ * This function returns all available options used by the WPGDPRC plugin.
490
+ * NOTE: Keep this list updated in case of newly added/updated options.
491
+ *
492
+ * @return array
493
+ */
494
+ public static function getAvailableOptions() {
495
+ $output = array();
496
+
497
+ // Settings for activated plugins
498
+ $activatedPlugins = Helper::getActivatedPlugins();
499
+ foreach ($activatedPlugins as $plugin) {
500
+ $output[] = WP_GDPR_C_PREFIX . '_integrations_' . $plugin['id'];
501
+ $output[] = WP_GDPR_C_PREFIX . '_integrations_' . $plugin['id'] . '_form_text';
502
+ $output[] = WP_GDPR_C_PREFIX . '_integrations_' . $plugin['id'] . '_error_message';
503
+ switch ($plugin['id']) {
504
+ case 'gravity-forms' :
505
+ case 'contact-form-7' :
506
+ $output[] = WP_GDPR_C_PREFIX . '_integrations_' . $plugin['id'] . '_forms';
507
+ break;
508
+ }
509
+ switch ($plugin['id']) {
510
+ case 'gravity-forms' :
511
+ case 'woocommerce' :
512
+ case 'wordpress' :
513
+ $output[] = WP_GDPR_C_PREFIX . '_integrations_' . $plugin['id'] . '_required_message';
514
+ break;
515
+ }
516
+ }
517
+
518
+ // Settings for the checklist
519
+ foreach (Helper::getCheckList() as $id => $check) {
520
+ $output[] = WP_GDPR_C_PREFIX . '_general_' . $id;
521
+ }
522
+
523
+ // Settings for the general things
524
+ $output[] = WP_GDPR_C_PREFIX . '_settings_privacy_policy_page';
525
+ $output[] = WP_GDPR_C_PREFIX . '_settings_privacy_policy_text';
526
+ $output[] = WP_GDPR_C_PREFIX . '_settings_enable_access_request';
527
+ if (Helper::isEnabled('enable_access_request', 'settings')) {
528
+ $output[] = WP_GDPR_C_PREFIX . '_settings_access_request_page';
529
+ $output[] = WP_GDPR_C_PREFIX . '_settings_access_request_form_checkbox_text';
530
+ $output[] = WP_GDPR_C_PREFIX . '_settings_delete_request_form_explanation_text';
531
+ }
532
+ $output[] = WP_GDPR_C_PREFIX . '_settings_consents_modal_title';
533
+ $output[] = WP_GDPR_C_PREFIX . '_settings_consents_modal_explanation_text';
534
+ $output[] = WP_GDPR_C_PREFIX . '_settings_consents_bar_explanation_text';
535
+
536
+ return $output;
537
+ }
538
+
539
  /**
540
  * @return bool|\WP_Post
541
  */
Includes/Integration.php CHANGED
@@ -113,7 +113,7 @@ class Integration {
113
  $errorMessage = CF7::getInstance()->getErrorMessage($form);
114
  $output .= '<li class="wpgdprc-clearfix">';
115
  $output .= '<div class="wpgdprc-checkbox">';
116
- $output .= '<input type="checkbox" name="' . $optionNameForms . '[]" id="' . $formSettingId . '" value="' . $form . '" tabindex="1" data-type="save_setting" data-option="' . $optionNameForms . '" data-append="1" ' . checked(true, $enabled, false) . ' />';
117
  $output .= '<label for="' . $formSettingId . '"><strong>' . sprintf(__('Form: %s', WP_GDPR_C_SLUG), get_the_title($form)) . '</strong></label>';
118
  $output .= '<span class="wpgdprc-instructions">' . __('Activate for this form:', WP_GDPR_C_SLUG) . '</span>';
119
  $output .= '</div>';
@@ -157,7 +157,7 @@ class Integration {
157
  $requiredMessage = esc_html(GForms::getInstance()->getRequiredMessage($form['id']));
158
  $output .= '<li class="wpgdprc-clearfix">';
159
  $output .= '<div class="wpgdprc-checkbox">';
160
- $output .= '<input type="checkbox" name="' . $optionNameForms . '[]" id="' . $formSettingId . '" value="' . $form['id'] . '" tabindex="1" data-type="save_setting" data-option="' . $optionNameForms . '" data-append="1" ' . checked(true, $enabled, false) . ' />';
161
  $output .= '<label for="' . $formSettingId . '"><strong>' . sprintf(__('Form: %s', WP_GDPR_C_SLUG), $form['title']) . '</strong></label>';
162
  $output .= '<span class="wpgdprc-instructions">' . __('Activate for this form:', WP_GDPR_C_SLUG) . '</span>';
163
  $output .= '</div>';
113
  $errorMessage = CF7::getInstance()->getErrorMessage($form);
114
  $output .= '<li class="wpgdprc-clearfix">';
115
  $output .= '<div class="wpgdprc-checkbox">';
116
+ $output .= '<input type="checkbox" name="' . $optionNameForms . '[]" id="' . $formSettingId . '" value="' . $form . '" tabindex="1" data-option="' . $optionNameForms . '" data-append="1" ' . checked(true, $enabled, false) . ' />';
117
  $output .= '<label for="' . $formSettingId . '"><strong>' . sprintf(__('Form: %s', WP_GDPR_C_SLUG), get_the_title($form)) . '</strong></label>';
118
  $output .= '<span class="wpgdprc-instructions">' . __('Activate for this form:', WP_GDPR_C_SLUG) . '</span>';
119
  $output .= '</div>';
157
  $requiredMessage = esc_html(GForms::getInstance()->getRequiredMessage($form['id']));
158
  $output .= '<li class="wpgdprc-clearfix">';
159
  $output .= '<div class="wpgdprc-checkbox">';
160
+ $output .= '<input type="checkbox" name="' . $optionNameForms . '[]" id="' . $formSettingId . '" value="' . $form['id'] . '" tabindex="1" data-option="' . $optionNameForms . '" data-append="1" ' . checked(true, $enabled, false) . ' />';
161
  $output .= '<label for="' . $formSettingId . '"><strong>' . sprintf(__('Form: %s', WP_GDPR_C_SLUG), $form['title']) . '</strong></label>';
162
  $output .= '<span class="wpgdprc-instructions">' . __('Activate for this form:', WP_GDPR_C_SLUG) . '</span>';
163
  $output .= '</div>';
Includes/Page.php CHANGED
@@ -172,7 +172,7 @@ class Page {
172
  <?php if ($plugin['supported']) : ?>
173
  <?php if (empty($notices)) : ?>
174
  <div class="wpgdprc-checkbox">
175
- <input type="checkbox" name="<?php echo $optionName; ?>" id="<?php echo $optionName; ?>" value="1" tabindex="1" data-type="save_setting" data-option="<?php echo $optionName; ?>" <?php checked(true, $checked); ?> />
176
  <label for="<?php echo $optionName; ?>"><?php echo $plugin['name']; ?></label>
177
  <span class="wpgdprc-instructions"><?php _e('Enable:', WP_GDPR_C_SLUG); ?></span>
178
  <div class="wpgdprc-switch" aria-hidden="true">
@@ -250,7 +250,7 @@ class Page {
250
  ?>
251
  <li class="wpgdprc-clearfix">
252
  <div class="wpgdprc-checkbox">
253
- <input type="checkbox" name="<?php echo $optionName; ?>" id="<?php echo $id; ?>" value="1" tabindex="1" data-type="save_setting" data-option="<?php echo $optionName; ?>" <?php checked(true, $checked); ?> />
254
  <label for="<?php echo $id; ?>"><?php echo $check['label']; ?></label>
255
  <div class="wpgdprc-switch wpgdprc-switch--reverse" aria-hidden="true">
256
  <div class="wpgdprc-switch-label">
172
  <?php if ($plugin['supported']) : ?>
173
  <?php if (empty($notices)) : ?>
174
  <div class="wpgdprc-checkbox">
175
+ <input type="checkbox" name="<?php echo $optionName; ?>" id="<?php echo $optionName; ?>" value="1" tabindex="1" data-option="<?php echo $optionName; ?>" <?php checked(true, $checked); ?> />
176
  <label for="<?php echo $optionName; ?>"><?php echo $plugin['name']; ?></label>
177
  <span class="wpgdprc-instructions"><?php _e('Enable:', WP_GDPR_C_SLUG); ?></span>
178
  <div class="wpgdprc-switch" aria-hidden="true">
250
  ?>
251
  <li class="wpgdprc-clearfix">
252
  <div class="wpgdprc-checkbox">
253
+ <input type="checkbox" name="<?php echo $optionName; ?>" id="<?php echo $id; ?>" value="1" tabindex="1" data-option="<?php echo $optionName; ?>" <?php checked(true, $checked); ?> />
254
  <label for="<?php echo $id; ?>"><?php echo $check['label']; ?></label>
255
  <div class="wpgdprc-switch wpgdprc-switch--reverse" aria-hidden="true">
256
  <div class="wpgdprc-switch-label">
Includes/Shortcode.php CHANGED
@@ -15,8 +15,8 @@ class Shortcode {
15
  */
16
  private static function getAccessRequestData() {
17
  $output = '';
18
- $request = (isset($_REQUEST['wpgdprc'])) ? unserialize(base64_decode(esc_html($_REQUEST['wpgdprc']))) : false;
19
- $request = (!empty($request)) ? AccessRequest::getInstance()->getByEmailAddressAndSessionId($request['email'], $request['sId']) : false;
20
  if ($request !== false) {
21
  if (
22
  SessionHelper::checkSession($request->getSessionId()) &&
15
  */
16
  private static function getAccessRequestData() {
17
  $output = '';
18
+ $token = (isset($_REQUEST['wpgdprc'])) ? esc_html(urldecode($_REQUEST['wpgdprc'])) : false;
19
+ $request = ($token !== false) ? AccessRequest::getInstance()->getByToken($token) : false;
20
  if ($request !== false) {
21
  if (
22
  SessionHelper::checkSession($request->getSessionId()) &&
assets/js/admin.js CHANGED
@@ -54,7 +54,7 @@
54
  * @param $element
55
  * @private
56
  */
57
- _doProcessAction = function ($element) {
58
  $element.addClass('processing');
59
  var $checkboxContainer = $element.closest('.wpgdprc-checkbox'),
60
  $checkboxData = ($checkboxContainer.length) ? $checkboxContainer.next('.wpgdprc-checkbox-data') : false;
@@ -63,26 +63,28 @@
63
  type: 'POST',
64
  dataType: 'JSON',
65
  data: {
66
- action: 'wpgdprc_process_action',
67
  security: ajaxSecurity,
68
  data: _getElementAjaxData($element)
69
  },
70
  success: function (response) {
71
  if (response) {
72
- if ($checkboxData.length) {
73
  if ($element.is(':checked')) {
74
- $checkboxData.stop(true, true).slideDown('fast');
75
- } else {
76
- $checkboxData.stop(true, true).slideUp('fast');
77
  }
78
- }
79
-
80
- if (response.error) {
81
  $element.addClass('alert');
82
- }
83
-
84
- if (response.redirect) {
85
- document.location.href = currentPage;
 
 
 
 
 
 
 
86
  }
87
  }
88
  },
@@ -143,9 +145,9 @@
143
  return;
144
  }
145
  $checkbox.on('change', function (e) {
146
- if ($(this).data('type')) {
147
  e.preventDefault();
148
- _doProcessAction($(this));
149
  }
150
  });
151
  },
54
  * @param $element
55
  * @private
56
  */
57
+ _doProcessSettings = function ($element) {
58
  $element.addClass('processing');
59
  var $checkboxContainer = $element.closest('.wpgdprc-checkbox'),
60
  $checkboxData = ($checkboxContainer.length) ? $checkboxContainer.next('.wpgdprc-checkbox-data') : false;
63
  type: 'POST',
64
  dataType: 'JSON',
65
  data: {
66
+ action: 'wpgdprc_process_settings',
67
  security: ajaxSecurity,
68
  data: _getElementAjaxData($element)
69
  },
70
  success: function (response) {
71
  if (response) {
72
+ if (response.error) {
73
  if ($element.is(':checked')) {
74
+ $element.prop('checked', false);
 
 
75
  }
 
 
 
76
  $element.addClass('alert');
77
+ } else {
78
+ if ($checkboxData.length) {
79
+ if ($element.is(':checked')) {
80
+ $checkboxData.stop(true, true).slideDown('fast');
81
+ } else {
82
+ $checkboxData.stop(true, true).slideUp('fast');
83
+ }
84
+ }
85
+ if (response.redirect) {
86
+ document.location.href = currentPage;
87
+ }
88
  }
89
  }
90
  },
145
  return;
146
  }
147
  $checkbox.on('change', function (e) {
148
+ if ($(this).data('option')) {
149
  e.preventDefault();
150
+ _doProcessSettings($(this));
151
  }
152
  });
153
  },
assets/js/front.js CHANGED
@@ -285,7 +285,7 @@
285
  security: ajaxSecurity,
286
  data: {
287
  type: 'delete_request',
288
- session: wpgdprcData.session,
289
  settings: JSON.parse($this.dataset.wpgdprc)
290
  }
291
  };
285
  security: ajaxSecurity,
286
  data: {
287
  type: 'delete_request',
288
+ token: wpgdprcData.token,
289
  settings: JSON.parse($this.dataset.wpgdprc)
290
  }
291
  };
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: gdpr, law, regulations, compliance, data, protection, privacy, data protec
4
  Requires at least: 4.5
5
  Tested up to: 4.9.4
6
  Requires PHP: 5.3
7
- Stable tag: 1.4.2
8
  License: GPLv2 or later
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -39,6 +39,12 @@ You'll find answers to many of your questions on [wpgdprc.com](https://www.wpgdp
39
 
40
  == Changelog ==
41
 
 
 
 
 
 
 
42
  = 1.4.2 =
43
  *Release date: July 6th, 2018*
44
  * Added the ability to add required 'Consents'. These Consents will always be triggered on page load.
4
  Requires at least: 4.5
5
  Tested up to: 4.9.4
6
  Requires PHP: 5.3
7
+ Stable tag: 1.4.3
8
  License: GPLv2 or later
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
10
 
39
 
40
  == Changelog ==
41
 
42
+ = 1.4.3 =
43
+ *Release date: November 7th, 2018*
44
+ * Security fix: Removed base64_decode() function.
45
+ * Security fix: Correctly escape input in $wpdb->prepare() function.
46
+ * Security fix: Only allow modifying WordPress options used by the plugin and by the user capabilities.
47
+
48
  = 1.4.2 =
49
  *Release date: July 6th, 2018*
50
  * Added the ability to add required 'Consents'. These Consents will always be triggered on page load.
wp-gdpr-compliance.php CHANGED
@@ -4,7 +4,7 @@
4
  Plugin Name: WP GDPR Compliance
5
  Plugin URI: https://www.wpgdprc.com/
6
  Description: This plugin assists website and webshop owners to comply with European privacy regulations known as GDPR. By May 24th, 2018 your website or shop has to comply to avoid large fines.
7
- Version: 1.4.2
8
  Author: Van Ons
9
  Author URI: https://www.van-ons.nl/
10
  License: GPL2
@@ -30,6 +30,7 @@ along with this program. If not, see http://www.gnu.org/licenses.
30
 
31
  namespace WPGDPRC;
32
 
 
33
  use WPGDPRC\Includes\Action;
34
  use WPGDPRC\Includes\Ajax;
35
  use WPGDPRC\Includes\Consent;
@@ -93,8 +94,9 @@ class WPGDPRC {
93
  add_action('wp_enqueue_scripts', array($this, 'loadAssets'), 999);
94
  add_action('admin_enqueue_scripts', array($this, 'loadAdminAssets'), 999);
95
  add_action('core_version_check_query_args', array(Action::getInstance(), 'onlySendEssentialDataDuringUpdateCheck'));
96
- add_action('wp_ajax_nopriv_wpgdprc_process_action', array(Ajax::getInstance(), 'processAction'));
97
  add_action('wp_ajax_wpgdprc_process_action', array(Ajax::getInstance(), 'processAction'));
 
98
  add_action('update_option_wpgdprc_settings_enable_access_request', array(Action::getInstance(), 'processToggleAccessRequest'));
99
  Integration::getInstance();
100
  if (Helper::isEnabled('enable_access_request', 'settings')) {
@@ -130,7 +132,7 @@ class WPGDPRC {
130
 
131
  public static function handleDatabaseTables() {
132
  $dbVersion = get_option('wpgdprc_db_version', 0);
133
- if (version_compare($dbVersion, '1.2', '==')) {
134
  return;
135
  }
136
 
@@ -172,6 +174,14 @@ class WPGDPRC {
172
  $wpdb->query($query);
173
  update_option('wpgdprc_db_version', '1.2');
174
  }
 
 
 
 
 
 
 
 
175
  }
176
 
177
  /**
@@ -198,7 +208,7 @@ class WPGDPRC {
198
  'ajaxSecurity' => wp_create_nonce('wpgdprc'),
199
  );
200
  if (!empty($_REQUEST['wpgdprc'])) {
201
- $data['session'] = esc_html($_REQUEST['wpgdprc']);
202
  }
203
  wp_localize_script('wpgdprc.js', 'wpgdprcData', $data);
204
  }
4
  Plugin Name: WP GDPR Compliance
5
  Plugin URI: https://www.wpgdprc.com/
6
  Description: This plugin assists website and webshop owners to comply with European privacy regulations known as GDPR. By May 24th, 2018 your website or shop has to comply to avoid large fines.
7
+ Version: 1.4.3
8
  Author: Van Ons
9
  Author URI: https://www.van-ons.nl/
10
  License: GPL2
30
 
31
  namespace WPGDPRC;
32
 
33
+ use WPGDPRC\Includes\AccessRequest;
34
  use WPGDPRC\Includes\Action;
35
  use WPGDPRC\Includes\Ajax;
36
  use WPGDPRC\Includes\Consent;
94
  add_action('wp_enqueue_scripts', array($this, 'loadAssets'), 999);
95
  add_action('admin_enqueue_scripts', array($this, 'loadAdminAssets'), 999);
96
  add_action('core_version_check_query_args', array(Action::getInstance(), 'onlySendEssentialDataDuringUpdateCheck'));
97
+ add_action('wp_ajax_wpgdprc_process_settings', array(Ajax::getInstance(), 'processSettings'));
98
  add_action('wp_ajax_wpgdprc_process_action', array(Ajax::getInstance(), 'processAction'));
99
+ add_action('wp_ajax_nopriv_wpgdprc_process_action', array(Ajax::getInstance(), 'processAction'));
100
  add_action('update_option_wpgdprc_settings_enable_access_request', array(Action::getInstance(), 'processToggleAccessRequest'));
101
  Integration::getInstance();
102
  if (Helper::isEnabled('enable_access_request', 'settings')) {
132
 
133
  public static function handleDatabaseTables() {
134
  $dbVersion = get_option('wpgdprc_db_version', 0);
135
+ if (version_compare($dbVersion, '1.3', '==')) {
136
  return;
137
  }
138
 
174
  $wpdb->query($query);
175
  update_option('wpgdprc_db_version', '1.2');
176
  }
177
+
178
+ // Add column 'token' to 'Access Requests' table
179
+ if (version_compare($dbVersion, '1.3', '<')) {
180
+ $query = "ALTER TABLE `" . AccessRequest::getDatabaseTableName() . "`
181
+ ADD column `token` text NOT NULL AFTER `ip_address`;";
182
+ $wpdb->query($query);
183
+ update_option('wpgdprc_db_version', '1.3');
184
+ }
185
  }
186
 
187
  /**
208
  'ajaxSecurity' => wp_create_nonce('wpgdprc'),
209
  );
210
  if (!empty($_REQUEST['wpgdprc'])) {
211
+ $data['token'] = esc_html(urldecode($_REQUEST['wpgdprc']));
212
  }
213
  wp_localize_script('wpgdprc.js', 'wpgdprcData', $data);
214
  }