Posted on: January 2, 2025
Last modified: May 7, 2025
The “Embedded Security Challenge” is a free challenge for all embedded developers. Advance step-by-step in securing your systems.
How does it work?
You have one challenge (a question, a task) to work on every week. I post the challenge every Thursday. Those challenges are platform-neutral; you can do them on embedded Linux, most RTOSes, and any hardware platform.
You can find challenged either on this website, or on Marta’s LinkedIn profile.
How to answer?
Comment on the post with your solutions; you can include links to your blog posts, social media posts, and the like.
After a week, you will find here an example solution and comment on the interesting approaches you have posted!

Challenge 1 : Network-enabled services
This week’s challenge is:
What are your product's services (applications, daemons) communicating, or potentially communicating with the Internet? Check all network interfaces. Also, check for both applications sending data and those listening.
Why is it important? This is the easiest way attackers can interact with your device.

Challenge 2 : Web-based administration and command injection
The application to administer an embedded device is a frequent target of attackers. It is easy to access (from the Internet), and bugs might be hiding inside.
The task for this week:
Use a web administration application on one of your embedded devices; it is better to have the source code. It needs to be a device you own and one not in production.
In various application forms, try special character combinations and check if you can escape the input parsing. Fix bugs you find.
You can try techniques like:
- Very long text
- Characters that end the string in the programming language of the application
- Unicode special characters
- Special characters line /n or /r
Strange behavior of the application after you type unusual characters might be a sign that you are on the right (buggy) track. Use the source code of the application to confirm how to trigger parsing bugs.
For examples of vulnerable sequences in Python, you can check out https://snyk.io/blog/command-injection-python-prevention-examples/
Similar guides exist for other programming languages.
Report what you have found out! (and report to upstream projects, if affected)

Challenge 3 : How do you store passwords?
Most devices store passwords. Those might be system passwords, passwords for a web interface login, or internal passwords for system services.
When you log in, the system compares the password you just typed with the password on record.
But how do we store that password on record? As-typed in a file? That looks like a bad idea if an attacker can copy that file…
We do not store passwords directly. Instead, we store a hash of a password. A hash is a cryptographic operation that generates a fixed-size value from any size of data or document. It is quite easy to calculate a hash, but it is hard to find the initial value from the hash (examples of popular hashes are SHA2 or SHA256, SHA3).
This is not all. Given enough time, if an attacker has access to the hash, they can try different combinations and figure out the passwords. Because of that, we do not hash once – but hundreds of thousands of times. You can find out more in the guide from OWASP: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html
The task for this week:
Find out where passwords are stored on your device, confirm that they are stored as hashes, and count how many times they are hashed.

Challenge 4 :
Testing embedded products is tough. Bugs often appear on the final device but not when running the same software on a development system. Should we stick to manual testing? Absolutely not.
Over the years, I’ve learned a few key rules for embedded testing:
– One test is better than none – perfection isn’t required.
– Test as much as possible on the host machine; use emulation when you can.
– On hardware, focus on what matters: flashing, rebooting, and hardware-specific modules.
– Test what really matters, not 100x the same arithmetic function.
– When you test on hardware, use programmable power switches for remote power cycling.
– Every bug you find? Add a test that would have caught it.
– Automate and test often – daily for teams, longer tests overnight or on weekends.
– Security releases need reliable tests to prevent regressions under pressure.
🔒 This is Thursday, the day of our Embedded security challenge. Your task for this week: Add one test of a critical functionality. No CI? Set up even a basic one.

Challenge 5 :
A sales kiosk malfunctions. The maintenance team is puzzled. No internet access, no obvious errors yet the software isn’t behaving as expected.
The culprit? One night, someone simply removed the front panel and plugged into a debug USB cable left in plain sight. They did some changes. It was easy as the USB console didn’t have any password…
Embedded devices often have hidden diagnostics and debug interfaces:
🛠️ USB console
🛠️ Physical UART
🛠️ JTAG
Too often, these stay unprotected in production – until an attacker finds them.
How about these countermeasures?
🔑 Password-protect the console
⚡ Disable USB/UART by default, enabling only in diagnostic mode
🔥 Permanently fuse off JTAG
This week’s security challenge: Which debug interfaces does your device have? How do you lock them down when not in use?

