Azure / Azure/app-service-linux-docs

Malicious script injection via DiagServer process in Azure App Service Linux Node.js 20 container image

Open
#260 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
150
Forks
90
Avg merge
2m
Merged PRs (30d)
1

Description

I discovered a malicious process running inside my Azure App Service Linux container (Node.js 20, runtime version 20.20.0) that was intercepting HTTP responses and injecting a JavaScript popunder script into all served HTML pages.
What I found:

A binary at /diagServer/DiagServer (43MB, dated May 29, 2024) was running as a background process, acting as a reverse proxy that injected into the of all served HTML responses
A launcher script at /run-diag.sh (dated Jan 15, 2025) started the DiagServer binary
A cron job at /etc/cron.d/diag-cron ran /run-diag.sh every 5 minutes to ensure persistence
The injected min.js script was a popunder that opened background browser tabs to a crypto casino site (jsx-7jp.pages.dev/index1) on user click, limited to 2 times per week per visitor using localStorage

How I confirmed it:

The malicious script tag was not present in my source code, local build output, or deployed files
The script tag appeared in HTML responses served to browsers (confirmed in incognito with no extensions)
Killing the DiagServer process and redeploying with clean files removed the injection
The DiagServer and cron job respawned on every container restart because they are part of the container image
Switching from Node.js 20 to Node.js 22 resolved the issue, confirming it was specific to the Node 20 container image

Environment:

Azure App Service Linux
Node.js 20 (v20.20.0, npm 10.9.2)
Debian GNU/Linux 12 (bookworm)
Resource group: meander-homepage
Region: East US 2

Impact: All visitors to my site were served malicious JavaScript that opened crypto casino popunders in background tabs. The attack was designed to be stealthy — limited frequency, background tab opening with blur/focus tricks to avoid detection.
Mitigation: Switching to Node.js 22 runtime resolved the issue. A startup command workaround (rm -f /run-diag.sh /etc/cron.d/diag-cron && kill $(pgrep -f DiagServer)) was also effective.

Contributor guide

No contributing guide indexed for this repository

Research direction

Inspect the Node.js 20 container image for /diagServer/DiagServer, /run-diag.sh, and /etc/cron.d/diag-cron, then compare its startup behavior with the Node.js 22 image. Reproduce the report using the documented process and HTML-response checks; done means the image no longer starts the reported process or injects scripts after restart.

Written by the indexing model from the issue text.

Assessment

Tech stack
azure, debian, linux, node.js
Domain
cloud, infrastructure, security
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.