Acunetix WP Security - Version 4.0

Version Description

Download this release

Release Info

Developer Acunetix
Plugin Icon wp plugin Acunetix WP Security
Version 4.0
Comparing to
See all releases

Code changes from version 3.1.0 to 4.0

Files changed (104) hide show
  1. backups/index.php +0 -1
  2. css/acx-wp-dashboard.css +0 -17
  3. css/wsd.css +0 -329
  4. images/acunetix.png +0 -0
  5. images/agent-green.png +0 -0
  6. images/agent-red.png +0 -0
  7. images/facebook.gif +0 -0
  8. images/loading45.gif +0 -0
  9. images/wsd-logo-small.png +0 -0
  10. images/wsd-logo.png +0 -0
  11. inc/admin/db.php +0 -60
  12. inc/admin/plugin_options.php +0 -64
  13. inc/admin/pwtool.php +0 -49
  14. inc/admin/scanner.php +0 -37
  15. inc/admin/security.php +0 -30
  16. inc/admin/support.php +0 -74
  17. inc/admin/templates/db-backup.php +0 -91
  18. inc/admin/templates/db-change-prefix.php +0 -143
  19. inc/admin/templates/footer.php +0 -17
  20. inc/admin/templates/header.php +0 -11
  21. index.php +65 -0
  22. js/json.js +0 -482
  23. js/md5.js +0 -201
  24. js/remove_wp_version.js +0 -3
  25. js/scripts.js +0 -27
  26. js/wsd.js +0 -188
  27. libs/functions.php +0 -584
  28. libs/json.php +0 -806
  29. libs/recaptchalib.php +0 -277
  30. libs/wpssUtil.php +0 -167
  31. libs/wsd.php +0 -835
  32. readme.txt +144 -70
  33. res/backups/index.php +1 -0
  34. res/css/acx-styles-extra.css +1 -0
  35. res/css/blog.css +66 -0
  36. res/css/index.php +1 -0
  37. res/css/styles.alerts.css +54 -0
  38. res/css/styles.base.css +31 -0
  39. res/css/styles.general.css +196 -0
  40. res/css/styles.status.css +38 -0
  41. res/images/ajax-loader.gif +0 -0
  42. res/images/alert-info-critical.png +0 -0
  43. res/images/alert-info-icon.png +0 -0
  44. res/images/alerts-page-ico.png +0 -0
  45. images/wpss_icon_small_combined.png → res/images/arrow-black-icon.png +0 -0
  46. res/images/blog/featured-slider-bg.jpg +0 -0
  47. res/images/blog/ico-facebook.png +0 -0
  48. res/images/blog/ico-twitter.png +0 -0
  49. res/images/blog/index.php +1 -0
  50. res/images/blog/logo.png +0 -0
  51. images/wpss_icon_large.png → res/images/checkbox.png +0 -0
  52. {images → res/images}/close-button.png +0 -0
  53. res/images/green-check-icon.png +0 -0
  54. res/images/icon-info.png +0 -0
  55. res/images/index.php +1 -0
  56. res/images/indicator-blue.png +0 -0
  57. res/images/indicator-green.png +0 -0
  58. res/images/indicator-red.png +0 -0
  59. res/images/indicator-yellow.png +0 -0
  60. images/wsd-logo-small-list.png → res/images/logo-small.png +0 -0
  61. res/images/logo.png +0 -0
  62. {images → res/images}/rss.png +0 -0
  63. res/images/tooltips/index.php +1 -0
  64. res/images/tooltips/tt_bottom.gif +0 -0
  65. res/images/tooltips/tt_top.gif +0 -0
  66. res/inc/WsdCheck.php +286 -0
  67. res/inc/WsdInfo.php +317 -0
  68. res/inc/WsdLiveTraffic.php +223 -0
  69. res/inc/WsdPlugin.php +380 -0
  70. res/inc/WsdScheduler.php +115 -0
  71. res/inc/WsdSecurity.php +726 -0
  72. res/inc/WsdUtil.php +601 -0
  73. res/inc/WsdWatch.php +67 -0
  74. res/inc/alerts.php +64 -0
  75. res/inc/index.php +1 -0
  76. res/inc/wss-functions.php +36 -0
  77. res/index.php +1 -0
  78. res/js/index.php +1 -0
  79. res/js/wsd-util.js +25 -0
  80. res/js/wsdplugin_glossary_tooltip.js +78 -0
  81. res/languages/index.php +1 -0
  82. res/pages/about.php +57 -0
  83. res/pages/blog.php +113 -0
  84. res/pages/dashboard.php +134 -0
  85. res/pages/database.php +61 -0
  86. res/pages/index.php +1 -0
  87. res/pages/live_traffic.php +272 -0
  88. res/pages/scanner.php +39 -0
  89. res/pages/settings.php +168 -0
  90. res/pages/tpl/box-available-backups.php +26 -0
  91. res/pages/tpl/box-banners.php +9 -0
  92. res/pages/tpl/box-database-backup.php +57 -0
  93. res/pages/tpl/box-database-change-prefix.php +243 -0
  94. res/pages/tpl/box-scan-results-file.php +108 -0
  95. res/pages/tpl/box-scan-results-wp.php +13 -0
  96. res/pages/tpl/box-server-results.php +3 -0
  97. res/pages/tpl/index.php +1 -0
  98. screenshot-1.jpg +0 -0
  99. screenshot-2.jpg +0 -0
  100. screenshot-3.jpg +0 -0
  101. screenshot-4.jpg +0 -0
  102. securityscan.php +0 -268
  103. uninstall.php +0 -12
  104. wss-settings.php +74 -0
backups/index.php DELETED
@@ -1 +0,0 @@
1
- <?php /*[ Only to prevent directory listing ]*/ ?>
 
