PageSourceSearch

https://paul.reviews/harmblock-worlds-safest-smartphone-please-rotate-responsibly/

html paul.reviews collected 2026-09-25 21:15:37 UTC 120,214 bytes, 1,201 lines download raw bytes

1
2<!DOCTYPE html>
3<html lang="en" data-color-scheme="light" dir="ltr">
4  <head>
5    <title>HarmBlock+ World&#x27;s Safest Smartphone: Please Rotate Responsibly.</title>
6    <meta charset="utf-8">
7    <meta name="viewport" content="width=device-width, initial-scale=1.0">
8    <meta name="view-transition" content="same-origin"> 
9    
10    
11<link rel="preconnect" href="https://fonts.bunny.net" crossorigin>
12<link rel="stylesheet" href="https://fonts.bunny.net/css?family=inter:100,200,300,400,500,600,700,800,900,100i,200i,300i,400i,500i,600i,700i,800i,900i
13&display=swap">
14<link rel="stylesheet" href="https://fonts.bunny.net/css?family=fira-sans:100,200,300,400,500,600,700,800,900,100i,200i,300i,400i,500i,600i,700i,800i,900i
15&display=swap">
16
17
18<style>
19  :root {
20    --color-accent: #d70947;
21    --cover-image: url(https://paul.reviews/content/images/2019/10/20190524_001312.jpg);
22    --font-heading: var(--gh-font-heading, "Inter");
23    --font-body: var(--gh-font-body, "Fira Sans");
24    --post-card-image-aspect-ratio: 16/9;
25    --radius-card: 12px;
26  }
27</style>
28
29<script>
30  window.themeConfig = {
31    colorScheme: "light",
32    site: {
33      url: "https://paul.reviews",
34      title: "Paul Moore: Information Security Consultant &amp; Researcher",
35      description: "Paul Moore: Information Security Consultant &amp; Researcher",
36      accentColor: "#d70947",
37      icon: "https://paul.reviews/content/images/2026/09/fnNCyHOc_400x400-2.jpg",
38      facebook: "",
39      twitter: "@paul_reviews",
40      primaryNavigation: [
41          {
42            label: "Home",
43            url: "https://paul.reviews"
44          },
45          {
46            label: "Twitter",
47            url: "https://twitter.com/paul_reviews"
48          },
49          {
50            label: "Email Me",
51            url: "mailto:[email protected]"
52          },
53      ],
54      secondaryNavigation: [
55      ]
56    }
57  }
58</script>
58
59
60
61    <link rel="stylesheet" type="text/css" href="/assets/build/style.css?v=cuOq2iyAg7cq-yFD">
62    <link rel="manifest" data-manifest />
63
64    
64<script type="module" src="/assets/build/main.js?v=Z7T24uSJU1BXpjis"></script>
64
65
66    <meta name="description" content="An independent review of the HMD Fuse, marketed as the World&#x27;s Safest Smartphone.">
67    <link rel="icon" href="https://paul.reviews/content/images/size/w256h256/format/jpeg/2026/09/fnNCyHOc_400x400-2.jpg" type="image/jpeg">
68    <link rel="canonical" href="https://paul.reviews/harmblock-worlds-safest-smartphone-please-rotate-responsibly/">
69    <meta name="referrer" content="no-referrer-when-downgrade">
70    
71    <meta property="og:site_name" content="Paul Moore: Information Security Consultant &amp; Researcher">
72    <meta property="og:type" content="article">
73    <meta property="og:title" content="World&#x27;s Safest Smartphone: Please Rotate Responsibly.">
74    <meta property="og:description" content="An independent review of the HMD Fuse, marketed as the World&#x27;s Safest Smartphone.">
75    <meta property="og:url" content="https://paul.reviews/harmblock-worlds-safest-smartphone-please-rotate-responsibly/">
76    <meta property="og:image" content="https://paul.reviews/content/images/size/w1200/2026/09/banner2-2.png">
77    <meta property="article:published_time" content="2026-09-22T11:31:38.000Z">
78    <meta property="article:modified_time" content="2026-09-23T15:00:38.000Z">
79    <meta property="article:tag" content="harmblock">
80    <meta property="article:tag" content="safetonet">
81    <meta property="article:tag" content="hmd fuse">
82    <meta property="article:tag" content="child safety">
83    <meta property="article:tag" content="keyboardprivacy">
84    <meta property="article:tag" content="security">
85    <meta property="article:tag" content="responsible disclosure">
86    
87    <meta name="twitter:card" content="summary_large_image">
88    <meta name="twitter:title" content="World&#x27;s Safest Smartphone: Please Rotate Responsibly.">
89    <meta name="twitter:description" content="An independent review of the HMD Fuse, marketed as the World&#x27;s Safest Smartphone.">
90    <meta name="twitter:url" content="https://paul.reviews/harmblock-worlds-safest-smartphone-please-rotate-responsibly/">
91    <meta name="twitter:image" content="https://paul.reviews/content/images/size/w1200/2026/09/banner2-1.png">
92    <meta name="twitter:label1" content="Written by">
93    <meta name="twitter:data1" content="Paul Moore">
94    <meta name="twitter:label2" content="Filed under">
95    <meta name="twitter:data2" content="harmblock, safetonet, hmd fuse, child safety, keyboardprivacy, security, responsible disclosure">
96    <meta name="twitter:site" content="@paul_reviews">
97    <meta property="og:image:width" content="1200">
98    <meta property="og:image:height" content="480">
99    
100    
100<script type="application/ld+json">
101{
102    "@context": "https://schema.org",
103    "@type": "Article",
104    "publisher": {
105        "@type": "Organization",
106        "name": "Paul Moore: Information Security Consultant & Researcher",
107        "url": "https://paul.reviews/",
108        "logo": {
109            "@type": "ImageObject",
110            "url": "https://paul.reviews/content/images/2026/09/ChatGPT-Image-Sep-15--2026--06_47_01-PM.png",
111            "width": 60,
112            "height": 60
113        }
114    },
115    "author": {
116        "@type": "Person",
117        "name": "Paul Moore",
118        "image": {
119            "@type": "ImageObject",
120            "url": "https://paul.reviews/content/images/2026/09/fnNCyHOc_400x400.jpg",
121            "width": 400,
122            "height": 400
123        },
124        "url": "https://paul.reviews/author/paul/",
125        "sameAs": []
126    },
127    "headline": "HarmBlock+ World's Safest Smartphone: Please Rotate Responsibly.",
128    "url": "https://paul.reviews/harmblock-worlds-safest-smartphone-please-rotate-responsibly/",
129    "datePublished": "2026-09-22T11:31:38.000Z",
130    "dateModified": "2026-09-23T15:00:38.000Z",
131    "image": {
132        "@type": "ImageObject",
133        "url": "https://paul.reviews/content/images/size/w1200/2026/09/banner2.png",
134        "width": 1200,
135        "height": 480
136    },
137    "keywords": "harmblock, safetonet, hmd fuse, child safety, keyboardprivacy, security, responsible disclosure",
138    "description": "** NSFW Warning **\n\nBack in July 2025, the Online Safety Act was a hot topic. Many sites were frantically adding age verification under threat of criminal prosecution, if they failed to protect children from online harm.\n\nThe law, technology and implementations were... flawed; I presented an AI-generated video of the-then Technology Secretary, Peter Kyle, in order to skip intrusive censorship. That turned out to be unnecessary, as a smiley face drawn on a thumb also bypassed the \"robust\" verific",
139    "mainEntityOfPage": "https://paul.reviews/harmblock-worlds-safest-smartphone-please-rotate-responsibly/"
140}
141    </script>
141
142
143    <meta name="generator" content="Ghost 6.63">
144    <link rel="alternate" type="application/rss+xml" title="Paul Moore: Information Security Consultant &amp; Researcher" href="https://paul.reviews/rss/">
145    
146    
146<script defer src="https://cdn.jsdelivr.net/ghost/sodo-search@~1.8/umd/sodo-search.min.js" data-key="be77b651957bed6ea3b23475cc" data-styles="https://cdn.jsdelivr.net/ghost/sodo-search@~1.8/umd/main.css" data-sodo-search="https://paul.reviews/" data-locale="en" crossorigin="anonymous"></script>
146
147    
148    <link href="https://paul.reviews/webmentions/receive/" rel="webmention">
149    
149<script defer src="/public/cards.min.js?v=ShRHxgy4po8zN-Wf"></script>
149<style>:root {--ghost-accent-color: #d70947;}</style>
150    <link rel="stylesheet" type="text/css" href="/public/cards.min.css?v=WwnU9jw5ancNC8Gc">
151    <style>
152.author,
153.author-card,
154.author-box,
155.author-profile {
156    display: none !important;
157}
158</style>
159  </head>
160  <body class="post-template tag-hash-table-of-content tag-harmblock tag-safetonet tag-hmd-fuse tag-child-safety tag-keyboardprivacy tag-security tag-responsible-disclosure">
161    
162<div class="w-screen">
163  
164<div
165  data-nav-close
166  class="
167    fixed inset-0 bg-black/20 backdrop-blur-xs z-10 opacity-0 pointer-events-none transition-opacity duration-250
168
169    xl:hidden max-xl:[body[data-nav-open='true']_&]:opacity-100 max-xl:[body[data-nav-open='true']_&]:pointer-events-auto
170  "
171>
172</div>
173
174<aside 
175  class="
176    site-sidebar 
177    
178    fixed top-0 h-screen bg-page border-r border-stroke w-(--site-sidebar-width) z-20 transition-transform duration-250
179    
180    max-xl:-translate-x-full max-xl:[body[data-nav-open='true']_&]:translate-x-0   
181  "
182>
183  <div class="flex flex-col pt-6 pb-16 px-8 max-h-full min-h-screen no-scrollbar overflow-y-auto">
184    <div class="flex items-center justify-between mb-8">
185      
186<a href="https://paul.reviews" class="site-logo " style="" aria-label="Paul Moore: Information Security Consultant &amp; Researcher - Home">
187    <img src="/content/images/2026/09/ChatGPT-Image-Sep-15--2026--06_47_01-PM.png" alt="Paul Moore: Information Security Consultant &amp; Researcher" loading="eager" class="logo"/>
188</a>
189    </div>
190
191      <p class="max-md:hidden text-sm text-content-muted mb-8">Paul Moore: Information Security Consultant &amp; Researcher</p>
192
193    <div class="flex items-center relative w-full mb-8 z-10 xl:hidden" data-ghost-search>
194      <span data-icon="search" class="absolute left-3 top-1/2 -translate-y-1/2 z-1 text-content-alt text-sm"></span>
195      <input type="text" placeholder='Search...' class="w-full input pl-9 shadow-2xs">
196      <span class="absolute right-3 top-1/2 -translate-y-1/2 z-1 text-content-muted text-xs opacity-80" data-search-hint>⌘K</span>
197    </div>
198
199    <menu-nav
200      class="flex flex-1"
201      values-path="themeConfig.site.primaryNavigation"
202      orientation="vertical"
203      nav-class="text-sm"
204      item-class="group w-full flex items-center py-1.5 pr-3 h-8 aria-[current=page]:font-bold aria-[current=page]:text-accent"
205      group-class="flex flex-col whitespace-nowrap flex-wrap h-fit w-full not-first:mt-8"
206      group-header-class="font-medium text-content-alt mb-2 h-5"
207      group-item-class="group w-full flex items-center py-1.5 pl-4 pr-3 h-8 border-l border-stroke/70 aria-[current=page]:font-bold aria-[current=page]:border-l-accent hover:border-l-content/50 aria-[current=page]:text-accent"
208      icon-class="w-4 h-4 line-height-1 mr-3 opacity-70 group-aria-[current=page]:opacity-100 group-hover:opacity-95 transition-opacity duration-250"
209      aria-label="Primary Navigation"
210    ></menu-nav>
211
212    <social-icons class="xl:hidden mt-16 text-sm opacity-90 hover:opacity-100 transition-opacity duration-250" aria-label="Mobile Social Media Links"></social-icons>
213    
214  </div>
215  
216  <div class="sticky max-xl:hidden bottom-0 py-4 px-8 border-t  bg-page/80 backdrop-blur-xs w-full">
217    <social-icons class="text-sm opacity-90 hover:opacity-100 transition-opacity duration-250" aria-label="Desktop Social Media Links"></social-icons>
218  </div>
219</aside>
220  <div class="site-content w-full xl:pl-(--site-sidebar-width)">
221
222    <header class="container relative z-1 items-center justify-between !py-6 hidden xl:flex">
223      <div class="flex items-center relative w-76" data-ghost-search>
224        <span data-icon="search" class="absolute left-3 top-1/2 -translate-y-1/2 z-1 text-content-alt text-sm"></span>
225        <input type="text" placeholder='Search...' class="w-full input pl-9 shadow-2xs">
226        <span class="absolute right-3 top-1/2 -translate-y-1/2 z-1 text-content-muted text-xs opacity-90" data-search-hint>⌘K</span>
227      </div>
228
229      
230    </header>
231
232    <header class="container relative z-1 flex items-center justify-between !py-6 xl:hidden" data-color-scheme="">
233      
234<a href="https://paul.reviews" class="site-logo " style="" aria-label="Paul Moore: Information Security Consultant &amp; Researcher - Home">
235    <img src="/content/images/2026/09/ChatGPT-Image-Sep-15--2026--06_47_01-PM.png" alt="Paul Moore: Information Security Consultant &amp; Researcher" loading="eager" class="logo"/>
236</a>
237      <div role="button" tabindex="0" aria-label="Open navigation menu" class="group flex items-center justify-center w-9 h-9 text-content-alt" data-nav-toggle>
238        <span data-icon="menu_search" class="text-2xl group-hover:scale-105 transition-transform ease-out-quad duration-400 text-content-alt"></span>
239      </div>
240    </header>
241
242    <main id="site-main" role="main" class="container !mt-3">
243      
244
245<article class="mt-2 post tag-hash-table-of-content tag-harmblock tag-safetonet tag-hmd-fuse tag-child-safety tag-keyboardprivacy tag-security tag-responsible-disclosure featured">
246    
247  <figure class="relative rounded-[calc(var(--radius-card)*2)] overflow-hidden max-h-[50vh] mb-8">
248    <img
249      alt="HarmBlock+ World&#x27;s Safest Smartphone: Please Rotate Responsibly."
250      class=""
251      loading="lazy"
252      src="/content/images/size/w600/2026/09/banner2.png" 
253      srcset="/content/images/2026/09/banner2.png 320w, 
254              /content/images/size/w600/2026/09/banner2.png 600w, 
255              /content/images/size/w960/2026/09/banner2.png 960w, 
256              /content/images/size/w1200/2026/09/banner2.png 1200w, 
257              /content/images/size/w2000/2026/09/banner2.png 2000w"
258    >
259  </figure>
260
261  <div class="flex gap-12 mb-16 flex-wrap justify-center xl:flex-row flex-col max-xl:items-center">
262    <div class="flex flex-col gap-4 max-w-(--post-content-max-width) xl:basis-(--post-content-max-width)">
263        <h1 class="!text-5xl leading-[1.15]">HarmBlock+ World&#x27;s Safest Smartphone: Please Rotate Responsibly.</h1>
264
265          
266<div class="flex items-center justify-between pb-4 mb-1.5 border-b">
267  <div class="flex items-center">
268    <div class="flex items-center flex-shrink-0">
269          <a href="/author/paul/" class="min-w-12 min-h-12 hover:-translate-y-0.5 transition-all duration-200 last:mr-4">
270            <img src="https://paul.reviews/content/images/2026/09/fnNCyHOc_400x400.jpg" alt="Paul Moore" class="w-12 h-12 rounded-full object-cover border-page-alt border ">
271          </a>
272    </div>
273    <div class="flex flex-col">
274      <div class="leading-1">
275          <a href="/author/paul/" class="text-sm font-semibold hover:underline">Paul Moore</a>
276      </div>
277      <div class="text-xs opacity-80">
278        <time datetime="2026-09-22">September 22, 2026</time>
279        – 18 min read
280      </div>
281    </div>
282  </div>
283
284  <div class="flex-shrink-0 flex items-center gap-2">
285    <a
286      href="#share"
287      class="flex items-center px-4 gap-2 py-2 bg-page-alt hover:bg-accent/10 text-content-alt hover:text-accent rounded-full transition-all duration-200 font-semibold text-sm"
288      title="Share this article"
289      aria-label="Share this article">
290      <div data-icon="share" class="scale-115 font-thin -mx-1 -mt-0.5"></div>
291      Share
292    </a>
293
294    
295<dialog id="share-dialog" class="p-8 sm:max-w-96">
296
297  <div class="flex items-center mb-3.5 -mt-2 justify-between shrink-0">
298    <h3 class="text-base font-semibold text-content m-0">Share this article</h3>
299    <div
300      role="button"
301      data-icon="close"
302      data-dialog-close
303      class="flex items-center justify-center w-8 h-8 hover:bg-page-alt text-content-alt rounded-full cursor-pointer transition-all duration-200 hover:opacity-90 scale-90"
304      aria-label="Close">
305    </div>
306  </div>
307
308  <div class="flex-1 overflow-hidden">
309    <div class="grid grid-cols-4 gap-4 -mx-1.75 py-2 overflow-hidden max-h-44 has-[:checked]:max-h-68 transition-all duration-150 ease-(--ease-out-quad)">
310      <input type="checkbox" id="show-more-share" class="hidden peer absolute" />
311      <a
312        href="https://www.facebook.com/sharer/sharer.php?u=https://paul.reviews/harmblock-worlds-safest-smartphone-please-rotate-responsibly/"
313        target="_blank"
314        rel="noopener noreferrer"
315        class="flex flex-1 flex-col items-center gap-2 group"
316        title="Facebook">
317        <div class="w-12 h-12 flex items-center justify-center bg-[#1877F2]/90 rounded-full transition-transform duration-[0.18s] ease-[var(--ease-out-quad)] group-hover:scale-105 will-change-transform translate-z-0">
318          <div data-icon="facebook" class="text-white"></div>
319        </div>
320        <span class="text-xs text-content tracking-tight font-medium">Facebook</span>
321      </a>
322
323      <a
324        href="https://x.com/intent/post?url=https://paul.reviews/harmblock-worlds-safest-smartphone-please-rotate-responsibly/&text=HarmBlock%2B%20World's%20Safest%20Smartphone%3A%20Please%20Rotate%20Responsibly."
325        target="_blank"
326        rel="noopener noreferrer"
327        class="flex flex-1 flex-col items-center gap-2 group"
328        title="X (Twitter)">
329        <div class="w-12 h-12 flex items-center justify-center bg-[#000000]/90 rounded-full transition-transform duration-[0.18s] ease-[var(--ease-out-quad)] group-hover:scale-105 will-change-transform translate-z-0">
330          <div data-icon="x" class="text-white"></div>
331        </div>
332        <span class="text-xs text-content tracking-tight font-medium">X</span>
333      </a>
334
335      <a
336        href="https://www.linkedin.com/shareArticle?mini=true&url=https://paul.reviews/harmblock-worlds-safest-smartphone-please-rotate-responsibly/&title=HarmBlock%2B%20World's%20Safest%20Smartphone%3A%20Please%20Rotate%20Responsibly.&summary=** NSFW Warning **
337
338Back in July 2025, the Online Safety Act was a hot topic. Many sites were frantically adding age verification under threat of criminal prosecution, if they failed to protect children from online harm.
339
340The law, technology and implementations were... flawed; I presented an AI-generated video of the-"
341        target="_blank"
342        rel="noopener noreferrer"
343        class="flex flex-1 flex-col items-center gap-2 group"
344        title="LinkedIn">
345        <div class="w-12 h-12 flex items-center justify-center bg-[#0A66C2]/90 rounded-full transition-transform duration-[0.18s] ease-[var(--ease-out-quad)] group-hover:scale-105 will-change-transform translate-z-0">
346          <div data-icon="linkedin" class="text-white scale-120 translate-x-0.25"></div>
347        </div>
348        <span class="text-xs text-content tracking-tight font-medium">LinkedIn</span>
349      </a>
350
351      <a href="/cdn-cgi/l/email-protection#e2dd91978088878196dfaa83908fa08e8d8189c7d0a0c7d0d2b58d908e86c591c7d0d2b18384879196c7d0d2b18f839096928a8d8c87c7d1a3c7d0d2b28e87839187c7d0d2b08d96839687c7d0d2b08791928d8c918b808e9bccc4808d869bdfa18a878189c28d9796c2968a8b91c28390968b818e87d8c28a96969291d8cdcd9283978ecc9087948b879591cd8a83908f808e8d8189cf958d908e8691cf918384879196cf918f839096928a8d8c87cf928e87839187cf908d96839687cf908791928d8c918b808e9bcd" target="_blank" rel="noopener noreferrer" class="flex flex-1 flex-col items-center gap-2 group" title="Email">
352        <div class="w-12 h-12 flex items-center justify-center bg-[#EA4335]/90 rounded-full transition-transform duration-[0.18s] ease-[var(--ease-out-quad)] group-hover:scale-105 will-change-transform translate-z-0">
353          <div data-icon="mail" class="text-white scale-110"></div>
354        </div>
355        <span class="text-xs text-content tracking-tight font-medium">Email</span>
356      </a>
357
358      <a
359        href="https://api.whatsapp.com/send?text=HarmBlock%2B%20World's%20Safest%20Smartphone%3A%20Please%20Rotate%20Responsibly.%20https://paul.reviews/harmblock-worlds-safest-smartphone-please-rotate-responsibly/"
360        target="_blank"
361        rel="noopener noreferrer"
362        class="flex flex-1 flex-col items-center gap-2 group"
363        title="WhatsApp">
364        <div class="w-12 h-12 flex items-center justify-center bg-[#25D366]/90 rounded-full transition-transform duration-[0.18s] ease-[var(--ease-out-quad)] group-hover:scale-105 will-change-transform translate-z-0">
365          <div data-icon="whatsapp" class="text-white scale-115"></div>
366        </div>
367        <span class="text-xs text-content tracking-tight font-medium">WhatsApp</span>
368      </a>
369
370      <a
371        href="https://t.me/share/url?url=https://paul.reviews/harmblock-worlds-safest-smartphone-please-rotate-responsibly/&text=HarmBlock%2B%20World's%20Safest%20Smartphone%3A%20Please%20Rotate%20Responsibly."
372        target="_blank"
373        rel="noopener noreferrer"
374        class="flex flex-1 flex-col items-center gap-2 group"
375        title="Telegram">
376        <div class="w-12 h-12 flex items-center justify-center bg-[#0088cc]/90 rounded-full transition-transform duration-[0.18s] ease-[var(--ease-out-quad)] group-hover:scale-105 will-change-transform translate-z-0">
377          <div data-icon="telegram" class="text-white scale-115 -translate-x-0.25 translate-y-0.25"></div>
378        </div>
379        <span class="text-xs text-content tracking-tight font-medium">Telegram</span>
380      </a>
381
382      <a
383        href="https://www.threads.net/intent/post?text=HarmBlock%2B%20World's%20Safest%20Smartphone%3A%20Please%20Rotate%20Responsibly.%20https://paul.reviews/harmblock-worlds-safest-smartphone-please-rotate-responsibly/"
384        target="_blank"
385        rel="noopener noreferrer"
386        class="flex flex-1 flex-col items-center gap-2 group"
387        title="Threads">
388        <div class="w-12 h-12 flex items-center justify-center bg-[#000000]/90 rounded-full transition-transform duration-[0.18s] ease-[var(--ease-out-quad)] group-hover:scale-105 will-change-transform translate-z-0">
389          <div data-icon="threads" class="text-white"></div>
390        </div>
391        <span class="text-xs text-content tracking-tight font-medium">Threads</span>
392      </a>
393
394      <label
395        for="show-more-share"
396        class="flex flex-1 flex-col items-center gap-2 group cursor-pointer peer-checked:hidden"
397        title="More options">
398        <div class="w-12 h-12 flex items-center justify-center bg-page-alt/90 rounded-full border border-stroke/40 transition-all duration-200 group-hover:scale-105">
399          <div data-icon="more_horiz" class="text-muted"></div>
400        </div>
401        <span class="text-xs text-content tracking-tight font-medium">More</span>
402      </label>
403
404      <a
405        href="https://bsky.app/intent/compose?text=HarmBlock%2B%20World's%20Safest%20Smartphone%3A%20Please%20Rotate%20Responsibly.%20https://paul.reviews/harmblock-worlds-safest-smartphone-please-rotate-responsibly/"
406        target="_blank"
407        rel="noopener noreferrer"
408        class="hidden peer-checked:flex flex-col items-center gap-2 group"
409        title="Bluesky">
410        <div class="w-12 h-12 flex items-center justify-center bg-[#1185fe]/90 rounded-full transition-transform duration-[0.18s] ease-[var(--ease-out-quad)] group-hover:scale-105 will-change-transform translate-z-0">
411          <div data-icon="bluesky" class="text-white scale-90 translate-y-0.25"></div>
412        </div>
413        <span class="text-xs text-content tracking-tight font-medium">Bluesky</span>
414      </a>
415
416      <a
417        href="https://mastodon.social/share?text=HarmBlock%2B%20World's%20Safest%20Smartphone%3A%20Please%20Rotate%20Responsibly.%20https://paul.reviews/harmblock-worlds-safest-smartphone-please-rotate-responsibly/"
418        target="_blank"
419        rel="noopener noreferrer"
420        class="flex flex-1 flex-col items-center gap-2 group"
421        title="Mastodon">
422        <div class="w-12 h-12 flex items-center justify-center bg-[#6364FF]/90 rounded-full transition-transform duration-[0.18s] ease-[var(--ease-out-quad)] group-hover:scale-105 will-change-transform translate-z-0">
423          <div data-icon="mastodon" class="text-white scale-135 translate-y-0.25"></div>
424        </div>
425        <span class="text-xs text-content tracking-tight font-medium">Mastodon</span>
426      </a>
427
428      <a
429        href="https://www.reddit.com/submit?url=https://paul.reviews/harmblock-worlds-safest-smartphone-please-rotate-responsibly/&title=HarmBlock%2B%20World's%20Safest%20Smartphone%3A%20Please%20Rotate%20Responsibly."
430        target="_blank"
431        rel="noopener noreferrer"
432        class="flex flex-1 flex-col items-center gap-2 group"
433        title="Reddit">
434        <div class="w-12 h-12 flex items-center justify-center bg-[#FF4500]/90 rounded-full transition-transform duration-[0.18s] ease-[var(--ease-out-quad)] group-hover:scale-105 will-change-transform translate-z-0">
435          <div data-icon="reddit" class="text-white scale-135"></div>
436        </div>
437        <span class="text-xs text-content tracking-tight font-medium">Reddit</span>
438      </a>
439
440      <a
441        href="https://pinterest.com/pin/create/button/?url=https://paul.reviews/harmblock-worlds-safest-smartphone-please-rotate-responsibly/&description=HarmBlock%2B%20World's%20Safest%20Smartphone%3A%20Please%20Rotate%20Responsibly."
442        target="_blank"
443        rel="noopener noreferrer"
444        class="flex flex-1 flex-col items-center gap-2 group"
445        title="Pinterest">
446        <div class="w-12 h-12 flex items-center justify-center bg-[#E60023]/90 rounded-full transition-transform duration-[0.18s] ease-[var(--ease-out-quad)] group-hover:scale-105 will-change-transform translate-z-0">
447          <div data-icon="pinterest" class="text-white scale-125"></div>
448        </div>
449        <span class="text-xs text-content tracking-tight font-medium">Pinterest</span>
450      </a>
451
452      <a
453        href="https://social-plugins.line.me/lineit/share?url=https://paul.reviews/harmblock-worlds-safest-smartphone-please-rotate-responsibly/"
454        target="_blank"
455        rel="noopener noreferrer"
456        class="flex flex-1 flex-col items-center gap-2 group"
457        title="LINE">
458        <div class="w-12 h-12 flex items-center justify-center bg-[#00B900]/90 rounded-full transition-transform duration-[0.18s] ease-[var(--ease-out-quad)] group-hover:scale-105 will-change-transform translate-z-0">
459          <div data-icon="line" class="text-white scale-125"></div>
460        </div>
461        <span class="text-xs text-content tracking-tight font-medium">LINE</span>
462      </a>
463    </div>
464
465    <div class="space-y-2 border-t pt-3 mt-4">
466      <h4 class="text-xs font-medium text-content">Page Link</h4>
467      <div class="flex items-center justify-between py-1 ps-3 pe-1.75 bg-page-alt rounded-lg">
468        <input
469          type="text"
470          value="https://paul.reviews/harmblock-worlds-safest-smartphone-please-rotate-responsibly/"
471          readonly
472          onfocus="this.select()"
473          class="flex-1 text-xs text-content-alt bg-transparent border-none outline-none ring-0 ring-offset-0 cursor-pointer p-0 m-0"
474        />
475        <div class="bg-gradient-to-r from-transparent to-page-alt to-[80%] h-4 w-8 -ms-8 z-10"></div>
476        <copy-button
477          value="https://paul.reviews/harmblock-worlds-safest-smartphone-please-rotate-responsibly/"
478          class="z-10"
479          label="Copy link"
480          label-copied="Copied!"
481          icon="copy"
482          icon-copied="ok"
483          inline-text="Copy link"
484          inline-text-copied="Copied!"
485          button-class="flex items-center gap-1.5 text-content-alt hover:text-accent hover:bg-accent/10 hover:border-accent/10 transition-all duration-200 text-xs font-medium whitespace-nowrap shrink-0 border px-2.5 py-1.5 min-w-25 rounded-md will-change-transform translate-z-0"
486          tooltip-content-class="hidden"
487        ></copy-button>
488      </div>
489    </div>
490  </div>
491</dialog>
492
493  </div>
494</div>
495      
496<article class="post-content mb-0 ">
497  <div class="post-body prose" data-content>
498    <h4 id="nsfw-warning">** NSFW Warning **</h4><p>Back in July 2025, the Online Safety Act was a hot topic.  Many sites were frantically adding age verification under threat of criminal prosecution, if they failed to protect children from online harm.</p><p>The law, technology and implementations were... flawed; I presented an <a href="https://www.telegraph.co.uk/business/2025/07/31/tech-secretary-peter-kyle-under-pressure-as-online-safety-a/?ref=paul.reviews" rel="noreferrer">AI-generated video</a> of the-then Technology Secretary, Peter Kyle, in order to skip intrusive censorship.  That turned out to be unnecessary, as a smiley face drawn on a thumb also bypassed the "robust" verification process.</p><p>The general public (and the media) were quick to condemn the technology.  In reality, these failures were largely caused by companies wanting to <em>appear </em>compliant with little/no impact on their financials.</p><p>But, what happens when safety isn't a reluctant add-on, but the entire selling point?</p><h2 id="premise">Premise</h2><p>In August 2025, HMD launched the Fuse: a children's phone built around an AI content filter called HarmBlock, developed by <a href="https://safetonet.com/?ref=paul.reviews" rel="noreferrer">SafeToNet</a>. It scans photos on-device and quarantines anything harmful before the child sees it. No cloud uploads, no privacy trade-off.  It's marketed as "the world's safest phone"</p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/yWMCTyOzkRA?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" title="Introducing the HMD Fuse, the phone that grows with your child."></iframe></figure><p>The device supposedly detects explicit and illegal harmful content, allows the parent/guardian to restrict app access and <strong>track their child's live GPS location</strong>.</p><p>Over the last 12 months, I've examined every layer of their security/privacy/safety claims: the AI model, the apps, the quarantine system, the file scanner, the camera integration, the backend API, and the code that ties it all together.</p><p>What I found is not a product that needs refinement. It is a product whose defining feature, the one on the box and in every press interview, is architecturally incapable of doing what it claims... whilst putting every child at significant risk.</p><p>Grab a coffee and let's dive in.</p><h2 id="findings">Findings</h2><h3 id="change-any-parents-password-september-2025">Change Any Parent's Password (September 2025)</h3><p>We've all done it.  A service asks for a password and your mind draws a blank.</p><p>You hit the "forgot password" button and receive a one-time password by email.</p><p>A secure system ensures your OTP is:</p><ol><li>used just once.</li><li>is actually yours.</li></ol><p>Xplora's API (the company running the Harmblock backend) had no such check.</p><p>The OTP simply gated access to a password entry/confirmation screen which, upon changing the email address, allowed an attacker to change the password for any/all accounts on the platform.</p><p>Keep in mind, they didn't notify the parent/guardian that their password had been changed.  The attacker effectively became the guardian of any account, simply by presenting an email address.</p><p>
498This flaw (along with others) prompted the system to be taken offline for the first time in 2025.  To my knowledge, nobody involved (SafeToNet/HMD/Xplora) put out a public statement.</p><p>I <strong>strongly </strong>advised everyone involved to have their entire platform thoroughly audited, though it's not clear if that ever happened.</p><hr><h3 id="harmblock-is-baked-into-the-device-it-cannot-be-disabled-bypassed-or-circumvented-it-is-the-government-of-the-device">"HarmBlock+ is baked into the device, it cannot be disabled, bypassed or circumvented. It is the government of the device"</h3><figure class="kg-card kg-video-card kg-width-regular" data-kg-thumbnail="https://paul.reviews/content/media/2026/09/permissions_thumb.jpg" data-kg-custom-thumbnail="">
499            <div class="kg-video-container">
500                <video src="https://paul.reviews/content/media/2026/09/permissions.mp4" poster="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" width="640" height="360" playsinline="" preload="metadata" style="aspect-ratio: 640 / 360; background: transparent url('https://paul.reviews/content/media/2026/09/permissions_thumb.jpg') 50% 50% / cover no-repeat;"></video>
501                <div class="kg-video-overlay">
502                    <button class="kg-video-large-play-icon" aria-label="Play video">
503                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
504                            <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"></path>
505                        </svg>
506                    </button>
507                </div>
508                <div class="kg-video-player-container">
509                    <div class="kg-video-player">
510                        <button class="kg-video-play-icon" aria-label="Play video">
511                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
512                                <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"></path>
513                            </svg>
514                        </button>
515                        <button class="kg-video-pause-icon kg-video-hide" aria-label="Pause video">
516                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
517                                <rect x="3" y="1" width="7" height="22" rx="1.5" ry="1.5"></rect>
518                                <rect x="14" y="1" width="7" height="22" rx="1.5" ry="1.5"></rect>
519                            </svg>
520                        </button>
521                        <span class="kg-video-current-time">0:00</span>
522                        <div class="kg-video-time">
523                            /<span class="kg-video-duration">0:33</span>
524                        </div>
525                        <input type="range" class="kg-video-seek-slider" max="100" value="0">
526                        <button class="kg-video-playback-rate" aria-label="Adjust playback speed">1×</button>
527                        <button class="kg-video-unmute-icon" aria-label="Unmute">
528                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
529                                <path d="M15.189 2.021a9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h1.794a.249.249 0 0 1 .221.133 9.73 9.73 0 0 0 7.924 4.85h.06a1 1 0 0 0 1-1V3.02a1 1 0 0 0-1.06-.998Z"></path>
530                            </svg>
531                        </button>
532                        <button class="kg-video-mute-icon kg-video-hide" aria-label="Mute">
533                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
534                                <path d="M16.177 4.3a.248.248 0 0 0 .073-.176v-1.1a1 1 0 0 0-1.061-1 9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h.114a.251.251 0 0 0 .177-.073ZM23.707 1.706A1 1 0 0 0 22.293.292l-22 22a1 1 0 0 0 0 1.414l.009.009a1 1 0 0 0 1.405-.009l6.63-6.631A.251.251 0 0 1 8.515 17a.245.245 0 0 1 .177.075 10.081 10.081 0 0 0 6.5 2.92 1 1 0 0 0 1.061-1V9.266a.247.247 0 0 1 .073-.176Z"></path>
535                            </svg>
536                        </button>
537                        <input type="range" class="kg-video-volume-slider" max="100" value="100">
538                    </div>
539                </div>
540            </div>
541            
542        </figure><p>The initial setup screen is an immediate red-flag.</p><p>If it's baked into firmware, why does a parent need to grant HarmBlock+ permissions to anything?</p><p>In reality, it's <strong>not </strong>baked into firmware in the way they claim.  It's effectively side-loaded, just like any other application.  This seems like trivial nit-picking at first, but you'll soon see why this matters.</p><h3 id="pairing-with-an-hmd-fuse">Pairing with an HMD Fuse</h3><figure class="kg-card kg-video-card kg-width-regular" data-kg-thumbnail="https://paul.reviews/content/media/2026/09/How-to-set-up-the-HMD-Fuse-protected-with-HarmBlock-_69_82_thumb.jpg" data-kg-custom-thumbnail="">
543            <div class="kg-video-container">
544                <video src="https://paul.reviews/content/media/2026/09/How-to-set-up-the-HMD-Fuse-protected-with-HarmBlock-_69_82.mp4" poster="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" width="640" height="360" playsinline="" preload="metadata" style="aspect-ratio: 640 / 360; background: transparent url('https://paul.reviews/content/media/2026/09/How-to-set-up-the-HMD-Fuse-protected-with-HarmBlock-_69_82_thumb.jpg') 50% 50% / cover no-repeat;"></video>
545                <div class="kg-video-overlay">
546                    <button class="kg-video-large-play-icon" aria-label="Play video">
547                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
548                            <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"></path>
549                        </svg>
550                    </button>
551                </div>
552                <div class="kg-video-player-container">
553                    <div class="kg-video-player">
554                        <button class="kg-video-play-icon" aria-label="Play video">
555                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
556                                <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"></path>
557                            </svg>
558                        </button>
559                        <button class="kg-video-pause-icon kg-video-hide" aria-label="Pause video">
560                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
561                                <rect x="3" y="1" width="7" height="22" rx="1.5" ry="1.5"></rect>
562                                <rect x="14" y="1" width="7" height="22" rx="1.5" ry="1.5"></rect>
563                            </svg>
564                        </button>
565                        <span class="kg-video-current-time">0:00</span>
566                        <div class="kg-video-time">
567                            /<span class="kg-video-duration">0:16</span>
568                        </div>
569                        <input type="range" class="kg-video-seek-slider" max="100" value="0">
570                        <button class="kg-video-playback-rate" aria-label="Adjust playback speed">1×</button>
571                        <button class="kg-video-unmute-icon" aria-label="Unmute">
572                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
573                                <path d="M15.189 2.021a9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h1.794a.249.249 0 0 1 .221.133 9.73 9.73 0 0 0 7.924 4.85h.06a1 1 0 0 0 1-1V3.02a1 1 0 0 0-1.06-.998Z"></path>
574                            </svg>
575                        </button>
576                        <button class="kg-video-mute-icon kg-video-hide" aria-label="Mute">
577                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
578                                <path d="M16.177 4.3a.248.248 0 0 0 .073-.176v-1.1a1 1 0 0 0-1.061-1 9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h.114a.251.251 0 0 0 .177-.073ZM23.707 1.706A1 1 0 0 0 22.293.292l-22 22a1 1 0 0 0 0 1.414l.009.009a1 1 0 0 0 1.405-.009l6.63-6.631A.251.251 0 0 1 8.515 17a.245.245 0 0 1 .177.075 10.081 10.081 0 0 0 6.5 2.92 1 1 0 0 0 1.061-1V9.266a.247.247 0 0 1 .073-.176Z"></path>
579                            </svg>
580                        </button>
581                        <input type="range" class="kg-video-volume-slider" max="100" value="100">
582                    </div>
583                </div>
584            </div>
585            
586        </figure><p>In order to "pair" with the child's device, you must scan a QR code.</p><p>I thought, somewhat naively, the QR code would be a unique, ephemeral secret which cryptographically tied the phone to the parent's guardian app.</p><p>Oh good lord, how wrong I was.</p><p><strong>It's the phone's IMEI number.</strong></p><p>No cryptography, no secrets, no challenge/response mechanism... just a <strong>predictable </strong>IMEI which you can trivially calculate in seconds.</p><p>Ironically, someone in post-production blurred the QR code in the demo to keep it a secret; unaware the value isn't a secret in the first place.  It's on the box, shown in pictures of ebay listings, sent across various networks, in several databases and used as identifiers across many mobile apps.</p><p>Crucially, it's a <strong>static </strong>non-secret.  No amount of factory resets can change it.  Remember that for later.</p><h4 id="what-can-you-do-with-it">What can you do with it?</h4><p>Become the parent/guardian of any child, anywhere in the world... and neither they nor the parent would know.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://paul.reviews/content/images/2026/09/HQzYwC1WEAA_OBO.jpg" class="kg-image" alt="" loading="lazy" width="1536" height="1024" srcset="https://paul.reviews/content/images/size/w600/2026/09/HQzYwC1WEAA_OBO.jpg 600w, https://paul.reviews/content/images/size/w1000/2026/09/HQzYwC1WEAA_OBO.jpg 1000w, https://paul.reviews/content/images/2026/09/HQzYwC1WEAA_OBO.jpg 1536w" sizes="(min-width: 720px) 720px"><figcaption><span style="white-space: pre-wrap;">Simulation of data exposure due to insufficient authentication.</span></figcaption></figure><p>There is no "pairing" mechanism in the typical sense.  You simply ask the API for access to a phone and it hands it over.  It doesn't even need to be powered on, or even sold.</p><p>Remember, this app provides <strong>live </strong>GPS coordinates of every child on the platform.</p><p>This wasn't a bug either. <strong>This was by design.</strong></p><p>Upon reporting this to HMD, the platform was taken offline immediately on July 8th 2026 and remained as such until September 10th 2026.  No announcement, no public statement... just "offline for maintenance", according to the app.</p><p>After a few weeks, parent's understandably started complaining and asking questions; one of which had seen my many tweets and asked HMD if the system had been breached &amp; was there any risk...</p><blockquote class="kg-blockquote-alt">"It has not been hacked. Everything is safe and nothing to worry about. Rest be assured", HMD Support, August 3rd 2026</blockquote><p>At which point, the app was updated to reflect the fact it had been down for a few weeks due to "<em>a technical issue</em>".  It's not clear who decided upon that vague wording, but it's not exactly transparent.</p><hr><h3 id="who-owns-this-imei">Who owns this IMEI?</h3><p>When you scanned the QR code, the app asked the API if the IMEI was valid/registered.</p><p>Instead of a somewhat safe "yes/no" response, the API dutifully returned the child's full name and telephone number.</p><hr><p>By simply registering, you've already leaked your child's live GPS location, name &amp;
586 telephone number.</p><p>An attacker can reset your password without your knowledge, to become the guardian of your child... or simply "pair" with your child's device to take full control over it.</p><p>At this point, it's already a write-off in terms of safety... but that ignores the potential benefits which <em>may </em>still outweigh the risk.</p><p>Let's look at HarmBlock itself.</p><p>Meet Richard &amp; Sharon Pursey, Directors at SafeToNet.</p><figure class="kg-card kg-video-card kg-width-regular" data-kg-thumbnail="https://paul.reviews/content/media/2026/09/whatisharmblock-3_thumb.jpg" data-kg-custom-thumbnail="">
587            <div class="kg-video-container">
588                <video src="https://paul.reviews/content/media/2026/09/whatisharmblock-3.mp4" poster="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" width="1280" height="720" playsinline="" preload="metadata" style="aspect-ratio: 1280 / 720; background: transparent url('https://paul.reviews/content/media/2026/09/whatisharmblock-3_thumb.jpg') 50% 50% / cover no-repeat;"></video>
589                <div class="kg-video-overlay">
590                    <button class="kg-video-large-play-icon" aria-label="Play video">
591                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
592                            <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"></path>
593                        </svg>
594                    </button>
595                </div>
596                <div class="kg-video-player-container">
597                    <div class="kg-video-player">
598                        <button class="kg-video-play-icon" aria-label="Play video">
599                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
600                                <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"></path>
601                            </svg>
602                        </button>
603                        <button class="kg-video-pause-icon kg-video-hide" aria-label="Pause video">
604                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
605                                <rect x="3" y="1" width="7" height="22" rx="1.5" ry="1.5"></rect>
606                                <rect x="14" y="1" width="7" height="22" rx="1.5" ry="1.5"></rect>
607                            </svg>
608                        </button>
609                        <span class="kg-video-current-time">0:00</span>
610                        <div class="kg-video-time">
611                            /<span class="kg-video-duration">0:13</span>
612                        </div>
613                        <input type="range" class="kg-video-seek-slider" max="100" value="0">
614                        <button class="kg-video-playback-rate" aria-label="Adjust playback speed">1×</button>
615                        <button class="kg-video-unmute-icon" aria-label="Unmute">
616                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
617                                <path d="M15.189 2.021a9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h1.794a.249.249 0 0 1 .221.133 9.73 9.73 0 0 0 7.924 4.85h.06a1 1 0 0 0 1-1V3.02a1 1 0 0 0-1.06-.998Z"></path>
618                            </svg>
619                        </button>
620                        <button class="kg-video-mute-icon kg-video-hide" aria-label="Mute">
621                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
622                                <path d="M16.177 4.3a.248.248 0 0 0 .073-.176v-1.1a1 1 0 0 0-1.061-1 9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h.114a.251.251 0 0 0 .177-.073ZM23.707 1.706A1 1 0 0 0 22.293.292l-22 22a1 1 0 0 0 0 1.414l.009.009a1 1 0 0 0 1.405-.009l6.63-6.631A.251.251 0 0 1 8.515 17a.245.245 0 0 1 .177.075 10.081 10.081 0 0 0 6.5 2.92 1 1 0 0 0 1.061-1V9.266a.247.247 0 0 1 .073-.176Z"></path>
623                            </svg>
624                        </button>
625                        <input type="range" class="kg-video-volume-slider" max="100" value="100">
626                    </div>
627                </div>
628            </div>
629            
630        </figure><p>We've already established it's not truly embedded into the device, but they seem to believe it's "safe the moment it's switched on".</p><p>But, that's not true.  Out of the box, the HMD Fuse is a standard smartphone.  If you factory reset it, it reverts to being a standard smartphone.  The parent <strong>must </strong>go through a fairly lengthy setup process in order to turn any protection on.</p><p>If the parent/child skips setup, it remains a standard smartphone.</p>
630<h3 id="everything-passes-through-harmblock-ai">"Everything passes through HarmBlock AI"</h3><figure class="kg-card kg-video-card kg-width-regular" data-kg-thumbnail="https://paul.reviews/content/media/2026/09/everyAppProtected_thumb.jpg" data-kg-custom-thumbnail="">
631            <div class="kg-video-container">
632                <video src="https://paul.reviews/content/media/2026/09/everyAppProtected.mp4" poster="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" width="1280" height="720" playsinline="" preload="metadata" style="aspect-ratio: 1280 / 720; background: transparent url('https://paul.reviews/content/media/2026/09/everyAppProtected_thumb.jpg') 50% 50% / cover no-repeat;"></video>
633                <div class="kg-video-overlay">
634                    <button class="kg-video-large-play-icon" aria-label="Play video">
635                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
636                            <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"></path>
637                        </svg>
638                    </button>
639                </div>
640                <div class="kg-video-player-container">
641                    <div class="kg-video-player">
642                        <button class="kg-video-play-icon" aria-label="Play video">
643                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
644                                <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"></path>
645                            </svg>
646                        </button>
647                        <button class="kg-video-pause-icon kg-video-hide" aria-label="Pause video">
648                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
649                                <rect x="3" y="1" width="7" height="22" rx="1.5" ry="1.5"></rect>
650                                <rect x="14" y="1" width="7" height="22" rx="1.5" ry="1.5"></rect>
651                            </svg>
652                        </button>
653                        <span class="kg-video-current-time">0:00</span>
654                        <div class="kg-video-time">
655                            /<span class="kg-video-duration">0:27</span>
656                        </div>
657                        <input type="range" class="kg-video-seek-slider" max="100" value="0">
658                        <button class="kg-video-playback-rate" aria-label="Adjust playback speed">1×</button>
659                        <button class="kg-video-unmute-icon" aria-label="Unmute">
660                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
661                                <path d="M15.189 2.021a9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h1.794a.249.249 0 0 1 .221.133 9.73 9.73 0 0 0 7.924 4.85h.06a1 1 0 0 0 1-1V3.02a1 1 0 0 0-1.06-.998Z"></path>
662                            </svg>
663                        </button>
664                        <button class="kg-video-mute-icon kg-video-hide" aria-label="Mute">
665                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
666                                <path d="M16.177 4.3a.248.248 0 0 0 .073-.176v-1.1a1 1 0 0 0-1.061-1 9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h.114a.251.251 0 0 0 .177-.073ZM23.707 1.706A1 1 0 0 0 22.293.292l-22 22a1 1 0 0 0 0 1.414l.009.009a1 1 0 0 0 1.405-.009l6.63-6.631A.251.251 0 0 1 8.515 17a.245.245 0 0 1 .177.075 10.081 10.081 0 0 0 6.5 2.92 1 1 0 0 0 1.061-1V9.266a.247.247 0 0 1 .073-.176Z"></path>
667                            </svg>
668                        </button>
669                        <input type="range" class="kg-video-volume-slider" max="100" value="100">
670                    </div>
671                </div>
672            </div>
673            
674        </figure><p>But that's not true either.</p><p>I think there's been a substantial breakdown in communication between HMD and SafeToNet here.  While SafeToNet's product can absolutely work across every application on the device, that's <strong>not </strong>the case on the HMD Fuse.</p><p>The Fuse has an explicit whitelist; 433 apps which are <strong>not </strong>scanned at all and cannot be removed from the whitelist.</p><p>They're not outliers either.  Wikipedia, ChatGPT and unbelievably, the Microsoft Office suite... exactly the applications a child will likely install &amp; use at school.  <a href="https://www.theguardian.com/technology/2025/apr/14/risks-children-roblox-deeply-disturbing-researchers?ref=paul.reviews" rel="noreferrer">Even Roblox is whitelisted</a>!</p><p>Initially, I thought this was dead code; an artifact of internal testing which someone forgot to remove... so I tested it.</p><p>Wikipedia:</p><figure class="kg-card kg-video-card kg-width-regular" data-kg-thumbnail="https://paul.reviews/content/media/2026/09/wikipedia_thumb.jpg" data-kg-custom-thumbnail="">
675            <div class="kg-video-container">
676                <video src="https://paul.reviews/content/media/2026/09/wikipedia.mp4" poster="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" width="1920" height="1080" playsinline="" preload="metadata" style="aspect-ratio: 1920 / 1080; background: transparent url('https://paul.reviews/content/media/2026/09/wikipedia_thumb.jpg') 50% 50% / cover no-repeat;"></video>
677                <div class="kg-video-overlay">
678                    <button class="kg-video-large-play-icon" aria-label="Play video">
679                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
680                            <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"></path>
681                        </svg>
682                    </button>
683                </div>
684                <div class="kg-video-player-container">
685                    <div class="kg-video-player">
686                        <button class="kg-video-play-icon" aria-label="Play video">
687                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
688                                <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"></path>
689                            </svg>
690                        </button>
691                        <button class="kg-video-pause-icon kg-video-hide" aria-label="Pause video">
692                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
693                                <rect x="3" y="1" width="7" height="22" rx="1.5" ry="1.5"></rect>
694                                <rect x="14" y="1" width="7" height="22" rx="1.5" ry="1.5"></rect>
695                            </svg>
696                        </button>
697                        <span class="kg-video-current-time">0:00</span>
698                        <div class="kg-video-time">
699                            /<span class="kg-video-duration">0:19</span>
700                        </div>
701                        <input type="range" class="kg-video-seek-slider" max="100" value="0">
702                        <button class="kg-video-playback-rate" aria-label="Adjust playback speed">1×</button>
703                        <button class="kg-video-unmute-icon" aria-label="Unmute">
704                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
705                                <path d="M15.189 2.021a9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h1.794a.249.249 0 0 1 .221.133 9.73 9.73 0 0 0 7.924 4.85h.06a1 1 0 0 0 1-1V3.02a1 1 0 0 0-1.06-.998Z"></path>
706                            </svg>
707                        </button>
708                        <button class="kg-video-mute-icon kg-video-hide" aria-label="Mute">
709                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
710                                <path d="M16.177 4.3a.248.248 0 0 0 .073-.176v-1.1a1 1 0 0 0-1.061-1 9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h.114a.251.251 0 0 0 .177-.073ZM23.707 1.706A1 1 0 0 0 22.293.292l-22 22a1 1 0 0 0 0 1.414l.009.009a1 1 0 0 0 1.405-.009l6.63-6.631A.251.251 0 0 1 8.515 17a.245.245 0 0 1 .177.075 10.081 10.081 0 0 0 6.5 2.92 1 1 0 0 0 1.061-1V9.266a.247.247 0 0 1 .073-.176Z"></path>
711                            </svg>
712                        </button>
713                        <input type="range" class="kg-video-volume-slider" max="100" value="100">
714                    </div>
715                </div>
716            </div>
717            
718        </figure><p>Microsoft Word:</p><figure class="kg-card kg-video-card kg-width-regular" data-kg-thumbnail="https://paul.reviews/content/media/2026/09/word_thumb.jpg" data-kg-custom-thumbnail="">
719            <div class="kg-video-container">
720                <video src="https://paul.reviews/content/media/2026/09/word.mp4" poster="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" width="1920" height="1080" playsinline="" preload="metadata" style="aspect-ratio: 1920 / 1080; background: transparent url('https://paul.reviews/content/media/2026/09/word_thumb.jpg') 50% 50% / cover no-repeat;"></video>
721                <div class="kg-video-overlay">
722                    <button class="kg-video-large-play-icon" aria-label="Play video">
723                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
724                            <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"></path>
725                        </svg>
726                    </button>
727                </div>
728                <div class="kg-video-player-container">
729                    <div class="kg-video-player">
730                        <button class="kg-video-play-icon" aria-label="Play video">
731                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
732                                <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"></path>
733                            </svg>
734                        </button>
735                        <button class="kg-video-pause-icon kg-video-hide" aria-label="Pause video">
736                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
737                                <rect x="3" y="1" width="7" height="22" rx="1.5" ry="1.5"></rect>
738                                <rect x="14" y="1" width="7" height="22" rx="1.5" ry="1.5"></rect>
739                            </svg>
740                        </button>
741                        <span class="kg-video-current-time">0:00</span>
742                        <div class="kg-video-time">
743                            /<span class="kg-video-duration">0:18</span>
744                        </div>
745                        <input type="range" class="kg-video-seek-slider" max="100" value="
7450">
746                        <button class="kg-video-playback-rate" aria-label="Adjust playback speed">1×</button>
747                        <button class="kg-video-unmute-icon" aria-label="Unmute">
748                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
749                                <path d="M15.189 2.021a9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h1.794a.249.249 0 0 1 .221.133 9.73 9.73 0 0 0 7.924 4.85h.06a1 1 0 0 0 1-1V3.02a1 1 0 0 0-1.06-.998Z"></path>
750                            </svg>
751                        </button>
752                        <button class="kg-video-mute-icon kg-video-hide" aria-label="Mute">
753                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
754                                <path d="M16.177 4.3a.248.248 0 0 0 .073-.176v-1.1a1 1 0 0 0-1.061-1 9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h.114a.251.251 0 0 0 .177-.073ZM23.707 1.706A1 1 0 0 0 22.293.292l-22 22a1 1 0 0 0 0 1.414l.009.009a1 1 0 0 0 1.405-.009l6.63-6.631A.251.251 0 0 1 8.515 17a.245.245 0 0 1 .177.075 10.081 10.081 0 0 0 6.5 2.92 1 1 0 0 0 1.061-1V9.266a.247.247 0 0 1 .073-.176Z"></path>
755                            </svg>
756                        </button>
757                        <input type="range" class="kg-video-volume-slider" max="100" value="100">
758                    </div>
759                </div>
760            </div>
761            
762        </figure><p>I genuinely don't understand the point of a whitelist.</p><p>They've invested millions developing a supposedly sophisticated AI "harm prevention" system... then disabled it for 433 apps by default.</p><p>That'd be fine if parents were aware, but they claim it operates across the "entire device, every app" and cannot be bypassed.</p><p>Kids are clever.  They'll often find new &amp; ingenious ways to get around any obstacle.</p><p>Unfortunately, the HMD Fuse is trivially easy to bypass.</p><h3 id="settingstxtlet-the-child-configure-it">Settings.txt - Let the child configure it</h3><p>The application uses a file called settings.txt to store screen scanning intervals.</p><p>By default, it's every 1000ms or 1 second.  That's fine.</p><p>The issue, is that settings.txt is accessible to the child &amp; can be modified to increase the interval from 1 second... to infinity.</p><figure class="kg-card kg-embed-card"><iframe width="200" height="150" src="https://www.youtube.com/embed/WVk5isXukQ8?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" title="Harmblock / HMD Fuse: Disable all protection with a text file."></iframe></figure><h3 id="settingstxtno-error-handling">Settings.txt - No error handling</h3><p>The application expects numbers, so let's give it a non-alphanumeric value.</p><figure class="kg-card kg-video-card kg-width-regular" data-kg-thumbnail="https://paul.reviews/content/media/2026/09/settingscrash_cut_thumb.jpg" data-kg-custom-thumbnail="">
763            <div class="kg-video-container">
764                <video src="https://paul.reviews/content/media/2026/09/settingscrash_cut.mp4" poster="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" width="1920" height="1080" playsinline="" preload="metadata" style="aspect-ratio: 1920 / 1080; background: transparent url('https://paul.reviews/content/media/2026/09/settingscrash_cut_thumb.jpg') 50% 50% / cover no-repeat;"></video>
765                <div class="kg-video-overlay">
766                    <button class="kg-video-large-play-icon" aria-label="Play video">
767                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
768                            <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"></path>
769                        </svg>
770                    </button>
771                </div>
772                <div class="kg-video-player-container">
773                    <div class="kg-video-player">
774                        <button class="kg-video-play-icon" aria-label="Play video">
775                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
776                                <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"></path>
777                            </svg>
778                        </button>
779                        <button class="kg-video-pause-icon kg-video-hide" aria-label="Pause video">
780                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
781                                <rect x="3" y="1" width="7" height="22" rx="1.5" ry="1.5"></rect>
782                                <rect x="14" y="1" width="7" height="22" rx="1.5" ry="1.5"></rect>
783                            </svg>
784                        </button>
785                        <span class="kg-video-current-time">0:00</span>
786                        <div class="kg-video-time">
787                            /<span class="kg-video-duration">2:53</span>
788                        </div>
789                        <input type="range" class="kg-video-seek-slider" max="100" value="0">
790                        <button class="kg-video-playback-rate" aria-label="Adjust playback speed">1×</button>
791                        <button class="kg-video-unmute-icon" aria-label="Unmute">
792                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
793                                <path d="M15.189 2.021a9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h1.794a.249.249 0 0 1 .221.133 9.73 9.73 0 0 0 7.924 4.85h.06a1 1 0 0 0 1-1V3.02a1 1 0 0 0-1.06-.998Z"></path>
794                            </svg>
795                        </button>
796                        <button class="kg-video-mute-icon kg-video-hide" aria-label="Mute">
797                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
798                                <path d="M16.177 4.3a.248.248 0 0 0 .073-.176v-1.1a1 1 0 0 0-1.061-1 9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h.114a.251.251 0 0 0 .177-.073ZM23.707 1.706A1 1 0 0 0 22.293.292l-22 22a1 1 0 0 0 0 1.414l.009.009a1 1 0 0 0 1.405-.009l6.63-6.631A.251.251 0 0 1 8.515 17a.245.245 0 0 1 .177.075 10.081 10.081 0 0 0 6.5 2.92 1 1 0 0 0 1.061-1V9.266a.247.247 0 0 1 .073-.176Z"></path>
799                            </svg>
800                        </button>
801                        <input type="range" class="kg-video-volume-slider" max="100" value="100">
802                    </div>
803                </div>
804            </div>
805            
806        </figure><h3 id="who-needs-permissions-anyway">Who needs permissions anyway?</h3><p>Incredibly, the application has no permissions.</p><p>Any app on the device can trigger the "setup completion" screen, allowing the child to simply disable any/all protection.</p><figure class="kg-card kg-video-card kg-width-regular" data-kg-thumbnail="https://paul.reviews/content/media/2026/09/permissions_disabled_thumb.jpg" data-kg-custom-thumbnail="">
807            <div class="kg-video-container">
808                <video src="https://paul.reviews/content/media/2026/09/permissions_disabled.mp4" poster="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" width="1920" height="1080" playsinline="" preload="metadata" style="aspect-ratio: 1920 / 1080; background: transparent url('https://paul.reviews/content/media/2026/09/permissions_disabled_thumb.jpg') 50% 50% / cover no-repeat;"></video>
809                <div class="kg-video-overlay">
810                    <button class="kg-video-large-play-icon" aria-label="Play video">
811                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
812                            <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"></path>
813                        </svg>
814                    </button>
815                </div>
816                <div class="kg-video-player-container">
817                    <div class="kg-video-player">
818                        <button class="kg-video-play-icon" aria-label="Play video">
819                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
820                                <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"></path>
821                            </svg>
822                        </button>
823                        <button class="kg-video-pause-icon kg-video-hide" aria-label="Pause video">
824                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
825                                <rect x="3" y="1" width="7" height="22" rx="1.5" ry="1.5"></rect>
826                                <rect x="14" y="1" width="7" height="22" rx="1.5" ry="1.5"></rect>
827                            </svg>
828                        </button>
829                        <span class="kg-video-current-time">0:00</span>
830                        <div class="kg-video-time">
831                            /<span class="kg-video-duration">0:20</span>
832                        </div>
833                        <input type="range" class="kg-video-seek-slider" max="100" value="0">
834                        <button class="kg-video-playback-rate" aria-label="Adjust playback speed">1×</button>
835                        <button class="kg-video-unmute-icon" aria-label="Unmute">
836                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
837                                <path d="M15.189 2.021a9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h1.794a.249.249 0 0 1 .221.133 9.73 9.73 0 0 0 7.924 4.85h.06a1 1 0 0 0 1-1V3.02a1 1 0 0 0-1.06-.998Z"></path>
838                            </svg>
839                        </button>
840                        <button class="kg-video-mute-icon kg-video-hide" aria-label="Mute">
841                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
842                                <path d="M16.177 4.3a.248.248 0 0 0 .073-.176v-1.1a1 1 0 0 0-1.061-1 9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h.114a.251.251 0 0 0 .177-.073ZM23.707 1.706A1 1 0 0 0 22.293.292l-22 22a1 1 0 0 0 0 1.414l.009.009a1 1 0 0 0 1.405-.009l6.63-6.631A.251.251 0 0 1 8.515 17a.245.245 0 0 1 .177.075 10.081 10.081 0 0 0 6.5 2.92 1 1 0 0 0 1.061-1V9.266a.247.247 0 0 1 .073-.176Z"></path>
843                            </svg>
844                        </button>
845                        <input type="range" class="kg-video-volume-slider" max="100" value="100">
846                    </div>
847                </div>
848            </div>
849            
850        </figure><hr><h3 id="disable-harmblock-via-adb">Disable HarmBlock via ADB</h3><p>Although they've made a poor attempt to disable ADB, it's still possible to remove all protection with a single command.</p><p>adb shell pm disable-user --user 0 com.hmdglobal.app.ksg</p><hr><h3 id="disable-harmblock-via-google-find-hub">Disable HarmBlock via Google Find Hub</h3><p>When your child loses their device, you can use Google's native "Find Hub" app to safely factory reset/wipe your HMD Fuse.</p><p>But, so can your child.</p><figure class="kg-card kg-image-card"><img src="https://paul.reviews/content/images/2026/09/findmy.png" class="kg-image" alt="" loading="lazy" width="927" height="1306" srcset="https://paul.reviews/content/images/size/w600/2026/09/findmy.png 600w, https://paul.reviews/content/images/2026/09/findmy.png 927w" sizes="(min-width: 720px) 720px"></figure><p>Click "Factory reset" and in a few minutes, the device is wiped completely.</p><p>This is not only native functionality to all certified Android devices, it <strong>cannot be removed/disabled</strong> without losing that certification.  That means losing access to the Play store and rendering the phone basically useless.</p><p>You'll recall, the device is a standard smartphone out of the box.  To make matters worse, the parent is none the wiser.  The Fuse still shows up in the Guardian app, but now the data is stale.  Their GPS doesn't update, you can no longer enable/disable apps - that link has been severed by a child doing nothing other than factory resetting their own phone.</p><hr><h3 id="static-rsa-keys">Static RSA keys?!</h3><p>The APK behind the Harmblock service contained <strong>static </strong>RSA keys, meaning they're identical across every device.</p><p>Once extracted, anyone can emulate any Fuse device, anywhere in the world.</p><p>As a proof of concept, I created a NodeJS application which presented itself to the API as a Fuse I didn't own/possess.  The API diligently updated its records, showing the device at the Eiffel Tower one moment, then back in the UK seconds later.</p><hr><h3 id="a-chinese-root-certificate-authority">A Chinese root certificate authority</h3><p>The device has a Chinese root CA from iHuatek - facilitating TLS traffic interception.</p><p>The password for the private key?<br>"Aa123456"</p><p>They don't appear to be doing anything more than SNI inspection, but quite why there's a Chinese CA on a child safety device is beyond me.</p><hr><h3 id="passwords-are-md5d-at-the-client">Passwords are MD5'd... at the client!</h3><p>
850MD5, deprecated in 2004, is entirely unsuitable for password hashing.</p><p>Despite the world moving away from it 22 years ago, Xplora (the HarmBlock+ backend) used MD5... in the client app of a child safety platform!  No salts either, so every password hashed to the same output.</p><hr><h3 id="password-reset-otps-have-no-rate-limiting">Password reset OTPs have no rate limiting.</h3><p>If you initiated a password reset, the resulting 6 digit OTP had no rate limiting whatsoever.  As a result, an attacker could send all 1 million possibilities to the API in just 42 seconds and gain access to any account.</p><p>Admittedly, this required a <em>reasonable </em>amount of effort which, upon further inspection, turned out to be entirely unnecessary as you could change anyone's password without the OTP.</p><hr><h3 id="password-reset-tokens-do-not-expire">Password Reset Tokens Do Not Expire</h3><p>Once a valid reset token had arrived in your inbox, it never expires... even after your password had changed.  Anyone, at any time thereafter, could use the same link to change the parent/guardian's password once again.</p><hr><h3 id="api-keys-hard-coded-in-the-apk">API keys hard-coded in the APK</h3><p>Production API keys in code?!</p><figure class="kg-card kg-image-card"><img src="https://paul.reviews/content/images/2026/09/8f479226-d70a-4a53-8669-53708e36ff74.png" class="kg-image" alt="" loading="lazy" width="653" height="127" srcset="https://paul.reviews/content/images/size/w600/2026/09/8f479226-d70a-4a53-8669-53708e36ff74.png 600w, https://paul.reviews/content/images/2026/09/8f479226-d70a-4a53-8669-53708e36ff74.png 653w"></figure><p>These were later changed... but it gives some insight into how the wider platform was developed.</p><p>As it turns out, the developers didn't use those constants anyway...</p><hr><h3 id="just-copypaste">Just copy/paste!</h3><p>Instead of referencing those constants throughout the code, the developer simply copy/pasted them instead.</p><figure class="kg-card kg-image-card"><img src="https://paul.reviews/content/images/2026/09/94b24695-60bf-4b85-9c31-b0a9401bf7dc.png" class="kg-image" alt="" loading="lazy" width="984" height="160" srcset="https://paul.reviews/content/images/size/w600/2026/09/94b24695-60bf-4b85-9c31-b0a9401bf7dc.png 600w, https://paul.reviews/content/images/2026/09/94b24695-60bf-4b85-9c31-b0a9401bf7dc.png 984w" sizes="(min-width: 720px) 720px"></figure><hr><h2 id=""></h2><h2 id="file-scanning">File Scanning</h2><p>When you copy a file to the HMD Fuse, or someone sends it via a messaging app, it hits the file system and triggers the file scanning service.</p><p>The AI then classifies the image and, if it's deemed harmful, quarantines it automatically.</p><p>Sounds great, in theory.  The child "can't save it, share it, view it" etc... as per the marketing material.</p><p>However, it works by scanning files <em>which are indexed by Android</em>.  But what happens if the file is in a directory path which <em>isn't </em>indexed, by design?</p><p>You guessed it.  Any directory with a .name convention is ignored completely.</p><p>So the child can create a folder called ".porn" and store whatever they like.  There's nothing preventing them sharing it either.</p><figure class="kg-card kg-video-card kg-width-regular" data-kg-thumbnail="https://paul.reviews/content/media/2026/09/filequarantined_thumb.jpg" data-kg-custom-thumbnail="">
851            <div class="kg-video-container">
852                <video src="https://paul.reviews/content/media/2026/09/filequarantined.mp4" poster="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" width="1920" height="1080" playsinline="" preload="metadata" style="aspect-ratio: 1920 / 1080; background: transparent url('https://paul.reviews/content/media/2026/09/filequarantined_thumb.jpg') 50% 50% / cover no-repeat;"></video>
853                <div class="kg-video-overlay">
854                    <button class="kg-video-large-play-icon" aria-label="Play video">
855                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
856                            <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"></path>
857                        </svg>
858                    </button>
859                </div>
860                <div class="kg-video-player-container">
861                    <div class="kg-video-player">
862                        <button class="kg-video-play-icon" aria-label="Play video">
863                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
864                                <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"></path>
865                            </svg>
866                        </button>
867                        <button class="kg-video-pause-icon kg-video-hide" aria-label="Pause video">
868                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
869                                <rect x="3" y="1" width="7" height="22" rx="1.5" ry="1.5"></rect>
870                                <rect x="14" y="1" width="7" height="22" rx="1.5" ry="1.5"></rect>
871                            </svg>
872                        </button>
873                        <span class="kg-video-current-time">0:00</span>
874                        <div class="kg-video-time">
875                            /<span class="kg-video-duration">0:51</span>
876                        </div>
877                        <input type="range" class="kg-video-seek-slider" max="100" value="0">
878                        <button class="kg-video-playback-rate" aria-label="Adjust playback speed">1×</button>
879                        <button class="kg-video-unmute-icon" aria-label="Unmute">
880                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
881                                <path d="M15.189 2.021a9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h1.794a.249.249 0 0 1 .221.133 9.73 9.73 0 0 0 7.924 4.85h.06a1 1 0 0 0 1-1V3.02a1 1 0 0 0-1.06-.998Z"></path>
882                            </svg>
883                        </button>
884                        <button class="kg-video-mute-icon kg-video-hide" aria-label="Mute">
885                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
886                                <path d="M16.177 4.3a.248.248 0 0 0 .073-.176v-1.1a1 1 0 0 0-1.061-1 9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h.114a.251.251 0 0 0 .177-.073ZM23.707 1.706A1 1 0 0 0 22.293.292l-22 22a1 1 0 0 0 0 1.414l.009.009a1 1 0 0 0 1.405-.009l6.63-6.631A.251.251 0 0 1 8.515 17a.245.245 0 0 1 .177.075 10.081 10.081 0 0 0 6.5 2.92 1 1 0 0 0 1.061-1V9.266a.247.247 0 0 1 .073-.176Z"></path>
887                            </svg>
888                        </button>
889                        <input type="range" class="kg-video-volume-slider" max="100" value="100">
890                    </div>
891                </div>
892            </div>
893            
894        </figure><hr><h2 id="camera-scanning">Camera Scanning</h2><p>The camera scanner works on the same premise; scan the picture for harm and if it's detected, block the camera with an overlay.</p><p>However, it's sluggish and very fragile.  If you happen to capture something harmful, you'd hope the file scanner would detect it afterwards.<
894/p><p>... and it does, unless you save it in .porn.</p><hr><h2 id="screen-scanning">Screen Scanning</h2><p>Here's where it gets really interesting.</p><p>In order to test the screen scanner effectively, I extracted the AI model from the HMD Fuse and began synthetic testing using their own code.</p><p>The results were... mind-boggling.  Suffice to say, the model's performance was so poor, I immediately began questioning my testing methodology.</p><figure class="kg-card kg-image-card"><img src="https://paul.reviews/content/images/2026/09/testbenchv1.png" class="kg-image" alt="" loading="lazy" width="1449" height="1233" srcset="https://paul.reviews/content/images/size/w600/2026/09/testbenchv1.png 600w, https://paul.reviews/content/images/size/w1000/2026/09/testbenchv1.png 1000w, https://paul.reviews/content/images/2026/09/testbenchv1.png 1449w" sizes="(min-width: 720px) 720px"></figure><p>At first glance, you'd be forgiven for thinking 15 false positives across 2000 test images is very good.</p><p>Look closer.</p><p>The model has multiple output neurons, but only 4 actually respond in any meaningful way.</p><p>The <strong>only two</strong> used by the SDK are "neutral" shown in blue and "NSFW" in red.</p><p>Spot the problem?</p><p>Whilst the "neutral" neuron varies as you'd expect, the "NSFW" neuron is basically fixed at 0.065; so slight, it doesn't show up on a graph.</p><p>The model/system has detected largely neutral/safe images, thus the majority of images pass as safe.</p><p>But, what happens if we test with 2000 NSFW images?</p><figure class="kg-card kg-image-card"><img src="https://paul.reviews/content/images/2026/09/testbenchv1-1.png" class="kg-image" alt="" loading="lazy" width="1031" height="561" srcset="https://paul.reviews/content/images/size/w600/2026/09/testbenchv1-1.png 600w, https://paul.reviews/content/images/size/w1000/2026/09/testbenchv1-1.png 1000w, https://paul.reviews/content/images/2026/09/testbenchv1-1.png 1031w" sizes="(min-width: 720px) 720px"></figure><p>1630 images blocked, 443 (21%) incorrectly categorized as safe.</p><p>Once again, the "NSFW" neuron output is basically fixed across all 2000 test images.</p><p>If the NSFW neuron isn't moving from an effectively fixed baseline, the model isn't detecting harm.  If it's not detecting harm, <strong>how does it work?</strong></p><hr><h2 id="when-all-else-fails-fresh-tactics">When all else fails, fresh tactics.</h2><p>I wasn't happy with those statistics; something didn't add up.</p><p>Either the model was effectively broken, or my testing procedure was giving anomalous data.</p><p>As a result, I moved away from synthetic testing and pivoted toward a much simpler, cleaner approach.</p><ol><li>Load an image on the phone.</li><li>Wait for the screenshot service to fire.</li><li>Grab the logs, parse the "neutral" and "porn" outputs.</li><li>Rinse, repeat.</li></ol><p>That way, there's no possible way I'm misinterpreting data.  I'm literally watching a physical device load neutral/porn images and collecting massive (and I mean <strong>massive</strong>) amounts of data.</p><p>The astute amongst you will note, I said "neutral" and "<strong>porn</strong>" in #3, as opposed to "NSFW".</p><p>That's not a mistake.  For whatever reason, the model labels them as "neutral" and "NSFW" but the SDK later reclassifies that output as "porn".</p><p>They're two entirely different concepts, but I digress.</p><p>The Harmblock SDK uses a "softmax" function.</p><figure class="kg-card kg-image-card"><img src="https://paul.reviews/content/images/2026/09/softmax_explanation.png" class="kg-image" alt="" loading="lazy" width="1536" height="1024" srcset="https://paul.reviews/content/images/size/w600/2026/09/softmax_explanation.png 600w, https://paul.reviews/content/images/size/w1000/2026/09/softmax_explanation.png 1000w, https://paul.reviews/content/images/2026/09/softmax_explanation.png 1536w" sizes="(min-width: 720px) 720px"></figure><p>Put simply, a softmax function creates a competition between neutral &amp; porn.</p><p><strong>This is a very ineffective way to measure harm in this context.</strong></p><p>If you measure harm as a competition against neutral, a failure to recognise neutral makes everything look like harm.</p><p>Let me put it another way...</p><p>Imagine a dog that barks at everyone it doesn't recognise. You could reasonably say, “<em>My dog barks at people he doesn't recognise</em>.” But you couldn't reasonably conclude, “<em>My dog barks at burglars 100% of the time.</em>”</p><p>The dog has no knowledge or understanding of what a burglar is. It is simply reacting to unfamiliarity, and occasionally a burglar will be among the people it barks at.</p><p>In deliberately simplified terms, that's the failure mode I'm seeing with HarmBlock. It doesn't look like “detect harm” so much as “if this doesn't look sufficiently like what I know to be neutral, increase the NSFW score.”</p><p>If you test the model directly with raw images, this becomes much easier to see. If you test the complete pipeline, including the softmax transformation, the distinction can be surprisingly easy to miss, even if you're looking at the system professionally.</p><h2 id="hang-on-a-minute">Hang on a minute?!</h2><p>If they've used a softmax function over <strong>two </strong>values, what happened to the claimed "11 unique categories of harm".</p><p>How can it possibly detect CSAM if the model doesn't output anything resembling a CSAM score?</p><p>Put simply, it can't.</p><p>There are 11 outputs from the SDK.</p><ol><li>Neutral</li><li>Porn</li><li>Art</li><li>CSAM</li><li>Face</li><li>Family</li><li>Hands</li><li>Hentai</li><li>Pet</li><li>Subjective</li><li>Confidence</li></ol><h3 id="hard-coded-categories-of-harm-including-csam">Hard-Coded Categories of Harm, including CSAM.</h3><p>So how do you get 11 values when the system only uses 2?</p><p>You hard-code them!</p><p>Seriously.  Every single category of harm, including CSAM, is hard-coded to 0.</p><p>Not "no data", not "coming soon"... the SDK gives the impression the model has output 0.  In reality, there was never any value to pass on... so it spoofs it.</p><h3 id="that-still-doesnt-explain-why-our-statistics-are-wildly-different">That still doesn't explain why our statistics are wildly different...</h3><p>My synthetic tests replicated their exact model &amp; code to the letter, yet my performance figures were off.</p><p>The results were mind-boggling. So much so, I had to rework the testbench and test the device itself.</p><h3 id="please-rotate-responsibly">Please Rotate Responsibly</h3><figure class="kg-card kg-embed-card"><iframe width="200" height="150" src="https://www.youtube.com/embed/B4jm3u30kjI?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture;
894 web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" title="HarmBlock AI's Fragile &quot;Child Safety&quot;"></iframe></figure><p>Forget how accurate the model is, even if it classifies an image as harmful, my testing shows a 70% chance that rotating the phone collapses the confidence level to such an extent, the harmful image reappears.</p><p>These aren't isolated cases either.  I ran the exact same corpus through the revised testbench... and the figures deviated by 2%, or within the margin of error.</p><p>Did nobody think to try the "world's safest phone" in landscape too?!</p><p>More to the point, why does the application (files/photos) affect the result so dramatically?  It's almost as if they've trained it not to recognise harm, but to recognise exceptions from normal.</p><p>The above video is running on the actual device and shows how the orientation massively affects the confidence score.</p><p>But it's not clear how so few pixels, from an application overlay to the navigation buttons materially affect the confidence score.</p><p>Here's a better example.</p><figure class="kg-card kg-video-card kg-width-regular" data-kg-thumbnail="https://paul.reviews/content/media/2026/09/fragile_thumb.jpg" data-kg-custom-thumbnail="">
895            <div class="kg-video-container">
896                <video src="https://paul.reviews/content/media/2026/09/fragile.mp4" poster="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" width="1920" height="1080" playsinline="" preload="metadata" style="aspect-ratio: 1920 / 1080; background: transparent url('https://paul.reviews/content/media/2026/09/fragile_thumb.jpg') 50% 50% / cover no-repeat;"></video>
897                <div class="kg-video-overlay">
898                    <button class="kg-video-large-play-icon" aria-label="Play video">
899                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
900                            <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"></path>
901                        </svg>
902                    </button>
903                </div>
904                <div class="kg-video-player-container">
905                    <div class="kg-video-player">
906                        <button class="kg-video-play-icon" aria-label="Play video">
907                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
908                                <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"></path>
909                            </svg>
910                        </button>
911                        <button class="kg-video-pause-icon kg-video-hide" aria-label="Pause video">
912                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
913                                <rect x="3" y="1" width="7" height="22" rx="1.5" ry="1.5"></rect>
914                                <rect x="14" y="1" width="7" height="22" rx="1.5" ry="1.5"></rect>
915                            </svg>
916                        </button>
917                        <span class="kg-video-current-time">0:00</span>
918                        <div class="kg-video-time">
919                            /<span class="kg-video-duration">0:53</span>
920                        </div>
921                        <input type="range" class="kg-video-seek-slider" max="100" value="0">
922                        <button class="kg-video-playback-rate" aria-label="Adjust playback speed">1×</button>
923                        <button class="kg-video-unmute-icon" aria-label="Unmute">
924                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
925                                <path d="M15.189 2.021a9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h1.794a.249.249 0 0 1 .221.133 9.73 9.73 0 0 0 7.924 4.85h.06a1 1 0 0 0 1-1V3.02a1 1 0 0 0-1.06-.998Z"></path>
926                            </svg>
927                        </button>
928                        <button class="kg-video-mute-icon kg-video-hide" aria-label="Mute">
929                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
930                                <path d="M16.177 4.3a.248.248 0 0 0 .073-.176v-1.1a1 1 0 0 0-1.061-1 9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h.114a.251.251 0 0 0 .177-.073ZM23.707 1.706A1 1 0 0 0 22.293.292l-22 22a1 1 0 0 0 0 1.414l.009.009a1 1 0 0 0 1.405-.009l6.63-6.631A.251.251 0 0 1 8.515 17a.245.245 0 0 1 .177.075 10.081 10.081 0 0 0 6.5 2.92 1 1 0 0 0 1.061-1V9.266a.247.247 0 0 1 .073-.176Z"></path>
931                            </svg>
932                        </button>
933                        <input type="range" class="kg-video-volume-slider" max="100" value="100">
934                    </div>
935                </div>
936            </div>
937            
938        </figure><p>To test my (admittedly wild) theory, I hit the model with thousands upon thous
938ands of bizarre images.  None of them NSFW in any measurable way, but sufficiently random to confuse a model looking not for harm, but deviations from normality.</p><figure class="kg-card kg-image-card"><img src="https://paul.reviews/content/images/2026/09/odd_result.png" class="kg-image" alt="" loading="lazy" width="516" height="233"></figure><p>Suffice to say, it failed miserably.</p><p>It really doesn't like pumpkins.  Ironically, it's not a fan of finger plasters either.</p><figure class="kg-card kg-video-card kg-width-regular" data-kg-thumbnail="https://paul.reviews/content/media/2026/09/invertedCat_thumb.jpg" data-kg-custom-thumbnail="">
939            <div class="kg-video-container">
940                <video src="https://paul.reviews/content/media/2026/09/invertedCat.mp4" poster="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" width="1280" height="720" playsinline="" preload="metadata" style="aspect-ratio: 1280 / 720; background: transparent url('https://paul.reviews/content/media/2026/09/invertedCat_thumb.jpg') 50% 50% / cover no-repeat;"></video>
941                <div class="kg-video-overlay">
942                    <button class="kg-video-large-play-icon" aria-label="Play video">
943                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
944                            <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"></path>
945                        </svg>
946                    </button>
947                </div>
948                <div class="kg-video-player-container">
949                    <div class="kg-video-player">
950                        <button class="kg-video-play-icon" aria-label="Play video">
951                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
952                                <path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"></path>
953                            </svg>
954                        </button>
955                        <button class="kg-video-pause-icon kg-video-hide" aria-label="Pause video">
956                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
957                                <rect x="3" y="1" width="7" height="22" rx="1.5" ry="1.5"></rect>
958                                <rect x="14" y="1" width="7" height="22" rx="1.5" ry="1.5"></rect>
959                            </svg>
960                        </button>
961                        <span class="kg-video-current-time">0:00</span>
962                        <div class="kg-video-time">
963                            /<span class="kg-video-duration">0:41</span>
964                        </div>
965                        <input type="range" class="kg-video-seek-slider" max="100" value="0">
966                        <button class="kg-video-playback-rate" aria-label="Adjust playback speed">1×</button>
967                        <button class="kg-video-unmute-icon" aria-label="Unmute">
968                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
969                                <path d="M15.189 2.021a9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h1.794a.249.249 0 0 1 .221.133 9.73 9.73 0 0 0 7.924 4.85h.06a1 1 0 0 0 1-1V3.02a1 1 0 0 0-1.06-.998Z"></path>
970                            </svg>
971                        </button>
972                        <button class="kg-video-mute-icon kg-video-hide" aria-label="Mute">
973                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
974                                <path d="M16.177 4.3a.248.248 0 0 0 .073-.176v-1.1a1 1 0 0 0-1.061-1 9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h.114a.251.251 0 0 0 .177-.073ZM23.707 1.706A1 1 0 0 0 22.293.292l-22 22a1 1 0 0 0 0 1.414l.009.009a1 1 0 0 0 1.405-.009l6.63-6.631A.251.251 0 0 1 8.515 17a.245.245 0 0 1 .177.075 10.081 10.081 0 0 0 6.5 2.92 1 1 0 0 0 1.061-1V9.266a.247.247 0 0 1 .073-.176Z"></path>
975                            </svg>
976                        </button>
977                        <input type="range" class="kg-video-volume-slider" max="100" value="100">
978                    </div>
979                </div>
980            </div>
981            
982        </figure><p>
982Richard's explanation gives us an insight into how their model has been trained... and possibly explains the failure modes I've witnessed.</p><p>Whilst there's nothing inherently wrong with hard-negative training to an extent, it's designed to help a model better understand the boundary between harm and harmless content. If the response to every false positive is simply to add more instances as “neutral”, the process progressively teaches the model what isn't harmful without proportionally strengthening its understanding of what is.</p><p>The correct question is to ask what about the false-positive image did the model consider harmful? Was it the lighting, exposure, angle, composition, or, in this particular case, something as simple as an elongated shape?</p><p>The negative class isn't supposed to become the thing the model primarily understands. Otherwise, you risk ending up with a model trained to identify exceptions from a rule, rather than harm itself.</p><p>Take that last image in particular. The model assigned it a 52% NSFW probability, enough to trigger the block. If we cannot reasonably identify what characteristics of the image constitute evidence of harm, that should trigger an uncomfortable question: have we collapsed to a bias? Has the model stopped learning “harmful” in any useful sense, and instead learned what does not look sufficiently neutral?</p><p>If you're not careful, you create an exception-driven training loop: every false positive becomes another exception to teach the model, rather than an opportunity to understand why it failed to recognise harm. You're treating the symptom, not the cause.</p><p>This is an important distinction, and one which has perhaps eluded SafeToNet.</p><p>Now, I can't point the finger squarely at Richard Pursey here. His passion clearly exceeds his technical knowledge, by his own admission. But when the person promoting the technology openly acknowledges that the model “blocks strange &amp; spurious things”, that should ring alarm bells. “Spurious” isn't a technical explanation for a false positive. It's a de
982scription of the failure. The question is whether the people building the system understand why it happens.</p><hr><h2 id="quarantined-files">Quarantined Files</h2><p>The quarantine section is a reasonable solution to inevitable false positives; giving the parent the ability to restore harmless images &amp; more importantly, delete harmful ones.</p><h3 id="encryption">"Encryption"</h3><p>When a file is quarantined, Harmblock encrypts it with AES-CBC and moves the file to a location inaccessible to the child.</p><p>Whilst the cryptographic primitive is sound, the implementation is not.</p><p>There's no HMAC, thus no integrity whatsoever.  But more importantly, the "secret" key they've used to protect the file is...</p><p><strong>The IMEI number.</strong></p><p>Someone thought they were being smart running it through PBKDF2 at 10,000 iterations, with a fixed salt of "HarmBlockFixedSalt" - but PBKDF2 is supposed to make brute-force attacks computationally infeasible against a <strong><em>secret</em></strong>.</p><p>It also has a faint whiff of someone who Google'd "how to encrypt files on Android" and copied the first result from 2015.  10,000 iterations was fine, in 2015.  In 2026, the recommended <strong>minimum </strong>is 600,000.  But again, nobody is brute-forcing a value printed on the box... they're just burning CPU cycles whilst pretending it adds security.</p><h3 id="youre-on-your-own-kid">You're on your own, kid.</h3><p>No model is perfect; false positives are a considered risk here.  Both genuinely harmful images &amp; false positives are quarantined automatically.</p><p>But what happens when the model fails to detect harmful content... a false negative?</p><p>Nothing.</p><figure class="kg-card kg-image-card"><img src="https://paul.reviews/content/images/2026/09/ChatGPT-Image-Sep-22--2026--08_11_00-AM.png" class="kg-image" alt="" loading="lazy" width="1536" height="1024" srcset="https://paul.reviews/content/images/size/w600/2026/09/ChatGPT-Image-Sep-22--2026--08_11_00-AM.png 600w, https://paul.reviews/content/images/size/w1000/2026/09/ChatGPT-Image-Sep-22--2026--08_11_00-AM.png 1000w, https://paul.reviews/content/images/2026/09/ChatGPT-Image-Sep-22--2026--08_11_00-AM.png 1536w" sizes="(min-width: 720px) 720px"></figure><p>Almost unbelievably, there's no mechanism for the child to protect themselves from content <strong>they </strong>deem harmful.</p><p>The entire safeguarding pathway depends on the model getting it right.</p><p>That's quite the omission in a child-safety device.</p><h3 id="pre-computed-recovery-paths">Pre-computed Recovery Paths</h3><p>When Harmblock quarantines a file, you'd be forgiven for thinking it digests the image, runs a complex hashing algorithm across it and makes damn sure it never shows a harmful image again.</p><p>Nope.</p><p>The entire quarantine system works on paths/filenames.</p><p>If a harmless image is quarantined as /storage/flowers.jpg and a parent subsequently restores it, it creates a file called recovery_map.json which whitelists /storage/flowers.jpg from the file scanner.</p><p>You can guess where this is going...</p><p>Now, an attacker (or the child) can download any pornographic image to /storage/flowers.jpg and the file scanner dutifully ignores it.</p><p>Sigh.  What a farce.</p><p>But because the recovery_map.json file is stored on external storage, you can simply create a file <strong>in advance</strong>, with all the pornographic images "<em>restored</em>".</p><hr><h3 id="pre-computed-recovery-pathsno-error-checking">Pre-computed Recovery Paths - No error checking</h3><p>Much like the settings.txt vulnerability earlier, there's no defensive code here either.</p><p>Create a file with an invalid character in recovery_map.json and the scanner crashes completely, never to return.</p><hr><h2 id="service-restoredignore-the-security-warning">Service Restored - Ignore the Security Warning</h2><p>When the service came back online on September 10th 2026, users were greeted with this.</p><figure class="kg-card kg-image-card"><img src="https://paul.reviews/content/images/2026/09/restored1_small-2.png" class="kg-image" alt="" loading="lazy" width="1028" height="1011" srcset="https://paul.reviews/content/images/size/w600/2026/09/restored1_small-2.png 600w, https://paul.reviews/content/images/size/w1000/2026/09/restored1_small-2.png 1000w, https://paul.reviews/content/images/2026/09/restored1_small-2.png 1028w" sizes="(min-width: 720px) 720px"></figure><p>Such was the rush to get this back into service, their instructions explicitly tell users to ignore Google's security warning and install the update anyway.</p><p>They're teaching parents to skip security warnings... on a child safety device?!  What could go wrong.</p><h2 id="an-indefensible-legal-problem">
982An indefensible legal problem?</h2><p>Remember, HarmBlock is marketed as detecting and blocking harmful content, including CSAM.</p><p>Yet, based on the code, there appears to be no separate safeguarding pathway for content that falls into the most serious category. Instead, potentially harmful imagery appears to enter the same quarantine mechanism.</p><p>Let me explain the flow, step by step.</p><ol><li>An image lands on the device.</li><li>The file-system scanner detects it and apparently classifies it.</li><li>The quarantine mechanism removes the original, <strong>creates a separate copy</strong> and encrypts that copy using a key derived from the device's IMEI.</li><li>That quarantined copy remains on the device for up to 30 days before automatic deletion.</li></ol><p>Now consider what happens if the image isn't merely pornography, but an indecent image of a child.</p><p>UK law treats the making and possession of indecent images of children extremely seriously. “Making” has been interpreted broadly and includes <strong>creating an electronic copy of an image</strong>.</p><p>Whilst there are specific legal protections for people who necessarily make copies in order to prevent, detect or investigate crime or report suspected child-abuse material, that doesn't apply here.  SafeToNet explicitly states "no data ever leaves the device" and although that's technically not true either, they make no attempt to notify the parent or authorities when an obvious CSAM image is detected.</p><p>But that makes the absence of an apparent safeguarding pathway even more important.</p><p>If the system has positively identified material as CSAM, what is the legal/moral reasoning behind creating a second encrypted copy, retaining it for 30 days, and making it available for subsequent parental review?  Once you become the digital custodian of CSAM and control access to it, you're likely in severe legal hot water.</p><p>What happens when a parent opens the quarantine and the device displays the suspected CSAM to them?  The application has literally disseminated material it knows is CSAM... and asks the parent to decide on an appropriate course of action.</p><p>Detection is not the end of the safeguarding process. It is the point at which the safeguarding process should begin.  If your child is actively being groomed, the HMD Fuse is diligently clearing up the evidence every 30 days.</p><h2 id="who-cares-we-care">Who cares? We care.</h2><p>I have to give massive credit to VodafoneThree for their response.</p><p>I notified the CEO, who promptly put me in touch with a senior executive.  Within hours, the product had been quarantined from their websites; swift &amp; decisive action. How refreshing.</p><p>That was a month ago... so I asked VodafoneThree for comment.</p><blockquote class="kg-blockquote-alt">"VodafoneThree has paused sales of the HMD Fuse while the reported issues are reviewed. We remain in close contact with HMD while it continues to address the issues raised."</blockquote><p>I'm slightly concerned to hear they've "paused sales", which suggests it may return... though I honestly can't see that happening.</p><p>I also asked the Internet Watch Foundation (IWF) for comment.</p><figure class="kg-card kg-image-card"><img src="https://paul.reviews/content/images/2026/09/iwfcomment.png" class="kg-image" alt="" loading="lazy" width="1573" height="1138" srcset="https://paul.reviews/content/images/size/w600/2026/09/iwfcomment.png 600w, https://paul.reviews/content/images/size/w1000/2026/09/iwfcomment.png 1000w, https://paul.reviews/content/images/2026/09/iwfcomment.png 1573w" sizes="(min-width: 720px) 720px"></figure><h2 id="summary">Summary</h2><p>Child safety is a complex, nuanced &amp; emotive topic.  Technical solutions like these require our utmost attention &amp; due diligence to ensure they deliver on their promises.</p><p>We desperately need more independent research to highlight material failures in basic governance, safety, security &amp; accountability.</p><p>If you/your child still has one of these devices, you can return them as "unfit for purpose".</p><p>Furthermore, I would <strong>strongly </strong>advise everyone to submit a subject access request (SAR) to HMD (and/or SafeToNet/Xplora where necessary) to see if you've been affected by any of these vulnerabilities.  Keep in mind, your logs will contain potentially sensitive information and should be handled appropriately; encrypted at source, shared securely and crucially... deleted upon closure of your account (right to erasure).</p><p>Do not simply throw your device away or stop using it.  You <strong>must </strong>ensure you/your child's information has been expunged entirely.</p>
983  </div>
984
985      <div class="flex gap-4 justify-between items-center -mb-4">
986        <div class="sm:hidden text-lg font-semibold">Share this article</div>
987        <a
988          href="#share"
989          class="flex items-center px-4 gap-2 py-2 bg-page-alt hover:bg-accent/10 text-content-alt hover:text-accent rounded-full transition-all duration-200 font-semibold text-sm h-9"
990          title="Share this article"
991          aria-label="Share this article">
992          <div data-icon="share" class="scale-115 font-thin -mx-1 -mt-0.5"></div>
993          Share
994        </a>
995
996          <div class="hidden sm:flex items-center gap-2 ">
997              <a href="/tag/harmblock/" class="flex items-center shrink-0 px-4 py-2 rounded-full text-xs font-semibold min-w-14 text-center transition-all duration-200 whitespace-nowrap h-9 bg-page-alt hover:bg-accent/10">harmblock</a>
998              <a href="/tag/safetonet/" class="flex items-center shrink-0 px-4 py-2 rounded-full text-xs font-semibold min-w-14 text-center transition-all duration-200 whitespace-nowrap h-9 bg-page-alt hover:bg-accent/10">safetonet</a>
999              <a href="/tag/hmd-fuse/" class="flex items-center shrink-0 px-4 py-2 rounded-full text-xs font-semibold min-w-14 text-center transition-all duration-200 whitespace-nowrap h-9 bg-page-alt hover:bg-accent/10">hmd fuse</a>
1000          </div>
1001      </div>
1002</article>
1003
1004
1005    </div>
1006    
1007<div class="max-w-(--post-content-max-width) w-full min-w-80 flex-1 ">
1008  <div class="flex flex-col gap-4 sticky top-0 lg:pt-4 max-lg:-mt-8">
1009      <table-of-contents
1010        class="mb-12 max-lg:hidden"
1011        list-class="list-none"
1012        h2-class="block py-1.5 pl-5 text-sm text-content-alt font-medium hover:text-content-muted transition-colors duration-200 no-underline border-l hover:border-content-muted [&[data-active]]:text-accent [&[data-active]]:border-accent"
1013        h3-class="block py-1.5 pl-8 text-sm text-content hover:text-content-muted transition-colors duration-200 no-underline border-l hover:border-content-muted [&[data-active]]:text-accent [&[data-active]]:border-accent">
1014        <h3 class="text-base font-semibold text-content flex items-center gap-2 -ml-0.5 mb-2">
1015          <span data-icon="menu" class="text-content-muted text-xs opacity-80 -mr-0.5"></span>
1016          On this page
1017        </h3>
1018      </table-of-contents>
1019    <h3 class="text-xl font-heading lg:text-lg lg:font-semibold">What&#x27;s Next?</h3>
1020    <div class="related-posts-list flex flex-col gap-6 max-lg:[&>*:nth-child(n+5)]:hidden lg:[&>*:nth-child(n+7)]:hidden " data-posts>
1021
1022        
1023<article
1024  
1025  data-post-id="6aa9420c9a33388bd4fe6377"
1026  style="--hover-bg-color:var(--color-page-alt); "
1027  class="
1028    post-card group relative z-0 flex flex-col [--post-card-roundness:calc(var(--radius-card)*2)]
1029    before:absolute before:-inset-3 before:rounded-(--post-card-roundness) before:content-[''] before:bg-(--hover-bg-color) before:opacity-0 before:scale-95 before:transition-all before:-z-10 before:duration-240 before:ease-out-quad hover:before:opacity-100 hover:before:scale-100
1030    
1031    @container !flex-row-reverse gap-3
1032  ">
1033
1034    
1035  <figure class="relative post-card-image w-full aspect-(--post-card-image-aspect-ratio) rounded-card overflow-hidden object-cover !max-w-30 !max-h-24 !w-full !h-full shrink-0 @max-[18rem]:hidden ">
1036    <img
1037      alt="The shocking state of ZPos: Order takeaway &amp; pay what you like."
1038      class="group-hover:scale-102 transition-all duration-230 ease-out-quad"
1039      loading="lazy"
1040      src="/content/images/size/w600/2025/06/logo.png" 
1041      srcset="/content/images/2025/06/logo.png 320w, 
1042              /content/images/size/w600/2025/06/logo.png 600w, 
1043              /content/images/size/w960/2025/06/logo.png 960w, 
1044              /content/images/size/w1200/2025/06/logo.png 1200w, 
1045              /content/images/size/w2000/2025/06/logo.png 2000w"
1046    >
1047      <figcaption class="hidden">The shocking state of ZPos. Order takeaway &amp; pay what you like.</figcaption>
1048      <a href="https://paul.reviews/the-shocking-state-of-zpos-order-takeaway-pay-what-you-like/" class="absolute inset-0 z-10" aria-label="Read: The shocking state of ZPos: Order takeaway & pay what you like."></a>
1049  </figure>
1050
1051  <a href="/the-shocking-state-of-zpos-order-takeaway-pay-what-you-like/" class="absolute inset-0 z-0" aria-label="Read: The shocking state of ZPos: Order takeaway &amp; pay what you like."></a>
1052
1053  <div class="post-card-content flex flex-col !py-0">
1054
1055    <div class="post-card-meta flex items-center gap-2 mb-2 min-h-7
1056      -mt-9 mb-5 mx-3 relative z-10
1057      !hidden">
1058
1059
1060    </div>
1061
1062    <h2 class="post-card-title text-xl leading-snug font-semibold line-clamp-2 !text-base !leading-snug">
1063      <a href="/the-shocking-state-of-zpos-order-takeaway-pay-what-you-like/">The shocking state of ZPos: Order takeaway &amp; pay what you like.</a>
1064    </h2>
1065
1066    <a href="/the-shocking-state-of-zpos-order-takeaway-pay-what-you-like/" class="post-card-excerpt line-clamp-3 text-sm leading-normal mt-2 opacity-95 !line-clamp-2 !mt-1">
1067        In July 2020, I ordered a takeaway from Napolis Pizza.
1068
1069Like many firms across the UK, they use ZPos for their websites and electronic point of sale. A snazzy website, simple &amp; easy to use ordering and minimal processing fees (compared to others in this space), it seems like a great deal for businesses and consumers alike.
1070
1071However, it quickly became clear that far from the &quot;super secure&quot; service they promote, it&#39;s an absolute mess which only places their client - and subsequently you &amp; I - at c
1072    </a>
1073
1074    <footer class="flex items-center gap-1.5 mt-2 text-xs [&amp;_.post-card-author-image]:hidden !mt-1 text-xs flex-wrap">
1075        <div class="post-card-author flex items-center gap-2">
1076            <img src="https://paul.reviews/content/images/2026/09/fnNCyHOc_400x400.jpg" alt="Paul Moore" class="post-card-author-image w-7 h-7 rounded-full object-cover">
1077          <a href="/author/paul/" class="post-card-author-name opacity-80 hover:underline">Paul Moore</a>
1078        </div>
1079        <span class="text-[0.75em] opacity-65">•</span>
1080      <time class="opacity-80" datetime="2025-06-19">
1081        <span>a year ago</span>
1082        <span class="hidden">Jun 19, 2025</span>
1083      </time>
1084    </footer>
1085  </div>
1086</article>
1087
1088
1089          
1090<article
1091  
1092  data-post-id="6aa9886018405a8ea1adc1d9"
1093  style="--hover-bg-color:var(--color-page-alt); "
1094  class="
1095    post-card group relative z-0 flex flex-col [--post-card-roundness:calc(var(--radius-card)*2)]
1096    before:absolute before:-inset-3 before:rounded-(--post-card-roundness) before:content-[''] before:bg-(--hover-bg-color) before:opacity-0 before:scale-95 before:transition-all before:-z-10 before:duration-240 before:ease-out-quad hover:before:opacity-100 hover:before:scale-100
1097    
1098    @container !flex-row-reverse gap-3
1099  ">
1100
1101    
1102  <figure class="relative post-card-image w-full aspect-(--post-card-image-aspect-ratio) rounded-card overflow-hidden object-cover !max-w-30 !max-h-24 !w-full !h-full shrink-0 @max-[18rem]:hidden ">
1103    <img
1104      alt="HarmBlock+ World&#x27;s Safest Smartphone: Please Rotate Responsibly."
1105      class="group-hover:scale-102 transition-all duration-230 ease-out-quad"
1106      loading="lazy"
1107      src="/content/images/size/w600/2026/09/banner2.png" 
1108      srcset="/content/images/2026/09/banner2.png 320w, 
1109              /content/images/size/w600/2026/09/banner2.png 600w, 
1110              /content/images/size/w960/2026/09/banner2.png 960w, 
1111              /content/images/size/w1200/2026/09/banner2.png 1200w, 
1112              /content/images/size/w2000/2026/09/banner2.png 2000w"
1113    >
1114      <a href="https://paul.reviews/harmblock-worlds-safest-smartphone-please-rotate-responsibly/" class="absolute inset-0 z-10" aria-label="Read: HarmBlock+ World's Safest Smartphone: Please Rotate Responsibly."></a>
1115  </figure>
1116
1117  <a href="/harmblock-worlds-safest-smartphone-please-rotate-responsibly/" class="absolute inset-0 z-0" aria-label="Read: HarmBlock+ World&#x27;s Safest Smartphone: Please Rotate Responsibly."></a>
1118
1119  <div class="post-card-content flex flex-col !py-0">
1120
1121    <div class="post-card-meta flex items-center gap-2 mb-2 min-h-7
1122      -mt-9 mb-5 mx-3 relative z-10
1123      !hidden">
1124
1125
1126    </div>
1127
1128    <h2 class="post-card-title text-xl leading-snug font-semibold line-clamp-2 !text-base !leading-snug">
1129      <a href="/harmblock-worlds-safest-smartphone-please-rotate-responsibly/">HarmBlock+ World&#x27;s Safest Smartphone: Please Rotate Responsibly.</a>
1130    </h2>
1131
1132    <a href="/harmblock-worlds-safest-smartphone-please-rotate-responsibly/" class="post-card-excerpt line-clamp-3 text-sm leading-normal mt-2 opacity-95 !line-clamp-2 !mt-1">
1133        ** NSFW Warning **
1134
1135Back in July 2025, the Online Safety Act was a hot topic. Many sites were frantically adding age verification under threat of criminal prosecution, if they failed to protect children from online harm.
1136
1137The law, technology and implementations were... flawed; I presented an AI-generated video of the-then Technology Secretary, Peter Kyle, in order to skip intrusive censorship. That turned out to be unnecessary, as a smiley face drawn on a thumb also bypassed the &quot;robust&quot; verific
1138    </a>
1139
1140    <footer class="flex items-center gap-1.5 mt-2 text-xs [&amp;_.post-card-author-image]:hidden !mt-1 text-xs flex-wrap">
1141        <div class="post-card-author flex items-center gap-2">
1142            <img src="https://paul.reviews/content/images/2026/09/fnNCyHOc_400x400.jpg" alt="Paul Moore" class="post-card-author-image w-7 h-7 rounded-full object-cover">
1143          <a href="/author/paul/" class="post-card-author-name opacity-80 hover:underline">Paul Moore</a>
1144        </div>
1145        <span class="text-[0.75em] opacity-65">•</span>
1146      <time class="opacity-80" datetime="2026-09-22">
1147        <span>3 days ago</span>
1148        <span class="hidden">Sep 22, 2026</span>
1149      </time>
1150    </footer>
1151  </div>
1152</article>
1153    </div>
1154  </div>
1155</div>
1156  </div>
1157</article>
1158
1159
1160    </main>
1161
1162    
1163<footer class="pt-6 pb-4 bg-page text-content-alt" data-footer>
1164  <div class="container">
1165    <div class="flex justify-between items-center">
1166      
1167<a href="https://paul.reviews" class="site-logo flex-1" style="" aria-label="Paul Moore: Information Security Consultant &amp; Researcher - Home">
1168    <img src="/content/images/2026/09/ChatGPT-Image-Sep-15--2026--06_47_01-PM.png" alt="Paul Moore: Information Security Consultant &amp; Researcher" loading="eager" class="logo"/>
1169</a>      <social-icons class="flex items-center justify-end flex-1 text-sm opacity-90 hover:opacity-100 transition-opacity duration-250" aria-label="Footer Social Media Links"></social-icons>
1170    </div>
1171
1172    <div class="flex justify-between flex-wrap md:flex-nowrap w-full py-4 my-4 gap-8 border-b border-t  border-b0">
1173      <menu-nav
1174        class="w-full max-md:basis-full flex-1 shrink-0"
1175        values-path="themeConfig.site.secondaryNavigation"
1176        orientation="horizontal"
1177        nav-class="text-sm"
1178        item-class="hover:underline"
1179        group-class="flex flex-col gap-1"
1180        group-header-class="font-medium mb-1"
1181        group-item-class="hover:underline text-sm text-content opacity-90 hover:opacity-100 transition-opacity duration-250"
1182        show-external-icon="true"
1183        aria-label="Footer Navigation"
1184      ></menu-nav>
1185    </div>
1186    <div class="flex justify-center items-center h-5.5">
1187      <p class="text-xs">
1188          &copy; 2026 Published with
1189          <a href="https://ghost.org" target="_blank" rel="noopener" class="underline">Ghost</a>
1190      </p>
1191    </div>
1192  </div>
1193</footer>  </div>
1194</div>
vendor: 123 bytes, lines 1194-1199
1194
1195
1196
1197    
1198    
1199  <script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script>
1199<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"03e8346f4b2d43c293c82f33938b432f","r":1,"spa":2}' crossorigin="anonymous"></script>
1199
1200</body>
1201</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.