Skip to content

Commit

Permalink
ported server.strip and server.encode features from suhosin
Browse files Browse the repository at this point in the history
  • Loading branch information
bef committed Sep 16, 2021
1 parent 31d6a3c commit 6e07cdb
Show file tree
Hide file tree
Showing 10 changed files with 165 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/config.m4
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ sources="$sources sp_disabled_functions.c sp_execute.c sp_upload_validation.c"
sources="$sources sp_cookie_encryption.c sp_network_utils.c tweetnacl.c"
sources="$sources sp_config_keywords.c sp_var_parser.c sp_var_value.c sp_tree.c"
sources="$sources sp_pcre_compat.c sp_crypt.c sp_session.c sp_sloppy.c sp_wrapper.c"
sources="$sources sp_ini.c sp_php_compat.c sp_config_scanner.c"
sources="$sources sp_ini.c sp_php_compat.c sp_config_scanner.c sp_ifilter.c"

PHP_ARG_ENABLE(snuffleupagus, whether to enable snuffleupagus support,
[ --enable-snuffleupagus Enable snuffleupagus support])
Expand Down
1 change: 1 addition & 0 deletions src/php_snuffleupagus.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ typedef void (*zif_handler)(INTERNAL_FUNCTION_PARAMETERS);
#include "sp_sloppy.h"
#include "sp_wrapper.h"
#include "sp_ini.h"
#include "sp_ifilter.h"

extern zend_module_entry snuffleupagus_module_entry;
#define phpext_snuffleupagus_ptr &snuffleupagus_module_entry
Expand Down
2 changes: 2 additions & 0 deletions src/snuffleupagus.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,8 @@ static PHP_INI_MH(OnUpdateConfiguration) {
sp_hook_ini();
}

sp_hook_register_server_variables();

