Azure / Azure/app-service-linux-docs
Malicious script injection via DiagServer process in Azure App Service Linux Node.js 20 container image
- 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