<commit_before>/*
 * Copyright 2017-2018 Baidu Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "openrasp_output_detect.h"
#include "openrasp_hook.h"
#include "openrasp_ini.h"
#include "agent/shared_config_manager.h"
#include "utils/regex.h"

ZEND_DECLARE_MODULE_GLOBALS(openrasp_output_detect)

static void _check_header_content_type_if_html(void *data, void *arg TSRMLS_DC);
static int _detect_param_occur_in_html_output(const char *param, OpenRASPActionType action TSRMLS_DC);
static bool _gpc_parameter_filter(const zval *param TSRMLS_DC);
static bool _is_content_type_html(TSRMLS_D);

#if (PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION <= 3)

void openrasp_detect_output(INTERNAL_FUNCTION_PARAMETERS)
{
    OUTPUT_G(output_detect) = true;
    char *input;
    int input_len;
    long mode;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &input, &input_len, &mode) == FAILURE)
    {
        RETVAL_FALSE;
    }
    if (_is_content_type_html(TSRMLS_C))
    {
        OpenRASPActionType action = openrasp::scm->get_buildin_check_action(XSS_USER_INPUT);
        int status = _detect_param_occur_in_html_output(input, action TSRMLS_CC);
        if (status == SUCCESS)
        {
            status = (AC_BLOCK == action) ? SUCCESS : FAILURE;
        }
        if (status == SUCCESS)
        {
            reset_response(TSRMLS_C);
            RETVAL_STRING("", 1);
        }
    }
}

#else

static php_output_handler *openrasp_output_handler_init(const char *handler_name, size_t handler_name_len, size_t chunk_size, int flags TSRMLS_DC);
static void openrasp_clean_output_start(const char *name, size_t name_len TSRMLS_DC);
static int openrasp_output_handler(void **nothing, php_output_context *output_context);

static int openrasp_output_handler(void **nothing, php_output_context *output_context)
{
    PHP_OUTPUT_TSRMLS(output_context);
    OUTPUT_G(output_detect) = true;
    int status = FAILURE;
    if (_is_content_type_html(TSRMLS_C) &&
        (output_context->op & PHP_OUTPUT_HANDLER_START) &&
        (output_context->op & PHP_OUTPUT_HANDLER_FINAL))
    {<commit_msg>[PHP5] fix 5.3 xss userinput<commit_after>/*
 * Copyright 2017-2018 Baidu Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "openrasp_output_detect.h"
#include "openrasp_hook.h"
#include "openrasp_ini.h"
#include "agent/shared_config_manager.h"
#include "utils/regex.h"

ZEND_DECLARE_MODULE_GLOBALS(openrasp_output_detect)

static void _check_header_content_type_if_html(void *data, void *arg TSRMLS_DC);
static int _detect_param_occur_in_html_output(const char *param, OpenRASPActionType action TSRMLS_DC);
static bool _gpc_parameter_filter(const zval *param TSRMLS_DC);
static bool _is_content_type_html(TSRMLS_D);

#if (PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION <= 3)

void openrasp_detect_output(INTERNAL_FUNCTION_PARAMETERS)
{
    OUTPUT_G(output_detect) = true;
    char *input;
    int input_len;
    long mode;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &input, &input_len, &mode) == FAILURE)
    {
        RETVAL_FALSE;
    }
    if (_is_content_type_html(TSRMLS_C))
    {
        OpenRASPActionType action = openrasp::scm->get_buildin_check_action(XSS_USER_INPUT);
        int status = _detect_param_occur_in_html_output(input, action TSRMLS_CC);
        if (status == SUCCESS)
        {
            status = (AC_BLOCK == action) ? SUCCESS : FAILURE;
        }
        if (status == SUCCESS)
        {
            reset_response(TSRMLS_C);
            RETVAL_STRING("", 1);
        }
    }
    RETVAL_STRINGL(input, input_len, 1);
}

#else

static php_output_handler *openrasp_output_handler_init(const char *handler_name, size_t handler_name_len, size_t chunk_size, int flags TSRMLS_DC);
static void openrasp_clean_output_start(const char *name, size_t name_len TSRMLS_DC);
static int openrasp_output_handler(void **nothing, php_output_context *output_context);

static int openrasp_output_handler(void **nothing, php_output_context *output_context)
{
    PHP_OUTPUT_TSRMLS(output_context);
    OUTPUT_G(output_detect) = true;
    int status = FAILURE;
    if (_is_content_type_html(TSRMLS_C) &&
        (output_context->op & PHP_OUTPUT_HANDLER_START) &&
        (output_context->op & PHP_OUTPUT_HANDLER_FINAL))
    {
{'fraction_non_alphanumeric': 0.09046362608367886, 'fraction_numerical': 0.006407840180927252, 'mean_word_length': 4.322968906720161, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5983848', 'n_tokens_mistral': 1834, 'n_tokens_neox': 1782, 'n_words': 429}