Skip to content

Commit 4d52406

Browse files
Merge pull request #18 from alvinjohnsonso/feature/request-auth-validation
feature/request-auth-validation - used application/json content type for ajax requests - added nonces to do CSRF checking - added user access checks for ajax urls
2 parents 96d1d17 + 13c6a1a commit 4d52406

File tree

7 files changed

+199
-101
lines changed

7 files changed

+199
-101
lines changed
Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,26 @@
11
jQuery(function() {
22
document.getElementById("defaultOpen").click();
33

4-
console.log(jQuery("#always_display").prop("checked"));
5-
if(jQuery("#always_display").prop("checked")){
4+
if (jQuery("#always_display").prop("checked")) {
65
jQuery('.twk_selected_display').hide();
76
jQuery('#show_onfrontpage').prop('disabled', true);
87
jQuery('#show_oncategory').prop('disabled', true);
98
jQuery('#show_ontagpage').prop('disabled', true);
109
jQuery('#show_onarticlepages').prop('disabled', true);
1110
jQuery('#include_url').prop('disabled', true);
12-
}else{
11+
} else {
1312
jQuery('.twk_selected_display').show();
14-
1513
}
1614

1715
jQuery("#always_display").change(function() {
18-
if(this.checked){
16+
if (this.checked) {
1917
jQuery('.twk_selected_display').fadeOut();
2018
jQuery('#show_onfrontpage').prop('disabled', true);
2119
jQuery('#show_oncategory').prop('disabled', true);
2220
jQuery('#show_ontagpage').prop('disabled', true);
2321
jQuery('#show_onarticlepages').prop('disabled', true);
2422
jQuery('#include_url').prop('disabled', true);
25-
}else{
23+
} else {
2624
jQuery('.twk_selected_display').fadeIn();
2725
jQuery('#show_onfrontpage').prop('disabled', false);
2826
jQuery('#show_oncategory').prop('disabled', false);
@@ -32,31 +30,29 @@ jQuery(function() {
3230
}
3331
});
3432

35-
3633
jQuery("#exclude_url").change(function() {
37-
if(this.checked){
34+
if (this.checked) {
3835
jQuery("#exlucded_urls_container").fadeIn();
39-
}else{
36+
} else {
4037
jQuery("#exlucded_urls_container").fadeOut();
4138
}
4239
});
4340

44-
if(jQuery("#include_url").prop("checked")){
41+
if (jQuery("#include_url").prop("checked")) {
4542
jQuery("#included_urls_container").show();
4643
}
4744

4845
jQuery("#include_url").change(function() {
49-
if(this.checked){
46+
if (this.checked) {
5047
jQuery("#included_urls_container").fadeIn();
51-
}else{
48+
} else {
5249
jQuery("#included_urls_container").fadeOut();
5350
}
5451
});
5552

56-
if(jQuery("#exclude_url").prop("checked")){
53+
if (jQuery("#exclude_url").prop("checked")) {
5754
jQuery("#exlucded_urls_container").fadeIn();
5855
}
59-
6056
});
6157

6258

tawkto/assets/js/tawk.selection.js

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// variables
2+
var currentHost = window.location.protocol + '//' + window.location.host;
3+
var iframeUrl = tawk_selection_data.url.iframe + '&parentDomain=' + currentHost;
4+
var baseUrl = tawk_selection_data.url.base;
5+
6+
jQuery('#tawkIframe').attr('src', iframeUrl);
7+
8+
window.addEventListener('message', function (e) {
9+
if(e.origin === baseUrl) {
10+
11+
if(e.data.action === 'setWidget') {
12+
setWidget(e);
13+
}
14+
15+
if(e.data.action === 'removeWidget') {
16+
removeWidget(e);
17+
}
18+
19+
if(e.data.action === 'reloadHeight') {
20+
reloadIframeHeight(e.data.height);
21+
}
22+
}
23+
});
24+
25+
function setWidget (e) {
26+
const data = {
27+
pageId : e.data.pageId,
28+
widgetId : e.data.widgetId,
29+
nonce : tawk_selection_data.nonce.setWidget
30+
};
31+
32+
jQuery.ajax({
33+
type : 'POST',
34+
url : ajaxurl + '?action=tawkto_setwidget',
35+
contentType : 'application/json',
36+
dataType : 'json',
37+
data : JSON.stringify(data),
38+
success : function (r) {
39+
if (!r.success) {
40+
return e.source.postMessage({action: 'setFail'}, baseUrl);
41+
}
42+
e.source.postMessage({action: 'setDone'}, baseUrl);
43+
},
44+
error : function () {
45+
e.source.postMessage({action: 'setFail'}, baseUrl);
46+
}
47+
});
48+
}
49+
50+
function removeWidget (e) {
51+
const data = {
52+
nonce : tawk_selection_data.nonce.removeWidget
53+
}
54+
55+
jQuery.ajax({
56+
type : 'POST',
57+
url : ajaxurl + '?action=tawkto_removewidget',
58+
contentType : 'application/json',
59+
dataType : 'json',
60+
data : JSON.stringify(data),
61+
success : function (r) {
62+
if (!r.success) {
63+
return e.source.postMessage({action: 'removeFail'}, baseUrl);
64+
}
65+
e.source.postMessage({action: 'removeDone'}, baseUrl);
66+
},
67+
error : function () {
68+
e.source.postMessage({action: 'removeFail'}, baseUrl);
69+
}
70+
});
71+
}
72+
73+
function reloadIframeHeight(height) {
74+
if (!height) {
75+
return;
76+
}
77+
78+
var iframe = jQuery('#tawkIframe');
79+
if (height === iframe.height()) {
80+
return;
81+
}
82+
83+
iframe.height(height);
84+
}

tawkto/readme.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
Contributors: tawkto
33
Tags: tawk,tawk.to,tawkto,chat,free chat,livechat,chat widget,plugin,chat for web,chat online,chat software,free live chat,IM Chat,,live chat,live support,live web chat,online chat,online support,snapengage,wordpress chat,wordpress live chat
44
Requires at least: 2.7
5+
Requires PHP: 5.6
56
Tested up to: 5.8
6-
Stable tag: 0.5.5
7+
Stable tag: 0.6.0
78

89
(OFFICIAL tawk.to plugin) Instantly chat with visitors on your website with the free tawk.to chat widget.
910
Website: [http://tawk.to](http://tawk.to)
@@ -55,6 +56,10 @@ Note: You will need a free tawk.to account : [Create one for free here!](https:/
5556

5657
== Changelog ==
5758

59+
= 0.6.0 =
60+
* **Security Update** Add CSRF tokens and specific action access checks.
61+
* **Security Update** Use `application/json` content type for ajax requests.
62+
5863
= 0.5.5 =
5964
* Supported version bump 5.8.
6065

tawkto/tawkto.php

Lines changed: 78 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Plugin Name: Tawk.to Live Chat
44
Plugin URI: https://www.tawk.to
55
Description: Embeds Tawk.to live chat widget to your site
6-
Version: 0.5.5
6+
Version: 0.6.0
77
Author: Tawkto
88
Text Domain: tawk-to-live-chat
99
*/
@@ -13,6 +13,8 @@ class TawkTo_Settings{
1313
const TAWK_WIDGET_ID_VARIABLE = 'tawkto-embed-widget-widget-id';
1414
const TAWK_PAGE_ID_VARIABLE = 'tawkto-embed-widget-page-id';
1515
const TAWK_VISIBILITY_OPTIONS = 'tawkto-visibility-options';
16+
const TAWK_ACTION_SET_WIDGET = 'tawkto-set-widget';
17+
const TAWK_ACTION_REMOVE_WIDGET = 'tawkto-remove-widget';
1618

1719
public function __construct(){
1820

@@ -52,10 +54,10 @@ public function tawk_settings_assets($hook)
5254
if($hook != 'settings_page_tawkto_plugin')
5355
return;
5456

55-
wp_register_style( 'tawk_admin_style', plugins_url( 'assets/tawk.admin.css' , __FILE__ ) );
56-
wp_enqueue_style( 'tawk_admin_style' );
57+
wp_register_style( 'tawk_admin_style', plugins_url( 'assets/css/tawk.admin.css' , __FILE__ ) );
58+
wp_enqueue_style( 'tawk_admin_style' );
5759

58-
wp_enqueue_script( 'tawk_admin_script', plugins_url( 'assets/tawk.admin.js' , __FILE__ ) );
60+
wp_enqueue_script( 'tawk_admin_script', plugins_url( 'assets/js/tawk.admin.js' , __FILE__ ) );
5961

6062
}
6163

@@ -66,22 +68,43 @@ public function admin_init(){
6668
public function action_setwidget() {
6769
header('Content-Type: application/json');
6870

69-
if (!isset($_POST['pageId']) || !isset($_POST['widgetId'])) {
70-
echo json_encode(array('success' => FALSE));
71-
die();
72-
}
71+
if (wp_is_json_request() === false) {
72+
$response['success'] = false;
73+
$response['message'] = 'Invalid request';
74+
wp_send_json($response);
75+
wp_die();
76+
};
77+
78+
$postData = json_decode(file_get_contents('php://input'), true);
7379

74-
if (!self::ids_are_correct($_POST['pageId'], $_POST['widgetId'])) {
75-
echo json_encode(array('success' => FALSE));
76-
die();
80+
$response = array(
81+
'success' => true
82+
);
83+
84+
if ($this->validate_request_auth($postData, self::TAWK_ACTION_SET_WIDGET) === false) {
85+
$response['success'] = false;
86+
$response['message'] = 'Unauthorized';
87+
wp_send_json($response);
88+
wp_die();
89+
};
90+
91+
if (!isset($postData['pageId']) || !isset($postData['widgetId'])) {
92+
$response['success'] = false;
93+
wp_send_json($response);
94+
wp_die();
7795
}
7896

79-
update_option(self::TAWK_PAGE_ID_VARIABLE, $_POST['pageId']);
80-
update_option(self::TAWK_WIDGET_ID_VARIABLE, $_POST['widgetId']);
97+
if (!self::ids_are_correct($postData['pageId'], $postData['widgetId'])) {
98+
$response['success'] = false;
99+
wp_send_json($response);
100+
wp_die();
101+
}
81102

103+
update_option(self::TAWK_PAGE_ID_VARIABLE, $postData['pageId']);
104+
update_option(self::TAWK_WIDGET_ID_VARIABLE, $postData['widgetId']);
82105

83-
echo json_encode(array('success' => TRUE));
84-
die();
106+
wp_send_json($response);
107+
wp_die();
85108
}
86109

87110
function tawk_admin_notice() {
@@ -99,11 +122,47 @@ function tawk_admin_notice() {
99122
public function action_removewidget() {
100123
header('Content-Type: application/json');
101124

125+
if (wp_is_json_request() === false) {
126+
$response['success'] = false;
127+
$response['message'] = 'Invalid request';
128+
wp_send_json($response);
129+
wp_die();
130+
};
131+
132+
$postData = json_decode(file_get_contents('php://input'), true);
133+
134+
$response = array(
135+
'success' => true
136+
);
137+
138+
if ($this->validate_request_auth($postData, self::TAWK_ACTION_REMOVE_WIDGET) === false) {
139+
$response['success'] = false;
140+
$response['message'] = 'Unauthorized';
141+
wp_send_json($response);
142+
wp_die();
143+
};
144+
102145
update_option(self::TAWK_PAGE_ID_VARIABLE, '');
103146
update_option(self::TAWK_WIDGET_ID_VARIABLE, '');
104147

105-
echo json_encode(array('success' => TRUE));
106-
die();
148+
wp_send_json($response);
149+
wp_die();
150+
}
151+
152+
private function validate_request_auth($postData = array(), $action) {
153+
if (current_user_can('administrator') === false) {
154+
return false;
155+
}
156+
157+
if (isset($postData['nonce']) === false) {
158+
return false;
159+
}
160+
161+
if (wp_verify_nonce($postData['nonce'], $action) === false) {
162+
return false;
163+
}
164+
165+
return true;
107166
}
108167

109168
public function validate_options($input){
@@ -167,6 +226,8 @@ public function create_plugin_settings_page(){
167226
.'&currentPageId='.$page_id
168227
.'&transparentBackground=1'
169228
.'&pltf=wordpress';
229+
$set_widget_nonce = wp_create_nonce(self::TAWK_ACTION_SET_WIDGET);
230+
$remove_widget_nonce = wp_create_nonce(self::TAWK_ACTION_REMOVE_WIDGET);
170231

171232

172233
include(sprintf("%s/templates/settings.php", dirname(__FILE__)));

0 commit comments

Comments
 (0)