if (true == SNUFFLEUPAGUS_G(config).config_global_strict->enable) {
if (!zend_get_extension(PHP_SNUFFLEUPAGUS_EXTNAME)) {
zend_extension_entry.startup = NULL;
Expand Down
4 changes: 4 additions & 0 deletions src/sp_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ typedef struct {
bool hook_execute;
char log_media;
u_long max_execution_depth;
bool server_encode;
bool server_strip;

HashTable *config_disabled_functions;
HashTable *config_disabled_functions_hooked;
Expand Down Expand Up @@ -288,6 +290,8 @@ typedef struct {
#define SP_TOKEN_ENV_VAR "cookie_env_var"
#define SP_TOKEN_LOG_MEDIA "log_media"
#define SP_TOKEN_MAX_EXECUTION_DEPTH "max_execution_depth"
#define SP_TOKEN_SERVER_ENCODE "server_encode"
#define SP_TOKEN_SERVER_STRIP "server_strip"

// upload_validator
#define SP_TOKEN_UPLOAD_SCRIPT "script"
Expand Down
2 changes: 2 additions & 0 deletions src/sp_config_keywords.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ SP_PARSE_FN(parse_global) {
{parse_str, SP_TOKEN_ENV_VAR, &(SNUFFLEUPAGUS_G(config).config_snuffleupagus->cookies_env_var)},
{parse_log_media, SP_TOKEN_LOG_MEDIA, &(SNUFFLEUPAGUS_G(config).log_media)},
{parse_ulong, SP_TOKEN_MAX_EXECUTION_DEPTH, &(SNUFFLEUPAGUS_G(config).max_execution_depth)},
{parse_enable, SP_TOKEN_SERVER_ENCODE, &(SNUFFLEUPAGUS_G(config).server_encode)},
{parse_enable, SP_TOKEN_SERVER_STRIP, &(SNUFFLEUPAGUS_G(config).server_strip)},
{0, 0, 0}};

SP_PROCESS_CONFIG_KEYWORDS_ERR();
Expand Down
103 changes: 103 additions & 0 deletions src/sp_ifilter.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#include "php_snuffleupagus.h"

static void (*orig_register_server_variables)(zval *track_vars_array) = NULL;

static const unsigned char sp_hexchars[] = "0123456789ABCDEF";

static const char sp_is_dangerous_char[256] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

static void sp_server_strip(HashTable *svars, char *key, int keylen) {
zval *value = zend_hash_str_find(svars, key, keylen);
if (!value || Z_TYPE_P(value) != IS_STRING) { return; }

zend_string *tmp_zstr = Z_STR_P(value);
char *tmp = ZSTR_VAL(tmp_zstr);
char *tmpend = tmp + ZSTR_LEN(tmp_zstr);

for (char *p = tmp; p < tmpend; p++) {
if (sp_is_dangerous_char[(int)*p]) {
*p = '_';
}
}
}

static void sp_server_encode(HashTable *svars, char *key, int keylen) {
zval *value = zend_hash_str_find(svars, key, keylen);
if (!value || Z_TYPE_P(value) != IS_STRING) { return; }

zend_string *tmp_zstr = Z_STR_P(value);
char *tmp = ZSTR_VAL(tmp_zstr);
char *tmpend = tmp + ZSTR_LEN(tmp_zstr);
int extra = 0;

for (char *p = tmp; p < tmpend; p++) {
extra += sp_is_dangerous_char[(int)*p] * 2;
}
if (!extra) { return; }

zend_string *new_zstr = zend_string_alloc(ZSTR_LEN(tmp_zstr) + extra, 0);
char *n = ZSTR_VAL(new_zstr);
for (char *p = tmp; p < tmpend; p++, n++) {
if (sp_is_dangerous_char[(int)*p]) {
*n++ = '%';
*n++ = sp_hexchars[*p >> 4];
*n = sp_hexchars[*p & 15];
} else {
*n = *p;
}
}
ZSTR_VAL(new_zstr)[ZSTR_LEN(new_zstr)] = 0;
Z_STR_P(value) = new_zstr;

zend_string_release_ex(tmp_zstr, 0);
}

static void sp_register_server_variables(zval *track_vars_array) {
orig_register_server_variables(track_vars_array);

HashTable *svars;
svars = Z_ARRVAL_P(track_vars_array);


if (SNUFFLEUPAGUS_G(config).server_encode) {
sp_server_encode(svars, ZEND_STRL("REQUEST_URI"));
sp_server_encode(svars, ZEND_STRL("QUERY_STRING"));
}

if (SNUFFLEUPAGUS_G(config).server_strip) {
sp_server_strip(svars, ZEND_STRL("PHP_SELF"));
sp_server_strip(svars, ZEND_STRL("HTTP_HOST"));
sp_server_strip(svars, ZEND_STRL("HTTP_USER_AGENT"));

// for cgi + fpm
sp_server_strip(svars, ZEND_STRL("PATH_INFO"));
sp_server_strip(svars, ZEND_STRL("PATH_TRANSLATED"));
sp_server_strip(svars, ZEND_STRL("ORIG_PATH_TRANSLATED"));
sp_server_strip(svars, ZEND_STRL("ORIG_PATH_INFO"));
}
}

void sp_hook_register_server_variables()
{
if (sapi_module.register_server_variables) {
orig_register_server_variables = sapi_module.register_server_variables;
sapi_module.register_server_variables = sp_register_server_variables;
}
}
3 changes: 3 additions & 0 deletions src/sp_ifilter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#pragma once

void sp_hook_register_server_variables();
3 changes: 3 additions & 0 deletions src/tests/filter/config/filter.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
sp.global.server_encode.enable();
sp.global.server_strip.enable();

25 changes: 25 additions & 0 deletions src/tests/filter/server_encode.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
--TEST--
input filter: server_encode
--SKIPIF--
<?php if (!extension_loaded("snuffleupagus")) print "skip"; ?>
--INI--
sp.configuration_file={PWD}/config/filter.ini
display_errors=1
display_startup_errors=1
error_reporting=E_ALL
--ENV--
return <<<EOF
REQUEST_URI=AAA<>"'`!AAA
EOF;
--COOKIE--
--GET--
BBB<>"'`!BBB
--POST--
--FILE--
<?php
var_dump($_SERVER['REQUEST_URI']);
var_dump($_SERVER['QUERY_STRING']);
--EXPECT--
string(22) "AAA%3C%3E%22%27%60!AAA"
string(22) "BBB%3C%3E%22%27%60!BBB"

21 changes: 21 additions & 0 deletions src/tests/filter/server_strip.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
--TEST--
input filter: server_strip
--SKIPIF--
<?php if (!extension_loaded("snuffleupagus")) print "skip"; ?>
--INI--
sp.configuration_file={PWD}/config/filter.ini
display_errors=1
display_startup_errors=1
error_reporting=E_ALL
--ENV--
return <<<EOF
HTTP_USER_AGENT=Mozilla/5.0 (Windows NT 6.0; rv:29.0) <script>alert('123');</script>Gecko/20100101 Firefox/29.0
EOF;
--COOKIE--
--GET--
--POST--
--FILE--
<?php
var_dump($_SERVER['HTTP_USER_AGENT']);
--EXPECT--
string(95) "Mozilla/5.0 (Windows NT 6.0; rv:29.0) _script_alert(_123_);_/script_Gecko/20100101 Firefox/29.0"

0 comments on commit 6e07cdb

Please sign in to comment.