Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
•
IT NachrichtenSamsung Galaxy S26 FE review: false economy(24.09.2026 um 22:07 Uhr)
••••••••••
IT NachrichtenSamsung Galaxy S26 FE review: false economy(24.09.2026 um 22:07 Uhr)
•••••••••
Intelligence View
⚡ tsecurity.de Intelligence

A UTF-8 Trap I Hit While Building a Customer Support Chat System

For years, I’ve been building an independent customer support chat system in my spare time. It didn’t start big. In the early days, only a handful of users tried it out of curiosity. Over time, it slowly grew into something real: a system …

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

For years, I’ve been building an independent customer support chat system in my spare time.



It didn’t start big. In the early days, only a handful of users tried it out of curiosity. Over time, it slowly grew into something real: a system running in production, used daily, deployed both as a hosted service and in on-premises environments. Along the way, I learned a lot—not just about writing code, but about operating and maintaining a long-lived product.



More than once, after releasing a new version, I caught myself thinking:




“This one is rock solid. Nothing can break it.”




And almost every time, reality responded a few weeks later with:




“Wait… how is this even possible?”




A few years ago, those moments happened all the time.

This year, only occasionally.

And recently, after upgrading several customer environments to the latest version without a single incident, I genuinely thought:




“Alright. This might finally be stable.”




Even my own production environment had changed.

User numbers were growing. Concurrent visitors were increasing.

Yet bug reports had almost disappeared.



That’s usually when you get careless.







“Why Is Yesterday’s Chat History Completely Gone?”



The report came in quietly:




“Why are yesterday’s conversations missing?”




No crash.

No alerts.

No errors reported by the application.



I started digging through logs late at night and found something unsettling:

the database was returning zero records—cleanly, normally. No timeout. No permission error.



It was as if the conversation had never existed.



Scrolling further back, I noticed something interesting.

The last message sent by the agent was:




“Alright, please wait a moment 🥲”




That single emoji turned out to be the culprit.



One small character had silently destroyed the entire chat record.







The Symptom: INSERT Looked Successful, but Data Was Gone



At first glance, everything looked fine.

The application logged “message saved successfully”.

No exception bubbled up.



But under the hood, the SQL statement had failed.



Here’s how the table was originally created:




CREATE TABLE chat_message (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
visitor_id VARCHAR(50),
content TEXT CHARACTER SET utf8 COLLATE utf8_general_ci,
created_at DATETIME
);






Looks reasonable, right?



Until a user sends a message containing a 4-byte character—like an emoji.




INSERT INTO chat_message (visitor_id, content, created_at)
VALUES ('A123', 'Alright, please wait 🥲', NOW());
-- Error: Incorrect string value: '\xF0\x9F\xA5\xB2' for column 'content'






The insert failed.

But the application didn’t notice.







The Hidden Problem: “utf8” in MySQL Is Not UTF-8



This is the trap.



In MySQL, utf8 is not full UTF-8.

It only supports 1–3 byte characters (the BMP).



Emoji live outside that range.




🥲 = U+1F972
UTF-8 bytes = F0 9F A5 B2






Result: the database rejects the value.



And here’s where it got worse.









The “Fake Success” at the Application Layer



I was using a .NET MySQL connector with default settings.

Combined with incomplete exception handling, the driver swallowed the failure.




try
{
await db.ExecuteAsync(
"INSERT INTO chat_message (visitor_id, content, created_at) VALUES (@v, @c, @t)",
new { v = visitorId, c = content, t = DateTime.UtcNow }
);
logger.Info("Message stored: " + content);
}
catch (Exception ex)
{
// Only logging ex.Message, no SQL error code
logger.Warn("Message error: " + ex.Message);
}






From the application’s point of view: success.

From the database’s point of view: nothing was saved.



So the agent thought the message was stored.

The next day, they opened the chat history—and found nothing.







The Fix: Switching Everything to utf8mb4



The solution itself was straightforward, once the root cause was clear.





Step 1: Update database and tables





ALTER DATABASE mychat
CHARACTER SET = utf8mb4
COLLATE = utf8mb4_unicode_ci;

ALTER TABLE chat_message
CONVERT TO CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;







Step 2: Explicitly set charset in the connection string





var connStr =
"Server=localhost;Database=mychat;Uid=root;Pwd=xxx;CharSet=utf8mb4;";







Step 3: Verify with real emoji data





var testMessage = "Welcome to our support system 🥳🔥";

await db.ExecuteAsync(
"INSERT INTO chat_message (visitor_id, content, created_at) VALUES (@v, @c, @t)",
new { v = "T001", c = testMessage, t = DateTime.UtcNow }
);

var result = await db.QuerySingleAsync<string>(
"SELECT content FROM chat_message ORDER BY id DESC LIMIT 1"
);

Console.WriteLine(result);
// Output: Welcome to our support system 🥳🔥





This time, it worked.







One More Trap: Index Length and utf8mb4



Switching to utf8mb4 introduced another surprise.




ALTER TABLE chat_message
ADD INDEX idx_v_c(visitor_id, content);
-- Error: Specified key was too long; max key length is 767 bytes






Each utf8mb4 character can take up to 4 bytes.

Indexing a long VARCHAR or TEXT column can easily exceed InnoDB limits.



The fix was to use a prefix index:




ALTER TABLE chat_message
ADD INDEX idx_v_c(visitor_id, content(100));






