summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config.m411
-rw-r--r--cookiecrypt.c146
-rw-r--r--crypt.c289
-rw-r--r--execute.c4
-rw-r--r--header.c158
-rw-r--r--ifilter.c90
-rw-r--r--log.c5
-rw-r--r--php_suhosin7.h44
-rw-r--r--suhosin7.c84
-rw-r--r--tests/cookie/crypt.checkraddr_4.phpt28
-rw-r--r--tests/cookie/crypt.checkraddr_4_incorrect.phpt26
-rw-r--r--tests/cookie/crypt.cryptlist.phpt29
-rw-r--r--tests/cookie/crypt.docroot.phpt27
-rw-r--r--tests/cookie/crypt.invalid.phpt26
-rw-r--r--tests/cookie/crypt.key_default.phpt23
-rw-r--r--tests/cookie/crypt.key_empty.phpt23
-rw-r--r--tests/cookie/crypt.key_empty_remote_addr.phpt27
-rw-r--r--tests/cookie/crypt.no_encryption.phpt16
-rw-r--r--tests/cookie/crypt.plainlist.phpt29
-rw-r--r--tests/cookie/crypt.raddr_1.phpt27
-rw-r--r--tests/cookie/crypt.raddr_2.phpt27
-rw-r--r--tests/cookie/crypt.raddr_3.phpt27
-rw-r--r--tests/cookie/crypt.raddr_4.phpt27
-rw-r--r--tests/cookie/crypt.ua.phpt27
-rw-r--r--tests/skipif.inc4
-rw-r--r--tests/skipifcli.inc8
-rw-r--r--tests/skipifnotcli.inc8
-rw-r--r--treat_data.c175
28 files changed, 1184 insertions, 231 deletions
diff --git a/config.m4 b/config.m4
index b5d8249..65b0c83 100644
--- a/config.m4
+++ b/config.m4
@@ -1,16 +1,17 @@
1dnl $Id$ 1dnl $Id$
2dnl config.m4 for extension suhosin7 2dnl config.m4 for extension suhosin7
3 3
4PHP_ARG_ENABLE(suhosin, whether to enable suhosin support, 4PHP_ARG_ENABLE(suhosin7, whether to enable suhosin support,
5[ --enable-suhosin Enable suhosin support]) 5[ --enable-suhosin7 Enable suhosin support])
6 6
7if test "$PHP_SUHOSIN" != "no"; then 7if test "$PHP_SUHOSIN7" != "no"; then
8 PHP_NEW_EXTENSION(suhosin7, suhosin7.c aes.c ifilter.c memory_limit.c sha256.c treat_data.c log.c execute.c, $ext_shared,, -DZEND_ENABLE_STATIC_ACHE=1) 8 PHP_NEW_EXTENSION(suhosin7, suhosin7.c ifilter.c memory_limit.c aes.c treat_data.c log.c execute.c crypt.c cookiecrypt.c header.c, $ext_shared,, -DZEND_ENABLE_STATIC_ACHE=1)
9 PHP_ADD_EXTENSION_DEP(suhosin7, hash)
9fi 10fi
10 11
11PHP_ARG_ENABLE(suhosin7-experimental, whether to enable experimental suhosin7 features, 12PHP_ARG_ENABLE(suhosin7-experimental, whether to enable experimental suhosin7 features,
12[ --enable-suhosin7-experimental Enable experimental suhosin7 features], no, no) 13[ --enable-suhosin7-experimental Enable experimental suhosin7 features], no, no)
13 14
14if test "$PHP_SUHOSIN7_EXPERIMENTAL" != "no"; then 15if test "$PHP_SUHOSIN7_EXPERIMENTAL" != "no"; then
15 AC_DEFINE(SUHOSIN7_EXPERIMENTAL, 1, [Whether to enable experimental suhosin7 features]) 16 AC_DEFINE(SUHOSIN7_EXPERIMENTAL, 1, [Whether to enable experimental suhosin7 features])
16fi 17fi
diff --git a/cookiecrypt.c b/cookiecrypt.c
new file mode 100644
index 0000000..70b0c5a
--- /dev/null
+++ b/cookiecrypt.c
@@ -0,0 +1,146 @@
1/*
2 +----------------------------------------------------------------------+
3 | Suhosin Version 1 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2006-2007 The Hardened-PHP Project |
6 | Copyright (c) 2007-2016 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 | Authors: Stefan Esser <sesser@sektioneins.de> |
17 | Ben Fuhrmannek <ben.fuhrmannek@sektioneins.de> |
18 +----------------------------------------------------------------------+
19*/
20/*
21 $Id: header.c,v 1.1.1.1 2007-11-28 01:15:35 sesser Exp $
22*/
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include "php.h"
29#include "ext/standard/url.h"
30#include "php_suhosin7.h"
31#include "php_variables.h"
32
33
34zend_string *suhosin_encrypt_single_cookie(char *name, int name_len, char *value, int value_len, char *key)
35{
36 int l;
37
38 name = estrndup(name, name_len);
39 name_len = php_url_decode(name, name_len);
40 suhosin_normalize_varname(name);
41 name_len = strlen(name);
42
43 if ((SUHOSIN7_G(cookie_plainlist) && zend_hash_str_exists(SUHOSIN7_G(cookie_plainlist), name, name_len)) ||
44 (SUHOSIN7_G(cookie_plainlist) == NULL && SUHOSIN7_G(cookie_cryptlist) && !zend_hash_str_exists(SUHOSIN7_G(cookie_cryptlist), name, name_len))) {
45 efree(name);
46 return zend_string_init(value, value_len, 0);
47 }
48
49 value = estrndup(value, value_len);
50 value_len = php_url_decode(value, value_len);
51
52 zend_string *d = suhosin_encrypt_string(value, value_len, name, name_len, key);
53 zend_string *d_url = php_url_encode(ZSTR_VAL(d), ZSTR_LEN(d));
54 zend_string_release(d);
55 efree(name);
56 efree(value);
57 return d_url;
58}
59
60char *suhosin_decrypt_single_cookie(char *name, int name_len, char *value, int value_len, char *key, char **out)
61{
62 char *name2 = estrndup(name, name_len);
63 int name2_len = php_url_decode(name2, name_len);
64 suhosin_normalize_varname(name2);
65 name2_len = strlen(name2);
66
67 if ((SUHOSIN7_G(cookie_plainlist) && zend_hash_str_exists(SUHOSIN7_G(cookie_plainlist), name2, name2_len)) ||
68 (SUHOSIN7_G(cookie_plainlist) == NULL && SUHOSIN7_G(cookie_cryptlist) && !zend_hash_str_exists(SUHOSIN7_G(cookie_cryptlist), name2, name2_len))) {
69 // if (1) {
70 efree(name2);
71 memcpy(*out, name, name_len);
72 *out += name_len;
73 **out = '='; *out +=1;
74 memcpy(*out, value, value_len);
75 *out += value_len;
76 return *out;
77 }
78
79 value = estrndup(value, value_len);
80 value_len = php_url_decode(value, value_len);
81
82 zend_string *d = suhosin_decrypt_string(value, value_len, name2, name2_len, key, SUHOSIN7_G(cookie_checkraddr));
83 if (d) {
84 zend_string *d_url = php_url_encode(ZSTR_VAL(d), ZSTR_LEN(d));
85 zend_string_release(d);
86 memcpy(*out, name, name_len);
87 *out += name_len;
88 **out = '='; *out += 1;
89 memcpy(*out, ZSTR_VAL(d_url), ZSTR_LEN(d_url));
90 *out += ZSTR_LEN(d_url);
91 zend_string_release(d_url);
92 }
93
94 efree(name2);
95 efree(value);
96
97 return *out;
98}
99
100/* {{{ suhosin_cookie_decryptor
101 */
102char *suhosin_cookie_decryptor(char *raw_cookie)
103{
104 // SDEBUG("raw cookie: %s", raw_cookie);
105 char *decrypted, *ret;
106 // int j;
107 char cryptkey[33];
108
109 suhosin_generate_key(SUHOSIN7_G(cookie_cryptkey), SUHOSIN7_G(cookie_cryptua), SUHOSIN7_G(cookie_cryptdocroot), SUHOSIN7_G(cookie_cryptraddr), cryptkey);
110 SDEBUG("cryptkey=%02x.%02x.%02x", cryptkey[0], cryptkey[1], cryptkey[2]);
111
112 ret = decrypted = emalloc(strlen(raw_cookie)*4+1);
113 raw_cookie = estrdup(raw_cookie);
114 SUHOSIN7_G(raw_cookie) = estrdup(raw_cookie);
115
116 char *strtok_buf = NULL;
117 char *var, *val;
118 const char *separator = ";\0";
119 for (char *var = php_strtok_r(raw_cookie, separator, &strtok_buf); var; var = php_strtok_r(NULL, separator, &strtok_buf)) {
120 val = strchr(var, '=');
121 while (isspace(*var)) { var++; }
122 if (var == val || *var == '\0') { continue; }
123 if (val) {
124 *val++ = '\0';
125 // size_t var_len = php_url_decode(var, strlen(var));
126 size_t var_len = strlen(var);
127 // size_t val_len = php_url_decode(val, strlen(val));
128 size_t val_len = strlen(val);
129 SDEBUG("decrypting cookie |%s|%s|", var, val);
130 suhosin_decrypt_single_cookie(var, var_len, val, val_len, cryptkey, &decrypted);
131 SDEBUG("ret is now %s", ret);
132 *decrypted++ = ';';
133 } else {
134 // ??
135 }
136 }
137
138 *decrypted++ = 0;
139 ret = erealloc(ret, decrypted-ret);
140
141 SUHOSIN7_G(decrypted_cookie) = ret;
142 efree(raw_cookie);
143
144 return ret;
145}
146/* }}} */
diff --git a/crypt.c b/crypt.c
new file mode 100644
index 0000000..6daaa03
--- /dev/null
+++ b/crypt.c
@@ -0,0 +1,289 @@
1/*
2 +----------------------------------------------------------------------+
3 | Suhosin Version 1 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2006-2007 The Hardened-PHP Project |
6 | Copyright (c) 2007-2016 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 | Authors: Stefan Esser <sesser@sektioneins.de> |
17 | Ben Fuhrmannek <ben.fuhrmannek@sektioneins.de> |
18 +----------------------------------------------------------------------+
19*/
20
21#ifdef HAVE_CONFIG_H
22#include "config.h"
23#endif
24
25#include "php.h"
26#include "php_suhosin7.h"
27#include "ext/standard/base64.h"
28// #include "sha256.h"
29#include "ext/hash/php_hash.h"
30#include "ext/hash/php_hash_sha.h"
31
32// TODO: IPv6 handling
33
34static void suhosin_get_ipv4(char *buf)
35{
36 char *raddr = suhosin_getenv(ZEND_STRL("REMOTE_ADDR"));
37 int i;
38
39
40 if (raddr == NULL) {
41 memset(buf, 0, 4);
42 return;
43 }
44
45 for (i=0; i<4; i++) {
46 if (raddr[0] == 0) {
47 buf[i] = 0;
48 } else {
49 buf[i] = strtol(raddr, &raddr, 10);
50 if (raddr[0] == '.') {
51 raddr++;
52 }
53 }
54 }
55}
56
57zend_string *suhosin_encrypt_string(char *str, int len, char *var, int vlen, char *key)
58{
59 int padded_len, i, slen;
60 unsigned char *crypted, *tmp;
61 unsigned int check = 0x13579BDF;
62
63 if (str == NULL) {
64 return NULL;
65 }
66
67 if (len == 0) {
68 return ZSTR_EMPTY_ALLOC();
69 }
70
71 suhosin_aes_gkey(4, 8, key);
72
73 padded_len = ((len+15) & ~0xF);
74 crypted = emalloc(16+padded_len+1);
75 memset(crypted, 0xff, 16+padded_len+1);
76 memcpy(crypted+16, str, len+1);
77
78 /* calculate check value */
79 for (i = 0; i < vlen; i++) {
80 check = (check << 3) | (check >> (32-3));
81 check += check << 1;
82 check ^= (unsigned char)var[i];
83 }
84 for (i = 0; i < len; i++) {
85 check = (check << 3) | (check >> (32-3));
86 check += check << 1;
87 check ^= (unsigned char)str[i];
88 }
89
90 /* store ip value */
91 suhosin_get_ipv4((char *)crypted + 4);
92
93 /* store check value */
94 crypted[8] = check & 0xff;
95 crypted[9] = (check >> 8) & 0xff;
96 crypted[10] = (check >> 16) & 0xff;
97 crypted[11] = (check >> 24) & 0xff;
98
99 /* store original length */
100 crypted[12] = len & 0xff;
101 crypted[13] = (len >> 8) & 0xff;
102 crypted[14] = (len >> 16) & 0xff;
103 crypted[15] = (len >> 24) & 0xff;
104
105 for (i = 0, tmp = crypted; i < padded_len + 16; i += 16, tmp += 16) {
106 if (i > 0) {
107 int j;
108 for (j=0; j<16; j++) tmp[j] ^= tmp[j-16];
109 }
110 suhosin_aes_encrypt((char *)tmp);
111 }
112
113 zend_string *zs = php_base64_encode(crypted, padded_len+16);
114 efree(crypted);
115 // slen=strlen((char *)tmp);
116 for (i = 0; i < ZSTR_LEN(zs); i++) {
117 switch (ZSTR_VAL(zs)[i]) {
118 case '/': ZSTR_VAL(zs)[i]='-'; break;
119 case '=': ZSTR_VAL(zs)[i]='.'; break;
120 case '+': ZSTR_VAL(zs)[i]='_'; break;
121 }
122 }
123 return zs;
124// return NULL;
125}
126
127zend_string *suhosin_decrypt_string(char *str, int padded_len, char *var, int vlen, char *key, int check_ra)
128{
129 SDEBUG("decrypting string |%s|", str);
130 int i;
131 unsigned int check = 0x13579BDF;
132
133 if (str == NULL) {
134 return NULL;
135 }
136
137 if (padded_len == 0) {
138 return ZSTR_EMPTY_ALLOC();
139 }
140 suhosin_aes_gkey(4, 8, key);
141
142 for (i = 0; i < padded_len; i++) {
143 switch (str[i]) {
144 case '-': str[i]='/'; break;
145 case '.': str[i]='='; break;
146 case '_': str[i]='+'; break;
147 }
148 }
149
150 zend_string *decrypted_zs = php_base64_decode((unsigned char *)str, padded_len);
151 if (decrypted_zs == NULL) {
152 return NULL;
153 }
154
155 unsigned char *decrypted = (unsigned char*)ZSTR_VAL(decrypted_zs);
156 int len = ZSTR_LEN(decrypted_zs);
157 SDEBUG("len=%d", len);
158 if (len < 2*16 || (len % 16) != 0) {
159 goto error_out;
160 }
161
162 unsigned char *tmp;
163 for (i = len - 16, tmp = decrypted + i; i >= 0; i -= 16, tmp -= 16) {
164 suhosin_aes_decrypt((char *)tmp);
165 if (i > 0) {
166 int j;
167 for (j=0; j<16; j++) tmp[j] ^= tmp[j-16];
168 }
169 }
170 SDEBUG("tmp=%s", tmp);
171 /* retrieve orig_len */
172 int o_len = decrypted[15];
173 o_len <<= 8;
174 o_len |= decrypted[14];
175 o_len <<= 8;
176 o_len |= decrypted[13];
177 o_len <<= 8;
178 o_len |= decrypted[12];
179
180 if (o_len < 0 || o_len > len-16) {
181 goto error_out;
182 }
183
184 /* calculate check value */
185 for (i = 0; i<vlen; i++) {
186 check = (check << 3) | (check >> (32-3));
187 check += check << 1;
188 check ^= (unsigned char)var[i];
189 }
190 for (i = 0; i<o_len; i++) {
191 check = (check << 3) | (check >> (32-3));
192 check += check << 1;
193 check ^= decrypted[16+i];
194 }
195
196 /* check value */
197 int invalid = (decrypted[8] != (check & 0xff)) ||
198 (decrypted[9] != ((check >> 8) & 0xff)) ||
199 (decrypted[10] != ((check >> 16) & 0xff)) ||
200 (decrypted[11] != ((check >> 24) & 0xff));
201
202 /* check IP */
203 if (check_ra) {
204 if (check_ra > 4) {
205 check_ra = 4;
206 }
207 char buf[4];
208 suhosin_get_ipv4(&buf[0]);
209 if (memcmp(buf, decrypted+4, check_ra) != 0) {
210 goto error_out;
211 }
212 }
213
214 if (invalid) {
215 goto error_out;
216 }
217
218 memmove(decrypted, decrypted+16, o_len);
219 decrypted[o_len] = 0;
220 ZSTR_LEN(decrypted_zs) = o_len;
221 /* we do not realloc() here because 16 byte less
222 is simply not worth the overhead */
223 return decrypted_zs;
224
225error_out:
226 SDEBUG("error_out");
227 if (decrypted_zs) {
228 zend_string_release(decrypted_zs);
229 }
230 return NULL;
231}
232
233char *suhosin_generate_key(char *key, zend_bool ua, zend_bool dr, long raddr, char *cryptkey)
234{
235 char *_ua = NULL;
236 char *_dr = NULL;
237 char *_ra = NULL;
238 PHP_SHA256_CTX ctx;
239
240 if (ua) {
241 _ua = suhosin_getenv(ZEND_STRL("HTTP_USER_AGENT"));
242 }
243
244 if (dr) {
245 _dr = suhosin_getenv(ZEND_STRL("DOCUMENT_ROOT"));
246 }
247
248 if (raddr > 0) {
249 _ra = suhosin_getenv(ZEND_STRL("REMOTE_ADDR"));
250 }
251
252 SDEBUG("KEY: %s - UA: %s - DR: %s - RA: %s", key,_ua,_dr,_ra);
253
254 PHP_SHA256Init(&ctx);
255 if (key == NULL || *key == 0) {
256 PHP_SHA256Update(&ctx, (unsigned char*)ZEND_STRL("D3F4UL7"));
257 } else {
258 PHP_SHA256Update(&ctx, (unsigned char*)key, strlen(key));
259 }
260 if (_ua) {
261 PHP_SHA256Update(&ctx, (unsigned char*)_ua, strlen(_ua));
262 }
263 if (_dr) {
264 PHP_SHA256Update(&ctx, (unsigned char*)_dr, strlen(_dr));
265 }
266 if (_ra) {
267 if (raddr >= 4) {
268 PHP_SHA256Update(&ctx, (unsigned char*)_ra, strlen(_ra));
269 } else {
270 long dots = 0;
271 char *tmp = _ra;
272
273 while (*tmp) {
274 if (*tmp == '.') {
275 dots++;
276 if (dots == raddr) {
277 break;
278 }
279 }
280 tmp++;
281 }
282 PHP_SHA256Update(&ctx, (unsigned char*)_ra, tmp-_ra);
283 }
284 }
285 PHP_SHA256Final((unsigned char *)cryptkey, &ctx);
286 cryptkey[32] = 0; /* uhmm... not really a string */
287
288 return cryptkey;
289}
diff --git a/execute.c b/execute.c
index 8abaff2..0e569e0 100644
--- a/execute.c
+++ b/execute.c
@@ -1198,8 +1198,8 @@ internal_function_handler ihandlers[] = {
1198 { NULL, NULL, NULL, NULL, NULL } 1198 { NULL, NULL, NULL, NULL, NULL }
1199}; 1199};
1200 1200
1201#define FUNCTION_WARNING() zend_error(E_WARNING, "%s() has been disabled for security reasons", get_active_function_name()); 1201#define FUNCTION_WARNING() zend_error(E_WARNING, "%s() has been disabled for security reasons", suhosin_get_active_function_name());
1202#define FUNCTION_SIMULATE_WARNING() zend_error(E_WARNING, "SIMULATION - %s() has been disabled for security reasons", get_active_function_name()); 1202#define FUNCTION_SIMULATE_WARNING() zend_error(E_WARNING, "SIMULATION - %s() has been disabled for security reasons", suhosin_get_active_function_name());
1203 1203
1204/* {{{ void suhosin_execute_internal 1204/* {{{ void suhosin_execute_internal
1205 * This function provides a hook for internal execution */ 1205 * This function provides a hook for internal execution */
diff --git a/header.c b/header.c
new file mode 100644
index 0000000..65b2c26
--- /dev/null
+++ b/header.c
@@ -0,0 +1,158 @@
1/*
2 +----------------------------------------------------------------------+
3 | Suhosin Version 1 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2006-2007 The Hardened-PHP Project |
6 | Copyright (c) 2007-2016 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 | Authors: Stefan Esser <sesser@sektioneins.de> |
17 | Ben Fuhrmannek <ben.fuhrmannek@sektioneins.de> |
18 +----------------------------------------------------------------------+
19*/
20/*
21 $Id: header.c,v 1.1.1.1 2007-11-28 01:15:35 sesser Exp $
22*/
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include "php.h"
29#include "php_suhosin7.h"
30#include "SAPI.h"
31
32
33static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers) = NULL;
34
35/* {{{ suhosin_header_handler
36 */
37static int suhosin_header_handler(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers)
38{
39 int retval = SAPI_HEADER_ADD;
40
41 if (op != SAPI_HEADER_ADD && op != SAPI_HEADER_REPLACE) {
42 goto suhosin_skip_header_handling;
43 }
44
45 if (sapi_header && sapi_header->header) {
46
47 char *tmp = sapi_header->header;
48
49 for (int i = 0; i < sapi_header->header_len; i++, tmp++) {
50 if (tmp[0] == 0) {
51 suhosin_log(S_MISC, "%s() - wanted to send a HTTP header with an ASCII NUL in it", suhosin_get_active_function_name());
52 if (!SUHOSIN7_G(simulation)) {
53 sapi_header->header_len = i;
54 }
55 }
56 if (SUHOSIN7_G(allow_multiheader)) {
57 continue;
58 } else if ((tmp[0] == '\r' && (tmp[1] != '\n' || i == 0)) ||
59 (tmp[0] == '\n' && (i == sapi_header->header_len-1 || i == 0 || (tmp[1] != ' ' && tmp[1] != '\t')))) {
60 suhosin_log(S_MISC, "%s() - wanted to send multiple HTTP headers at once", suhosin_get_active_function_name());
61 if (!SUHOSIN7_G(simulation)) {
62 sapi_header->header_len = i;
63 tmp[0] = 0;
64 }
65 }
66 }
67 }
68
69 /* Handle a potential cookie */
70
71 if (SUHOSIN7_G(cookie_encrypt) && (strncasecmp("Set-Cookie:", sapi_header->header, sizeof("Set-Cookie:")-1) == 0)) {
72
73 char *start, *end, *rend, *tmp;
74 char *name, *value;
75 int nlen, vlen, len, tlen;
76 char cryptkey[33];
77
78 suhosin_generate_key(SUHOSIN7_G(cookie_cryptkey), SUHOSIN7_G(cookie_cryptua), SUHOSIN7_G(cookie_cryptdocroot), SUHOSIN7_G(cookie_cryptraddr), (char *)&cryptkey TSRMLS_CC);
79 start = estrndup(sapi_header->header, sapi_header->header_len);
80 rend = end = start + sapi_header->header_len;
81
82 tmp = memchr(start, ';', end-start);
83 if (tmp != NULL) {
84 end = tmp;
85 }
86
87 tmp = start + sizeof("Set-Cookie:") - 1;
88 while (tmp < end && isspace(*tmp)) {
89 tmp++;
90 }
91 name = tmp;
92 nlen = end-name;
93 tmp = memchr(name, '=', nlen);
94 if (tmp == NULL) {
95 value = end;
96 } else {
97 value = tmp+1;
98 nlen = tmp-name;
99 }
100 vlen = end-value;
101
102 zend_string *zs_val = suhosin_encrypt_single_cookie(name, nlen, value, vlen, (char *)cryptkey);
103
104 len = sizeof("Set-Cookie: ")-1 + nlen + 1 + ZSTR_LEN(zs_val) + rend-end;
105 tmp = emalloc(len + 1);
106 tlen = sprintf(tmp, "Set-Cookie: %.*s=%s", nlen, name, ZSTR_VAL(zs_val));
107 memcpy(tmp + tlen, end, rend-end);
108 tmp[len] = 0;
109
110 efree(sapi_header->header);
111 // efree(value);
112 zend_string_release(zs_val);
113 efree(start);
114
115 sapi_header->header = tmp;
116 sapi_header->header_len = len;
117 }
118
119suhosin_skip_header_handling:
120 /* If existing call the sapi header handler */
121 if (orig_header_handler) {
122 retval = orig_header_handler(sapi_header, op, sapi_headers TSRMLS_CC);
123 }
124
125 return retval;
126}
127/* }}} */
128
129
130/* {{{ suhosin_hook_header_handler
131 */
132void suhosin_hook_header_handler()
133{
134 if (orig_header_handler == NULL) {
135 orig_header_handler = sapi_module.header_handler;
136 sapi_module.header_handler = suhosin_header_handler;
137 }
138}
139/* }}} */
140
141/* {{{ suhosin_unhook_header_handler
142 */
143void suhosin_unhook_header_handler()
144{
145 sapi_module.header_handler = orig_header_handler;
146 orig_header_handler = NULL;
147}
148/* }}} */
149
150
151/*
152 * Local variables:
153 * tab-width: 4
154 * c-basic-offset: 4
155 * End:
156 * vim600: noet sw=4 ts=4 fdm=marker
157 * vim<600: noet sw=4 ts=4
158 */
diff --git a/ifilter.c b/ifilter.c
index 3cbbc4e..5f55710 100644
--- a/ifilter.c
+++ b/ifilter.c
@@ -41,7 +41,7 @@ static size_t strnlen(const char *s, size_t maxlen) {
41} 41}
42#endif 42#endif
43 43
44size_t suhosin_strnspn(const char *input, size_t n, const char *accept) 44static size_t suhosin_strnspn(const char *input, size_t n, const char *accept)
45{ 45{
46 size_t count = 0; 46 size_t count = 0;
47 for (; *input != '\0' && count < n; input++, count++) { 47 for (; *input != '\0' && count < n; input++, count++) {
@@ -51,7 +51,7 @@ size_t suhosin_strnspn(const char *input, size_t n, const char *accept)
51 return count; 51 return count;
52} 52}
53 53
54size_t suhosin_strncspn(const char *input, size_t n, const char *reject) 54static size_t suhosin_strncspn(const char *input, size_t n, const char *reject)
55{ 55{
56 size_t count = 0; 56 size_t count = 0;
57 for (; *input != '\0' && count < n; input++, count++) { 57 for (; *input != '\0' && count < n; input++, count++) {
@@ -62,9 +62,9 @@ size_t suhosin_strncspn(const char *input, size_t n, const char *reject)
62} 62}
63 63
64 64
65/* {{{ normalize_varname 65/* {{{ suhosin_normalize_varname
66 */ 66 */
67void normalize_varname(char *varname) 67void suhosin_normalize_varname(char *varname)
68{ 68{
69 char *s=varname, *index=NULL, *indexend=NULL, *p; 69 char *s=varname, *index=NULL, *indexend=NULL, *p;
70 70
@@ -285,46 +285,11 @@ void suhosin_register_server_variables(zval *track_vars_array)
285 285
286 286
287/* Old Input filter */ 287/* Old Input filter */
288// unsigned int (*old_input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len) = NULL; 288static SAPI_INPUT_FILTER_FUNC((*orig_input_filter)) = NULL;
289unsigned int (*old_input_filter)(int arg, char *var, char **val, size_t val_len, size_t *new_val_len);
290
291/* {{{ suhosin_input_filter_wrapper
292 */
293unsigned int suhosin_input_filter_wrapper(int arg, char *var, char **val, size_t val_len, size_t *new_val_len)
294{
295 // zend_bool already_scanned = SUHOSIN7_G(already_scanned);
296 // SUHOSIN7_G(already_scanned) = 0;
297 // SDEBUG("ifilter arg=%d var=%s do_not_scan=%d already_scanned=%d", arg, var, SUHOSIN7_G(do_not_scan), already_scanned);
298 // SDEBUG("ifilter arg=%d var=%s do_not_scan=%d", arg, var, SUHOSIN7_G(do_not_scan));
299 SDEBUG("ifilter arg=%d var=%s", arg, var);
300
301 // if (SUHOSIN7_G(do_not_scan)) {
302 // SDEBUG("do_not_scan");
303 // if (new_val_len) {
304 // *new_val_len = val_len;
305 // }
306 // return 1;
307 // }
308
309 // if (!already_scanned) {
310 if (suhosin_input_filter(arg, var, val, val_len, new_val_len)==0) {
311 SUHOSIN7_G(abort_request)=1;
312 return 0;
313 }
314 if (new_val_len) {
315 val_len = *new_val_len;
316 }
317 // }
318 if (old_input_filter) {
319 return old_input_filter(arg, var, val, val_len, new_val_len);
320 } else {
321 return 1;
322 }
323}
324 289
325/* {{{ suhosin_input_filter 290/* {{{ suhosin_input_filter
326 */ 291 */
327unsigned int suhosin_input_filter(int arg, char *var, char **val, size_t val_len, size_t *new_val_len) 292static SAPI_INPUT_FILTER_FUNC(suhosin_input_filter)
328{ 293{
329 SDEBUG("%s=%s arg=%d", var, *val, arg); 294 SDEBUG("%s=%s arg=%d", var, *val, arg);
330 char *index, *prev_index = NULL; 295 char *index, *prev_index = NULL;
@@ -456,7 +421,7 @@ unsigned int suhosin_input_filter(int arg, char *var, char **val, size_t val_len
456 } 421 }
457 422
458 /* Normalize the variable name */ 423 /* Normalize the variable name */
459 normalize_varname(var); 424 suhosin_normalize_varname(var);
460 425
461 /* Find length of variable name */ 426 /* Find length of variable name */
462 index = strchr(var, '['); 427 index = strchr(var, '[');
@@ -650,6 +615,39 @@ unsigned int suhosin_input_filter(int arg, char *var, char **val, size_t val_len
650} 615}
651/* }}} */ 616/* }}} */
652 617
618/* {{{ suhosin_input_filter_wrapper
619 */
620SAPI_INPUT_FILTER_FUNC(suhosin_input_filter_wrapper)
621{
622 // zend_bool already_scanned = SUHOSIN7_G(already_scanned);
623 // SUHOSIN7_G(already_scanned) = 0;
624 // SDEBUG("ifilter arg=%d var=%s do_not_scan=%d already_scanned=%d", arg, var, SUHOSIN7_G(do_not_scan), already_scanned);
625 // SDEBUG("ifilter arg=%d var=%s do_not_scan=%d", arg, var, SUHOSIN7_G(do_not_scan));
626 SDEBUG("ifilter arg=%d var=%s", arg, var);
627
628 // if (SUHOSIN7_G(do_not_scan)) {
629 // SDEBUG("do_not_scan");
630 // if (new_val_len) {
631 // *new_val_len = val_len;
632 // }
633 // return 1;
634 // }
635
636 // if (!already_scanned) {
637 if (suhosin_input_filter(arg, var, val, val_len, new_val_len)==0) {
638 SUHOSIN7_G(abort_request)=1;
639 return 0;
640 }
641 if (new_val_len) {
642 val_len = *new_val_len;
643 }
644 // }
645 if (orig_input_filter) {
646 return orig_input_filter(arg, var, val, val_len, new_val_len);
647 } else {
648 return 1;
649 }
650}
653 651
654 652
655/* {{{ suhosin_hook_register_server_variables 653/* {{{ suhosin_hook_register_server_variables
@@ -663,6 +661,14 @@ void suhosin_hook_register_server_variables()
663} 661}
664/* }}} */ 662/* }}} */
665 663
664void suhosin_hook_input_filter()
665{
666 if (orig_input_filter == NULL) {
667 orig_input_filter = sapi_module.input_filter;
668 }
669 sapi_module.input_filter = suhosin_input_filter_wrapper;
670}
671
666 672
667/* 673/*
668 * Local variables: 674 * Local variables:
diff --git a/log.c b/log.c
index 3201c09..5b14c61 100644
--- a/log.c
+++ b/log.c
@@ -3,7 +3,7 @@
3 | Suhosin Version 1 | 3 | Suhosin Version 1 |
4 +----------------------------------------------------------------------+ 4 +----------------------------------------------------------------------+
5 | Copyright (c) 2006-2007 The Hardened-PHP Project | 5 | Copyright (c) 2006-2007 The Hardened-PHP Project |
6 | Copyright (c) 2007-2015 SektionEins GmbH | 6 | Copyright (c) 2007-2016 SektionEins GmbH |
7 +----------------------------------------------------------------------+ 7 +----------------------------------------------------------------------+
8 | This source file is subject to version 3.01 of the PHP license, | 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 | 9 | that is bundled with this package in the file LICENSE, and is |
@@ -13,7 +13,8 @@
13 | obtain it through the world-wide-web, please send a note 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. | 14 | license@php.net so we can mail you a copy immediately. |
15 +----------------------------------------------------------------------+ 15 +----------------------------------------------------------------------+
16 | Author: Stefan Esser <sesser@sektioneins.de> | 16 | Authors: Stefan Esser <sesser@sektioneins.de> |
17 | Ben Fuhrmannek <ben.fuhrmannek@sektioneins.de> |
17 +----------------------------------------------------------------------+ 18 +----------------------------------------------------------------------+
18*/ 19*/
19/* 20/*
diff --git a/php_suhosin7.h b/php_suhosin7.h
index 0a40316..eaf2f87 100644
--- a/php_suhosin7.h
+++ b/php_suhosin7.h
@@ -122,8 +122,6 @@ protected_varname:
122 122
123 123
124ZEND_BEGIN_MODULE_GLOBALS(suhosin7) 124ZEND_BEGIN_MODULE_GLOBALS(suhosin7)
125 // zend_long global_value;
126 // char *global_string;
127 zend_bool protectkey; 125 zend_bool protectkey;
128 126
129 zend_bool simulation; 127 zend_bool simulation;
@@ -307,7 +305,7 @@ ZEND_BEGIN_MODULE_GLOBALS(suhosin7)
307 zend_bool log_file_time; 305 zend_bool log_file_time;
308 306
309 /* header handler */ 307 /* header handler */
310 // zend_bool allow_multiheader; 308 zend_bool allow_multiheader;
311 309
312 /* mailprotect */ 310 /* mailprotect */
313 // long mailprotect; 311 // long mailprotect;
@@ -362,18 +360,43 @@ ZEND_EXTERN_MODULE_GLOBALS(suhosin7)
362 360
363/* functions */ 361/* functions */
364 362
365unsigned int suhosin_input_filter(int arg, char *var, char **val, size_t val_len, size_t *new_val_len); 363// unsigned int suhosin_input_filter(int arg, char *var, char **val, size_t val_len, size_t *new_val_len);
366unsigned int suhosin_input_filter_wrapper(int arg, char *var, char **val, size_t val_len, size_t *new_val_len); 364// unsigned int suhosin_input_filter_wrapper(int arg, char *var, char **val, size_t val_len, size_t *new_val_len);
367SUHOSIN7_API void suhosin_log(int loglevel, char *fmt, ...); 365SUHOSIN7_API void suhosin_log(int loglevel, char *fmt, ...);
368extern unsigned int (*old_input_filter)(int arg, char *var, char **val, size_t val_len, size_t *new_val_len); 366// extern unsigned int (*orig_input_filter)(int arg, char *var, char **val, size_t val_len, size_t *new_val_len);
369char *suhosin_getenv(char *name, size_t name_len); 367char *suhosin_getenv(char *name, size_t name_len);
370 368
369// hooks
371void suhosin_hook_memory_limit(); 370void suhosin_hook_memory_limit();
372void suhosin_hook_treat_data(); 371void suhosin_hook_treat_data();
373void suhosin_hook_execute(); 372void suhosin_hook_input_filter();
374void suhosin_hook_register_server_variables(); 373void suhosin_hook_register_server_variables();
374void suhosin_hook_header_handler();
375void suhosin_unhook_header_handler();
376void suhosin_hook_execute();
375// void suhosin_hook_sha256(); 377// void suhosin_hook_sha256();
376 378
379// ifilter.c
380void suhosin_normalize_varname(char *varname);
381
382// cookiecrypt.c
383char *suhosin_cookie_decryptor(char *raw_cookie);
384zend_string *suhosin_encrypt_single_cookie(char *name, int name_len, char *value, int value_len, char *key);
385char *suhosin_decrypt_single_cookie(char *name, int name_len, char *value, int value_len, char *key, char **out);
386
387// crypt.c
388zend_string *suhosin_encrypt_string(char *str, int len, char *var, int vlen, char *key);
389zend_string *suhosin_decrypt_string(char *str, int padded_len, char *var, int vlen, char *key, int check_ra);
390char *suhosin_generate_key(char *key, zend_bool ua, zend_bool dr, long raddr, char *cryptkey);
391
392// aes.c
393void suhosin_aes_gentables();
394void suhosin_aes_gkey(int nb,int nk,char *key);
395void suhosin_aes_encrypt(char *buff);
396void suhosin_aes_decrypt(char *buff);
397
398//
399
377static inline void suhosin_bailout() 400static inline void suhosin_bailout()
378{ 401{
379 if (!SUHOSIN7_G(simulation)) { 402 if (!SUHOSIN7_G(simulation)) {
@@ -381,6 +404,13 @@ static inline void suhosin_bailout()
381 } 404 }
382} 405}
383 406
407static inline char *suhosin_get_active_function_name() {
408 char *fn = (char *)get_active_function_name();
409 if (fn == NULL) {
410 return "unknown";
411 }
412 return fn;
413}
384 414
385#endif /* PHP_SUHOSIN7_H */ 415#endif /* PHP_SUHOSIN7_H */
386 416
diff --git a/suhosin7.c b/suhosin7.c
index 9ed1eca..3b84767 100644
--- a/suhosin7.c
+++ b/suhosin7.c
@@ -1,8 +1,9 @@
1/* 1/*
2 +----------------------------------------------------------------------+ 2 +----------------------------------------------------------------------+
3 | PHP Version 7 | 3 | Suhosin Version 1 |
4 +----------------------------------------------------------------------+ 4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2015 The PHP Group | 5 | Copyright (c) 2006-2007 The Hardened-PHP Project |
6 | Copyright (c) 2007-2016 SektionEins GmbH |
6 +----------------------------------------------------------------------+ 7 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, | 8 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is | 9 | that is bundled with this package in the file LICENSE, and is |
@@ -12,7 +13,8 @@
12 | obtain it through the world-wide-web, please send a note to | 13 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. | 14 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+ 15 +----------------------------------------------------------------------+
15 | Author: | 16 | Authors: Stefan Esser <sesser@sektioneins.de> |
17 | Ben Fuhrmannek <ben.fuhrmannek@sektioneins.de> |
16 +----------------------------------------------------------------------+ 18 +----------------------------------------------------------------------+
17*/ 19*/
18 20
@@ -270,16 +272,10 @@ DEF_LOG_UPDATER(OnUpdateSuhosin_log_stdout, log_stdout, "suhosin.log.stdout")
270 STD_PHP_INI_ENTRY(name, default_value, modifiable, on_modify, property_name, zend_suhosin7_globals, suhosin7_globals) 272 STD_PHP_INI_ENTRY(name, default_value, modifiable, on_modify, property_name, zend_suhosin7_globals, suhosin7_globals)
271#define STD_S7_INI_BOOLEAN(name, default_value, modifiable, on_modify, property_name) \ 273#define STD_S7_INI_BOOLEAN(name, default_value, modifiable, on_modify, property_name) \
272 STD_PHP_INI_BOOLEAN(name, default_value, modifiable, on_modify, property_name, zend_suhosin7_globals, suhosin7_globals) 274 STD_PHP_INI_BOOLEAN(name, default_value, modifiable, on_modify, property_name, zend_suhosin7_globals, suhosin7_globals)
273// #define STD_S7_INI_LIST(name, modifiable, )
274 275
275/* {{{ PHP_INI 276/* {{{ PHP_INI
276 */ 277 */
277PHP_INI_BEGIN() 278PHP_INI_BEGIN()
278 // STD_S7_INI_BOOLEAN("suhosin.protectkey", "1", PHP_INI_SYSTEM, OnUpdateBool, protectkey, zend_suhosin7_globals, suhosin7_globals)
279 // STD_S7_INI_BOOLEAN("suhosin.cookie.cryptkey", "1", PHP_INI_SYSTEM, OnUpdateBool, protectkey, zend_suhosin7_globals, suhosin7_globals)
280 // STD_S7_INI_ENTRY("suhosin.global_value", "42", PHP_INI_ALL, OnUpdateLong, global_value, zend_suhosin7_globals, suhosin7_globals)
281 // STD_S7_INI_ENTRY("suhosin.global_string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_suhosin7_globals, suhosin7_globals)
282
283 PHP_INI_ENTRY("suhosin.perdir", "0", PHP_INI_SYSTEM, OnUpdateSuhosin_perdir) 279 PHP_INI_ENTRY("suhosin.perdir", "0", PHP_INI_SYSTEM, OnUpdateSuhosin_perdir)
284 // PHP_INI_ENTRY("suhosin.log.syslog", NULL, PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateSuhosin_log_syslog) 280 // PHP_INI_ENTRY("suhosin.log.syslog", NULL, PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateSuhosin_log_syslog)
285 // PHP_INI_ENTRY("suhosin.log.syslog.facility", NULL, PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateSuhosin_log_syslog_facility) 281 // PHP_INI_ENTRY("suhosin.log.syslog.facility", NULL, PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateSuhosin_log_syslog_facility)
@@ -311,14 +307,14 @@ PHP_INI_BEGIN()
311 STD_S7_INI_ENTRY("suhosin.executor.max_depth", "750", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateExecLong, max_execution_depth) 307 STD_S7_INI_ENTRY("suhosin.executor.max_depth", "750", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateExecLong, max_execution_depth)
312 // 308 //
313 // 309 //
314 // STD_S7_INI_BOOLEAN("suhosin.multiheader", "0", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateMiscBool, allow_multiheader) 310 STD_S7_INI_BOOLEAN("suhosin.multiheader", "0", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateMiscBool, allow_multiheader)
315 // STD_S7_INI_ENTRY("suhosin.mail.protect", "0", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateMiscLong, mailprotect) 311 // STD_S7_INI_ENTRY("suhosin.mail.protect", "0", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateMiscLong, mailprotect)
316 // STD_S7_INI_ENTRY("suhosin.memory_limit", "0", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateMiscLong, memory_limit) 312 // STD_S7_INI_ENTRY("suhosin.memory_limit", "0", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateMiscLong, memory_limit)
317 // STD_S7_INI_BOOLEAN("suhosin.simulation", "0", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateMiscBool, simulation) 313 // STD_S7_INI_BOOLEAN("suhosin.simulation", "0", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateMiscBool, simulation)
318 // STD_S7_INI_ENTRY("suhosin.filter.action", NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateMiscString, filter_action) 314 // STD_S7_INI_ENTRY("suhosin.filter.action", NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateMiscString, filter_action)
319 // 315 //
320 // STD_S7_INI_BOOLEAN("suhosin.protectkey", "1", PHP_INI_SYSTEM, OnUpdateBool, protectkey) 316 STD_S7_INI_BOOLEAN("suhosin.protectkey", "1", PHP_INI_SYSTEM, OnUpdateBool, protectkey)
321 // STD_S7_INI_BOOLEAN("suhosin.coredump", "0", PHP_INI_SYSTEM, OnUpdateBool, coredump) 317 STD_S7_INI_BOOLEAN("suhosin.coredump", "0", PHP_INI_SYSTEM, OnUpdateBool, coredump)
322 // STD_S7_INI_BOOLEAN("suhosin.stealth", "1", PHP_INI_SYSTEM, OnUpdateBool, stealth) 318 // STD_S7_INI_BOOLEAN("suhosin.stealth", "1", PHP_INI_SYSTEM, OnUpdateBool, stealth)
323 // STD_S7_INI_BOOLEAN("suhosin.apc_bug_workaround", "0", PHP_INI_SYSTEM, OnUpdateBool, apc_bug_workaround) 319 // STD_S7_INI_BOOLEAN("suhosin.apc_bug_workaround", "0", PHP_INI_SYSTEM, OnUpdateBool, apc_bug_workaround)
324 STD_S7_INI_BOOLEAN("suhosin.disable.display_errors", "0", PHP_INI_SYSTEM, OnUpdate_disable_display_errors, disable_display_errors) 320 STD_S7_INI_BOOLEAN("suhosin.disable.display_errors", "0", PHP_INI_SYSTEM, OnUpdate_disable_display_errors, disable_display_errors)
@@ -399,15 +395,15 @@ PHP_INI_BEGIN()
399#endif /* HAVE_PHP_SESSION */ 395#endif /* HAVE_PHP_SESSION */
400 396
401 397
402 // STD_S7_INI_BOOLEAN("suhosin.cookie.encrypt", "0", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateCookieBool, cookie_encrypt) 398 STD_S7_INI_BOOLEAN("suhosin.cookie.encrypt", "0", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateCookieBool, cookie_encrypt)
403 // STD_S7_INI_ENTRY("suhosin.cookie.cryptkey", "", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateCookieString, cookie_cryptkey) 399 STD_S7_INI_ENTRY("suhosin.cookie.cryptkey", "", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateCookieString, cookie_cryptkey)
404 // STD_S7_INI_BOOLEAN("suhosin.cookie.cryptua", "1", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateCookieBool, cookie_cryptua) 400 STD_S7_INI_BOOLEAN("suhosin.cookie.cryptua", "1", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateCookieBool, cookie_cryptua)
405 // STD_S7_INI_BOOLEAN("suhosin.cookie.cryptdocroot", "1", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateCookieBool, cookie_cryptdocroot) 401 STD_S7_INI_BOOLEAN("suhosin.cookie.cryptdocroot", "1", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateCookieBool, cookie_cryptdocroot)
406 // STD_S7_INI_ENTRY("suhosin.cookie.cryptraddr", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateCookieLong, cookie_cryptraddr) 402 STD_S7_INI_ENTRY("suhosin.cookie.cryptraddr", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateCookieLong, cookie_cryptraddr)
407 // STD_S7_INI_ENTRY("suhosin.cookie.checkraddr", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateCookieLong, cookie_checkraddr) 403 STD_S7_INI_ENTRY("suhosin.cookie.checkraddr", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateCookieLong, cookie_checkraddr)
408 PHP_INI_ENTRY("suhosin.cookie.cryptlist", NULL, PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateSuhosin_cookie_cryptlist) 404 PHP_INI_ENTRY("suhosin.cookie.cryptlist", NULL, PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateSuhosin_cookie_cryptlist)
409 PHP_INI_ENTRY("suhosin.cookie.plainlist", NULL, PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateSuhosin_cookie_plainlist) 405 PHP_INI_ENTRY("suhosin.cookie.plainlist", NULL, PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateSuhosin_cookie_plainlist)
410 // 406 //
411 STD_S7_INI_BOOLEAN("suhosin.server.encode", "1", PHP_INI_SYSTEM, OnUpdateBool, server_encode) 407 STD_S7_INI_BOOLEAN("suhosin.server.encode", "1", PHP_INI_SYSTEM, OnUpdateBool, server_encode)
412 STD_S7_INI_BOOLEAN("suhosin.server.strip", "1", PHP_INI_SYSTEM, OnUpdateBool, server_strip) 408 STD_S7_INI_BOOLEAN("suhosin.server.strip", "1", PHP_INI_SYSTEM, OnUpdateBool, server_strip)
413 // 409 //
@@ -511,11 +507,17 @@ PHP_MINIT_FUNCTION(suhosin7)
511 zend_string_release(val0); 507 zend_string_release(val0);
512 } 508 }
513 509
510 // init
511 suhosin_aes_gentables();
512
514 // hooks 513 // hooks
515 // suhosin_hook_memory_limit();
516 suhosin_hook_treat_data(); 514 suhosin_hook_treat_data();
517 suhosin_hook_execute(); 515 suhosin_hook_input_filter();
518 suhosin_hook_register_server_variables(); 516 suhosin_hook_register_server_variables();
517 suhosin_hook_header_handler();
518 suhosin_hook_execute();
519
520 // suhosin_hook_memory_limit();
519 // suhosin_hook_sha256(); 521 // suhosin_hook_sha256();
520 522
521 return SUCCESS; 523 return SUCCESS;
@@ -538,6 +540,9 @@ PHP_MSHUTDOWN_FUNCTION(suhosin7)
538PHP_RINIT_FUNCTION(suhosin7) 540PHP_RINIT_FUNCTION(suhosin7)
539{ 541{
540 SDEBUG("(RINIT)"); 542 SDEBUG("(RINIT)");
543 SUHOSIN7_G(in_code_type) = SUHOSIN_NORMAL;
544 SUHOSIN7_G(execution_depth) = 0;
545
541 return SUCCESS; 546 return SUCCESS;
542} 547}
543/* }}} */ 548/* }}} */
@@ -548,6 +553,43 @@ PHP_RINIT_FUNCTION(suhosin7)
548PHP_RSHUTDOWN_FUNCTION(suhosin7) 553PHP_RSHUTDOWN_FUNCTION(suhosin7)
549{ 554{
550 SDEBUG("(RSHUTDOWN)"); 555 SDEBUG("(RSHUTDOWN)");
556 /* We need to clear the input filtering
557 variables in the request shutdown
558 because input filtering is done before
559 RINIT */
560
561 SUHOSIN7_G(cur_request_variables) = 0;
562 SUHOSIN7_G(cur_cookie_vars) = 0;
563 SUHOSIN7_G(cur_get_vars) = 0;
564 SUHOSIN7_G(cur_post_vars) = 0;
565 SUHOSIN7_G(att_request_variables) = 0;
566 SUHOSIN7_G(att_cookie_vars) = 0;
567 SUHOSIN7_G(att_get_vars) = 0;
568 SUHOSIN7_G(att_post_vars) = 0;
569 // SUHOSIN7_G(num_uploads) = 0;
570
571 SUHOSIN7_G(no_more_variables) = 0;
572 SUHOSIN7_G(no_more_get_variables) = 0;
573 SUHOSIN7_G(no_more_post_variables) = 0;
574 SUHOSIN7_G(no_more_cookie_variables) = 0;
575 SUHOSIN7_G(no_more_uploads) = 0;
576
577 SUHOSIN7_G(abort_request) = 0;
578
579 // if (SUHOSIN7_G(reseed_every_request)) {
580 // SUHOSIN7_G(r_is_seeded) = 0;
581 // SUHOSIN7_G(mt_is_seeded) = 0;
582 // }
583
584 if (SUHOSIN7_G(decrypted_cookie)) {
585 efree(SUHOSIN7_G(decrypted_cookie));
586 SUHOSIN7_G(decrypted_cookie)=NULL;
587 }
588 if (SUHOSIN7_G(raw_cookie)) {
589 efree(SUHOSIN7_G(raw_cookie));
590 SUHOSIN7_G(raw_cookie)=NULL;
591 }
592
551 return SUCCESS; 593 return SUCCESS;
552} 594}
553/* }}} */ 595/* }}} */
diff --git a/tests/cookie/crypt.checkraddr_4.phpt b/tests/cookie/crypt.checkraddr_4.phpt
new file mode 100644
index 0000000..35c3495
--- /dev/null
+++ b/tests/cookie/crypt.checkraddr_4.phpt
@@ -0,0 +1,28 @@
1--TEST--
2cookie encryption with checkraddr=4
3--SKIPIF--
4<?php include "../skipif.inc"; ?>
5--INI--
6suhosin.cookie.encrypt=1
7suhosin.cookie.cryptkey=
8suhosin.cookie.cryptua=Off
9suhosin.cookie.cryptdocroot=Off
10suhosin.cookie.cryptraddr=0
11suhosin.cookie.checkraddr=4
12;suhosin.cookie.cryptlist=
13;suhosin.cookie.plainlist=
14--ENV--
15return <<<END
16REMOTE_ADDR=127.0.0.1
17END;
18--COOKIE--
19foo=EgJxlQxzPwoAcVFj395vssv3hy1rAem1lH9qZYUvRi8.
20--FILE--
21<?php
22var_dump($_COOKIE);
23?>
24--EXPECTF--
25array(1) {
26 ["foo"]=>
27 string(3) "bar"
28} \ No newline at end of file
diff --git a/tests/cookie/crypt.checkraddr_4_incorrect.phpt b/tests/cookie/crypt.checkraddr_4_incorrect.phpt
new file mode 100644
index 0000000..00c2e23
--- /dev/null
+++ b/tests/cookie/crypt.checkraddr_4_incorrect.phpt
@@ -0,0 +1,26 @@
1--TEST--
2cookie encryption with checkraddr=4
3--SKIPIF--
4<?php include "../skipif.inc"; ?>
5--INI--
6suhosin.cookie.encrypt=1
7suhosin.cookie.cryptkey=
8suhosin.cookie.cryptua=Off
9suhosin.cookie.cryptdocroot=Off
10suhosin.cookie.cryptraddr=0
11suhosin.cookie.checkraddr=4
12;suhosin.cookie.cryptlist=
13;suhosin.cookie.plainlist=
14--ENV--
15return <<<END
16REMOTE_ADDR=127.0.0.2
17END;
18--COOKIE--
19foo=EgJxlQxzPwoAcVFj395vssv3hy1rAem1lH9qZYUvRi8.
20--FILE--
21<?php
22var_dump($_COOKIE);
23?>
24--EXPECTF--
25array(0) {
26} \ No newline at end of file
diff --git a/tests/cookie/crypt.cryptlist.phpt b/tests/cookie/crypt.cryptlist.phpt
new file mode 100644
index 0000000..e56ac24
--- /dev/null
+++ b/tests/cookie/crypt.cryptlist.phpt
@@ -0,0 +1,29 @@
1--TEST--
2cookie encryption with cryptlist set
3--SKIPIF--
4<?php include "../skipif.inc"; ?>
5--INI--
6suhosin.cookie.encrypt=1
7suhosin.cookie.cryptkey=
8suhosin.cookie.cryptua=0
9suhosin.cookie.cryptdocroot=0
10suhosin.cookie.cryptraddr=0
11suhosin.cookie.checkraddr=0
12suhosin.cookie.cryptlist=a,b,foo,c
13;suhosin.cookie.plainlist=
14--ENV--
15return <<<END
16REMOTE_ADDR=127.0.0.1
17END;
18--COOKIE--
19a=b
20--FILE--
21<?php
22setcookie('foo', 'bar');
23setcookie('foo2', 'bar2');
24$ch = preg_grep("/^Set-Cookie:/", headers_list());
25echo join("\n", array_values($ch));
26?>
27--EXPECTF--
28Set-Cookie: foo=EgJxlQxzPwoAcVFj395vssv3hy1rAem1lH9qZYUvRi8.
29Set-Cookie: foo2=bar2 \ No newline at end of file
diff --git a/tests/cookie/crypt.docroot.phpt b/tests/cookie/crypt.docroot.phpt
new file mode 100644
index 0000000..9eeb24b
--- /dev/null
+++ b/tests/cookie/crypt.docroot.phpt
@@ -0,0 +1,27 @@
1--TEST--
2cookie encryption using document root
3--SKIPIF--
4<?php include "../skipif.inc"; ?>
5--INI--
6suhosin.cookie.encrypt=1
7suhosin.cookie.cryptkey=
8suhosin.cookie.cryptua=Off
9suhosin.cookie.cryptdocroot=On
10suhosin.cookie.cryptraddr=0
11suhosin.cookie.checkraddr=0
12;suhosin.cookie.cryptlist=
13;suhosin.cookie.plainlist=
14--ENV--
15return <<<END
16DOCUMENT_ROOT=/var/www
17END;
18--COOKIE--
19a=b
20--FILE--
21<?php
22setcookie('foo', 'bar');
23$ch = preg_grep("/^Set-Cookie:/", headers_list());
24echo join("\n", array_values($ch));
25?>
26--EXPECTF--
27Set-Cookie: foo=CY8CspcGmDQPsap1NqJO1uAjB6fobur1Os5ZCqFGhU8. \ No newline at end of file
diff --git a/tests/cookie/crypt.invalid.phpt b/tests/cookie/crypt.invalid.phpt
new file mode 100644
index 0000000..b1d11dd
--- /dev/null
+++ b/tests/cookie/crypt.invalid.phpt
@@ -0,0 +1,26 @@
1--TEST--
2cookie encryption with invalid cookie
3--SKIPIF--
4<?php include "../skipif.inc"; ?>
5--INI--
6suhosin.cookie.encrypt=1
7suhosin.cookie.cryptkey=
8suhosin.cookie.cryptua=Off
9suhosin.cookie.cryptdocroot=Off
10suhosin.cookie.cryptraddr=0
11suhosin.cookie.checkraddr=0
12;suhosin.cookie.cryptlist=
13;suhosin.cookie.plainlist=
14--ENV--
15return <<<END
16REMOTE_ADDR=127.0.0.1
17END;
18--COOKIE--
19foo=test
20--FILE--
21<?php
22var_dump($_COOKIE);
23?>
24--EXPECTF--
25array(0) {
26} \ No newline at end of file
diff --git a/tests/cookie/crypt.key_default.phpt b/tests/cookie/crypt.key_default.phpt
new file mode 100644
index 0000000..91b1fcf
--- /dev/null
+++ b/tests/cookie/crypt.key_default.phpt
@@ -0,0 +1,23 @@
1--TEST--
2cookie encryption with default key
3--SKIPIF--
4<?php include "../skipif.inc"; ?>
5--INI--
6suhosin.cookie.encrypt=1
7suhosin.cookie.cryptkey=D3F4UL7
8suhosin.cookie.cryptua=0
9suhosin.cookie.cryptdocroot=0
10suhosin.cookie.cryptraddr=0
11suhosin.cookie.checkraddr=0
12;suhosin.cookie.cryptlist=
13;suhosin.cookie.plainlist=
14--COOKIE--
15a=b
16--FILE--
17<?php
18setcookie('foo', 'bar');
19$ch = preg_grep("/^Set-Cookie:/", headers_list());
20echo join("\n", array_values($ch));
21?>
22--EXPECTF--
23Set-Cookie: foo=Jq5FsTmo4aEWrLMKdoEeUuFxZ4IujCzrQjg-8Y-xphg. \ No newline at end of file
diff --git a/tests/cookie/crypt.key_empty.phpt b/tests/cookie/crypt.key_empty.phpt
new file mode 100644
index 0000000..1736575
--- /dev/null
+++ b/tests/cookie/crypt.key_empty.phpt
@@ -0,0 +1,23 @@
1--TEST--
2cookie encryption with empty key
3--SKIPIF--
4<?php include "../skipif.inc"; ?>
5--INI--
6suhosin.cookie.encrypt=1
7suhosin.cookie.cryptkey=
8suhosin.cookie.cryptua=0
9suhosin.cookie.cryptdocroot=0
10suhosin.cookie.cryptraddr=0
11suhosin.cookie.checkraddr=0
12;suhosin.cookie.cryptlist=
13;suhosin.cookie.plainlist=
14--COOKIE--
15a=b
16--FILE--
17<?php
18setcookie('foo', 'bar');
19$ch = preg_grep("/^Set-Cookie:/", headers_list());
20echo join("\n", array_values($ch));
21?>
22--EXPECTF--
23Set-Cookie: foo=Jq5FsTmo4aEWrLMKdoEeUuFxZ4IujCzrQjg-8Y-xphg. \ No newline at end of file
diff --git a/tests/cookie/crypt.key_empty_remote_addr.phpt b/tests/cookie/crypt.key_empty_remote_addr.phpt
new file mode 100644
index 0000000..fb00766
--- /dev/null
+++ b/tests/cookie/crypt.key_empty_remote_addr.phpt
@@ -0,0 +1,27 @@
1--TEST--
2cookie encryption with empty key and REMOTE_ADDR set
3--SKIPIF--
4<?php include "../skipif.inc"; ?>
5--INI--
6suhosin.cookie.encrypt=1
7suhosin.cookie.cryptkey=
8suhosin.cookie.cryptua=0
9suhosin.cookie.cryptdocroot=0
10suhosin.cookie.cryptraddr=0
11suhosin.cookie.checkraddr=0
12;suhosin.cookie.cryptlist=
13;suhosin.cookie.plainlist=
14--ENV--
15return <<<END
16REMOTE_ADDR=127.0.0.1
17END;
18--COOKIE--
19a=b
20--FILE--
21<?php
22setcookie('foo', 'bar');
23$ch = preg_grep("/^Set-Cookie:/", headers_list());
24echo join("\n", array_values($ch));
25?>
26--EXPECTF--
27Set-Cookie: foo=EgJxlQxzPwoAcVFj395vssv3hy1rAem1lH9qZYUvRi8. \ No newline at end of file
diff --git a/tests/cookie/crypt.no_encryption.phpt b/tests/cookie/crypt.no_encryption.phpt
new file mode 100644
index 0000000..095ce5f
--- /dev/null
+++ b/tests/cookie/crypt.no_encryption.phpt
@@ -0,0 +1,16 @@
1--TEST--
2cookie without encryption
3--SKIPIF--
4<?php include "../skipif.inc"; ?>
5--INI--
6suhosin.cookie.encrypt=0
7--COOKIE--
8a=b
9--FILE--
10<?php
11setcookie('foo', 'bar');
12$ch = preg_grep("/^Set-Cookie:/", headers_list());
13echo join("\n", array_values($ch));
14?>
15--EXPECTF--
16Set-Cookie: foo=bar \ No newline at end of file
diff --git a/tests/cookie/crypt.plainlist.phpt b/tests/cookie/crypt.plainlist.phpt
new file mode 100644
index 0000000..8a29bb0
--- /dev/null
+++ b/tests/cookie/crypt.plainlist.phpt
@@ -0,0 +1,29 @@
1--TEST--
2cookie encryption with plainlist set
3--SKIPIF--
4<?php include "../skipif.inc"; ?>
5--INI--
6suhosin.cookie.encrypt=1
7suhosin.cookie.cryptkey=
8suhosin.cookie.cryptua=0
9suhosin.cookie.cryptdocroot=0
10suhosin.cookie.cryptraddr=0
11suhosin.cookie.checkraddr=0
12;suhosin.cookie.cryptlist=
13suhosin.cookie.plainlist=a,b,foo2,c
14--ENV--
15return <<<END
16REMOTE_ADDR=127.0.0.1
17END;
18--COOKIE--
19a=b
20--FILE--
21<?php
22setcookie('foo', 'bar');
23setcookie('foo2', 'bar2');
24$ch = preg_grep("/^Set-Cookie:/", headers_list());
25echo join("\n", array_values($ch));
26?>
27--EXPECTF--
28Set-Cookie: foo=EgJxlQxzPwoAcVFj395vssv3hy1rAem1lH9qZYUvRi8.
29Set-Cookie: foo2=bar2 \ No newline at end of file
diff --git a/tests/cookie/crypt.raddr_1.phpt b/tests/cookie/crypt.raddr_1.phpt
new file mode 100644
index 0000000..54400b5
--- /dev/null
+++ b/tests/cookie/crypt.raddr_1.phpt
@@ -0,0 +1,27 @@
1--TEST--
2cookie encryption using REMOTE_ADDR (cryptraddr=1)
3--SKIPIF--
4<?php include "../skipif.inc"; ?>
5--INI--
6suhosin.cookie.encrypt=1
7suhosin.cookie.cryptkey=
8suhosin.cookie.cryptua=Off
9suhosin.cookie.cryptdocroot=Off
10suhosin.cookie.cryptraddr=1
11suhosin.cookie.checkraddr=0
12;suhosin.cookie.cryptlist=
13;suhosin.cookie.plainlist=
14--ENV--
15return <<<END
16REMOTE_ADDR=127.0.0.1
17END;
18--COOKIE--
19a=b
20--FILE--
21<?php
22setcookie('foo', 'bar');
23$ch = preg_grep("/^Set-Cookie:/", headers_list());
24echo join("\n", array_values($ch));
25?>
26--EXPECTF--
27Set-Cookie: foo=lwB1g2gEIQbzRLsbKEyLcKlmu6kpBNRd6sft46-la-4. \ No newline at end of file
diff --git a/tests/cookie/crypt.raddr_2.phpt b/tests/cookie/crypt.raddr_2.phpt
new file mode 100644
index 0000000..e87b5e7
--- /dev/null
+++ b/tests/cookie/crypt.raddr_2.phpt
@@ -0,0 +1,27 @@
1--TEST--
2cookie encryption using REMOTE_ADDR (cryptraddr=2)
3--SKIPIF--
4<?php include "../skipif.inc"; ?>
5--INI--
6suhosin.cookie.encrypt=1
7suhosin.cookie.cryptkey=
8suhosin.cookie.cryptua=Off
9suhosin.cookie.cryptdocroot=Off
10suhosin.cookie.cryptraddr=2
11suhosin.cookie.checkraddr=0
12;suhosin.cookie.cryptlist=
13;suhosin.cookie.plainlist=
14--ENV--
15return <<<END
16REMOTE_ADDR=127.0.0.1
17END;
18--COOKIE--
19a=b
20--FILE--
21<?php
22setcookie('foo', 'bar');
23$ch = preg_grep("/^Set-Cookie:/", headers_list());
24echo join("\n", array_values($ch));
25?>
26--EXPECTF--
27Set-Cookie: foo=iTnKmpON_PFkZ2Sv8omXt_myOw0LIxwZTmj5OZYQ5c8. \ No newline at end of file
diff --git a/tests/cookie/crypt.raddr_3.phpt b/tests/cookie/crypt.raddr_3.phpt
new file mode 100644
index 0000000..a1394a5
--- /dev/null
+++ b/tests/cookie/crypt.raddr_3.phpt
@@ -0,0 +1,27 @@
1--TEST--
2cookie encryption using REMOTE_ADDR (cryptraddr=3)
3--SKIPIF--
4<?php include "../skipif.inc"; ?>
5--INI--
6suhosin.cookie.encrypt=1
7suhosin.cookie.cryptkey=
8suhosin.cookie.cryptua=Off
9suhosin.cookie.cryptdocroot=Off
10suhosin.cookie.cryptraddr=3
11suhosin.cookie.checkraddr=0
12;suhosin.cookie.cryptlist=
13;suhosin.cookie.plainlist=
14--ENV--
15return <<<END
16REMOTE_ADDR=127.0.0.1
17END;
18--COOKIE--
19a=b
20--FILE--
21<?php
22setcookie('foo', 'bar');
23$ch = preg_grep("/^Set-Cookie:/", headers_list());
24echo join("\n", array_values($ch));
25?>
26--EXPECTF--
27Set-Cookie: foo=q2LriHN5UE2RN8YKu8N-k2hE5ShtXbk8vZooBU0idWg. \ No newline at end of file
diff --git a/tests/cookie/crypt.raddr_4.phpt b/tests/cookie/crypt.raddr_4.phpt
new file mode 100644
index 0000000..2862f9f
--- /dev/null
+++ b/tests/cookie/crypt.raddr_4.phpt
@@ -0,0 +1,27 @@
1--TEST--
2cookie encryption using REMOTE_ADDR (cryptraddr=4)
3--SKIPIF--
4<?php include "../skipif.inc"; ?>
5--INI--
6suhosin.cookie.encrypt=1
7suhosin.cookie.cryptkey=
8suhosin.cookie.cryptua=Off
9suhosin.cookie.cryptdocroot=Off
10suhosin.cookie.cryptraddr=4
11suhosin.cookie.checkraddr=0
12;suhosin.cookie.cryptlist=
13;suhosin.cookie.plainlist=
14--ENV--
15return <<<END
16REMOTE_ADDR=127.0.0.1
17END;
18--COOKIE--
19a=b
20--FILE--
21<?php
22setcookie('foo', 'bar');
23$ch = preg_grep("/^Set-Cookie:/", headers_list());
24echo join("\n", array_values($ch));
25?>
26--EXPECTF--
27Set-Cookie: foo=KYNdxYn5b1vujSEplr6YyON2A04YRH0YY4pCZWQDxG8. \ No newline at end of file
diff --git a/tests/cookie/crypt.ua.phpt b/tests/cookie/crypt.ua.phpt
new file mode 100644
index 0000000..48a98b3
--- /dev/null
+++ b/tests/cookie/crypt.ua.phpt
@@ -0,0 +1,27 @@
1--TEST--
2cookie with encryption using HTTP_USER_AGENT
3--SKIPIF--
4<?php include "../skipif.inc"; ?>
5--INI--
6suhosin.cookie.encrypt=1
7suhosin.cookie.cryptkey=
8suhosin.cookie.cryptua=On
9suhosin.cookie.cryptdocroot=0
10suhosin.cookie.cryptraddr=0
11suhosin.cookie.checkraddr=0
12;suhosin.cookie.cryptlist=
13;suhosin.cookie.plainlist=
14--ENV--
15return <<<END
16HTTP_USER_AGENT=test
17END;
18--COOKIE--
19a=b
20--FILE--
21<?php
22setcookie('foo', 'bar');
23$ch = preg_grep("/^Set-Cookie:/", headers_list());
24echo join("\n", array_values($ch));
25?>
26--EXPECTF--
27Set-Cookie: foo=ZWvJsNdplAsT5Uz57vuUq7-_pbjyXTGeMrUfSrgre5w. \ No newline at end of file
diff --git a/tests/skipif.inc b/tests/skipif.inc
new file mode 100644
index 0000000..ce51bec
--- /dev/null
+++ b/tests/skipif.inc
@@ -0,0 +1,4 @@
1<?php
2if(!extension_loaded("suhosin7"))
3 print "skip - SUHOSIN7 extension not available";
4?>
diff --git a/tests/skipifcli.inc b/tests/skipifcli.inc
new file mode 100644
index 0000000..6aac5a0
--- /dev/null
+++ b/tests/skipifcli.inc
@@ -0,0 +1,8 @@
1<?php
2if (php_sapi_name()=='cli') {
3 print 'skip - SAPI == cli';
4} else {
5if(!extension_loaded("suhosin7"))
6 print "skip - SUHOSIN7 extension not available";
7}
8?>
diff --git a/tests/skipifnotcli.inc b/tests/skipifnotcli.inc
new file mode 100644
index 0000000..6021b74
--- /dev/null
+++ b/tests/skipifnotcli.inc
@@ -0,0 +1,8 @@
1<?php
2if (php_sapi_name()!='cli') {
3 print 'skip - SAPI != cli';
4} else {
5if(!extension_loaded("suhosin7"))
6 print "skip - SUHOSIN7 extension not available";
7}
8?>
diff --git a/treat_data.c b/treat_data.c
index d842afc..bdd06c0 100644
--- a/treat_data.c
+++ b/treat_data.c
@@ -3,7 +3,7 @@
3 | Suhosin Version 1 | 3 | Suhosin Version 1 |
4 +----------------------------------------------------------------------+ 4 +----------------------------------------------------------------------+
5 | Copyright (c) 2006-2007 The Hardened-PHP Project | 5 | Copyright (c) 2006-2007 The Hardened-PHP Project |
6 | Copyright (c) 2007-2015 SektionEins GmbH | 6 | Copyright (c) 2007-2016 SektionEins GmbH |
7 +----------------------------------------------------------------------+ 7 +----------------------------------------------------------------------+
8 | This source file is subject to version 3.01 of the PHP license, | 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 | 9 | that is bundled with this package in the file LICENSE, and is |
@@ -13,7 +13,8 @@
13 | obtain it through the world-wide-web, please send a note 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. | 14 | license@php.net so we can mail you a copy immediately. |
15 +----------------------------------------------------------------------+ 15 +----------------------------------------------------------------------+
16 | Author: Stefan Esser <sesser@sektioneins.de> | 16 | Authors: Stefan Esser <sesser@sektioneins.de> |
17 | Ben Fuhrmannek <ben.fuhrmannek@sektioneins.de> |
17 +----------------------------------------------------------------------+ 18 +----------------------------------------------------------------------+
18*/ 19*/
19/* 20/*
@@ -31,176 +32,46 @@
31#include "php_variables.h" 32#include "php_variables.h"
32#include "ext/standard/url.h" 33#include "ext/standard/url.h"
33 34
35static SAPI_TREAT_DATA_FUNC((*orig_treat_data)) = NULL;
36
34SAPI_TREAT_DATA_FUNC(suhosin_treat_data) 37SAPI_TREAT_DATA_FUNC(suhosin_treat_data)
35{ 38{
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) { 39 switch (arg) {
48 case PARSE_POST: 40 case PARSE_POST:
49 case PARSE_GET: 41 if (SUHOSIN7_G(max_request_variables) && (SUHOSIN7_G(max_post_vars) == 0 ||
50 case PARSE_COOKIE: 42 SUHOSIN7_G(max_request_variables) <= SUHOSIN7_G(max_post_vars))) {
51 array_init(&array); 43 SUHOSIN7_G(max_post_vars) = SUHOSIN7_G(max_request_variables);
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 } 44 }
78 break; 45 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: 46 case PARSE_GET:
120 case PARSE_STRING: 47 if (SUHOSIN7_G(max_request_variables) && (SUHOSIN7_G(max_get_vars) == 0 ||
121 separator = (char *) estrdup(PG(arg_separator).input); 48 SUHOSIN7_G(max_request_variables) <= SUHOSIN7_G(max_get_vars))) {
49 SUHOSIN7_G(max_get_vars) = SUHOSIN7_G(max_request_variables);
50 }
122 break; 51 break;
123 case PARSE_COOKIE: 52 case PARSE_COOKIE:
124 separator = ";\0"; 53 if (SUHOSIN7_G(max_request_variables) && (SUHOSIN7_G(max_cookie_vars) == 0 ||
125 break; 54 SUHOSIN7_G(max_request_variables) <= SUHOSIN7_G(max_cookie_vars))) {
126 } 55 SUHOSIN7_G(max_cookie_vars) = SUHOSIN7_G(max_request_variables);
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 } 56 }
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; 57 break;
146 }
147 SDEBUG("calling input filter from treat_data");
148
149 if (val) { /* have a value */
150 size_t val_len;
151 size_t new_val_len;
152
153 *val++ = '\0';
154 php_url_decode(var, strlen(var));
155 val_len = php_url_decode(val, strlen(val));
156 val = estrndup(val, val_len);
157 if (suhosin_input_filter(arg, var, &val, val_len, &new_val_len)) {
158 // if (sapi_module.input_filter(arg, var, &val, new_val_len, &new_val_len)) {
159 php_register_variable_safe(var, val, new_val_len, &array);
160 // }
161 } else {
162 SUHOSIN7_G(abort_request) = 1;
163 }
164 efree(val);
165 } else {
166 size_t val_len;
167 size_t new_val_len;
168
169 php_url_decode(var, strlen(var));
170 val_len = 0;
171 val = estrndup("", val_len);
172 if (suhosin_input_filter(arg, var, &val, val_len, &new_val_len)) {
173 // if (sapi_module.input_filter(arg, var, &val, new_val_len, &new_val_len)) {
174 php_register_variable_safe(var, val, new_val_len, &array);
175 // }
176 } else {
177 SUHOSIN7_G(abort_request) = 1;
178 }
179 efree(val);
180 }
181next_cookie:
182 var = php_strtok_r(NULL, separator, &strtok_buf);
183 } 58 }
184 59
185 if (arg != PARSE_COOKIE) { 60 if (arg == PARSE_COOKIE && SUHOSIN7_G(cookie_encrypt) && SG(request_info).cookie_data) {
186 efree(separator); 61 SG(request_info).cookie_data = suhosin_cookie_decryptor(SG(request_info).cookie_data);
187 } 62 }
188 63
189 if (free_buffer) { 64 if (orig_treat_data) {
190 efree(res); 65 orig_treat_data(arg, str, destArray);
191 } 66 }
192
193} 67}
194 68
195
196void suhosin_hook_treat_data() 69void suhosin_hook_treat_data()
197{ 70{
198 // sapi_register_treat_data(suhosin_treat_data); 71 if (orig_treat_data == NULL) {
199 72 orig_treat_data = sapi_module.treat_data;
200 if (old_input_filter == NULL) {
201 old_input_filter = sapi_module.input_filter;
202 } 73 }
203 sapi_module.input_filter = suhosin_input_filter_wrapper; 74 sapi_module.treat_data = suhosin_treat_data;
204} 75}
205 76
206 77