summaryrefslogtreecommitdiff
path: root/src/sp_cookie_encryption.c
diff options
context:
space:
mode:
authorxXx-caillou-xXx2017-11-24 14:03:37 +0100
committerjvoisin2017-11-24 14:03:37 +0100
commit5a224ee0c92d1639395d6a0c629316ae64226125 (patch)
tree8925d27e2bbfa877e9fb1fc20868fbef3d009b04 /src/sp_cookie_encryption.c
parent79304a29661476dc75bba07c5a83133122bbcb5c (diff)
Implement anti csrf measures
This is done by using the "samesite" cookie attribute.
Diffstat (limited to 'src/sp_cookie_encryption.c')
-rw-r--r--src/sp_cookie_encryption.c39
1 files changed, 28 insertions, 11 deletions
diff --git a/src/sp_cookie_encryption.c b/src/sp_cookie_encryption.c
index 2ebcc96..eb20c52 100644
--- a/src/sp_cookie_encryption.c
+++ b/src/sp_cookie_encryption.c
@@ -45,12 +45,12 @@ int decrypt_cookie(zval *pDest, int num_args, va_list args,
45 size_t value_len; 45 size_t value_len;
46 zend_string *debase64; 46 zend_string *debase64;
47 unsigned char *decrypted; 47 unsigned char *decrypted;
48 sp_cookie *cookie = zend_hash_find_ptr(SNUFFLEUPAGUS_G(config).config_cookie->cookies,
49 hash_key->key);
48 int ret = 0; 50 int ret = 0;
49 51
50 /* If the cookie isn't in the conf, it shouldn't be encrypted. */ 52 /* If the cookie isn't in the conf, it shouldn't be encrypted. */
51 if (0 == 53 if (!cookie || !cookie->encrypt) {
52 zend_hash_exists(SNUFFLEUPAGUS_G(config).config_cookie_encryption->names,
53 hash_key->key)) {
54 return ZEND_HASH_APPLY_KEEP; 54 return ZEND_HASH_APPLY_KEEP;
55 } 55 }
56 56
@@ -135,11 +135,13 @@ static zend_string *encrypt_data(char *data, unsigned long long data_len) {
135 135
136PHP_FUNCTION(sp_setcookie) { 136PHP_FUNCTION(sp_setcookie) {
137 zval params[7] = { 0 }; 137 zval params[7] = { 0 };
138 zend_string *name = NULL, *value = NULL, *path = NULL, *domain = NULL; 138 zend_string *name = NULL, *value = NULL, *path = NULL, *domain = NULL, *samesite = NULL;
139 zend_long expires = 0; 139 zend_long expires = 0;
140 zend_bool secure = 0, httponly = 0; 140 zend_bool secure = 0, httponly = 0;
141 zval ret_val; 141 zval ret_val;
142 const sp_cookie *cookie_node = NULL;
142 zval func_name; 143 zval func_name;
144 char *cookie_samesite;
143 145
144 146
145 // LCOV_EXCL_BR_START 147 // LCOV_EXCL_BR_START
@@ -167,17 +169,18 @@ PHP_FUNCTION(sp_setcookie) {
167 } 169 }
168 } 170 }
169 171
172 cookie_node =
173 zend_hash_find_ptr(SNUFFLEUPAGUS_G(config).config_cookie->cookies, name);
174
170 /* If the cookie's value is encrypted, it won't be usable by 175 /* If the cookie's value is encrypted, it won't be usable by
171 * javascript anyway. 176 * javascript anyway.
172 */ 177 */
173 if (zend_hash_exists(SNUFFLEUPAGUS_G(config).config_cookie_encryption->names, 178 if (cookie_node && cookie_node->encrypt) {
174 name) > 0) {
175 httponly = 1; 179 httponly = 1;
176 } 180 }
177 181
178 /* Shall we encrypt the cookie's value? */ 182 /* Shall we encrypt the cookie's value? */
179 if (zend_hash_exists(SNUFFLEUPAGUS_G(config).config_cookie_encryption->names, 183 if (httponly && value) {
180 name) > 0 && value) {
181 zend_string *encrypted_data = encrypt_data(value->val, value->len); 184 zend_string *encrypted_data = encrypt_data(value->val, value->len);
182 ZVAL_STR_COPY(&params[1], encrypted_data); 185 ZVAL_STR_COPY(&params[1], encrypted_data);
183 zend_string_release(encrypted_data); 186 zend_string_release(encrypted_data);
@@ -188,9 +191,6 @@ PHP_FUNCTION(sp_setcookie) {
188 ZVAL_STRING(&func_name, "setcookie"); 191 ZVAL_STRING(&func_name, "setcookie");
189 ZVAL_STR_COPY(&params[0], name); 192 ZVAL_STR_COPY(&params[0], name);
190 ZVAL_LONG(&params[2], expires); 193 ZVAL_LONG(&params[2], expires);
191 if (path) {
192 ZVAL_STR_COPY(&params[3], path);
193 }
194 if (domain) { 194 if (domain) {
195 ZVAL_STR_COPY(&params[4], domain); 195 ZVAL_STR_COPY(&params[4], domain);
196 } 196 }
@@ -201,6 +201,23 @@ PHP_FUNCTION(sp_setcookie) {
201 ZVAL_LONG(&params[6], httponly); 201 ZVAL_LONG(&params[6], httponly);
202 } 202 }
203 203
204 /* param[3](path) is concatenated to path= and is not filtered, we can inject
205 the samesite parameter here */
206 if (cookie_node && cookie_node->samesite) {
207 if (!path) {
208 path = zend_string_init("", 0, 0);
209 }
210 cookie_samesite = (cookie_node->samesite == lax) ? SAMESITE_COOKIE_FORMAT SP_TOKEN_SAMESITE_LAX
211 : SAMESITE_COOKIE_FORMAT SP_TOKEN_SAMESITE_STRICT;
212 /* Concatenating everything, as is in PHP internals */
213 samesite = zend_string_extend(path, ZSTR_LEN(path) + strlen(cookie_samesite) + 1, 0);
214 memcpy(ZSTR_VAL(samesite) + ZSTR_LEN(path), cookie_samesite, strlen(cookie_samesite) + 1);
215 ZVAL_STR_COPY(&params[3], samesite);
216 zend_string_release(path);
217 } else if (path) {
218 ZVAL_STR_COPY(&params[3], path);
219 }
220
204 /* This is the _fun_ part: because PHP is utterly idiotic and nonsensical, 221 /* This is the _fun_ part: because PHP is utterly idiotic and nonsensical,
205 the `call_user_function` macro will __discard__ (yes) its first argument 222 the `call_user_function` macro will __discard__ (yes) its first argument
206 (the hashtable), effectively calling functions from `CG(function_table)`. 223 (the hashtable), effectively calling functions from `CG(function_table)`.