diff options
| author | Ben Fuhrmannek | 2016-02-24 00:36:35 +0100 |
|---|---|---|
| committer | Ben Fuhrmannek | 2016-02-24 00:36:35 +0100 |
| commit | 346455c6b5716c8ce095235428614e15c0adf13e (patch) | |
| tree | aaa648869e88287ed34c6d36cc06474d062b4b32 | |
| parent | 35b7c9a0e3f8a0daf1718a8ba9889a2aec24dc84 (diff) | |
cookie encryption
28 files changed, 1184 insertions, 231 deletions
| @@ -1,16 +1,17 @@ | |||
| 1 | dnl $Id$ | 1 | dnl $Id$ |
| 2 | dnl config.m4 for extension suhosin7 | 2 | dnl config.m4 for extension suhosin7 |
| 3 | 3 | ||
| 4 | PHP_ARG_ENABLE(suhosin, whether to enable suhosin support, | 4 | PHP_ARG_ENABLE(suhosin7, whether to enable suhosin support, |
| 5 | [ --enable-suhosin Enable suhosin support]) | 5 | [ --enable-suhosin7 Enable suhosin support]) |
| 6 | 6 | ||
| 7 | if test "$PHP_SUHOSIN" != "no"; then | 7 | if 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) | ||
| 9 | fi | 10 | fi |
| 10 | 11 | ||
| 11 | PHP_ARG_ENABLE(suhosin7-experimental, whether to enable experimental suhosin7 features, | 12 | PHP_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 | ||
| 14 | if test "$PHP_SUHOSIN7_EXPERIMENTAL" != "no"; then | 15 | if 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]) |
| 16 | fi | 17 | fi |
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 | |||
| 34 | zend_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 | |||
| 60 | char *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 | */ | ||
| 102 | char *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 | /* }}} */ | ||
| @@ -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 | |||
| 34 | static 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 | |||
| 57 | zend_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 | |||
| 127 | zend_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 | |||
| 225 | error_out: | ||
| 226 | SDEBUG("error_out"); | ||
| 227 | if (decrypted_zs) { | ||
| 228 | zend_string_release(decrypted_zs); | ||
| 229 | } | ||
| 230 | return NULL; | ||
| 231 | } | ||
| 232 | |||
| 233 | char *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 | } | ||
| @@ -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 | |||
| 33 | static 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 | */ | ||
| 37 | static 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 | |||
| 119 | suhosin_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 | */ | ||
| 132 | void 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 | */ | ||
| 143 | void 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 | */ | ||
| @@ -41,7 +41,7 @@ static size_t strnlen(const char *s, size_t maxlen) { | |||
| 41 | } | 41 | } |
| 42 | #endif | 42 | #endif |
| 43 | 43 | ||
| 44 | size_t suhosin_strnspn(const char *input, size_t n, const char *accept) | 44 | static 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 | ||
| 54 | size_t suhosin_strncspn(const char *input, size_t n, const char *reject) | 54 | static 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 | */ |
| 67 | void normalize_varname(char *varname) | 67 | void 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; | 288 | static SAPI_INPUT_FILTER_FUNC((*orig_input_filter)) = NULL; |
| 289 | unsigned 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 | */ | ||
| 293 | unsigned 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 | */ |
| 327 | unsigned int suhosin_input_filter(int arg, char *var, char **val, size_t val_len, size_t *new_val_len) | 292 | static 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 | */ | ||
| 620 | SAPI_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 | ||
| 664 | void 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: |
| @@ -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 | ||
| 124 | ZEND_BEGIN_MODULE_GLOBALS(suhosin7) | 124 | ZEND_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 | ||
| 365 | unsigned 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); |
| 366 | unsigned 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); |
| 367 | SUHOSIN7_API void suhosin_log(int loglevel, char *fmt, ...); | 365 | SUHOSIN7_API void suhosin_log(int loglevel, char *fmt, ...); |
| 368 | extern 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); |
| 369 | char *suhosin_getenv(char *name, size_t name_len); | 367 | char *suhosin_getenv(char *name, size_t name_len); |
| 370 | 368 | ||
| 369 | // hooks | ||
| 371 | void suhosin_hook_memory_limit(); | 370 | void suhosin_hook_memory_limit(); |
| 372 | void suhosin_hook_treat_data(); | 371 | void suhosin_hook_treat_data(); |
| 373 | void suhosin_hook_execute(); | 372 | void suhosin_hook_input_filter(); |
| 374 | void suhosin_hook_register_server_variables(); | 373 | void suhosin_hook_register_server_variables(); |
| 374 | void suhosin_hook_header_handler(); | ||
| 375 | void suhosin_unhook_header_handler(); | ||
| 376 | void suhosin_hook_execute(); | ||
| 375 | // void suhosin_hook_sha256(); | 377 | // void suhosin_hook_sha256(); |
| 376 | 378 | ||
| 379 | // ifilter.c | ||
| 380 | void suhosin_normalize_varname(char *varname); | ||
| 381 | |||
| 382 | // cookiecrypt.c | ||
| 383 | char *suhosin_cookie_decryptor(char *raw_cookie); | ||
| 384 | zend_string *suhosin_encrypt_single_cookie(char *name, int name_len, char *value, int value_len, char *key); | ||
| 385 | char *suhosin_decrypt_single_cookie(char *name, int name_len, char *value, int value_len, char *key, char **out); | ||
| 386 | |||
| 387 | // crypt.c | ||
| 388 | zend_string *suhosin_encrypt_string(char *str, int len, char *var, int vlen, char *key); | ||
| 389 | zend_string *suhosin_decrypt_string(char *str, int padded_len, char *var, int vlen, char *key, int check_ra); | ||
| 390 | char *suhosin_generate_key(char *key, zend_bool ua, zend_bool dr, long raddr, char *cryptkey); | ||
| 391 | |||
| 392 | // aes.c | ||
| 393 | void suhosin_aes_gentables(); | ||
| 394 | void suhosin_aes_gkey(int nb,int nk,char *key); | ||
| 395 | void suhosin_aes_encrypt(char *buff); | ||
| 396 | void suhosin_aes_decrypt(char *buff); | ||
| 397 | |||
| 398 | // | ||
| 399 | |||
| 377 | static inline void suhosin_bailout() | 400 | static 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 | ||
| 407 | static 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 | ||
| @@ -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 | */ |
| 277 | PHP_INI_BEGIN() | 278 | PHP_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) | |||
| 538 | PHP_RINIT_FUNCTION(suhosin7) | 540 | PHP_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) | |||
| 548 | PHP_RSHUTDOWN_FUNCTION(suhosin7) | 553 | PHP_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-- | ||
| 2 | cookie encryption with checkraddr=4 | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php include "../skipif.inc"; ?> | ||
| 5 | --INI-- | ||
| 6 | suhosin.cookie.encrypt=1 | ||
| 7 | suhosin.cookie.cryptkey= | ||
| 8 | suhosin.cookie.cryptua=Off | ||
| 9 | suhosin.cookie.cryptdocroot=Off | ||
| 10 | suhosin.cookie.cryptraddr=0 | ||
| 11 | suhosin.cookie.checkraddr=4 | ||
| 12 | ;suhosin.cookie.cryptlist= | ||
| 13 | ;suhosin.cookie.plainlist= | ||
| 14 | --ENV-- | ||
| 15 | return <<<END | ||
| 16 | REMOTE_ADDR=127.0.0.1 | ||
| 17 | END; | ||
| 18 | --COOKIE-- | ||
| 19 | foo=EgJxlQxzPwoAcVFj395vssv3hy1rAem1lH9qZYUvRi8. | ||
| 20 | --FILE-- | ||
| 21 | <?php | ||
| 22 | var_dump($_COOKIE); | ||
| 23 | ?> | ||
| 24 | --EXPECTF-- | ||
| 25 | array(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-- | ||
| 2 | cookie encryption with checkraddr=4 | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php include "../skipif.inc"; ?> | ||
| 5 | --INI-- | ||
| 6 | suhosin.cookie.encrypt=1 | ||
| 7 | suhosin.cookie.cryptkey= | ||
| 8 | suhosin.cookie.cryptua=Off | ||
| 9 | suhosin.cookie.cryptdocroot=Off | ||
| 10 | suhosin.cookie.cryptraddr=0 | ||
| 11 | suhosin.cookie.checkraddr=4 | ||
| 12 | ;suhosin.cookie.cryptlist= | ||
| 13 | ;suhosin.cookie.plainlist= | ||
| 14 | --ENV-- | ||
| 15 | return <<<END | ||
| 16 | REMOTE_ADDR=127.0.0.2 | ||
| 17 | END; | ||
| 18 | --COOKIE-- | ||
| 19 | foo=EgJxlQxzPwoAcVFj395vssv3hy1rAem1lH9qZYUvRi8. | ||
| 20 | --FILE-- | ||
| 21 | <?php | ||
| 22 | var_dump($_COOKIE); | ||
| 23 | ?> | ||
| 24 | --EXPECTF-- | ||
| 25 | array(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-- | ||
| 2 | cookie encryption with cryptlist set | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php include "../skipif.inc"; ?> | ||
| 5 | --INI-- | ||
| 6 | suhosin.cookie.encrypt=1 | ||
| 7 | suhosin.cookie.cryptkey= | ||
| 8 | suhosin.cookie.cryptua=0 | ||
| 9 | suhosin.cookie.cryptdocroot=0 | ||
| 10 | suhosin.cookie.cryptraddr=0 | ||
| 11 | suhosin.cookie.checkraddr=0 | ||
| 12 | suhosin.cookie.cryptlist=a,b,foo,c | ||
| 13 | ;suhosin.cookie.plainlist= | ||
| 14 | --ENV-- | ||
| 15 | return <<<END | ||
| 16 | REMOTE_ADDR=127.0.0.1 | ||
| 17 | END; | ||
| 18 | --COOKIE-- | ||
| 19 | a=b | ||
| 20 | --FILE-- | ||
| 21 | <?php | ||
| 22 | setcookie('foo', 'bar'); | ||
| 23 | setcookie('foo2', 'bar2'); | ||
| 24 | $ch = preg_grep("/^Set-Cookie:/", headers_list()); | ||
| 25 | echo join("\n", array_values($ch)); | ||
| 26 | ?> | ||
| 27 | --EXPECTF-- | ||
| 28 | Set-Cookie: foo=EgJxlQxzPwoAcVFj395vssv3hy1rAem1lH9qZYUvRi8. | ||
| 29 | Set-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-- | ||
| 2 | cookie encryption using document root | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php include "../skipif.inc"; ?> | ||
| 5 | --INI-- | ||
| 6 | suhosin.cookie.encrypt=1 | ||
| 7 | suhosin.cookie.cryptkey= | ||
| 8 | suhosin.cookie.cryptua=Off | ||
| 9 | suhosin.cookie.cryptdocroot=On | ||
| 10 | suhosin.cookie.cryptraddr=0 | ||
| 11 | suhosin.cookie.checkraddr=0 | ||
| 12 | ;suhosin.cookie.cryptlist= | ||
| 13 | ;suhosin.cookie.plainlist= | ||
| 14 | --ENV-- | ||
| 15 | return <<<END | ||
| 16 | DOCUMENT_ROOT=/var/www | ||
| 17 | END; | ||
| 18 | --COOKIE-- | ||
| 19 | a=b | ||
| 20 | --FILE-- | ||
| 21 | <?php | ||
| 22 | setcookie('foo', 'bar'); | ||
| 23 | $ch = preg_grep("/^Set-Cookie:/", headers_list()); | ||
| 24 | echo join("\n", array_values($ch)); | ||
| 25 | ?> | ||
| 26 | --EXPECTF-- | ||
| 27 | Set-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-- | ||
| 2 | cookie encryption with invalid cookie | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php include "../skipif.inc"; ?> | ||
| 5 | --INI-- | ||
| 6 | suhosin.cookie.encrypt=1 | ||
| 7 | suhosin.cookie.cryptkey= | ||
| 8 | suhosin.cookie.cryptua=Off | ||
| 9 | suhosin.cookie.cryptdocroot=Off | ||
| 10 | suhosin.cookie.cryptraddr=0 | ||
| 11 | suhosin.cookie.checkraddr=0 | ||
| 12 | ;suhosin.cookie.cryptlist= | ||
| 13 | ;suhosin.cookie.plainlist= | ||
| 14 | --ENV-- | ||
| 15 | return <<<END | ||
| 16 | REMOTE_ADDR=127.0.0.1 | ||
| 17 | END; | ||
| 18 | --COOKIE-- | ||
| 19 | foo=test | ||
| 20 | --FILE-- | ||
| 21 | <?php | ||
| 22 | var_dump($_COOKIE); | ||
| 23 | ?> | ||
| 24 | --EXPECTF-- | ||
| 25 | array(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-- | ||
| 2 | cookie encryption with default key | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php include "../skipif.inc"; ?> | ||
| 5 | --INI-- | ||
| 6 | suhosin.cookie.encrypt=1 | ||
| 7 | suhosin.cookie.cryptkey=D3F4UL7 | ||
| 8 | suhosin.cookie.cryptua=0 | ||
| 9 | suhosin.cookie.cryptdocroot=0 | ||
| 10 | suhosin.cookie.cryptraddr=0 | ||
| 11 | suhosin.cookie.checkraddr=0 | ||
| 12 | ;suhosin.cookie.cryptlist= | ||
| 13 | ;suhosin.cookie.plainlist= | ||
| 14 | --COOKIE-- | ||
| 15 | a=b | ||
| 16 | --FILE-- | ||
| 17 | <?php | ||
| 18 | setcookie('foo', 'bar'); | ||
| 19 | $ch = preg_grep("/^Set-Cookie:/", headers_list()); | ||
| 20 | echo join("\n", array_values($ch)); | ||
| 21 | ?> | ||
| 22 | --EXPECTF-- | ||
| 23 | Set-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-- | ||
| 2 | cookie encryption with empty key | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php include "../skipif.inc"; ?> | ||
| 5 | --INI-- | ||
| 6 | suhosin.cookie.encrypt=1 | ||
| 7 | suhosin.cookie.cryptkey= | ||
| 8 | suhosin.cookie.cryptua=0 | ||
| 9 | suhosin.cookie.cryptdocroot=0 | ||
| 10 | suhosin.cookie.cryptraddr=0 | ||
| 11 | suhosin.cookie.checkraddr=0 | ||
| 12 | ;suhosin.cookie.cryptlist= | ||
| 13 | ;suhosin.cookie.plainlist= | ||
| 14 | --COOKIE-- | ||
| 15 | a=b | ||
| 16 | --FILE-- | ||
| 17 | <?php | ||
| 18 | setcookie('foo', 'bar'); | ||
| 19 | $ch = preg_grep("/^Set-Cookie:/", headers_list()); | ||
| 20 | echo join("\n", array_values($ch)); | ||
| 21 | ?> | ||
| 22 | --EXPECTF-- | ||
| 23 | Set-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-- | ||
| 2 | cookie encryption with empty key and REMOTE_ADDR set | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php include "../skipif.inc"; ?> | ||
| 5 | --INI-- | ||
| 6 | suhosin.cookie.encrypt=1 | ||
| 7 | suhosin.cookie.cryptkey= | ||
| 8 | suhosin.cookie.cryptua=0 | ||
| 9 | suhosin.cookie.cryptdocroot=0 | ||
| 10 | suhosin.cookie.cryptraddr=0 | ||
| 11 | suhosin.cookie.checkraddr=0 | ||
| 12 | ;suhosin.cookie.cryptlist= | ||
| 13 | ;suhosin.cookie.plainlist= | ||
| 14 | --ENV-- | ||
| 15 | return <<<END | ||
| 16 | REMOTE_ADDR=127.0.0.1 | ||
| 17 | END; | ||
| 18 | --COOKIE-- | ||
| 19 | a=b | ||
| 20 | --FILE-- | ||
| 21 | <?php | ||
| 22 | setcookie('foo', 'bar'); | ||
| 23 | $ch = preg_grep("/^Set-Cookie:/", headers_list()); | ||
| 24 | echo join("\n", array_values($ch)); | ||
| 25 | ?> | ||
| 26 | --EXPECTF-- | ||
| 27 | Set-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-- | ||
| 2 | cookie without encryption | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php include "../skipif.inc"; ?> | ||
| 5 | --INI-- | ||
| 6 | suhosin.cookie.encrypt=0 | ||
| 7 | --COOKIE-- | ||
| 8 | a=b | ||
| 9 | --FILE-- | ||
| 10 | <?php | ||
| 11 | setcookie('foo', 'bar'); | ||
| 12 | $ch = preg_grep("/^Set-Cookie:/", headers_list()); | ||
| 13 | echo join("\n", array_values($ch)); | ||
| 14 | ?> | ||
| 15 | --EXPECTF-- | ||
| 16 | Set-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-- | ||
| 2 | cookie encryption with plainlist set | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php include "../skipif.inc"; ?> | ||
| 5 | --INI-- | ||
| 6 | suhosin.cookie.encrypt=1 | ||
| 7 | suhosin.cookie.cryptkey= | ||
| 8 | suhosin.cookie.cryptua=0 | ||
| 9 | suhosin.cookie.cryptdocroot=0 | ||
| 10 | suhosin.cookie.cryptraddr=0 | ||
| 11 | suhosin.cookie.checkraddr=0 | ||
| 12 | ;suhosin.cookie.cryptlist= | ||
| 13 | suhosin.cookie.plainlist=a,b,foo2,c | ||
| 14 | --ENV-- | ||
| 15 | return <<<END | ||
| 16 | REMOTE_ADDR=127.0.0.1 | ||
| 17 | END; | ||
| 18 | --COOKIE-- | ||
| 19 | a=b | ||
| 20 | --FILE-- | ||
| 21 | <?php | ||
| 22 | setcookie('foo', 'bar'); | ||
| 23 | setcookie('foo2', 'bar2'); | ||
| 24 | $ch = preg_grep("/^Set-Cookie:/", headers_list()); | ||
| 25 | echo join("\n", array_values($ch)); | ||
| 26 | ?> | ||
| 27 | --EXPECTF-- | ||
| 28 | Set-Cookie: foo=EgJxlQxzPwoAcVFj395vssv3hy1rAem1lH9qZYUvRi8. | ||
| 29 | Set-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-- | ||
| 2 | cookie encryption using REMOTE_ADDR (cryptraddr=1) | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php include "../skipif.inc"; ?> | ||
| 5 | --INI-- | ||
| 6 | suhosin.cookie.encrypt=1 | ||
| 7 | suhosin.cookie.cryptkey= | ||
| 8 | suhosin.cookie.cryptua=Off | ||
| 9 | suhosin.cookie.cryptdocroot=Off | ||
| 10 | suhosin.cookie.cryptraddr=1 | ||
| 11 | suhosin.cookie.checkraddr=0 | ||
| 12 | ;suhosin.cookie.cryptlist= | ||
| 13 | ;suhosin.cookie.plainlist= | ||
| 14 | --ENV-- | ||
| 15 | return <<<END | ||
| 16 | REMOTE_ADDR=127.0.0.1 | ||
| 17 | END; | ||
| 18 | --COOKIE-- | ||
| 19 | a=b | ||
| 20 | --FILE-- | ||
| 21 | <?php | ||
| 22 | setcookie('foo', 'bar'); | ||
| 23 | $ch = preg_grep("/^Set-Cookie:/", headers_list()); | ||
| 24 | echo join("\n", array_values($ch)); | ||
| 25 | ?> | ||
| 26 | --EXPECTF-- | ||
| 27 | Set-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-- | ||
| 2 | cookie encryption using REMOTE_ADDR (cryptraddr=2) | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php include "../skipif.inc"; ?> | ||
| 5 | --INI-- | ||
| 6 | suhosin.cookie.encrypt=1 | ||
| 7 | suhosin.cookie.cryptkey= | ||
| 8 | suhosin.cookie.cryptua=Off | ||
| 9 | suhosin.cookie.cryptdocroot=Off | ||
| 10 | suhosin.cookie.cryptraddr=2 | ||
| 11 | suhosin.cookie.checkraddr=0 | ||
| 12 | ;suhosin.cookie.cryptlist= | ||
| 13 | ;suhosin.cookie.plainlist= | ||
| 14 | --ENV-- | ||
| 15 | return <<<END | ||
| 16 | REMOTE_ADDR=127.0.0.1 | ||
| 17 | END; | ||
| 18 | --COOKIE-- | ||
| 19 | a=b | ||
| 20 | --FILE-- | ||
| 21 | <?php | ||
| 22 | setcookie('foo', 'bar'); | ||
| 23 | $ch = preg_grep("/^Set-Cookie:/", headers_list()); | ||
| 24 | echo join("\n", array_values($ch)); | ||
| 25 | ?> | ||
| 26 | --EXPECTF-- | ||
| 27 | Set-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-- | ||
| 2 | cookie encryption using REMOTE_ADDR (cryptraddr=3) | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php include "../skipif.inc"; ?> | ||
| 5 | --INI-- | ||
| 6 | suhosin.cookie.encrypt=1 | ||
| 7 | suhosin.cookie.cryptkey= | ||
| 8 | suhosin.cookie.cryptua=Off | ||
| 9 | suhosin.cookie.cryptdocroot=Off | ||
| 10 | suhosin.cookie.cryptraddr=3 | ||
| 11 | suhosin.cookie.checkraddr=0 | ||
| 12 | ;suhosin.cookie.cryptlist= | ||
| 13 | ;suhosin.cookie.plainlist= | ||
| 14 | --ENV-- | ||
| 15 | return <<<END | ||
| 16 | REMOTE_ADDR=127.0.0.1 | ||
| 17 | END; | ||
| 18 | --COOKIE-- | ||
| 19 | a=b | ||
| 20 | --FILE-- | ||
| 21 | <?php | ||
| 22 | setcookie('foo', 'bar'); | ||
| 23 | $ch = preg_grep("/^Set-Cookie:/", headers_list()); | ||
| 24 | echo join("\n", array_values($ch)); | ||
| 25 | ?> | ||
| 26 | --EXPECTF-- | ||
| 27 | Set-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-- | ||
| 2 | cookie encryption using REMOTE_ADDR (cryptraddr=4) | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php include "../skipif.inc"; ?> | ||
| 5 | --INI-- | ||
| 6 | suhosin.cookie.encrypt=1 | ||
| 7 | suhosin.cookie.cryptkey= | ||
| 8 | suhosin.cookie.cryptua=Off | ||
| 9 | suhosin.cookie.cryptdocroot=Off | ||
| 10 | suhosin.cookie.cryptraddr=4 | ||
| 11 | suhosin.cookie.checkraddr=0 | ||
| 12 | ;suhosin.cookie.cryptlist= | ||
| 13 | ;suhosin.cookie.plainlist= | ||
| 14 | --ENV-- | ||
| 15 | return <<<END | ||
| 16 | REMOTE_ADDR=127.0.0.1 | ||
| 17 | END; | ||
| 18 | --COOKIE-- | ||
| 19 | a=b | ||
| 20 | --FILE-- | ||
| 21 | <?php | ||
| 22 | setcookie('foo', 'bar'); | ||
| 23 | $ch = preg_grep("/^Set-Cookie:/", headers_list()); | ||
| 24 | echo join("\n", array_values($ch)); | ||
| 25 | ?> | ||
| 26 | --EXPECTF-- | ||
| 27 | Set-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-- | ||
| 2 | cookie with encryption using HTTP_USER_AGENT | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php include "../skipif.inc"; ?> | ||
| 5 | --INI-- | ||
| 6 | suhosin.cookie.encrypt=1 | ||
| 7 | suhosin.cookie.cryptkey= | ||
| 8 | suhosin.cookie.cryptua=On | ||
| 9 | suhosin.cookie.cryptdocroot=0 | ||
| 10 | suhosin.cookie.cryptraddr=0 | ||
| 11 | suhosin.cookie.checkraddr=0 | ||
| 12 | ;suhosin.cookie.cryptlist= | ||
| 13 | ;suhosin.cookie.plainlist= | ||
| 14 | --ENV-- | ||
| 15 | return <<<END | ||
| 16 | HTTP_USER_AGENT=test | ||
| 17 | END; | ||
| 18 | --COOKIE-- | ||
| 19 | a=b | ||
| 20 | --FILE-- | ||
| 21 | <?php | ||
| 22 | setcookie('foo', 'bar'); | ||
| 23 | $ch = preg_grep("/^Set-Cookie:/", headers_list()); | ||
| 24 | echo join("\n", array_values($ch)); | ||
| 25 | ?> | ||
| 26 | --EXPECTF-- | ||
| 27 | Set-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 | ||
| 2 | if(!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 | ||
| 2 | if (php_sapi_name()=='cli') { | ||
| 3 | print 'skip - SAPI == cli'; | ||
| 4 | } else { | ||
| 5 | if(!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 | ||
| 2 | if (php_sapi_name()!='cli') { | ||
| 3 | print 'skip - SAPI != cli'; | ||
| 4 | } else { | ||
| 5 | if(!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 | ||
| 35 | static SAPI_TREAT_DATA_FUNC((*orig_treat_data)) = NULL; | ||
| 36 | |||
| 34 | SAPI_TREAT_DATA_FUNC(suhosin_treat_data) | 37 | SAPI_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 | } | ||
| 181 | next_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 | |||
| 196 | void suhosin_hook_treat_data() | 69 | void 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 | ||