css/acx-wp-dashboard.css DELETED
@@ -1,17 +0,0 @@
1
- /*
2
- * manage the rss box on dashboard
3
- */
4
-
5
- #acx_plugin_dashboard_widget h3.hndle{
6
- background: url('../images/wsd-logo-small.png') no-repeat 5px 50%;
7
- padding-left: 35px; padding-top: 10px;
8
- }
9
- #acx_plugin_dashboard_widget h4 {
10
- margin: 0 0; font-size: 1.2em;
11
- /* background: url('../images/arrow-black-icon.png') no-repeat left center;
12
- background: url('../images/wsd-logo-small-list.png') no-repeat left center;
13
- padding-left: 20px;*/
14
- }
15
- #acx_plugin_dashboard_widget p { margin: 3px 0; }
16
-
17
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/wsd.css DELETED
@@ -1,329 +0,0 @@
1
- /********************************************************
2
- * BEGIN >> General styling
3
- */
4
- p.wsd-error-summary {
5
- background-color: #F9EFAC;
6
- border: 1px dotted #f00;
7
- color: #DC143C;
8
- padding: 5px 10px;
9
- margin: 10px;
10
- font-weight: bold;
11
- cursor: default;
12
- }
13
-
14
- span.wsd-error-summary-detail {
15
- color: #000;
16
- font-weight: normal;
17
- font-size: 11px;
18
- cursor: default;
19
- }
20
-
21
-
22
- p.wsd-success-summary {
23
- background-color: #90EE90;
24
- border: 1px dotted #f00;
25
- color: #000;
26
- padding: 5px 10px;
27
- margin: 10px;
28
- font-weight: bold;
29
- cursor: default;
30
- }
31
-
32
- span.wsd-success-summary-detail {
33
- color: #000;
34
- font-weight: normal;
35
- font-size: 11px;
36
- cursor: default;
37
- }
38
-
39
-
40
- p.wsd-login-notice {
41
- font-weight: bold;
42
- color: #000;
43
- margin-top: -10px;
44
- margin-bottom: 20px;
45
- }
46
-
47
- .wsd-inside {
48
- padding: 10px;
49
- font-family: Verdana, Arial, sans-serif !important;
50
- font-size: 100% !important;
51
- }
52
-
53
- p.wsd-error-summary a, .wsd-inside a {
54
- color: #CC0000;
55
- text-decoration: none;
56
- }
57
-
58
- p.wsd-error-summary a:hover, .wsd-inside a:hover {
59
- color: #CC0000;
60
- text-decoration: underline;
61
- }
62
-
63
- /********************************************************
64
- * BEGIN >> Login form styling
65
- */
66
- #wsd_login_form {
67
- margin: 0px;
68
- }
69
-
70
- #wsd_login_form .wsd-login-section {
71
- display: block;
72
- float: left;
73
- width: 100%;
74
- margin-bottom: 5px;
75
- }
76
-
77
- #wsd_login_form .wsd-login-section label {
78
- display: block;
79
- float: left;
80
- width: 70px;
81
- padding-top: 6px;
82
- }
83
-
84
- #wsd_login_form .wsd-login-section input {
85
- display: block;
86
- width: 200px;
87
- float: left;
88
- }
89
-
90
- #wsd_login_form #wsd-login {
91
- clear: left;
92
- margin-left: 70px;
93
- }
94
-
95
-
96
-
97
- /********************************************************
98
- * BEGIN >> Registration form styling
99
- */
100
- #wsd_new_user_form {
101
- margin: 0px;
102
- }
103
-
104
- #wsd_new_user_form .wsd-new-user-section {
105
- display: block;
106
- float: left;
107
- width: 100%;
108
- margin-bottom: 5px;
109
- }
110
-
111
- #wsd_new_user_form .wsd-new-user-section label {
112
- display: block;
113
- float: left;
114
- width: 120px;
115
- padding-top: 6px;
116
- }
117
-
118
- #wsd_new_user_form .wsd-new-user-section input {
119
- display: block;
120
- width: 200px;
121
- float: left;
122
- }
123
-
124
- #wsd_new_user_form #wsd-login {
125
- clear: left;
126
- margin-left: 70px;
127
- }
128
-
129
-
130
-
131
- /********************************************************
132
- * BEGIN >> Initial scan widget styling
133
- */
134
- #wsd-information-scan-list {
135
- list-style-type: disc;
136
- margin: 10px;
137
- padding-left: 20px;
138
- }
139
-
140
-
141
-
142
- #wsd-initial-scan { }
143
-
144
- #wsd-initial-scan .wsd-initial-scan-section {
145
- line-height: 1.4em;
146
- display: block;
147
- color: #090;
148
- }
149
-
150
-
151
- /********************************************************
152
- * BEGIN >> Target update form styling
153
- */
154
- #wsd_target_id_form {
155
- width: 100%;
156
- }
157
-
158
- #wsd_target_id_form #targetid {
159
- width: 300px;
160
- }
161
-
162
-
163
-
164
- /********************************************************
165
- * BEGIN >> Status content styling
166
- */
167
- div#wsd-target-status-holder {
168
- overflow: hidden;
169
- }
170
-
171
- p.wsd-target-status-title {
172
- font-weight: bold;
173
- }
174
-
175
- div.wsd-target-status-section {
176
- display: block;
177
- float: left;
178
- margin-right: 5px;
179
- }
180
-
181
- span.wsd-target-status-section-label {
182
- display: block;
183
- padding: 5px 4px;
184
- float: left;
185
- color: #999999
186
- }
187
-
188
- span.wsd-target-status-section-enabled {
189
- display: block;
190
- padding: 5px 0px;
191
- background-color: #0f0;
192
- color: #000;
193
- float: left;
194
- width: 50px;
195
- height: 24px;
196
- border-radius: 3px;
197
- -moz-border-radius: 3px;
198
- -webkit-border-radius: 3px;
199
- text-align: center;
200
- font-weight: bold;
201
-
202
- background: url('../images/agent-green.png') no-repeat scroll left top transparent;
203
- }
204
-
205
- span.wsd-target-status-section-disabled {
206
- display: block;
207
- padding: 5px 0px;
208
- background-color: #f00;
209
- color: #fff;
210
- float: left;
211
- width: 50px;
212
- height: 24px;
213
- border-radius: 3px;
214
- -moz-border-radius: 3px;
215
- -webkit-border-radius: 3px;
216
- text-align: center;
217
- font-weight: bold;
218
-
219
- background: url('../images/agent-red.png') no-repeat scroll left top transparent;
220
- }
221
-
222
-
223
-
224
-
225
- /********************************************************
226
- * BEGIN >> Password meter styling
227
- */
228
- #wsd_new_user_form label.password-meter {
229
- display: none;
230
- -webkit-border-radius: 3px;
231
- -moz-border-radius: 3px;
232
- font-weight: bolder;
233
- border-radius: 3px;
234
- text-align: center;
235
- font-size: 12px;
236
- color: #000;
237
- width: 80px;
238
- margin-left: 20px;
239
- padding: 4px;
240
- cursor: default;
241
- }
242
-
243
-
244
- /*
245
- * 3.0.2
246
- */
247
- .scanpass { color: #090; }
248
-
249
- .mrt_wpss_note {
250
- text-align: center;
251
- color: grey;
252
- margin-top: 20px;
253
- margin-bottom: 20px;
254
- }
255
-
256
- .wpss_icon {
257
- background: url(../images/wsd-logo.png) no-repeat left center;
258
- margin-top: 10px !important;
259
- padding: 5px 0 3px 50px !important;
260
- }
261
-
262
- .wsd_user_notify {
263
- border: solid 1px #fc0; background: #ffc;
264
- padding: 5px 5px;
265
- font-size: 100%;
266
- }
267
- .wsd_user_information {
268
- border: solid 1px #324FB2; background: #E5EAF0;
269
- padding: 5px 5px;
270
- font-size: 100%;
271
- }
272
- .wsd_user_success {
273
- border: solid 1px #030; background: #090;
274
- padding: 5px 5px;
275
- font-size: 100%;
276
- color: #fff;
277
- }
278
- .wsd_info_list {
279
- list-style-type: disc;
280
- list-style-position: outside;
281
- margin: 0 0 10px 25px;
282
- }
283
- div.wsd_user_information, div.wsd_user_notify, div.wsd_user_success { margin: 1em 0 !important; }
284
-
285
- #Words { overflow: hidden; min-height: 1px; margin: 0 0 0 0 !important; padding: 0 0 0 0 !important; }
286
- #Words p { float: left; display: block; width: 150px; line-height: normal !important; padding: 0 0 0 0; margin: 6px 0 0 0 !important; }
287
- #Words p.indicator { height: 4px; }
288
- #Words p.indicator-1 { background: #f00;}
289
- #Words p.indicator-2 { background: #990000; }
290
- #Words p.indicator-3 { background: #990099; }
291
- #Words p.indicator-4 { background: #000099; }
292
- #Words p.indicator-5 { background: #0000ff; }
293
- #Words p.indicator-6 { background: #ffffff; }
294
- #Words p+p {margin: 0 0 0 5px !important; padding: 0 0 0 0 !important; line-height: normal !important;}
295
- #wsd_pwdtool { margin-top: 10px; }
296
-
297
- .wsd_commonList {
298
- list-style-type: none;
299
- margin: 0 0 10px 0;
300
- padding-left: 0;
301
- }
302
- .wsd_commonList li {
303
- font-style: italic !important;
304
- background: url('../images/wsd-logo-small-list.png') no-repeat 0 50%;
305
- padding: 2px 0 2px 20px !important;
306
- }
307
-
308
- .wsd-inside p, .wsd-inside ul, .wsd-inside ol, .wsd-inside blockquote, .wsd-inside input, .wsd-inside select {
309
- font-size: 100%;
310
- }
311
-
312
- .wsd-inside, .wsd-inside p, .wsd-inside li, .wsd-inside dl, .wsd-inside dd, .wsd-inside dt {
313
- line-height: normal !important;
314
- }
315
-
316
- #wsd_db_wrapper .inner-sidebar1 { margin: 10px 10px 0 10px; }
317
- #wsd_db_wrapper, #wsd_db_wrapper .metabox-holder {overflow:hidden; min-height:1px; }
318
- #wsd_permissions_table { margin: 15px 0; }
319
- #wsd_permissions_table th,
320
- #wsd_permissions_table td { text-align: left; }
321
- #wsd_permissions_table td { padding: 1px 7px;}
322
- #wsd_tables_list_block { clear: both;}
323
-
324
- .wsd_cursor_help { cursor: help; border-bottom: dotted 1px #000; }
325
-
326
-
327
-
328
-
329
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
images/acunetix.png DELETED
Binary file
images/agent-green.png DELETED
Binary file
images/agent-red.png DELETED
Binary file
images/facebook.gif DELETED
Binary file
images/loading45.gif DELETED
Binary file
images/wsd-logo-small.png DELETED
Binary file
images/wsd-logo.png DELETED
Binary file
inc/admin/db.php DELETED
@@ -1,60 +0,0 @@
1
- <?php
2
- function mrt_sub3()
3
- {
4
- // Show header
5
- mrt_wpss_menu_head('WP - Database Security');
6
-
7
- $wsd_wpConfigFile = ABSPATH.'wp-config.php';
8
-
9
- // internal flag
10
- $canLoadPage = false;
11
- if (wsd_wpConfigCheckPermissions($wsd_wpConfigFile)) {
12
- $canLoadPage = true;
13
- }
14
- ?>
15
- <p class="wsd_user_notify">
16
- <strong>Important</strong>: Make a backup of your database before using this tool!
17
- </p>
18
- <?php
19
- if (!$canLoadPage) {
20
- // Display the error message
21
- echo wsd_eInfo('
22
- The <strong>wp-config.php</strong> file MUST be writable in order to perform this action.
23
- You have to manually change permissions for this file.');
24
- }
25
- ?>
26
-
27
-
28
- <?php /*[ BEGIN PAGE DATABASE ]*/ ?>
29
- <div id="wsd_db_wrapper">
30
- <?php
31
- /* Display the Database backup page */
32
- echo wsd_getTemplate('db-backup');
33
- ?>
34
-
35
- <br/>
36
- <div style="clear:both;"></div>
37
-
38
- <?php
39
- /* Stop here if the wp-config file is not writable or if we cannot change its permissions */
40
- if ($canLoadPage)
41
- {
42
- // Display the Change Database Table prefix page
43
- echo wsd_getTemplate('db-change-prefix',array(
44
- 'wsd_wpConfigFile' => $wsd_wpConfigFile,
45
- 'old_prefix' => $GLOBALS['table_prefix'],
46
- 'new_prefix' => (empty($_POST['newPrefixInput']) ? '' : $_POST['newPrefixInput']),
47
- 'isPostBack' => (($_SERVER['REQUEST_METHOD'] == 'POST') ? true : false)
48
- ));
49
- }
50
- ?>
51
- </div>
52
- <?php /*[ END PAGE DATABASE ]*/ ?>
53
-
54
- <p style="height:200px;"></p>
55
-
56
- <?php
57
- // Show footer
58
- mrt_wpss_menu_footer();
59
- }//function mrt_sub3
60
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/admin/plugin_options.php DELETED
@@ -1,64 +0,0 @@
1
- <?php
2
- function mrt_sub4(){
3
-
4
- mrt_wpss_menu_head('Plugin options');
5
-
6
- ?>
7
-
8
- <div class="metabox-holder">
9
- <div class="postbox" style="width: 60%;">
10
- <h3 class="hndle"><span><?php echo __('Plugin options');?></span></h3>
11
- <div class="inside">
12
- <p></p>
13
- <?php
14
- //# 10/04/2011
15
- $_checked = false;
16
- if ($_SERVER['REQUEST_METHOD'] == 'POST')
17
- {
18
- if($_POST['show_rss_widget'] == 'on'){
19
- update_option('WSD-RSS-WGT-DISPLAY', 'yes');
20
- $_checked = true;
21
- }
22
- else {
23
- update_option('WSD-RSS-WGT-DISPLAY', 'no');
24
- $_checked = false;
25
- }
26
- }
27
- $wsdRssWidgetVisible = get_option('WSD-RSS-WGT-DISPLAY');
28
- if (empty($wsdRssWidgetVisible) || $wsdRssWidgetVisible=='yes') {
29
- add_option('WSD-RSS-WGT-DISPLAY', 'yes');
30
- $_checked = true;
31
- }
32
- else {
33
- if (strtolower($wsdRssWidgetVisible) == 'no') {
34
- $_checked = false;
35
- }
36
- }
37
- //@++
38
- ?>
39
- <div class="acx-section-box">
40
-
41
- <form id="plugin_options_form" method="post">
42
- <div>
43
- <input type="checkbox" name="show_rss_widget" id="show_rss_widget" <?php echo ($_checked ? 'checked="checked"' : '');?> />
44
- <label for="show_rss_widget"><?php echo __("Show the WebsiteDefender News dashboard widget");?></label>
45
- </div>
46
-
47
- <div>
48
- <p style="margin-top: 25px">
49
- <input type="submit" class="button-primary" value="<?php echo __('Update');?>"/>
50
- </p>
51
- </div>
52
- </form>
53
-
54
- </div>
55
- <p></p>
56
- </div>
57
- </div>
58
- </div>
59
-
60
-
61
- <?php
62
- mrt_wpss_menu_footer();
63
-
64
- } ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/admin/pwtool.php DELETED
@@ -1,49 +0,0 @@
1
- <?php
2
- function mrt_sub1(){
3
-
4
- mrt_wpss_menu_head('WP - Password Tools');
5
-
6
- ?>
7
-
8
- <div class="metabox-holder">
9
- <div class="postbox" style="width: 60%;">
10
- <h3 class="hndle"><span><?php echo __('Password Strength Tool');?></span></h3>
11
- <div class="inside">
12
- <p></p>
13
- <table id="wsd_pwdtool">
14
- <tr valign="top">
15
- <td>
16
- <form name="commandForm">
17
- Type password: <input type="password" size="30" maxlength="50" name="password" onkeyup="testPassword(this.value);" value="" />
18
- <br/>
19
- <span style="color:#808080">Minimum 6 Characters</span>
20
- </form>
21
- </td>
22
- <td style="padding-left: 6px;">
23
- <span>Password Strength:</span>
24
- <div id="Words">
25
- <p class="indicator"></p>
26
- <p><strong>Begin Typing</strong></p>
27
- </div>
28
- </td>
29
- </tr>
30
- </table>
31
- <p></p>
32
- </div>
33
- </div>
34
- </div>
35
-
36
- <div>
37
- <?php
38
- echo "<br /><strong>Strong Password Generator</strong><br />";
39
- echo "Strong Password: " . '<span style="color:#f00;">' . make_password(15) . "</span>";
40
- ?>
41
- </div>
42
- <br/><br/>
43
- <p style="margin-top: 75px;"></p>
44
- <hr align="left" size="2" width="612px" />
45
-
46
- <?php
47
- mrt_wpss_menu_footer();
48
-
49
- } ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/admin/scanner.php DELETED
@@ -1,37 +0,0 @@
1
- <?php
2
- function mrt_sub0(){
3
-
4
- mrt_wpss_menu_head('WP - Security Scan');?>
5
-
6
- <div class="metabox-holder">
7
- <div class="postbox">
8
- <h3 class="hndle"><span><?php echo __('Directory Info');?></span></h3>
9
- <div class="inside">
10
- <table id="wsd_permissions_table" width="100%" border="0" cellspacing="0" cellpadding="3"
11
- style="text-align:center; border: solid 1px #333;">
12
- <thead style="background: #333;">
13
- <th style="border:0px; padding: 4px 4px;"><strong style="color: #f5f5f5">Name</strong></th>
14
- <th style="border:0px; padding: 4px 4px;"><strong style="color: #f5f5f5">File/Dir</strong></th>
15
- <th style="border:0px; padding: 4px 4px;"><strong style="color: #f5f5f5">Needed Chmod</strong></th>
16
- <th style="border:0px; padding: 4px 4px;"><strong style="color: #f5f5f5">Current Chmod</strong></th>
17
- </thead>
18
- <tbody>
19
- <?php
20
- // DIR_NAME | DIR_PATH | EXPECTED_PERMISSION
21
- check_perms("root directory","../","0755");
22
- check_perms("wp-includes/","../wp-includes","0755");
23
- check_perms(".htaccess","../.htaccess","0644");
24
- check_perms("wp-admin/index.php","index.php","0644");
25
- check_perms("wp-admin/js/","js/","0755");
26
- check_perms("wp-content/themes/","../wp-content/themes","0755");
27
- check_perms("wp-content/plugins/","../wp-content/plugins","0755");
28
- check_perms("wp-admin/","../wp-admin","0755");
29
- check_perms("wp-content/","../wp-content","0755");
30
- ?>
31
- </tbody>
32
- </table>
33
-
34
- </div></div></div>
35
- <?php
36
- mrt_wpss_menu_footer();
37
- } ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/admin/security.php DELETED
@@ -1,30 +0,0 @@
1
- <?php
2
-
3
- function mrt_opt_mng_pg() {
4
- mrt_wpss_menu_head('WP-Security Admin tools by WebsiteDefender');
5
-
6
- add_meta_box("wpss_mrt_1", 'Initial Scan', "wpss_mrt_meta_box", "wpss");
7
- add_meta_box("wpss_mrt_2", 'System Information Scan', "wpss_mrt_meta_box2", "wpss2");
8
- add_meta_box("wpss_mrt_3", 'About Website Defender', "wsd_render_main", "wpss_wsd");
9
-
10
- echo '
11
- <div class="metabox-holder">
12
- <div style="float:left; width:48%;" class="inner-sidebar1">';
13
-
14
- do_meta_boxes('wpss','advanced','');
15
- do_meta_boxes('wpss2','advanced','');
16
-
17
- echo '
18
- </div>
19
- <div style="float:right;width:48%;" class="inner-sidebar1">';
20
- do_meta_boxes('wpss_wsd','advanced','');
21
- echo '
22
- </div>
23
-
24
- <div style="clear:both"></div>
25
- </div>';
26
-
27
- mrt_wpss_menu_footer();
28
-
29
- }
30
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/admin/support.php DELETED
@@ -1,74 +0,0 @@
1
- <?php
2
- function mrt_sub2()
3
- {
4
- mrt_wpss_menu_head('WP - Security Support');
5
- ?><?php /*
6
- <div>
7
- <br/>
8
- <p>Under Construction...</p>
9
- <br /><br />
10
- <ul>
11
- <li><a href='http://www.websitedefender.com/category/faq/' target="_blank">Documentation</a></li>
12
- </ul>
13
- <br /><br />
14
- <strong>Backup early, backup often!</strong>
15
- <br /><br /><br /><br /><br />
16
- </div>
17
- */?>
18
-
19
- <div class="metabox-holder">
20
- <div class="postbox">
21
- <h3 class="hndle"><span><?php echo __('About WebsiteDefender');?></span></h3>
22
- <div class="inside">
23
- <p><?php echo __('A secure website, free from malware, where your customers can feel safe is vital to your online success.
24
- Unfortunately, the number of web hacking attacks has risen dramatically. Website security is an absolute must.
25
- If you do not protect your website, hackers can gain access to your website, modify your web content, install malware
26
- and have your site banned from Google. They could modify scripts and gain access to your customer data and their credit card details…');?></p>
27
-
28
- <p><?php echo __('WebsiteDefender is an online service that monitors your website for hacker activity, audits the security
29
- of your web site and gives you easy to understand solutions to keep your website safe. With WebsiteDefender you can:');?></p>
30
-
31
- <ul class="wsd_info_list">
32
- <li><?php echo __('Detect Malware present on your website');?></li>
33
- <li><?php echo __('Audit your web site for security issues');?></li>
34
- <li><?php echo __('Avoid getting blacklisted by Google');?></li>
35
- <li><?php echo __('Keep your web site content &amp; data safe');?></li>
36
- <li><?php echo __('Get alerted to suspicious hacker activity');?></li>
37
- </ul>
38
-
39
- <p><?php echo __('All via an easy-to-understand web based dashboard which gives step by step solutions!
40
- Sign up for your FREE account <a href="admin.php?page=wp-security-scan/securityscan.php">here</a>.');?></p>
41
- </div>
42
- </div>
43
- </div>
44
-
45
-
46
- <div class="metabox-holder">
47
- <div class="postbox">
48
- <h3 class="hndle"><span><?php echo __('Get Involved!');?></span></h3>
49
- <div class="inside">
50
- <p></p>
51
- <ul class="wsd_info_list">
52
- <li>
53
- <span><a href="http://www.websitedefender.com/forums/" target="_blank"><?php echo __('WebsiteDefender forums');?></a></span>
54
- </li>
55
- <li>
56
- <span><a href="http://www.websitedefender.com/blog/" target="_blank"><?php echo __('WebsiteDefender blog');?></a></span>
57
- </li>
58
- <li>
59
- <span><a href="http://twitter.com/#!/websitedefender" target="_blank"><?php echo __('WebsiteDefender on Twitter');?></a></span>
60
- </li>
61
- <li>
62
- <span><a href="http://www.facebook.com/WebsiteDefender" target="_blank"><?php echo __('WebsiteDefender on Facebook');?></a></span>
63
- </li>
64
- </ul>
65
- <p></p>
66
- </div>
67
- </div>
68
- </div>
69
-
70
-
71
- <?php
72
- mrt_wpss_menu_footer();
73
- }
74
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/admin/templates/db-backup.php DELETED
@@ -1,91 +0,0 @@
1
- <?php
2
- /*
3
- * Backup Database
4
- */
5
- ?>
6
- <?php
7
- /*
8
- * BACKUP DATABASE SECTION
9
- */
10
- ?>
11
- <br/><br/>
12
- <h2 class="wpss_icon">Backup your database</h2>
13
-
14
- <?php
15
- /*
16
- * Check if the backups directory is writable
17
- */
18
- $wsd_bckDirPath = ABSPATH.PLUGINDIR.'/wp-security-scan/backups/';
19
- if (is_dir($wsd_bckDirPath) && is_writable($wsd_bckDirPath)) :
20
- ?>
21
-
22
- <div style="padding: 7px 7px; margin: 10px 10px;">
23
- <form action="#bck" method="post">
24
- <input type="hidden" name="wsd_db_backup"/>
25
- <input type="submit" name="backupDatabaseButton" value="Backup now!"/>
26
- </form>
27
- </div>
28
-
29
- <?php
30
- if ($_SERVER['REQUEST_METHOD'] == 'POST')
31
- {
32
- if (isset($_POST['wsd_db_backup']))
33
- {
34
- $tables = '*';
35
- if (isset($_POST['tables'])) {
36
- $tables = implode(',',$_POST['tables']);
37
- }
38
-
39
- if (($fname = wsd_backupDatabase($tables)) <> '') {
40
- echo '<p id="bck" class="wsd_user_success">';
41
- echo '<span style="color:#fff;">Database successfully backed up!</span>';
42
- echo '<br/><span style="color:#fff;">Download backup file: </span>';
43
- echo '<a href="',get_option('siteurl'),'/wp-content/plugins/wp-security-scan/backups/',$fname,'" style="color:#0f0">',$fname,'</a>';
44
- echo '</p>';
45
- }
46
- else {
47
- echo '<p id="bck" class="wsd_user_notify">';
48
- echo 'The database could not be backed up!';
49
- echo '<br/>A posible error might be that you didn\'t set up writing permissions for the backups directory!';
50
- echo '</p>';
51
- }
52
- }
53
- }
54
- ?>
55
- <?php else :
56
- // The directory is not writable. Display info message
57
- echo wsd_eInfo('<strong>Important</strong>: The <strong title="'.$wsd_bckDirPath.'" class="wsd_cursor_help">backups</strong> directory must be writable in order to use this functionality!');
58
- endif; ?>
59
-
60
-
61
-
62
- <?php
63
- /*
64
- * DISPLAY AVAILABLE DOWNLOADS
65
- */
66
- ?>
67
- <?php
68
- function wsd_db_download_list()
69
- {
70
- echo '<div>';
71
- $files = wsd_getAvailableBackupFiles();
72
- if (empty($files)) {
73
- echo '<p style="margin:5px 5px;">There are no backup files available for download yet!</p>';
74
- }
75
- else {
76
- echo '<ul id="wsd-information-scan-list">';
77
- foreach($files as $fileName) {
78
- echo '<li>';
79
- echo '<a href="',get_option('siteurl'),'/wp-content/plugins/wp-security-scan/backups/',$fileName,'">',$fileName,'</a>';
80
- echo '</li>';
81
- }
82
- echo '</ul>';
83
- }
84
- echo '</div>';
85
- }
86
- add_meta_box("wpss_mrt_1", 'Available database backups', "wsd_db_download_list", "wsd_db_bck_dwl");
87
- echo '<div style="float:left; width:50%;" class="inner-sidebar1">';
88
- echo '<div class="metabox-holder">';
89
- do_meta_boxes('wsd_db_bck_dwl','advanced','');
90
- echo '</div></div>';
91
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/admin/templates/db-change-prefix.php DELETED
@@ -1,143 +0,0 @@
1
- <?php
2
- /*
3
- * Change Database table Prefix
4
- */
5
- ?>
6
- <br/><br/>
7
- <h2 class="wpss_icon">Change database table prefix</h2>
8
-
9
- <?php
10
- // Holds the error/info messages generated on form postback
11
- $infoMessage = '';
12
-
13
- // Check if user has enough rights to alter the Table structure
14
- $wsd_userDbRights = wsd_getDbUserRights();
15
- $showPage = false; // assume we don't have ALTER rights
16
- if ($wsd_userDbRights['rightsEnough']) {
17
- $showPage = true;
18
- $canAlter = '<span style="color: #060; font-weight: 900;">(Yes)</span>';
19
- }
20
- else { $canAlter = '<span style="color: #f00; font-weight: 900;">(No)</span>'; }
21
- ?>
22
- <p>Change your database table prefix to mitigate zero-day SQL Injection attacks.</p>
23
- <p><strong>Before running this script:</strong>
24
- <ul class="wsd_info_list">
25
- <li>The <strong title="<?php echo ABSPATH.'wp-config.php'; ?>" class="wsd_cursor_help">wp-config.php</strong> file must be set to writable before running this script. <span style="color: #060; font-weight: 900;">(Yes)</span></li>
26
- <li>The database user you're using with WordPress must have <strong>ALTER</strong> rights. <?php echo $canAlter;?></li>
27
- </ul>
28
- <?php
29
- /*
30
- * If the user doesn't have ALTER rights
31
- */
32
- if ( ! $showPage )
33
- {
34
- echo wsd_eInfo('The User: <strong>'.DB_USER.'</strong> used to access the database server must have <strong>ALTER</strong> rights in order to perform this action!');
35
-
36
- // Stop here, no need to load the rest of the page
37
- return;
38
- }
39
- ?>
40
-
41
- <?php
42
- /*
43
- * Issue the file permissions warning
44
- */
45
- $infoMessage = 'It\'s a security risk to have your files writable (0777)!
46
- Please make sure that after running this script, the <strong title="'.ABSPATH.'wp-config.php" class="wsd_cursor_help">wp-config.php</strong> file\'s permissions are set to 0644!
47
- <br/> See: <a href="http://codex.wordpress.org/Changing_File_Permissions" target="_blank">http://codex.wordpress.org/Changing_File_Permissions</a> for more information.';
48
- echo wsd_eInfo($infoMessage,'information');
49
- ?>
50
-
51
-
52
- <?php
53
- /*
54
- * VALIDATE FORM
55
- */
56
- if (!empty($_POST['newPrefixInput']) && isset($_POST['changePrefixButton']))
57
- {
58
- $wsd_isPostBack = true;
59
-
60
- check_admin_referer('prefix-changer-change_prefix');
61
-
62
- $wpdb =& $GLOBALS['wpdb'];
63
- $new_prefix = preg_replace("[^0-9a-zA-Z_]", "", $_POST['newPrefixInput']);
64
- if (empty($wsd_userDbRights['rightsEnough'])) {
65
- $wsd_Message .= wsd_eInfo('The User which is used to access your Wordpress Database, hasn\'t enough rights (is missing the ALTER right) to alter the Table structure.
66
- <br/>Please visit the <a href="http://www.websitedefender.com/category/faq/" target=_blank">WebsiteDefender WP Security Scan WordPress plugin documentation</a> website for more information.
67
- <br/>If the user <code>has ALTER rights</code> and the tool is still not working, please <a href="http://www.websitedefender.com/support/" target="_blank">contact us</a> for assistance!');
68
- }
69
- if (!empty($wsd_userDbRights['rightsTooMuch'])) {
70
- $wsd_Message .= wsd_eInfo('Your currently used User to access the Wordpress Database, holds too many rights.'.
71
- '<br/>We suggest that you limit his rights or to use another User with more limited rights instead, to increase your Security.','information');
72
- }
73
- if (strlen($new_prefix) < strlen($_POST['newPrefixInput'])){
74
- $wsd_Message .= wsd_eInfo('You used some characters disallowed in Table names. The sanitized prefix will be used instead: '. $new_prefix,'information');
75
- }
76
- if ($new_prefix == $old_prefix) {
77
- $wsd_Message .= wsd_eInfo('No change! Please select a new table prefix value.');
78
- }
79
- else
80
- {
81
- // Get the list of tables to modify
82
- $tables = wsd_getTablesToAlter();
83
- if (empty($tables))
84
- {
85
- $wsd_Message .= wsd_eInfo('There are no tables to rename!');
86
- }
87
- else
88
- {
89
- $result = wsd_renameTables($tables, $old_prefix, $new_prefix);
90
-
91
- // check for errors
92
- if (!empty($result))
93
- {
94
- $wsd_Message .= wsd_eInfo('All tables have been successfully updated!','success');
95
-
96
- // try to rename the fields
97
- $wsd_Message .= wsd_renameDbFields($old_prefix, $new_prefix);
98
-
99
- if (wsd_updateWpConfigTablePrefix($wsd_wpConfigFile, $old_prefix, $new_prefix))
100
- {
101
- $wsd_Message .= wsd_eInfo('The wp-config file has been successfully updated!','success');
102
- }
103
- else {
104
- $wsd_Message .= wsd_eInfo('The wp-config file could not be updated! You have to manually update the table_prefix variable
105
- to the one you have specified: '.$new_prefix);
106
- }
107
- }// End if tables successfully renamed
108
- else {
109
- $wsd_Message .= wsd_eInfo('An error has occurred and the tables could not be updated!');
110
- }
111
- }// End if there are tables to rename
112
- }
113
- }// End if (!empty($_POST['newPrefixInput']))
114
- else {
115
- $new_prefix = $old_prefix;
116
- }
117
- ?>
118
-
119
-
120
-
121
- <br/>
122
- <form action="#cdtp" method="post" name="prefixchanging">
123
- <?php
124
- if (function_exists('wp_nonce_field')) {
125
- wp_nonce_field('prefix-changer-change_prefix');
126
- }
127
- ?>
128
- <p>Change the current:
129
- <input type="text" name="newPrefixInput" value="<?php echo $new_prefix;?>" size="20" maxlength="15"/>
130
- table prefix to something different.</p>
131
- <p>Allowed characters: all latin alphanumeric as well as the <strong>_</strong> (underscore).</p>
132
- <input type="submit" name="changePrefixButton" value="Start Renaming" />
133
- </form>
134
-
135
- <div id="cdtp">
136
- <?php
137
- // Display status information
138
- if ($isPostBack)
139
- {
140
- echo $wsd_Message;
141
- }
142
- ?>
143
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/admin/templates/footer.php DELETED
@@ -1,17 +0,0 @@
1
- <?php
2
-
3
- function mrt_wpss_menu_footer(){
4
- echo '
5
- <div style="clear:both;"></div>
6
- <br />
7
- <em>For comments, suggestions, queries and bug reports please visit
8
- the <a href="http://www.websitedefender.com/forums/" target="_blank"
9
- title="WebsiteDefender Forums">WebsiteDefender Forums</a></em>.
10
-
11
- Plugin by <a href="http://websitedefender.com/" target="_blank"
12
- title="WebsiteDefender">WebsiteDefender</a>
13
- </div>
14
- ';
15
- }
16
-
17
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/admin/templates/header.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- function mrt_wpss_menu_head($title){
4
-
5
- echo '
6
- <div class="wrap">
7
- <h2 class="wpss_icon">' . $title . '</h2>';
8
-
9
- }
10
-
11
- ?>
 
 
 
 
 
 
 
 
 
 
 
index.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ Plugin Name: Acunetix WP Security
4
+ Plugin URI: http://www.acunetix.com/websitesecurity/wordpress-security-plugin/
5
+ Description: The Acunetix WP Security plugin is the ultimate must-have tool when it comes to WordPress security. The plugin is free and monitors your website for security weaknesses that hackers might exploit and tells you how to easily fix them.
6
+ Version: 4.0.0
7
+ Author: Acunetix
8
+ Author URI: http://www.acunetix.com/
9
+ License: GPLv2 or later
10
+ Text Domain: WSDWP_SECURITY
11
+ Domain Path: /languages
12
+ */
13
+ define('WSS_PLUGIN_PREFIX', 'wss_');
14
+ define('WSS_PLUGIN_NAME', 'Acunetix WP Security');
15
+ define('WSS_PLUGIN_URL', trailingslashit(plugins_url('', __FILE__)));
16
+ define('WSS_PLUGIN_DIR', trailingslashit(plugin_dir_path(__FILE__)));
17
+ define('WSS_PLUGIN_BASE_NAME', basename(__DIR__));
18
+
19
+
20
+ require('wss-settings.php');
21
+ require('res/inc/alerts.php');
22
+ require('res/inc/WsdUtil.php');
23
+ require('res/inc/WsdPlugin.php');
24
+ require('res/inc/WsdInfo.php');
25
+ require('res/inc/WsdSecurity.php');
26
+ require('res/inc/WsdCheck.php');
27
+ require('res/inc/WsdScheduler.php');
28
+ require('res/inc/WsdWatch.php');
29
+ require('res/inc/WsdLiveTraffic.php');
30
+ require('res/inc/wss-functions.php');
31
+
32
+
33
+ //#!--
34
+ add_action('admin_init', array('WsdUtil','loadPluggable'));
35
+ register_activation_hook( __FILE__, array('WsdPlugin', 'activate') );
36
+ register_deactivation_hook( __FILE__, array('WsdPlugin', 'deactivate') );
37
+ register_uninstall_hook( __FILE__, array('WsdPlugin', 'uninstall') );
38
+ //#++
39
+
40
+
41
+ //#! register tasks
42
+ if(false !== get_option('WSD-PLUGIN-CAN-RUN-TASKS',false))
43
+ {
44
+ WsdScheduler::registerTask(array('WsdPlugin','loadResources'), 'init');
45
+ WsdScheduler::registerTask(array('WsdPlugin','createWpMenu'), 'admin_menu');
46
+ WsdScheduler::registerTask(array('WsdLiveTraffic','registerHit'), 'init');
47
+ WsdScheduler::registerTask(array('WsdLiveTraffic','ajaxGetTrafficData'), 'wp_ajax_ajaxGetTrafficData');
48
+ WsdScheduler::registerTask(array('WsdLiveTraffic','ajaxGetTrafficData'), 'wp_ajax_nopriv_ajaxGetTrafficData');
49
+ WsdScheduler::registerTask(array('WsdUtil','addDashboardWidget'), 'wp_dashboard_setup');
50
+
51
+ // override - scheduled task
52
+ WsdScheduler::registerCronTask('wsd_check_user_admin', array('WsdCheck','adminUsername'), '8h');
53
+
54
+ // scheduled task - hourly cleanup of events in live traffic
55
+ WsdScheduler::registerCronTask('wsd_cleanup_live_traffic', array('WsdLiveTraffic','clearEvents'), 'hourly');
56
+
57
+ // stacked
58
+ WsdScheduler::registerTask(array('WsdWatch','userPasswordUpdate'));
59
+
60
+ // #! run fixes. Only those checked by the user will run (@see: settings page)
61
+ WsdScheduler::registerClassTasks('WsdSecurity','fix_');
62
+
63
+ //#! run checks.
64
+ WsdScheduler::registerClassTasks('WsdCheck','check_');
65
+ }
js/json.js DELETED
@@ -1,482 +0,0 @@
1
- /*
2
- http://www.JSON.org/json2.js
3
- 2010-03-20
4
-
5
- Public Domain.
6
-
7
- NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
8
-
9
- See http://www.JSON.org/js.html
10
-
11
-
12
- This code should be minified before deployment.
13
- See http://javascript.crockford.com/jsmin.html
14
-
15
- USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
16
- NOT CONTROL.
17
-
18
-
19
- This file creates a global JSON object containing two methods: stringify
20
- and parse.
21
-
22
- JSON.stringify(value, replacer, space)
23
- value any JavaScript value, usually an object or array.
24
-
25
- replacer an optional parameter that determines how object
26
- values are stringified for objects. It can be a
27
- function or an array of strings.
28
-
29
- space an optional parameter that specifies the indentation
30
- of nested structures. If it is omitted, the text will
31
- be packed without extra whitespace. If it is a number,
32
- it will specify the number of spaces to indent at each
33
- level. If it is a string (such as '\t' or '&nbsp;'),
34
- it contains the characters used to indent at each level.
35
-
36
- This method produces a JSON text from a JavaScript value.
37
-
38
- When an object value is found, if the object contains a toJSON
39
- method, its toJSON method will be called and the result will be
40
- stringified. A toJSON method does not serialize: it returns the
41
- value represented by the name/value pair that should be serialized,
42
- or undefined if nothing should be serialized. The toJSON method
43
- will be passed the key associated with the value, and this will be
44
- bound to the value
45
-
46
- For example, this would serialize Dates as ISO strings.
47
-
48
- Date.prototype.toJSON = function (key) {
49
- function f(n) {
50
- // Format integers to have at least two digits.
51
- return n < 10 ? '0' + n : n;
52
- }
53
-
54
- return this.getUTCFullYear() + '-' +
55
- f(this.getUTCMonth() + 1) + '-' +
56
- f(this.getUTCDate()) + 'T' +
57
- f(this.getUTCHours()) + ':' +
58
- f(this.getUTCMinutes()) + ':' +
59
- f(this.getUTCSeconds()) + 'Z';
60
- };
61
-
62
- You can provide an optional replacer method. It will be passed the
63
- key and value of each member, with this bound to the containing
64
- object. The value that is returned from your method will be
65
- serialized. If your method returns undefined, then the member will
66
- be excluded from the serialization.
67
-
68
- If the replacer parameter is an array of strings, then it will be
69
- used to select the members to be serialized. It filters the results
70
- such that only members with keys listed in the replacer array are
71
- stringified.
72
-
73
- Values that do not have JSON representations, such as undefined or
74
- functions, will not be serialized. Such values in objects will be
75
- dropped; in arrays they will be replaced with null. You can use
76
- a replacer function to replace those with JSON values.
77
- JSON.stringify(undefined) returns undefined.
78
-
79
- The optional space parameter produces a stringification of the
80
- value that is filled with line breaks and indentation to make it
81
- easier to read.
82
-
83
- If the space parameter is a non-empty string, then that string will
84
- be used for indentation. If the space parameter is a number, then
85
- the indentation will be that many spaces.
86
-
87
- Example:
88
-
89
- text = JSON.stringify(['e', {pluribus: 'unum'}]);
90
- // text is '["e",{"pluribus":"unum"}]'
91
-
92
-
93
- text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
94
- // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
95
-
96
- text = JSON.stringify([new Date()], function (key, value) {
97
- return this[key] instanceof Date ?
98
- 'Date(' + this[key] + ')' : value;
99
- });
100
- // text is '["Date(---current time---)"]'
101
-
102
-
103
- JSON.parse(text, reviver)
104
- This method parses a JSON text to produce an object or array.
105
- It can throw a SyntaxError exception.
106
-
107
- The optional reviver parameter is a function that can filter and
108
- transform the results. It receives each of the keys and values,
109
- and its return value is used instead of the original value.
110
- If it returns what it received, then the structure is not modified.
111
- If it returns undefined then the member is deleted.
112
-
113
- Example:
114
-
115
- // Parse the text. Values that look like ISO date strings will
116
- // be converted to Date objects.
117
-
118
- myData = JSON.parse(text, function (key, value) {
119
- var a;
120
- if (typeof value === 'string') {
121
- a =
122
- /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
123
- if (a) {
124
- return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
125
- +a[5], +a[6]));
126
- }
127
- }
128
- return value;
129
- });
130
-
131
- myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
132
- var d;
133
- if (typeof value === 'string' &&
134
- value.slice(0, 5) === 'Date(' &&
135
- value.slice(-1) === ')') {
136
- d = new Date(value.slice(5, -1));
137
- if (d) {
138
- return d;
139
- }
140
- }
141
- return value;
142
- });
143
-
144
-
145
- This is a reference implementation. You are free to copy, modify, or
146
- redistribute.
147
- */
148
-
149
- /*jslint evil: true, strict: false */
150
-
151
- /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
152
- call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
153
- getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
154
- lastIndex, length, parse, prototype, push, replace, slice, stringify,
155
- test, toJSON, toString, valueOf
156
- */
157
-
158
-
159
- // Create a JSON object only if one does not already exist. We create the
160
- // methods in a closure to avoid creating global variables.
161
-
162
- if (!this.JSON) {
163
- this.JSON = {};
164
- }
165
-
166
- (function () {
167
-
168
- function f(n) {
169
- // Format integers to have at least two digits.
170
- return n < 10 ? '0' + n : n;
171
- }
172
-
173
- if (typeof Date.prototype.toJSON !== 'function') {
174
-
175
- Date.prototype.toJSON = function (key) {
176
-
177
- return isFinite(this.valueOf()) ?
178
- this.getUTCFullYear() + '-' +
179
- f(this.getUTCMonth() + 1) + '-' +
180
- f(this.getUTCDate()) + 'T' +
181
- f(this.getUTCHours()) + ':' +
182
- f(this.getUTCMinutes()) + ':' +
183
- f(this.getUTCSeconds()) + 'Z' : null;
184
- };
185
-
186
- String.prototype.toJSON =
187
- Number.prototype.toJSON =
188
- Boolean.prototype.toJSON = function (key) {
189
- return this.valueOf();
190
- };
191
- }
192
-
193
- var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
194
- escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
195
- gap,
196
- indent,
197
- meta = { // table of character substitutions
198
- '\b': '\\b',
199
- '\t': '\\t',
200
- '\n': '\\n',
201
- '\f': '\\f',
202
- '\r': '\\r',
203
- '"' : '\\"',
204
- '\\': '\\\\'
205
- },
206
- rep;
207
-
208
-
209
- function quote(string) {
210
-
211
- // If the string contains no control characters, no quote characters, and no
212
- // backslash characters, then we can safely slap some quotes around it.
213
- // Otherwise we must also replace the offending characters with safe escape
214
- // sequences.
215
-
216
- escapable.lastIndex = 0;
217
- return escapable.test(string) ?
218
- '"' + string.replace(escapable, function (a) {
219
- var c = meta[a];
220
- return typeof c === 'string' ? c :
221
- '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
222
- }) + '"' :
223
- '"' + string + '"';
224
- }
225
-
226
-
227
- function str(key, holder) {
228
-
229
- // Produce a string from holder[key].
230
-
231
- var i, // The loop counter.
232
- k, // The member key.
233
- v, // The member value.
234
- length,
235
- mind = gap,
236
- partial,
237
- value = holder[key];
238
-
239
- // If the value has a toJSON method, call it to obtain a replacement value.
240
-
241
- if (value && typeof value === 'object' &&
242
- typeof value.toJSON === 'function') {
243
- value = value.toJSON(key);
244
- }
245
-
246
- // If we were called with a replacer function, then call the replacer to
247
- // obtain a replacement value.
248
-
249
- if (typeof rep === 'function') {
250
- value = rep.call(holder, key, value);
251
- }
252
-
253
- // What happens next depends on the value's type.
254
-
255
- switch (typeof value) {
256
- case 'string':
257
- return quote(value);
258
-
259
- case 'number':
260
-
261
- // JSON numbers must be finite. Encode non-finite numbers as null.
262
-
263
- return isFinite(value) ? String(value) : 'null';
264
-
265
- case 'boolean':
266
- case 'null':
267
-
268
- // If the value is a boolean or null, convert it to a string. Note:
269
- // typeof null does not produce 'null'. The case is included here in
270
- // the remote chance that this gets fixed someday.
271
-
272
- return String(value);
273
-
274
- // If the type is 'object', we might be dealing with an object or an array or
275
- // null.
276
-
277
- case 'object':
278
-
279
- // Due to a specification blunder in ECMAScript, typeof null is 'object',
280
- // so watch out for that case.
281
-
282
- if (!value) {
283
- return 'null';
284
- }
285
-
286
- // Make an array to hold the partial results of stringifying this object value.
287
-
288
- gap += indent;
289
- partial = [];
290
-
291
- // Is the value an array?
292
-
293
- if (Object.prototype.toString.apply(value) === '[object Array]') {
294
-
295
- // The value is an array. Stringify every element. Use null as a placeholder
296
- // for non-JSON values.
297
-
298
- length = value.length;
299
- for (i = 0; i < length; i += 1) {
300
- partial[i] = str(i, value) || 'null';
301
- }
302
-
303
- // Join all of the elements together, separated with commas, and wrap them in
304
- // brackets.
305
-
306
- v = partial.length === 0 ? '[]' :
307
- gap ? '[\n' + gap +
308
- partial.join(',\n' + gap) + '\n' +
309
- mind + ']' :
310
- '[' + partial.join(',') + ']';
311
- gap = mind;
312
- return v;
313
- }
314
-
315
- // If the replacer is an array, use it to select the members to be stringified.
316
-
317
- if (rep && typeof rep === 'object') {
318
- length = rep.length;
319
- for (i = 0; i < length; i += 1) {
320
- k = rep[i];
321
- if (typeof k === 'string') {
322
- v = str(k, value);
323
- if (v) {
324
- partial.push(quote(k) + (gap ? ': ' : ':') + v);
325
- }
326
- }
327
- }
328
- } else {
329
-
330
- // Otherwise, iterate through all of the keys in the object.
331
-
332
- for (k in value) {
333
- if (Object.hasOwnProperty.call(value, k)) {
334
- v = str(k, value);
335
- if (v) {
336
- partial.push(quote(k) + (gap ? ': ' : ':') + v);
337
- }
338
- }
339
- }
340
- }
341
-
342
- // Join all of the member texts together, separated with commas,
343
- // and wrap them in braces.
344
-
345
- v = partial.length === 0 ? '{}' :
346
- gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
347
- mind + '}' : '{' + partial.join(',') + '}';
348
- gap = mind;
349
- return v;
350
- }
351
- }
352
-
353
- // If the JSON object does not yet have a stringify method, give it one.
354
-
355
- if (typeof JSON.stringify !== 'function') {
356
- JSON.stringify = function (value, replacer, space) {
357
-
358
- // The stringify method takes a value and an optional replacer, and an optional
359
- // space parameter, and returns a JSON text. The replacer can be a function
360
- // that can replace values, or an array of strings that will select the keys.
361
- // A default replacer method can be provided. Use of the space parameter can
362
- // produce text that is more easily readable.
363
-
364
- var i;
365
- gap = '';
366
- indent = '';
367
-
368
- // If the space parameter is a number, make an indent string containing that
369
- // many spaces.
370
-
371
- if (typeof space === 'number') {
372
- for (i = 0; i < space; i += 1) {
373
- indent += ' ';
374
- }
375
-
376
- // If the space parameter is a string, it will be used as the indent string.
377
-
378
- } else if (typeof space === 'string') {
379
- indent = space;
380
- }
381
-
382
- // If there is a replacer, it must be a function or an array.
383
- // Otherwise, throw an error.
384
-
385
- rep = replacer;
386
- if (replacer && typeof replacer !== 'function' &&
387
- (typeof replacer !== 'object' ||
388
- typeof replacer.length !== 'number')) {
389
- throw new Error('JSON.stringify');
390
- }
391
-
392
- // Make a fake root object containing our value under the key of ''.
393
- // Return the result of stringifying the value.
394
-
395
- return str('', {'': value});
396
- };
397
- }
398
-
399
-
400
- // If the JSON object does not yet have a parse method, give it one.
401
-
402
- if (typeof JSON.parse !== 'function') {
403
- JSON.parse = function (text, reviver) {
404
-
405
- // The parse method takes a text and an optional reviver function, and returns
406
- // a JavaScript value if the text is a valid JSON text.
407
-
408
- var j;
409
-
410
- function walk(holder, key) {
411
-
412
- // The walk method is used to recursively walk the resulting structure so
413
- // that modifications can be made.
414
-
415
- var k, v, value = holder[key];
416
- if (value && typeof value === 'object') {
417
- for (k in value) {
418
- if (Object.hasOwnProperty.call(value, k)) {
419
- v = walk(value, k);
420
- if (v !== undefined) {
421
- value[k] = v;
422
- } else {
423
- delete value[k];
424
- }
425
- }
426
- }
427
- }
428
- return reviver.call(holder, key, value);
429
- }
430
-
431
-
432
- // Parsing happens in four stages. In the first stage, we replace certain
433
- // Unicode characters with escape sequences. JavaScript handles many characters
434
- // incorrectly, either silently deleting them, or treating them as line endings.
435
-
436
- text = String(text);
437
- cx.lastIndex = 0;
438
- if (cx.test(text)) {
439
- text = text.replace(cx, function (a) {
440
- return '\\u' +
441
- ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
442
- });
443
- }
444
-
445
- // In the second stage, we run the text against regular expressions that look
446
- // for non-JSON patterns. We are especially concerned with '()' and 'new'
447
- // because they can cause invocation, and '=' because it can cause mutation.
448
- // But just to be safe, we want to reject all unexpected forms.
449
-
450
- // We split the second stage into 4 regexp operations in order to work around
451
- // crippling inefficiencies in IE's and Safari's regexp engines. First we
452
- // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
453
- // replace all simple value tokens with ']' characters. Third, we delete all
454
- // open brackets that follow a colon or comma or that begin the text. Finally,
455
- // we look to see that the remaining characters are only whitespace or ']' or
456
- // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
457
-
458
- if (/^[\],:{}\s]*$/.
459
- test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
460
- replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
461
- replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
462
-
463
- // In the third stage we use the eval function to compile the text into a
464
- // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
465
- // in JavaScript: it can begin a block or an object literal. We wrap the text
466
- // in parens to eliminate the ambiguity.
467
-
468
- j = eval('(' + text + ')');
469
-
470
- // In the optional fourth stage, we recursively walk the new structure, passing
471
- // each name/value pair to a reviver function for possible transformation.
472
-
473
- return typeof reviver === 'function' ?
474
- walk({'': j}, '') : j;
475
- }
476
-
477
- // If the text is not JSON parseable, then a SyntaxError is thrown.
478
-
479
- throw new SyntaxError('JSON.parse');
480
- };
481
- }
482
- }());