pax_global_header00006660000000000000000000000064151206602250014511gustar00rootroot0000000000000052 comment=0e77f38d0ddf1ee3445024a8d875413418636245 openresty-xss-nginx-module-0e77f38/000077500000000000000000000000001512066022500173255ustar00rootroot00000000000000openresty-xss-nginx-module-0e77f38/.gitattributes000066400000000000000000000000331512066022500222140ustar00rootroot00000000000000*.t linguist-language=Text openresty-xss-nginx-module-0e77f38/.gitignore000066400000000000000000000010451512066022500213150ustar00rootroot00000000000000*.mobi genmobi.sh .libs *.swp *.slo *.la *.swo *.lo *~ *.o print.txt .rsync *.tar.gz dist build[789] build build1[0-9] tags update-readme *.tmp test/Makefile test/blib test.sh go t/t.sh test/t/servroot/ releng reset *.t_ src/handler.h src/util.c src/module.h src/module.c src/drizzle.c src/processor.h src/handler.c src/util.h src/drizzle.h src/processor.c src/output.c src/output.h libdrizzle ctags src/stream.h nginx keepalive reindex src/module.h src/module.c src/util.h src/util.c src/util.rl all t/servroot/ buildroot/ build12 *.plist Makefile openresty-xss-nginx-module-0e77f38/.travis.yml000066400000000000000000000052251512066022500214420ustar00rootroot00000000000000sudo: required dist: focal branches: only: - "master" os: linux language: c compiler: gcc addons: apt: packages: [ axel, ragel, cpanminus, libtest-base-perl, libtext-diff-perl, liburi-perl, libwww-perl, libtest-longstring-perl, liblist-moreutils-perl ] cache: apt: true env: global: - LUAJIT_PREFIX=/opt/luajit21 - LUAJIT_LIB=$LUAJIT_PREFIX/lib - LD_LIBRARY_PATH=$LUAJIT_LIB:$LD_LIBRARY_PATH - LUAJIT_INC=$LUAJIT_PREFIX/include/luajit-2.1 - LUA_INCLUDE_DIR=$LUAJIT_INC - LUA_CMODULE_DIR=/lib - JOBS=3 - PCRE_VER=10.46 - OPENSSL_PREFIX=/usr/local/openresty/pcre2 - PCRE_LIB=$PCRE_PREFIX/lib - PCRE_INC=$PCRE_PREFIX/include - OPENSSL_PREFIX=/usr/local/openresty/openssl3 - OPENSSL_LIB=$OPENSSL_PREFIX/lib - OPENSSL_INC=$OPENSSL_PREFIX/include - NGX_BUILD_JOBS=$JOBS - TEST_NGINX_SLEEP=0.006 matrix: - NGINX_VERSION=1.29.4 OPENSSL_VER=3.5.4 install: - if [ ! -d download-cache ]; then mkdir download-cache; fi - git clone https://github.com/openresty/nginx-devel-utils.git - git clone https://github.com/openresty/openresty.git ../openresty - git clone https://github.com/openresty/lua-resty-core.git ../lua-resty-core - git clone https://github.com/openresty/lua-resty-lrucache.git ../lua-resty-lrucache - git clone https://github.com/openresty/no-pool-nginx.git ../no-pool-nginx - git clone https://github.com/simpl/ngx_devel_kit.git ../ndk-nginx-module - git clone https://github.com/openresty/test-nginx.git - git clone -b v2.1-agentzh https://github.com/openresty/luajit2.git - git clone https://github.com/openresty/lua-nginx-module.git ../lua-nginx-module - git clone https://github.com/openresty/echo-nginx-module.git ../echo-nginx-module - wget -O - https://openresty.org/package/pubkey.gpg | sudo apt-key add - - echo "deb http://openresty.org/package/ubuntu $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/openresty.list - sudo apt-get update - sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends openresty-pcre2 openresty-openssl3 openresty-pcre2-dev openresty-openssl3-dev script: - cd luajit2 - make -j$JOBS CCDEBUG=-g Q= PREFIX=$LUAJIT_PREFIX CC=$CC XCFLAGS='-DLUA_USE_APICHECK -DLUA_USE_ASSERT' > build.log 2>&1 || (cat build.log && exit 1) - sudo make install PREFIX=$LUAJIT_PREFIX > build.log 2>&1 || (cat build.log && exit 1) - cd ../test-nginx && sudo cpanm . && cd .. - export PATH=$PWD/work/nginx/sbin:$PWD/nginx-devel-utils:$PATH - export NGX_BUILD_CC=$CC - sh util/build.sh $NGINX_VERSION > build.log 2>&1 || (cat build.log && exit 1) - nginx -V - ldd `which nginx`|grep -E 'luajit|ssl' - prove -I. -r t openresty-xss-nginx-module-0e77f38/README.md000066400000000000000000000175511512066022500206150ustar00rootroot00000000000000Name ==== xss-nginx-module - Native cross-site scripting support in nginx Table of Contents ================= * [Name](#name) * [Synopsis](#synopsis) * [Description](#description) * [Directives](#directives) * [xss_get](#xss_get) * [xss_callback_arg](#xss_callback_arg) * [xss_override_status](#xss_override_status) * [xss_check_status](#xss_check_status) * [xss_input_types](#xss_input_types) * [Limitations](#limitations) * [Trouble Shooting](#trouble-shooting) * [Installation](#installation) * [Compatibility](#compatibility) * [TODO](#todo) * [Author](#author) * [Copyright & License](#copyright--license) * [See Also](#see-also) Synopsis ======== ```nginx # accessing /foo?callback=process gives the response # body "process(...);" (without quotes) where "..." # is the original response body of the /foo location. server { location /foo { # your content handler goes here... xss_get on; xss_callback_arg 'callback'; xss_input_types 'application/json'; # default xss_output_type 'application/x-javascript'; # default } ... } ``` Description =========== This module adds cross-site AJAX support to nginx. Currently only cross-site GET is supported. But cross-site POST will be added in the future. The cross-site GET is currently implemented as JSONP (or "JSON with padding"). See http://en.wikipedia.org/wiki/JSON#JSONP for more details. Directives ========== [Back to TOC](#table-of-contents) xss_get ------- **syntax:** *xss_get on | off* **default:** *xss_get off* **context:** *http, server, location, if location* Enables JSONP support for GET requests. [Back to TOC](#table-of-contents) xss_callback_arg ---------------- **syntax:** *xss_callback_arg <name>* **default:** *none* **context:** *http, http, location, if location* Specifies the JavaScript callback function name used in the responses. For example, ```nginx location /foo { xss_get on; xss_callback_arg c; ... } ``` then ``` GET /foo?c=blah ``` returns ```javascript blah(...); ``` [Back to TOC](#table-of-contents) xss_override_status ------------------- **syntax:** *xss_override_status on | off* **default:** *xss_check_status on* **context:** *http, server, location, if location* Specifies whether to override 30x, 40x and 50x status to 200 when the response is actually being processed. [Back to TOC](#table-of-contents) xss_check_status ----------------- **syntax:** *xss_check_status on | off* **default:** *xss_check_status on* **context:** *http, server, location, if location* By default, ngx_xss only process responses with the status code 200 or 201. [Back to TOC](#table-of-contents) xss_input_types --------------- **syntax:** *xss_input_types [mime-type]...* **default:** *xss_input_types application/json* **context:** *http, server, location, if location* Only processes the responses of the specified MIME types. Example: ```nginx xss_input_types application/json text/plain; ``` [Back to TOC](#table-of-contents) Limitations =========== * ngx_xss will not work with [ngx_echo](https://github.com/openresty/echo-nginx-module)'s subrequest interfaces, due to the underlying limitations imposed by subrequests' "postponed chain" mechanism in the nginx core. The standard ngx_addition module also falls into this category. You're recommended, however, to use [ngx_lua](https://github.com/openresty/lua-nginx-module) as the content handler to issue subrequests *and* ngx_xss to do JSONP, because [ngx_lua](https://github.com/openresty/lua-nginx-module)'s [ngx.location.capture()](https://github.com/openresty/lua-nginx-module#ngxlocationcapture) interface does not utilize the "postponed chain" mechanism, thus getting out of this limitation. We're taking this approach in production and it works great. [Back to TOC](#table-of-contents) Trouble Shooting ================ Use the "info" error log level (or lower) to get more diagnostics when things go wrong. [Back to TOC](#table-of-contents) Installation ============ You're recommended to install this module (as well as the Nginx core and many other goodies) via the [OpenResty bundle](http://openresty.org). See [the detailed instructions](http://openresty.org/#Installation) for downloading and installing OpenResty into your system. This is the easiest and most safe way to set things up. Alternatively, you can install this module manually with the Nginx source: Grab the nginx source code from [nginx.org](http://nginx.org/), for example, the version 1.13.6 (see [nginx compatibility](#compatibility)), and then build the source with this module: ```bash $ wget 'http://nginx.org/download/nginx-1.13.6.tar.gz' $ tar -xzvf nginx-1.13.6.tar.gz $ cd nginx-1.13.6/ # Here we assume you would install you nginx under /opt/nginx/. $ ./configure --prefix=/opt/nginx \ --add-module=/path/to/xss-nginx-module # Or --add-dynamic-module=../xss-nginx-module $ make -j2 $ make install ``` Download the latest version of the release tarball of this module from [xss-nginx-module file list](https://github.com/openresty/xss-nginx-module/tags). Also, this module is included and enabled by default in the [OpenResty bundle](http://openresty.org). [Back to TOC](#table-of-contents) Compatibility ============= The following versions of Nginx should work with this module: * **1.13.x** (last tested: 1.13.6) * **1.12.x** * **1.11.x** (last tested: 1.11.2) * **1.10.x** * **1.9.x** (last tested: 1.9.7) * **1.8.x** * **1.7.x** (last tested: 1.7.10) * **1.6.x** * **1.5.x** * **1.4.x** (last tested: 1.4.3) * **1.2.x** (last tested: 1.2.9) * **1.0.x** (last tested: 1.0.10) * **0.9.x** (last tested: 0.9.4) * **0.8.x** (last tested: 0.8.54) * **0.7.x** >= 0.7.30 (last tested: 0.7.67) Earlier versions of Nginx like 0.6.x and 0.5.x will *not* work. If you find that any particular version of Nginx above 0.7.30 does not work with this module, please consider reporting a bug. [Back to TOC](#table-of-contents) TODO ==== * add cross-site POST support. [Back to TOC](#table-of-contents) Author ====== Yichun "agentzh" Zhang (章亦春) <agentzh@gmail@com> [Back to TOC](#table-of-contents) Copyright & License =================== The implementation of the builtin connection pool has borrowed a lot of code from Maxim Dounin's upstream_keepalive module. This part of code is copyrighted by Maxim Dounin. This module is licenced under the BSD license. Copyright (C) 2009-2018 by Yichun "agentzh" Zhang (章亦春) <agentzh@gmail.com> OpenResty Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [Back to TOC](#table-of-contents) See Also ======== * [Introduction to JSONP](http://en.wikipedia.org/wiki/JSONP) * [ngx_lua](https://github.com/openresty/lua-nginx-module) [Back to TOC](#table-of-contents) openresty-xss-nginx-module-0e77f38/config000066400000000000000000000015411512066022500205160ustar00rootroot00000000000000ngx_addon_name=ngx_http_xss_filter_module # add dynamic module supported for NGINX v1.9.11 STUB_TYPE=HTTP_AUX_FILTER STUB_DEPS="$ngx_addon_dir/src/ddebug.h $ngx_addon_dir/src/ngx_http_xss_filter_module.h $ngx_addon_dir/src/ngx_http_xss_util.h" STUB_SRCS="$ngx_addon_dir/src/ngx_http_xss_filter_module.c $ngx_addon_dir/src/ngx_http_xss_util.c" STUB_INCS= STUB_LIBS= if test -n "$ngx_module_link"; then ngx_module_type="$STUB_TYPE" ngx_module_name="$ngx_addon_name" ngx_module_deps="$STUB_DEPS" ngx_module_srcs="$STUB_SRCS" ngx_module_incs="$STUB_INCS" ngx_module_libs="$STUB_LIBS" . auto/module else eval "$STUB_TYPE"'_MODULES="$'"$STUB_TYPE"'_MODULES $ngx_addon_name"' NGX_ADDON_DEPS="$NGX_ADDON_DEPS $STUB_DEPS" NGX_ADDON_SRCS="$NGX_ADDON_SRCS $STUB_SRCS" CORE_INCS="$CORE_INCS $STUB_INCS" CORE_LIBS="$CORE_LIBS $STUB_LIBS" fi openresty-xss-nginx-module-0e77f38/src/000077500000000000000000000000001512066022500201145ustar00rootroot00000000000000openresty-xss-nginx-module-0e77f38/src/ddebug.h000066400000000000000000000030701512066022500215170ustar00rootroot00000000000000#ifndef DDEBUG_H #define DDEBUG_H #include #include #if defined(DDEBUG) && (DDEBUG) # if (NGX_HAVE_VARIADIC_MACROS) # define dd(...) fprintf(stderr, "xss *** "); \ fprintf(stderr, __VA_ARGS__); \ fprintf(stderr, " at %s line %d.\n", __FILE__, __LINE__) # else #include #include #include static ngx_inline void dd(const char * fmt, ...) { } # endif #else # if (NGX_HAVE_VARIADIC_MACROS) # define dd(...) # else #include static ngx_inline void dd(const char * fmt, ...) { } # endif #endif #if defined(DDEBUG) && (DDEBUG) #define dd_check_read_event_handler(r) \ dd("r->read_event_handler = %s", \ r->read_event_handler == ngx_http_block_reading ? \ "ngx_http_block_reading" : \ r->read_event_handler == ngx_http_test_reading ? \ "ngx_http_test_reading" : \ r->read_event_handler == ngx_http_request_empty_handler ? \ "ngx_http_request_empty_handler" : "UNKNOWN") #define dd_check_write_event_handler(r) \ dd("r->write_event_handler = %s", \ r->write_event_handler == ngx_http_handler ? \ "ngx_http_handler" : \ r->write_event_handler == ngx_http_core_run_phases ? \ "ngx_http_core_run_phases" : \ r->write_event_handler == ngx_http_request_empty_handler ? \ "ngx_http_request_empty_handler" : "UNKNOWN") #else #define dd_check_read_event_handler(r) #define dd_check_write_event_handler(r) #endif #endif /* DDEBUG_H */ openresty-xss-nginx-module-0e77f38/src/ngx_http_xss_filter_module.c000066400000000000000000000315311512066022500257250ustar00rootroot00000000000000 /* * Copyright (C) agentzh */ #ifndef DDEBUG #define DDEBUG 0 #endif #include "ddebug.h" #include "ngx_http_xss_filter_module.h" #include "ngx_http_xss_util.h" #include #include #define ngx_http_xss_default_output_type "application/x-javascript" static ngx_str_t ngx_http_xss_default_types[] = { ngx_string("application/json"), ngx_null_string }; static void *ngx_http_xss_create_loc_conf(ngx_conf_t *cf); static char *ngx_http_xss_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child); static ngx_int_t ngx_http_xss_filter_init(ngx_conf_t *cf); static void *ngx_http_xss_create_main_conf(ngx_conf_t *cf); static char *ngx_http_xss_get(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static volatile ngx_cycle_t *ngx_http_xss_prev_cycle = NULL; static ngx_command_t ngx_http_xss_commands[] = { { ngx_string("xss_get"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF |NGX_HTTP_LIF_CONF|NGX_CONF_FLAG, ngx_http_xss_get, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_xss_loc_conf_t, get_enabled), NULL }, { ngx_string("xss_callback_arg"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF |NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_xss_loc_conf_t, callback_arg), NULL }, { ngx_string("xss_input_types"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF |NGX_CONF_1MORE|NGX_HTTP_LIF_CONF, ngx_http_types_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_xss_loc_conf_t, input_types_keys), &ngx_http_xss_default_types[0] }, { ngx_string("xss_check_status"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF |NGX_CONF_FLAG|NGX_HTTP_LIF_CONF, ngx_conf_set_flag_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_xss_loc_conf_t, check_status), NULL }, { ngx_string("xss_override_status"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF |NGX_CONF_FLAG|NGX_HTTP_LIF_CONF, ngx_conf_set_flag_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_xss_loc_conf_t, override_status), NULL }, { ngx_string("xss_output_type"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF |NGX_CONF_1MORE|NGX_HTTP_LIF_CONF, ngx_conf_set_str_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_xss_loc_conf_t, output_type), NULL }, ngx_null_command }; static ngx_http_module_t ngx_http_xss_filter_module_ctx = { NULL, /* preconfiguration */ ngx_http_xss_filter_init, /* postconfiguration */ ngx_http_xss_create_main_conf, /* create main configuration */ NULL, /* init main configuration */ NULL, /* create server configuration */ NULL, /* merge server configuration */ ngx_http_xss_create_loc_conf, /* create location configuration */ ngx_http_xss_merge_loc_conf /* merge location configuration */ }; ngx_module_t ngx_http_xss_filter_module = { NGX_MODULE_V1, &ngx_http_xss_filter_module_ctx, /* module context */ ngx_http_xss_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ NULL, /* exit process */ NULL, /* exit master */ NGX_MODULE_V1_PADDING }; static ngx_http_output_header_filter_pt ngx_http_next_header_filter; static ngx_http_output_body_filter_pt ngx_http_next_body_filter; static ngx_int_t ngx_http_xss_header_filter(ngx_http_request_t *r) { ngx_http_xss_ctx_t *ctx; ngx_http_xss_loc_conf_t *xlcf; ngx_str_t callback; u_char *p, *src, *dst; if (r != r->main) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "xss skipped in subrequests"); return ngx_http_next_header_filter(r); } xlcf = ngx_http_get_module_loc_conf(r, ngx_http_xss_filter_module); if (!xlcf->get_enabled) { return ngx_http_next_header_filter(r); } if (r->method != NGX_HTTP_GET) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "xss skipped due to the unmatched request method: %V", &r->method_name); return ngx_http_next_header_filter(r); } if (xlcf->check_status) { if (r->headers_out.status != NGX_HTTP_OK && r->headers_out.status != NGX_HTTP_CREATED) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "xss skipped due to unmatched response status " "\"%ui\"", r->headers_out.status); return ngx_http_next_header_filter(r); } } if (xlcf->callback_arg.len == 0) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "xss: xss_get is enabled but no xss_callback_arg " "specified"); return ngx_http_next_header_filter(r); } if (ngx_http_test_content_type(r, &xlcf->input_types) == NULL) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "xss skipped due to unmatched Content-Type response " "header"); return ngx_http_next_header_filter(r); } if (ngx_http_arg(r, xlcf->callback_arg.data, xlcf->callback_arg.len, &callback) != NGX_OK) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "xss skipped: no GET argument \"%V\" specified in " "the request", &xlcf->callback_arg); return ngx_http_next_header_filter(r); } p = ngx_palloc(r->pool, callback.len); if (p == NULL) { return NGX_ERROR; } src = callback.data; dst = p; ngx_unescape_uri(&dst, &src, callback.len, NGX_UNESCAPE_URI_COMPONENT); if (src != callback.data + callback.len) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "xss: unescape uri: input data not consumed completely"); return NGX_ERROR; } callback.data = p; callback.len = dst - p; if (ngx_http_xss_test_callback(callback.data, callback.len) != NGX_OK) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "xss: bad callback argument: \"%V\"", &callback); return ngx_http_next_header_filter(r); } ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_xss_ctx_t)); if (ctx == NULL) { return NGX_ERROR; } /* * set by ngx_pcalloc(): * * ctx->callback = { 0, NULL }; * ctx->before_body_sent = 0; */ ctx->callback = callback; ngx_http_set_ctx(r, ctx, ngx_http_xss_filter_module); r->headers_out.content_type = xlcf->output_type; r->headers_out.content_type_len = xlcf->output_type.len; r->headers_out.content_type_lowcase = NULL; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "xss output Content-Type header \"%V\"", &xlcf->output_type); ngx_http_clear_content_length(r); ngx_http_clear_accept_ranges(r); if (xlcf->override_status && r->headers_out.status >= NGX_HTTP_SPECIAL_RESPONSE) { r->headers_out.status = NGX_HTTP_OK; } return ngx_http_next_header_filter(r); } static ngx_int_t ngx_http_xss_body_filter(ngx_http_request_t *r, ngx_chain_t *in) { ngx_uint_t last; ngx_chain_t *cl, *orig_in; ngx_chain_t **ll = NULL; ngx_http_xss_ctx_t *ctx; size_t len; ngx_buf_t *b; if (in == NULL || r->header_only) { return ngx_http_next_body_filter(r, in); } ctx = ngx_http_get_module_ctx(r, ngx_http_xss_filter_module); if (ctx == NULL) { return ngx_http_next_body_filter(r, in); } orig_in = in; if (!ctx->before_body_sent) { ctx->before_body_sent = 1; dd("callback: %.*s", (int) ctx->callback.len, ctx->callback.data); len = ctx->callback.len + sizeof("(") - 1; b = ngx_create_temp_buf(r->pool, len); if (b == NULL) { return NGX_ERROR; } b->last = ngx_copy(b->last, ctx->callback.data, ctx->callback.len); *b->last++ = '('; cl = ngx_alloc_chain_link(r->pool); if (cl == NULL) { return NGX_ERROR; } cl->buf = b; cl->next = in; in = cl; } last = 0; for (cl = orig_in; cl; cl = cl->next) { if (cl->buf->last_buf) { cl->buf->last_buf = 0; cl->buf->sync = 1; ll = &cl->next; last = 1; } } if (last) { len = sizeof(");") - 1; b = ngx_create_temp_buf(r->pool, len); if (b == NULL) { return NGX_ERROR; } *b->last++ = ')'; *b->last++ = ';'; b->last_buf = 1; cl = ngx_alloc_chain_link(r->pool); if (cl == NULL) { return NGX_ERROR; } cl->buf = b; cl->next = NULL; *ll = cl; ngx_http_set_ctx(r, NULL, ngx_http_xss_filter_module); } return ngx_http_next_body_filter(r, in); } static ngx_int_t ngx_http_xss_filter_init(ngx_conf_t *cf) { int multi_http_blocks; ngx_http_xss_main_conf_t *xmcf; xmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_xss_filter_module); if (ngx_http_xss_prev_cycle != ngx_cycle) { ngx_http_xss_prev_cycle = ngx_cycle; multi_http_blocks = 0; } else { multi_http_blocks = 1; } if (multi_http_blocks || xmcf->requires_filter) { ngx_http_next_header_filter = ngx_http_top_header_filter; ngx_http_top_header_filter = ngx_http_xss_header_filter; ngx_http_next_body_filter = ngx_http_top_body_filter; ngx_http_top_body_filter = ngx_http_xss_body_filter; } return NGX_OK; } static void * ngx_http_xss_create_loc_conf(ngx_conf_t *cf) { ngx_http_xss_loc_conf_t *conf; conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_xss_loc_conf_t)); if (conf == NULL) { return NULL; } /* * set by ngx_pcalloc(): * * conf->callback_arg = { 0, NULL }; * conf->input_types = { NULL }; * conf->input_types_keys = NULL; * conf->output_type = { 0, NULL }; */ conf->get_enabled = NGX_CONF_UNSET; conf->check_status = NGX_CONF_UNSET; conf->override_status = NGX_CONF_UNSET; return conf; } static char * ngx_http_xss_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) { ngx_http_xss_loc_conf_t *prev = parent; ngx_http_xss_loc_conf_t *conf = child; ngx_conf_merge_str_value(conf->callback_arg, prev->callback_arg, ""); ngx_conf_merge_value(conf->get_enabled, prev->get_enabled, 0); ngx_conf_merge_value(conf->check_status, prev->check_status, 1); ngx_conf_merge_value(conf->override_status, prev->override_status, 1); #if defined(nginx_version) && nginx_version >= 8029 if (ngx_http_merge_types(cf, &conf->input_types_keys, &conf->input_types, &prev->input_types_keys, &prev->input_types, ngx_http_xss_default_types) != NGX_OK) #else /* 0.7.x or 0.8.x < 0.8.29 */ if (ngx_http_merge_types(cf, conf->input_types_keys, &conf->input_types, prev->input_types_keys, &prev->input_types, ngx_http_xss_default_types) != NGX_OK) #endif { return NGX_CONF_ERROR; } ngx_conf_merge_str_value(conf->output_type, prev->output_type, ngx_http_xss_default_output_type); return NGX_CONF_OK; } static void * ngx_http_xss_create_main_conf(ngx_conf_t *cf) { ngx_http_xss_main_conf_t *conf; conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_xss_main_conf_t)); if (conf == NULL) { return NULL; } /* set by ngx_pcalloc: * conf->requires_filter = 0; */ return conf; } static char * ngx_http_xss_get(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_xss_main_conf_t *xmcf; xmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_xss_filter_module); xmcf->requires_filter = 1; return ngx_conf_set_flag_slot(cf, cmd, conf); } openresty-xss-nginx-module-0e77f38/src/ngx_http_xss_filter_module.h000066400000000000000000000012141512066022500257250ustar00rootroot00000000000000#ifndef NGX_HTTP_XSS_FILTER_MODULE_H #define NGX_HTTP_XSS_FILTER_MODULE_H #include #include typedef struct { ngx_str_t callback_arg; ngx_hash_t input_types; ngx_array_t *input_types_keys; ngx_str_t output_type; ngx_flag_t get_enabled; ngx_flag_t check_status; ngx_flag_t override_status; } ngx_http_xss_loc_conf_t; typedef struct { ngx_int_t requires_filter; } ngx_http_xss_main_conf_t; typedef struct { ngx_str_t callback; ngx_flag_t before_body_sent; } ngx_http_xss_ctx_t; #endif /* NGX_HTTP_XSS_FILTER_MODULE_H */ openresty-xss-nginx-module-0e77f38/src/ngx_http_xss_util.c000066400000000000000000000051171512066022500240510ustar00rootroot00000000000000 #line 1 "src/ngx_http_xss_util.rl" /* * Copyright (C) agentzh */ #ifndef DDEBUG #define DDEBUG 0 #endif #include "ddebug.h" #include "ngx_http_xss_util.h" #line 16 "src/ngx_http_xss_util.rl" #line 21 "src/ngx_http_xss_util.c" static const char _javascript_key_offsets[] = { 0, 0, 6, 9, 11, 14, 18, 28 }; static const char _javascript_trans_keys[] = { 36, 95, 65, 90, 97, 122, 46, 48, 57, 48, 57, 93, 48, 57, 46, 93, 48, 57, 36, 46, 91, 95, 48, 57, 65, 90, 97, 122, 0 }; static const char _javascript_single_lengths[] = { 0, 2, 1, 0, 1, 2, 4, 0 }; static const char _javascript_range_lengths[] = { 0, 2, 1, 1, 1, 1, 3, 0 }; static const char _javascript_index_offsets[] = { 0, 0, 5, 8, 10, 13, 17, 25 }; static const char _javascript_trans_targs[] = { 6, 6, 6, 6, 0, 3, 5, 0, 4, 0, 7, 4, 0, 3, 7, 5, 0, 6, 1, 2, 6, 6, 6, 6, 0, 0, 0 }; static const int javascript_start = 1; #line 17 "src/ngx_http_xss_util.rl" ngx_int_t ngx_http_xss_test_callback(u_char *data, size_t len) { signed char *p = (signed char *) data; signed char *pe; int cs; pe = p + len; #line 70 "src/ngx_http_xss_util.c" { cs = javascript_start; } #line 75 "src/ngx_http_xss_util.c" { int _klen; const char *_keys; int _trans; if ( p == pe ) goto _test_eof; if ( cs == 0 ) goto _out; _resume: _keys = _javascript_trans_keys + _javascript_key_offsets[cs]; _trans = _javascript_index_offsets[cs]; _klen = _javascript_single_lengths[cs]; if ( _klen > 0 ) { const char *_lower = _keys; const char *_mid; const char *_upper = _keys + _klen - 1; while (1) { if ( _upper < _lower ) break; _mid = _lower + ((_upper-_lower) >> 1); if ( (*p) < *_mid ) _upper = _mid - 1; else if ( (*p) > *_mid ) _lower = _mid + 1; else { _trans += (unsigned int)(_mid - _keys); goto _match; } } _keys += _klen; _trans += _klen; } _klen = _javascript_range_lengths[cs]; if ( _klen > 0 ) { const char *_lower = _keys; const char *_mid; const char *_upper = _keys + (_klen<<1) - 2; while (1) { if ( _upper < _lower ) break; _mid = _lower + (((_upper-_lower) >> 1) & ~1); if ( (*p) < _mid[0] ) _upper = _mid - 2; else if ( (*p) > _mid[1] ) _lower = _mid + 2; else { _trans += (unsigned int)((_mid - _keys)>>1); goto _match; } } _trans += _klen; } _match: cs = _javascript_trans_targs[_trans]; if ( cs == 0 ) goto _out; if ( ++p != pe ) goto _resume; _test_eof: {} _out: {} } #line 38 "src/ngx_http_xss_util.rl" if (cs < 6 || p != pe) { return NGX_DECLINED; } return NGX_OK; } openresty-xss-nginx-module-0e77f38/src/ngx_http_xss_util.h000066400000000000000000000005771512066022500240630ustar00rootroot00000000000000#ifndef NGX_HTTP_XSS_UTIL_H #define NGX_HTTP_XSS_UTIL_H #include #include #ifndef ngx_copy_const_str #define ngx_copy_const_str(p, s) ngx_copy(p, s, sizeof(s) - 1) #endif #ifndef NGX_UNESCAPE_URI_COMPONENT #define NGX_UNESCAPE_URI_COMPONENT 0 #endif ngx_int_t ngx_http_xss_test_callback(u_char *data, size_t len); #endif /* NGX_HTTP_XSS_UTIL_H */ openresty-xss-nginx-module-0e77f38/src/ngx_http_xss_util.rl000066400000000000000000000013001512066022500242320ustar00rootroot00000000000000 /* * Copyright (C) agentzh */ #ifndef DDEBUG #define DDEBUG 0 #endif #include "ddebug.h" #include "ngx_http_xss_util.h" %% machine javascript; %% write data; ngx_int_t ngx_http_xss_test_callback(u_char *data, size_t len) { signed char *p = (signed char *) data; signed char *pe; int cs; pe = p + len; %%{ identifier = [$A-Za-z_] [$A-Za-z0-9_]*; index = [0-9]* '.' [0-9]+ | [0-9]+ ; main := identifier ( '.' identifier )* ('[' index ']')? ; write init; write exec; }%% if (cs < %%{ write first_final; }%% || p != pe) { return NGX_DECLINED; } return NGX_OK; } openresty-xss-nginx-module-0e77f38/t/000077500000000000000000000000001512066022500175705ustar00rootroot00000000000000openresty-xss-nginx-module-0e77f38/t/gzip.t000066400000000000000000000013521512066022500207270ustar00rootroot00000000000000# vi:filetype= use lib 'lib'; use Test::Nginx::Socket; repeat_each(2); plan tests => repeat_each() * (3 * blocks() + 1); #no_long_string(); log_level 'warn'; run_tests(); #no_diff(); __DATA__ === TEST 1: xss_get is on while no xss_callback_arg & xss_output_type --- config xss_get on; # enable cross-site GET support xss_callback_arg c; # use $arg_callback gzip on; gzip_types application/json application/x-javascript; location /foo { default_type "application/json"; echo -n '{"cat":32}'; } --- more_headers Accept-Encoding: gzip --- request GET /foo?c=blah --- response_headers Content-Type: application/x-javascript Content-Encoding: gzip --- response_body_like eval "\x{00}\x{00}\x{00}" openresty-xss-nginx-module-0e77f38/t/sanity.t000066400000000000000000000131101512066022500212600ustar00rootroot00000000000000# vi:filetype= use lib 'lib'; use Test::Nginx::Socket; repeat_each(1); plan tests => repeat_each() * 3 * blocks(); no_long_string(); run_tests(); #no_diff(); __DATA__ === TEST 1: skipped: no callback arg given --- config location /foo { default_type 'application/json'; xss_get on; xss_callback_arg foo; echo '[]'; } --- request GET /foo --- response_headers_like Content-Type: application/json --- response_body [] === TEST 2: sanity --- config location /foo { default_type 'application/json'; xss_get on; xss_callback_arg a; echo '[]'; } --- request GET /foo?foo=blar&a=bar --- response_headers_like Content-Type: application/x-javascript --- response_body chop bar([] ); === TEST 3: bug --- config location /foo { default_type 'application/json'; xss_get on; xss_callback_arg foo; echo '[]'; } --- request GET /foo?foo=bar --- response_headers_like Content-Type: application/x-javascript --- response_body chop bar([] ); === TEST 4: uri escaped --- config location /foo { default_type 'application/json'; xss_get on; xss_callback_arg _callback; echo '[]'; } --- request GET /foo?_callback=OpenResty.callbackMap%5b32%5D --- response_headers_like Content-Type: application/x-javascript --- response_body chop OpenResty.callbackMap[32]([] ); === TEST 5: test invalid callback --- config location /foo { default_type 'application/json'; xss_get on; xss_callback_arg _callback; echo '[]'; } --- request GET /foo?_callback=a();b --- response_headers_like Content-Type: application/json --- response_body [] --- error_code: 200 === TEST 6: input type mismatch --- config location /foo { default_type 'text/plain'; xss_get on; xss_callback_arg foo; echo '[]'; } --- request GET /foo?foo=bar --- response_headers_like Content-Type: text/plain --- response_body [] === TEST 7: input type match by setting xss_input_types --- config location /foo { default_type 'text/plain'; xss_get on; xss_callback_arg foo; xss_input_types text/plain text/css; echo '[]'; } --- request GET /foo?foo=bar --- response_headers_like Content-Type: application/x-javascript --- response_body chop bar([] ); === TEST 8: set a different output type --- config location /foo { default_type 'text/plain'; xss_get on; xss_callback_arg foo; xss_input_types text/plain text/css; xss_output_type text/html; echo '[]'; } --- request GET /foo?foo=bar --- response_headers_like Content-Type: text/html --- response_body chop bar([] ); === TEST 9: xss_get is on while no xss_callback_arg --- config location /foo { default_type 'application/json'; xss_get on; #xss_callback_arg foo; echo '[]'; } --- request GET /foo?foo=bar --- response_headers_like Content-Type: application/json --- response_body [] === TEST 10: xss_get is on while no xss_callback_arg --- config location /foo { default_type "application/json"; echo '{"errcode":400,"errstr":"Bad Request"}'; xss_get on; # enable cross-site GET support xss_callback_arg callback; # use $arg_callback } --- request GET /foo?callback=blah --- response_headers Content-Type: application/x-javascript --- response_body chop blah({"errcode":400,"errstr":"Bad Request"} ); === TEST 11: xss_get is on while no xss_callback_arg & xss_output_type --- config location /foo { default_type "application/json"; echo '{"errcode":400,"errstr":"Bad Request"}'; xss_get on; # enable cross-site GET support xss_callback_arg callback; # use $arg_callback xss_output_type text/javascript; } --- request GET /foo?callback=blah --- response_headers Content-Type: text/javascript --- response_body chop blah({"errcode":400,"errstr":"Bad Request"} ); === TEST 12: check status and override status --- config location /foo { xss_get on; xss_callback_arg c; xss_check_status off; default_type application/json; content_by_lua ' ngx.status = 404 ngx.print("hello") '; } --- request GET /foo?c=blah --- response_body chop blah(hello); --- error_code: 200 --- response_headers Content-Type: application/x-javascript === TEST 13: check status and NO override status --- config location /foo { xss_get on; xss_callback_arg c; xss_override_status off; xss_check_status off; default_type application/json; content_by_lua ' ngx.status = 404 ngx.print("hello") '; } --- request GET /foo?c=blah --- response_body chop blah(hello); --- error_code: 404 --- response_headers Content-Type: application/x-javascript === TEST 14: bug: keys started by underscore --- config location /foo { default_type 'application/json'; xss_get on; xss_callback_arg _callback; echo '[]'; } --- request GET /foo?_callback=foo._bar --- response_headers_like Content-Type: application/x-javascript --- response_body chop foo._bar([] ); === TEST 15: exec --- config location /foo { default_type "application/json"; echo -n hello world; xss_get on; xss_callback_arg _c; } location /lua { echo_exec /foo $args; } --- request GET /lua?_c=bah --- response_headers Content-Type: application/x-javascript --- response_body chop bah(hello world); openresty-xss-nginx-module-0e77f38/t/unused.t000066400000000000000000000032131512066022500212570ustar00rootroot00000000000000# vi:filetype= use lib 'lib'; use Test::Nginx::Socket; repeat_each(2); plan tests => repeat_each() * (4 * blocks()); #no_long_string(); log_level 'warn'; run_tests(); #no_diff(); __DATA__ === TEST 1: used --- config location = /t { echo hello; xss_get on; xss_callback_arg c; } --- more_headers Accept-Encoding: gzip --- request GET /t --- stap F(ngx_http_xss_header_filter) { println("xss header filter") } F(ngx_http_xss_body_filter) { println("xss body filter") } --- stap_out xss header filter xss body filter xss body filter --- response_body hello --- no_error_log [error] === TEST 2: not used --- config location = /t { echo hello; } --- more_headers Accept-Encoding: gzip --- request GET /t --- stap F(ngx_http_xss_header_filter) { println("xss header filter") } F(ngx_http_xss_body_filter) { println("xss body filter") } --- stap_out --- response_body hello --- no_error_log [error] === TEST 3: used (multiple http {} blocks) This test case won't run with nginx 1.9.3+ since duplicate http {} blocks have been prohibited since then. --- SKIP --- config location = /t { default_type application/json; xss_callback_arg 'callback'; echo -n hello; xss_get on; } --- more_headers Accept-Encoding: gzip --- request GET /t?callback=foo --- stap F(ngx_http_xss_header_filter) { println("xss header filter") } F(ngx_http_xss_body_filter) { println("xss body filter") } --- stap_out xss header filter xss body filter xss body filter --- post_main_config http { } --- response_body chop foo(hello); --- no_error_log [error] openresty-xss-nginx-module-0e77f38/util/000077500000000000000000000000001512066022500203025ustar00rootroot00000000000000openresty-xss-nginx-module-0e77f38/util/build.sh000077500000000000000000000023151512066022500217410ustar00rootroot00000000000000#!/bin/bash # this file is mostly meant to be used by the author himself. ragel -T1 src/ngx_http_xss_util.rl || exit 1 if [ $? != 0 ]; then echo 'Failed to generate the ngx_http_xss_util.c.' 1>&2 exit 1; fi ./util/fix-clang-warnings || exit 1 root=`pwd` version=$1 force=$2 ngx-build $force $version \ --with-cc-opt="-I$PCRE_INC -I$OPENSSL_INC" \ --with-ld-opt="-L$PCRE_LIB -L$OPENSSL_LIB -Wl,-rpath,$PCRE_LIB:$OPENSSL_LIB" \ --with-http_ssl_module \ --without-mail_pop3_module \ --without-mail_imap_module \ --without-mail_smtp_module \ --without-http_upstream_ip_hash_module \ --without-http_empty_gif_module \ --without-http_memcached_module \ --without-http_referer_module \ --without-http_autoindex_module \ --without-http_auth_basic_module \ --without-http_userid_module \ --add-module=../echo-nginx-module \ --add-module=../ndk-nginx-module \ --add-module=../lua-nginx-module \ --add-module=$root $opts \ --with-debug #--with-cc-opt="-g3 -O0" #--add-module=$root/../echo-nginx-module \ #--without-http_ssi_module # we cannot disable ssi because echo_location_async depends on it (i dunno why?!) openresty-xss-nginx-module-0e77f38/util/fix-clang-warnings000077500000000000000000000022411512066022500237250ustar00rootroot00000000000000#!/usr/bin/env perl use strict; use warnings; use File::Temp 'tempfile'; my $infile = "src/ngx_http_xss_util.c"; my ($out, $outfile) = tempfile(); open my $in, $infile or die "Cannot open $infile for reading: $!\n"; my $hits = 0; while (<$in>) { if (/ \b javascript_ (?: en_main | error | first_final ) \b /x) { #warn "HIT!"; $hits++; next; } print $out $_; } close $in; close $out; if ($hits) { my $cmd = "cp $outfile $infile"; system($cmd) == 0 or die "Cannot run command \"$cmd\": $!"; } #die; __END__ This script is to fix the following clang warnings when using Ragel 6.8/6.9/etc: rc/ngx_http_xss_util.c:22:18: error: unused variable 'javascript_first_final' [-Werror,-Wunused-const-variable] static const int javascript_first_final = 6; ^ src/ngx_http_xss_util.c:23:18: error: unused variable 'javascript_error' [-Werror,-Wunused-const-variable] static const int javascript_error = 0; ^ src/ngx_http_xss_util.c:25:18: error: unused variable 'javascript_en_main' [-Werror,-Wunused-const-variable] static const int javascript_en_main = 1; ^ 3 errors generated. openresty-xss-nginx-module-0e77f38/util/update-readme.sh000077500000000000000000000001421512066022500233530ustar00rootroot00000000000000#!/bin/bash perl util/wiki2pod.pl doc/manpage.wiki > /tmp/a.pod && pod2text /tmp/a.pod > README openresty-xss-nginx-module-0e77f38/util/wiki2pod.pl000066400000000000000000000060641512066022500223750ustar00rootroot00000000000000#!/usr/bin/env perl use strict; use warnings; use bytes; my @nl_counts; my $last_nl_count_level; my @bl_counts; my $last_bl_count_level; sub fmt_pos ($) { (my $s = $_[0]) =~ s{\#(.*)}{/"$1"}; $s; } sub fmt_mark ($$) { my ($tag, $s) = @_; my $max_level = 0; while ($s =~ /([<>])\1*/g) { my $level = length $&; if ($level > $max_level) { $max_level = $level; } } my $times = $max_level + 1; if ($times > 1) { $s = " $s "; } return $tag . ('<' x $times) . $s . ('>' x $times); } print "=encoding utf-8\n\n"; while (<>) { if ($. == 1) { # strip the leading U+FEFF byte in MS-DOS text files my $first = ord(substr($_, 0, 1)); #printf STDERR "0x%x", $first; #my $second = ord(substr($_, 2, 1)); #printf STDERR "0x%x", $second; if ($first == 0xEF) { substr($_, 0, 1, ''); #warn "Hit!"; } } s{\[(http[^ \]]+) ([^\]]*)\]}{$2 (L<$1>)}gi; s{ \[\[ ( [^\]\|]+ ) \| ([^\]]*) \]\] }{"L<$2|" . fmt_pos($1) . ">"}gixe; s{(.*?)}{fmt_mark('C', $1)}gie; s{'''(.*?)'''}{fmt_mark('B', $1)}ge; s{''(.*?)''}{fmt_mark('I', $1)}ge; if (s{^\s*<[^>]+>\s*$}{}) { next; } if (/^\s*$/) { print "\n"; next; } =begin cmt if ($. == 1) { warn $_; for my $i (0..length($_) - 1) { my $chr = substr($_, $i, 1); warn "chr ord($i): ".ord($chr)." \"$chr\"\n"; } } =end cmt =cut if (/(=+) (.*) \1$/) { #warn "HERE! $_" if $. == 1; my ($level, $title) = (length $1, $2); collapse_lists(); print "\n=head$level $title\n\n"; } elsif (/^(\#+) (.*)/) { my ($level, $txt) = (length($1) - 1, $2); if (defined $last_nl_count_level && $level != $last_nl_count_level) { print "\n=back\n\n"; } $last_nl_count_level = $level; $nl_counts[$level] ||= 0; if ($nl_counts[$level] == 0) { print "\n=over\n\n"; } $nl_counts[$level]++; print "\n=item $nl_counts[$level].\n\n"; print "$txt\n"; } elsif (/^(\*+) (.*)/) { my ($level, $txt) = (length($1) - 1, $2); if (defined $last_bl_count_level && $level != $last_bl_count_level) { print "\n=back\n\n"; } $last_bl_count_level = $level; $bl_counts[$level] ||= 0; if ($bl_counts[$level] == 0) { print "\n=over\n\n"; } $bl_counts[$level]++; print "\n=item *\n\n"; print "$txt\n"; } else { collapse_lists(); print; } } collapse_lists(); sub collapse_lists { while (defined $last_nl_count_level && $last_nl_count_level >= 0) { print "\n=back\n\n"; $last_nl_count_level--; } undef $last_nl_count_level; undef @nl_counts; while (defined $last_bl_count_level && $last_bl_count_level >= 0) { print "\n=back\n\n"; $last_bl_count_level--; } undef $last_bl_count_level; undef @bl_counts; } openresty-xss-nginx-module-0e77f38/valgrind.suppress000066400000000000000000000043671512066022500227530ustar00rootroot00000000000000{ Memcheck:Addr4 fun:ngx_init_cycle fun:ngx_master_process_cycle fun:main } { Memcheck:Leak fun:malloc fun:ngx_calloc fun:ngx_event_process_init } { Memcheck:Leak fun:malloc fun:ngx_alloc fun:ngx_event_process_init } { Memcheck:Param epoll_ctl(event) fun:epoll_ctl } { Memcheck:Cond fun:ngx_conf_flush_files } { nginx-core-process-init Memcheck:Leak fun:malloc fun:ngx_alloc fun:ngx_event_process_init } { nginx-core-crc32-init Memcheck:Leak fun:malloc fun:ngx_alloc fun:ngx_crc32_table_init fun:main } { palloc_large_for_init_request Memcheck:Leak fun:malloc fun:ngx_alloc fun:ngx_palloc_large fun:ngx_palloc fun:ngx_pcalloc fun:ngx_http_init_request fun:ngx_epoll_process_events fun:ngx_process_events_and_timers } { palloc_large_for_create_temp_buf Memcheck:Leak fun:malloc fun:ngx_alloc fun:ngx_palloc_large fun:ngx_palloc fun:ngx_create_temp_buf fun:ngx_http_init_request fun:ngx_epoll_process_events fun:ngx_process_events_and_timers } { accept_create_pool Memcheck:Leak fun:memalign fun:posix_memalign fun:ngx_memalign fun:ngx_create_pool fun:ngx_event_accept fun:ngx_epoll_process_events fun:ngx_process_events_and_timers } { create_pool_for_init_req Memcheck:Leak fun:memalign fun:posix_memalign fun:ngx_memalign fun:ngx_create_pool fun:ngx_http_init_request fun:ngx_epoll_process_events fun:ngx_process_events_and_timers } { Memcheck:Cond fun:index fun:expand_dynamic_string_token fun:_dl_map_object fun:map_doit fun:_dl_catch_error fun:do_preload fun:dl_main } { Memcheck:Leak match-leak-kinds: definite fun:malloc fun:ngx_alloc fun:ngx_set_environment fun:ngx_single_process_cycle } { Memcheck:Leak match-leak-kinds: definite fun:malloc fun:ngx_alloc fun:ngx_set_environment fun:ngx_worker_process_init fun:ngx_worker_process_cycle }