Challenge 6 :
This is a product release in an embedded company from hell: the final firmware is built on the lead developer’s machine. 🚨
You’d expect the shipped firmware to be properly tested. Automated. Reproducible. And increasingly, it is.
But not everywhere.
Remember the bricked trains example from last year? (If you missed it, check out the LWN article: https://lwn.net/Articles/970818/) One striking detail in the firmware analysis: nearly every train had a different firmware, with build machine names that didn’t look automated. How could that happen? A heavy suspicion: manual builds for each unit.
What could possibly go wrong? Well…
👉 You don’t know exactly what’s in each device – tiny differences add up.
👉 Testing is likely inconsistent (who wants to rerun full validation for every manual build?).
👉 Security patching? A complete nightmare.
Your embedded security challenge this Thursday: review your release process. At the very least, script your release preparation – no manual tweaks. Even better? Run it in an automated system on a separate build machine (GitHub, GitLab or anything else… no excuses).

Challenge 7 :
You’re troubleshooting a field incident. The device is misbehaving. Turns out it’s running firmware v3.2.7… or was it 3.2.7b? Or maybe 3.2.7-leaddev-fix-final-really-final?
No one’s quite sure.
– The version label is hardcoded manually.
– The CI pipeline? Doesn’t exist.
– The changelog? In someone’s inbox.
You finally get your hands on three firmware images from the same product line – supposedly all “the latest.”
Except that they differ. And one of them is vulnerable. Nobody knows which one.
Want to avoid this mess?
📦 Maintain proper versioning – in your version control system, not inboxes
📦 Track what’s inside your firmware (by SBOMs, commit and binary hashes, even git commit hashes baked in – if you have the bad luck to have that)
📦 Keep your builds reproducible
📦 And yes, even .bat files and Perl scripts can (and should) live in git – despite what That One Developer(TM) might tell you
Otherwise? You’ll be hunting ghosts with a hex editor.
Your embedded security challenge this Thursday: you’re given three similar firmware images. Which tools would you use to:
👉 Identify any differences between them
👉 Find the one with the known vulnerability
👉 Determine if any of them actually fix it
Good luck – and may your hashes match.

Challenge 8 :
Feeling swamped with tasks? You’re not alone – learning often kicks in only when we have to use a new tool.
But for embedded developers, staying ahead means knowing basics about topics like:
– Software Bills of Materials (SBOMs),
– vulnerability reporting and Common Vulnerability Enumeration (CVEs)
– the regulation like the Cyber Resilience Act (CRA)
– secure boot (hint: there is no magic checkbox to have it going by pressing a single button)
– continuous integration and test coverage
– static analysis
– what attackers are really up to lately
This week’s embedded security challenge:
Block just 30 minutes to dive into one security topic that interests you. A conference talk, a blog post – whatever works.
It’s not about becoming a world authority on the subject. It’s about knowing more than 80% of developers.

Challenge 9 :
“Why would anyone target me?” – a common thought among developers. But attackers know exactly who they’re after.
– They go after VSCode extensions (plugins for a popular development text editor and development environment) because developers use them. https://blog.extensiontotal.com/the-story-of-extensiontotal-how-we-hacked-the-vscode-marketplace-5c6e66a0e9d7
– They steal credentials – like in the recent tj-actions incident. https://lnkd.in/eC_3d7cc
They compromise what devs have access to:
🔐 confidential code bases
🔐 test systems
🔐 CI clusters (great for mining crypto or sending spam)
Developers are absolutely a target.
Today it’s Thursday and it’s time for this week’s embedded security challenge: Review security of your accounts.
Change weak passwords, enable 2FA (Two Factor Authentication), and revoke old tokens.

Challenge 10 :
Debugging a embedded system can feel like chasing ghosts – everything looks random, nothing makes sense. The funny fact? Computers (and processors) are actually deterministic machines.
The irony? They’re terrible at generating randomness.
And yet, random numbers are everywhere.
You need them:
– For generating encryption keys
– Network connections (yes, even unencrypted TCP sequence numbers)
– Initializing various applications
In summary: you need random numbers at your embedded device from the very start.
So where does your device get its randomness?
– If you use Linux, it mixes in unpredictable hardware events (with quite the complex pipeline)
– Some (most) chips provide a hardware random number generator
– And if there’s no other option, you can provision devices with pre-generated random files to seed the random number generator
This week’s embedded security challenge: find out exactly how your device generates randomness.
Because security often starts with entropy.

Challenge 11 :
“My device isn’t of any interest,” says the manufacturer – while their product mines bitcoin for someone else 🪙
Many still believe cyberattacks only hit office networks, or that attackers are after financial data, customer lists, or 1980s-style free long-distance calls using beeps on the phone.
But the reality is broader – and worse.
There are three main types of attackers:
– Those targeting your device directly
– Competitors
– Those hijacking your device to go after something (or someone) else
No device is “unimportant” when it’s in exactly the spot an attacker wants to reach.
What can they do?
➡️ Infect a hospital’s devices and hold them for ransom
➡️ Copy proprietary code or AI models running on your hardware
➡️ Spy on unencrypted traffic via a rootkit on a router
➡️ Hijack a machine to cause physical damage – and ruin your reputation
➡️ Steal crypto wallets
➡️ Steal a car – if they can open and turn it on remotely
➡️ Record people’s homes from vacuum cleaners
➡️ Or even grab a copy of that confidential document – straight from the printer (yes, that’s real)
It’s Thursday – time for a security challenge:
👉 Identify three possible attackers for your device.

Challenge 12 :
A customer reports a malfunction. It never happened in the lab. It only occurs on their network.
What do you do?
Luckily, your device logs are detailed. You check a file – and there it is: the exact error message. You write a test, fix the bug, and close the issue.
Logging saves the day.
But… what else are you logging?
Logs can be just as useful to attackers as they are to developers – especially when they contain:
– Passwords, API keys, or tokens
– Personal data like names or GPS coordinates (or biometric sensor data)
– Raw memory dumps, or stack traces
– Precise error codes from authentication or cryptographic processes, including secure boot
It’s Thursday, the day of the Embedded Security Challenge.
👉 Today’s task: check your logs. Are you logging too much?

Challenge 13 :
You throw away an old device. Or maybe resell it for refurbishing. But what if your personal data is still inside?
Embedded devices often hold more than just your name.
They might store location history, Wi-Fi credentials, API tokens, or even medical info – especially if it’s something like a smartwatch 🔑🩺
Most devices offer a way to reset or wipe user data.
But is it actually secure?
Simply deleting a file isn’t enough – in many cases, the data can be recovered with basic tools.
Some tips for proper cleanup for embedded developers:
✅ Keep user data in as few places as possible – ideally on a dedicated partition
✅ Encrypt it with a unique, randomly generated key – then securely destroy the key when wiping. The data becomes garbage.
✅ When deleting, overwrite data with a pattern – the number of passes depends on your hardware storage
It’s Thursday – time for the Embedded Security Challenge
👉 This week: Review how your system removes user data. Is it secure enough?

Challenge 14 :
How about celebrating International Workers’ Day… by automating your tests?
What do final release tests look like for an embedded product?
If you’re lucky:
✅ Tests run on a server, and you get a clean report.
If you’re not:
❌ There’s still a big manual part – especially for the user controls or web admin interface.
User interface (UI) testing used to be painful. Not anymore. Tools like Selenium or Cypress let you fully script interface tests.
The same applies to hardware: With a programmable power supply, and tools like Labgrid, you can even automate reboot tests. Pair it with Robot Framework for even more effect.
If your test process still feels like 2010s, it might be time for a refresh.
Manual release testing? That’s frustrating, and error-prone.
Today is Thursday, and it’s time for the Embedded Security Challenge:
👉 And, as all security bugs are also regular bugs: find one tool that can automate part of your test flow.
Start small. Save time. Share your preferred tools in the comments.

Challenge 15 :
Embedded devices often store more valuable data than you think.
– A phone or wearable can track the owner’s complete location history
– A smart home system knows exactly when you leave and return home
– An industrial robot might store precise chemical formulas, possibly trade secrets
This data isn’t just valuable to the user.
It can also be of interest to partners, competitors… or attackers.
🔓 If your device stores sensitive data unencrypted, it’s time to rethink the design.
But simply adding encryption isn’t enough.
If every device uses the same key, it is close to no encryption at all.
Here’s what you really need:
✅ A unique key per device
✅ Stored securely – in a TPM or another secure block
✅ Released only after verified boot (and/or user login)
✅ Generated from strong random data at first boot
This week’s Embedded Security Challenge:
👉 Add exemplary secure storage of user data in your devices.