Skip to content

plugin: detect low keepalive_requests #37

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
211 changes: 0 additions & 211 deletions README.md

This file was deleted.

1 change: 1 addition & 0 deletions README.md
94 changes: 75 additions & 19 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,43 @@ GIXY
[![GitHub issues](https://img.shields.io/github/issues/dvershinin/gixy.svg?style=flat-square)](https://github.com/dvershinin/gixy/issues)
[![GitHub pull requests](https://img.shields.io/github/issues-pr/dvershinin/gixy.svg?style=flat-square)](https://github.com/dvershinin/gixy/pulls)

> [!TIP]
> This is an **actively maintained fork** of the original [Gixy](https://github.com/yandex/gixy) project by **Yandex LLC**.

# Overview
<img style="float: right;" width="192" height="192" src="gixy.png" alt="Gixy logo">
<img align="right" width="192" height="192" src="docs/gixy.png">

Gixy is a tool to analyze Nginx configuration.
Gixy is a tool to analyze NGINX configuration.
The main goal of Gixy is to prevent security misconfiguration and automate flaw detection.

Currently supported Python versions are 3.6 through 3.13.

Disclaimer: Gixy is well tested only on GNU/Linux, other OSs may have some issues.

# What it can do

Right now Gixy can find:

* [[ssrf] Server Side Request Forgery](en/plugins/ssrf.md)
* [[http_splitting] HTTP Splitting](en/plugins/httpsplitting.md)
* [[origins] Problems with referrer/origin validation](en/plugins/origins.md)
* [[add_header_redefinition] Redefining of response headers by "add_header" directive](en/plugins/addheaderredefinition.md)
* [[host_spoofing] Request's Host header forgery](en/plugins/hostspoofing.md)
* [[valid_referrers] none in valid_referers](en/plugins/validreferers.md)
* [[add_header_multiline] Multiline response headers](en/plugins/addheadermultiline.md)
* [[alias_traversal] Path traversal via misconfigured alias](en/plugins/aliastraversal.md)
* [[if_is_evil] If is evil when used in location context](en/plugins/if_is_evil.md)
* [[allow_without_deny] Allow specified without deny](en/plugins/allow_without_deny.md)
* [[add_header_content_type] Setting Content-Type via add_header](en/plugins/add_header_content_type.md)
* [[ssrf] Server Side Request Forgery](https://github.com/dvershinin/gixy/blob/master/docs/en/plugins/ssrf.md)
* [[http_splitting] HTTP Splitting](https://github.com/dvershinin/gixy/blob/master/docs/en/plugins/httpsplitting.md)
* [[origins] Problems with referrer/origin validation](https://github.com/dvershinin/gixy/blob/master/docs/en/plugins/origins.md)
* [[add_header_redefinition] Redefining of response headers by "add_header" directive](https://github.com/dvershinin/gixy/blob/master/docs/en/plugins/addheaderredefinition.md)
* [[host_spoofing] Request's Host header forgery](https://github.com/dvershinin/gixy/blob/master/docs/en/plugins/hostspoofing.md)
* [[valid_referers] none in valid_referers](https://github.com/dvershinin/gixy/blob/master/docs/en/plugins/validreferers.md)
* [[add_header_multiline] Multiline response headers](https://github.com/dvershinin/gixy/blob/master/docs/en/plugins/addheadermultiline.md)
* [[alias_traversal] Path traversal via misconfigured alias](https://github.com/dvershinin/gixy/blob/master/docs/en/plugins/aliastraversal.md)
* [[if_is_evil] If is evil when used in location context](https://github.com/dvershinin/gixy/blob/master/docs/en/plugins/if_is_evil.md)
* [[allow_without_deny] Allow specified without deny](https://github.com/dvershinin/gixy/blob/master/docs/en/plugins/allow_without_deny.md)
* [[add_header_content_type] Setting Content-Type via add_header](https://github.com/dvershinin/gixy/blob/master/docs/en/plugins/add_header_content_type.md)
* [[resolver_external] Using external DNS nameservers](https://blog.zorinaq.com/nginx-resolver-vulns/)
* [[version_disclosure] Using insecure values for server_tokens](en/plugins/version_disclosure.md)
* [[proxy_pass_normalized] Using proxy_pass with a pathname will normalize and decode the requested path when proxying](https://joshua.hu/proxy-pass-nginx-decoding-normalizing-url-path-dangerous#nginx-proxy_pass)
* [[version_disclosure] Using insecure values for server_tokens](https://github.com/dvershinin/gixy/blob/master/docs/en/plugins/version_disclosure.md)
* [[try_files_is_evil_too] The `try_files` directive is evil without open_file_cache](https://www.getpagespeed.com/server-setup/nginx-try_files-is-evil-too)
* [[proxy_pass_normalized] `proxy_pass` will decode and normalize paths when specified with a path](https://joshua.hu/proxy-pass-nginx-decoding-normalizing-url-path-dangerous#nginx-proxy_pass)
* [[worker_rlimit_nofile_vs_connections] `worker_rlimit_nofile` must be at least twice `worker_connections`](https://gixy.getpagespeed.com/en/plugins/worker_rlimit_nofile_vs_connections/)
* [[error_log_off] `error_log` set to `off`](https://gixy.getpagespeed.com/en/plugins/error_log_off/)
* [[unanchored_regex] Regular expression without anchors](https://gixy.getpagespeed.com/en/plugins/unanchored_regex/)
* [[regex_redos] Regular expressions may result in easy denial-of-service (ReDoS) attacks](https://joshua.hu/regex-redos-recheck-nginx-gixy)
* [[low_keepalive_requests] `keepalive_requests` below 1000](https://joshua.hu/http2-burp-proxy-mitmproxy-nginx-failing-load-resources-chromium#nginx-keepalive_requests)

You can find things that Gixy is learning to detect at [Issues labeled with "new plugin"](https://github.com/dvershinin/gixy/issues?q=is%3Aissue+is%3Aopen+label%3A%22new+plugin%22)

Expand All @@ -60,17 +69,17 @@ gixy

# Usage

By default, Gixy will try to analyze Nginx configuration placed in `/etc/nginx/nginx.conf`.
By default, Gixy will try to analyze NGINX configuration placed in `/etc/nginx/nginx.conf`.

But you can always specify needed path:
But you can always specify the needed path:
```
$ gixy /etc/nginx/nginx.conf

==================== Results ===================

Problem: [http_splitting] Possible HTTP-Splitting vulnerability.
Description: Using variables that can contain "\n" may lead to http injection.
Additional info: https://github.com/dvershinin/gixy/blob/master/docs/ru/plugins/httpsplitting.md
Additional info: https://github.com/dvershinin/gixy/blob/master/docs/en/plugins/httpsplitting.md
Reason: At least variable "$action" can contain "\n"
Pseudo config:
include /etc/nginx/sites/default.conf;
Expand Down Expand Up @@ -142,6 +151,53 @@ Total issues:
High: 0

```
## Kubernetes usage
Given you are using the official NGINX ingress controller, not the kubernetes one, you can use this
https://github.com/nginx/kubernetes-ingress

```
kubectl exec -it my-release-nginx-ingress-controller-54d96cb5cd-pvhx5 -- /bin/bash -c "cat /etc/nginx/conf.d/*" | docker run -i getpagespeed/gixy -
```

```
==================== Results ===================

>> Problem: [version_disclosure] Do not enable server_tokens on or server_tokens build
Severity: HIGH
Description: Using server_tokens on; or server_tokens build; allows an attacker to learn the version of NGINX you are running, which can be used to exploit known vulnerabilities.
Additional info: https://gixy.getpagespeed.com/en/plugins/version_disclosure/
Reason: Using server_tokens value which promotes information disclosure
Pseudo config:

server {
server_name XXXXX.dev;
server_tokens on;
}

server {
server_name XXXXX.dev;
server_tokens on;
}

server {
server_name XXXXX.dev;
server_tokens on;
}

server {
server_name XXXXX.dev;
server_tokens on;
}

==================== Summary ===================
Total issues:
Unspecified: 0
Low: 0
Medium: 0
High: 4

```


# Contributing
Contributions to Gixy are always welcome! You can help us in different ways:
Expand All @@ -151,4 +207,4 @@ Contributions to Gixy are always welcome! You can help us in different ways:

Code guidelines:
* Python code style should follow [pep8](https://www.python.org/dev/peps/pep-0008/) standards whenever possible;
* Pull requests with new plugins must have unit tests for them.
* Pull requests with new plugins must have unit tests for it.
6 changes: 2 additions & 4 deletions gixy/plugins/error_log_off.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Module for try_files_is_evil_too plugin."""
"""Module for error_log_off plugin."""

import gixy
from gixy.plugins.plugin import Plugin
Expand All @@ -7,9 +7,7 @@
class error_log_off(Plugin):
"""
Insecure example:
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
error_log off;
"""

summary = "The error_log directive does not take the off parameter."
Expand Down
25 changes: 25 additions & 0 deletions gixy/plugins/low_keepalive_requests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"""Module for low_keepalive_requests plugin."""

import gixy
from gixy.plugins.plugin import Plugin


class low_keepalive_requests(Plugin):
"""
Insecure example:
keepalive_requests 100;
"""

summary = "The keepalive_requests directive should be at least 1000."
severity = gixy.severity.LOW
description = "The keepalive_requests directive should be at least 1000. Any value lower than this may result in client disconnections."
help_url = "https://joshua.hu/http2-burp-proxy-mitmproxy-nginx-failing-load-resources-chromium#nginx-keepalive_requests"
directives = ["keepalive_requests"]

def audit(self, directive):
if int(directive.args[0]) < 1000:
self.add_issue(
severity=self.severity,
directive=[directive],
reason="The keepalive_requests directive should be at least 1000.",
)
Loading