Or, depending on the use case, a full-text index.









Lessons Learned (the Hard Way)





  1. Never assume utf8 means UTF-8 in MySQL. It doesn’t.


  2. Always log real SQL error codes. Silent failures are worse than crashes.


  3. Test with emoji. Real users will use them—constantly.



I ended up adding this test to our deployment pipeline:




it("should store emoji without errors", async () => {
const message = "Emoji test 🐱🐶🔥";
await api.sendMessage({ visitorId: "U999", content: message });
const saved = await api.getLastMessage("U999");
expect(saved.content).toBe(message);
});






It runs every time we deploy.



Because no system—no matter how many years it’s been running—

should ever lose history to a single 🥲 again.









Wrapping up



ShenDesk is still evolving.



If you’ve ever built or deployed a real-time chat system, I’d genuinely love to hear your experience—

how you handled live updates, load balancing, or flexible deployment models in production.



Let’s compare notes.









If you’re curious



I’ve been building ShenDesk, a customer support chat system designed to run reliably

both online and on your own infrastructure.





You can try it for free, whether you prefer a hosted setup or self-hosting.



Feedback from developers interested in self-hosted systems, real-time communication,

and customer experience engineering is always welcome.









UI snapshots



Visitor side

Fast loading, no message loss



Visitor



Agent side

Reliable, feature-rich, built for real-world support work



Agent



Web admin panel



Web admin panel

CTI Threat Relationship Graph2 Knoten / 1 Relationen
CVE / Incident Software MITRE ATT&CK CWE Weakness IoC
SOC Incident Playbook: Vulnerability Remediation & Verification
Syntax validiert (0 Fehler)
title: Detect Exploitation - A UTF-8 Trap I Hit While Building a Customer Support Chat System
id: fe885abb-f299-401b-8d6d-1b6e2a08eecc
status: experimental
description: Automatisch generierte SIEM-Erkennungsregel basierend auf CTI Intelligence
references:
  - https://tsecurity.de/
author: iShareStuff CTI Automated Detection Engine
date: 2026-09-24
logsource:
  category: network_connection
  product: any
detection:
  selection:
      CommandLine|contains:
        - 'exploit'
  condition: selection
falsepositives:
  - Legitime administrative Zugriffe oder Penetrationstests
level: high
tags:
  - attack.initial_access
Syntax validiert (0 Fehler)
rule CTI_Threat_Indicator {
    meta:
        author = "iShareStuff CTI Automated Detection Engine"
        date = "2026-09-24"
        description = "YARA Signature for "
    strings:
        $str = "A UTF-8 Trap I Hit While Build" ascii wide
    condition:
        any of them
}
Syntax validiert (0 Fehler)
index=security sourcetype IN ("cisco:asa", "pan:traffic", "zeek_conn", "suricata", "WinEventLog:Security")
("A UTF-8 Trap I Hit While Building a Cust")
| stats count earliest(_time) as first_seen latest(_time) as last_seen by src_ip, dest_ip, dest_host, signature
| eval first_seen=strftime(first_seen, "%Y-%m-%d %H:%M:%S"), last_seen=strftime(last_seen, "%Y-%m-%d %H:%M:%S")
| sort - count
Syntax validiert (0 Fehler)
message: "*A UTF-8 Trap I Hit While Building a Cust*"
Syntax validiert (0 Fehler)
CommonSecurityLog
| where Message has "A UTF-8 Trap I Hit While Building a Cust"
| summarize EventCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceIP, DestinationIP, DestinationPort, Activity
| extend DetectionRule = "iShareStuff-CTI-Compiled"
| sort by EventCount desc
🎯
MITRE ATT&CK Matrix Navigator 14 Taktiken
Reconnaissance
-
Resource Development
-
Initial Access
Execution
Persistence
-
Privilege Escalation
Defense Evasion
Credential Access
-
Discovery
-
Lateral Movement
-
Collection
-
Command and Control
Exfiltration
-
Impact
tsecurity.de Cognitive Threat RAG
Fokus-Vektor:

Kognitive Analyse für identifizierte Bedrohung: Erhöhte Bedrohungslage im Bereich A UTF-8 Trap I Hit While Building a Cust.... Basierend auf 368k Vektor-Korrelationen werden sofortige Isolationsmaßnahmen für betroffene Endpunkte empfohlen.

🛡️ Angriffsfläche & Exposure

Netzwerk/Remote-Zugriff ohne Vorauthentifizierung möglich.

⚡ Empfohlene Sofortmaßnahmen
  • 1. Perimeter-Inspektion: Relevante Portfreigaben und exponierte Endpunkte unverzüglich scannen.
  • 2. Patch-Applikation: Hersteller-Hotfix einspielen oder betroffene Daemons in isolierte DMZ-Segmente überführen.
  • 3. Telemetrie & EDR-Alerts: Prozessaufrufe und Child-Processes auf anomale Shell-Spawns überwachen.
🔗 Semantisch verwandte Zero-Days MariaDB 11.7 VEC
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten A UTF-8 Trap I Hit While Building a Customer Support Chat System

Thematisch verwandte Begriffe: UTF8, Trap, While, Building · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-61823 | code16 Sharp is a Laravel-based framework for building content-managemen…
Advisory →
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel • Rechts: nächster Artikel • unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel TTP ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...
↗ Original-Quelle