summaryrefslogtreecommitdiff
path: root/treat_data.c
diff options
context:
space:
mode:
authorStefan Esser2015-12-17 16:35:34 +0100
committerStefan Esser2015-12-17 16:35:34 +0100
commitc4c9192839ba7842f5da58f5fd525056c77cfe54 (patch)
tree810854ddb53e03d7320570ec8d634390a849d6b2 /treat_data.c
parentaee7faf18880573b60606756a61faea32a1bb89a (diff)
Continue the actual porting work on GitHub
Diffstat (limited to 'treat_data.c')
-rw-r--r--treat_data.c214
1 files changed, 214 insertions, 0 deletions
diff --git a/treat_data.c b/treat_data.c
new file mode 100644
index 0000000..86fcd9f
--- /dev/null
+++ b/treat_data.c
@@ -0,0 +1,214 @@
1/*
2 +----------------------------------------------------------------------+
3 | Suhosin Version 1 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2006-2007 The Hardened-PHP Project |
6 | Copyright (c) 2007-2015 SektionEins GmbH |
7 +----------------------------------------------------------------------+
8 | This source file is subject to version 3.01 of the PHP license, |
9 | that is bundled with this package in the file LICENSE, and is |
10 | available through the world-wide-web at the following url: |
11 | http://www.php.net/license/3_01.txt |
12 | If you did not receive a copy of the PHP license and are unable to |
13 | obtain it through the world-wide-web, please send a note to |
14 | license@php.net so we can mail you a copy immediately. |
15 +----------------------------------------------------------------------+
16 | Author: Stefan Esser <sesser@sektioneins.de> |
17 +----------------------------------------------------------------------+
18*/
19/*
20 $Id: treat_data.c $
21*/
22
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
26
27#include "php.h"
28#include "php_ini.h"
29#include "php_suhosin7.h"
30#include "SAPI.h"
31#include "php_variables.h"
32#include "ext/standard/url.h"
33
34SAPI_TREAT_DATA_FUNC(suhosin_treat_data)
35{
36 char *res = NULL, *var, *val, *separator = NULL;
37 const char *c_var;
38 zval array;
39 int free_buffer = 0;
40 char *strtok_buf = NULL;
41 zend_long count = 0;
42
43 /* Mark that we were not yet called */
44 SUHOSIN7_G(already_scanned) = 0;
45
46 ZVAL_UNDEF(&array);
47 switch (arg) {
48 case PARSE_POST:
49 case PARSE_GET:
50 case PARSE_COOKIE:
51 array_init(&array);
52 switch (arg) {
53 case PARSE_POST:
54 zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_POST]);
55 ZVAL_COPY_VALUE(&PG(http_globals)[TRACK_VARS_POST], &array);
56 if (SUHOSIN7_G(max_request_variables) && (SUHOSIN7_G(max_post_vars) == 0 ||
57 SUHOSIN7_G(max_request_variables) <= SUHOSIN7_G(max_post_vars))) {
58 SUHOSIN7_G(max_post_vars) = SUHOSIN7_G(max_request_variables);
59 }
60 break;
61 case PARSE_GET:
62 zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_GET]);
63 ZVAL_COPY_VALUE(&PG(http_globals)[TRACK_VARS_GET], &array);
64 if (SUHOSIN7_G(max_request_variables) && (SUHOSIN7_G(max_get_vars) == 0 ||
65 SUHOSIN7_G(max_request_variables) <= SUHOSIN7_G(max_get_vars))) {
66 SUHOSIN7_G(max_get_vars) = SUHOSIN7_G(max_request_variables);
67 }
68 break;
69 case PARSE_COOKIE:
70 zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_COOKIE]);
71 ZVAL_COPY_VALUE(&PG(http_globals)[TRACK_VARS_COOKIE], &array);
72 if (SUHOSIN7_G(max_request_variables) && (SUHOSIN7_G(max_cookie_vars) == 0 ||
73 SUHOSIN7_G(max_request_variables) <= SUHOSIN7_G(max_cookie_vars))) {
74 SUHOSIN7_G(max_cookie_vars) = SUHOSIN7_G(max_request_variables);
75 }
76 break;
77 }
78 break;
79 default:
80 ZVAL_COPY_VALUE(&array, destArray);
81 break;
82 }
83
84 if (arg == PARSE_POST) {
85 sapi_handle_post(&array);
86 return;
87 }
88
89 if (arg == PARSE_GET) { /* GET data */
90 c_var = SG(request_info).query_string;
91 if (c_var && *c_var) {
92 res = (char *) estrdup(c_var);
93 free_buffer = 1;
94 } else {
95 free_buffer = 0;
96 }
97 } else if (arg == PARSE_COOKIE) { /* Cookie data */
98 c_var = SG(request_info).cookie_data;
99 if (c_var && *c_var) {
100 if (SUHOSIN7_G(cookie_encrypt)) {
101 res = (char *) estrdup(suhosin_cookie_decryptor());
102 } else {
103 res = (char *) estrdup(c_var);
104 }
105 free_buffer = 1;
106 } else {
107 free_buffer = 0;
108 }
109 } else if (arg == PARSE_STRING) { /* String data */
110 res = str;
111 free_buffer = 1;
112 }
113
114 if (!res) {
115 return;
116 }
117
118 switch (arg) {
119 case PARSE_GET:
120 case PARSE_STRING:
121 separator = (char *) estrdup(PG(arg_separator).input);
122 break;
123 case PARSE_COOKIE:
124 separator = ";\0";
125 break;
126 }
127
128 var = php_strtok_r(res, separator, &strtok_buf);
129
130 while (var) {
131 val = strchr(var, '=');
132
133 if (arg == PARSE_COOKIE) {
134 /* Remove leading spaces from cookie names, needed for multi-cookie header where ; can be followed by a space */
135 while (isspace(*var)) {
136 var++;
137 }
138 if (var == val || *var == '\0') {
139 goto next_cookie;
140 }
141 }
142
143 if (++count > PG(max_input_vars)) {
144 php_error_docref(NULL, E_WARNING, "Input variables exceeded " ZEND_LONG_FMT ". To increase the limit change max_input_vars in php.ini.", PG(max_input_vars));
145 break;
146 }
147
148 if (val) { /* have a value */
149 size_t val_len;
150 size_t new_val_len;
151
152 *val++ = '\0';
153 php_url_decode(var, strlen(var));
154 val_len = php_url_decode(val, strlen(val));
155 val = estrndup(val, val_len);
156 if (suhosin_input_filter(arg, var, &val, val_len, &new_val_len)) {
157 if (sapi_module.input_filter(arg, var, &val, new_val_len, &new_val_len)) {
158 php_register_variable_safe(var, val, new_val_len, &array);
159 }
160 } else {
161 SUHOSIN7_G(abort_request) = 1;
162 }
163 efree(val);
164 } else {
165 size_t val_len;
166 size_t new_val_len;
167
168 php_url_decode(var, strlen(var));
169 val_len = 0;
170 val = estrndup("", val_len);
171 if (suhosin_input_filter(arg, var, &val, val_len, &new_val_len)) {
172 if (sapi_module.input_filter(arg, var, &val, new_val_len, &new_val_len)) {
173 php_register_variable_safe(var, val, new_val_len, &array);
174 }
175 } else {
176 SUHOSIN7_G(abort_request) = 1;
177 }
178 efree(val);
179 }
180next_cookie:
181 var = php_strtok_r(NULL, separator, &strtok_buf);
182 }
183
184 if (arg != PARSE_COOKIE) {
185 efree(separator);
186 }
187
188 if (free_buffer) {
189 efree(res);
190 }
191
192}
193
194
195void suhosin_hook_treat_data()
196{
197 sapi_register_treat_data(suhosin_treat_data);
198
199 if (old_input_filter == NULL) {
200 old_input_filter = sapi_module.input_filter;
201 }
202 sapi_module.input_filter = suhosin_input_filter_wrapper;
203}
204
205
206/*
207 * Local variables:
208 * tab-width: 4
209 * c-basic-offset: 4
210 * End:
211 * vim600: noet sw=4 ts=4 fdm=marker
212 * vim<600: noet sw=4 ts=4
213 */
214