Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
Sichere ProgrammierungKI half beim Finden: iOS 27 schließt mehr als 100 Sicherheitslücken(21.09.2026 um 06:00 Uhr)
Sichere ProgrammierungWhat Is Rowhammer? How Can Repeated Memory Access Flip Bits in RAM?(21.09.2026 um 07:12 Uhr)
Sichere Programmierungnpm publish Ignores .gitignore: The .npmignore Override Rule(21.09.2026 um 07:15 Uhr)
Sichere ProgrammierungAphelion Editor - A free node-based video / VFX editor(21.09.2026 um 07:21 Uhr)
Sichere ProgrammierungGovernance Attack Surface Review: OKX(21.09.2026 um 07:31 Uhr)
Sichere ProgrammierungJSM Portal Request Create Property Panel Submit(21.09.2026 um 07:34 Uhr)
Reverse Engineeringsearch instructions assembly easy (X86,RISCV,AARCH64,etc)(20.09.2026 um 15:44 Uhr)
Sichere ProgrammierungKI half beim Finden: iOS 27 schließt mehr als 100 Sicherheitslücken(21.09.2026 um 06:00 Uhr)
Sichere ProgrammierungWhat Is Rowhammer? How Can Repeated Memory Access Flip Bits in RAM?(21.09.2026 um 07:12 Uhr)
Sichere Programmierungnpm publish Ignores .gitignore: The .npmignore Override Rule(21.09.2026 um 07:15 Uhr)
Sichere ProgrammierungAphelion Editor - A free node-based video / VFX editor(21.09.2026 um 07:21 Uhr)
Sichere ProgrammierungGovernance Attack Surface Review: OKX(21.09.2026 um 07:31 Uhr)
Sichere ProgrammierungJSM Portal Request Create Property Panel Submit(21.09.2026 um 07:34 Uhr)
Reverse Engineeringsearch instructions assembly easy (X86,RISCV,AARCH64,etc)(20.09.2026 um 15:44 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

How I Found a High-Severity Directory Traversal in Flask-Admin

Reagiere als Erste:r — dein Feedback zählt!

Table of Contents

  • Choosing the Target
  • Reading the Code
  • A Small Test
  • Building a Test Environment
  • Testing the Application
  • It Wasn’t Just File Read
  • Understanding the Root Cause
  • Responsible Disclosure
  • Final Thoughts

Every security researcher has a different way of finding vulnerabilities.

Some start with automated scanners.

Some begin by fuzzing endpoints.

For me…

It usually starts with reading the source code.

Sometimes a single function is enough to raise a question.

This is the story of how a simple helper function in Flask-Admin’s FileAdmin led me to discover a high-severity Directory Traversal vulnerability.

1.Choosing the Target

Recently, I wanted to spend more time reviewing open-source projects.

Open-source applications are a great way to improve code review skills because you can understand exactly how a feature works instead of guessing from HTTP responses.

One project that caught my attention was Flask-Admin.

If you’ve worked with Flask before, you’ve probably heard of it.

One feature inside Flask-Admin interested me the most:FileAdmin.

It allows users to browse, upload, rename, delete, and download files from a configured directory.

Whenever I see code interacting with the filesystem, I become curious.

Because history has shown us that many security issues begin with improper file handling.

So instead of opening Burp Suite…

I opened the source code.

2.Reading the Code

I wasn’t looking for a specific vulnerability.

I simply wanted to understand one thing.

“How does FileAdmin make sure users cannot escape the configured directory?”

After following a few function calls, I found the validation logic.

def is_in_folder(self, base_path, directory):
return self.normpath(directory).startswith(base_path)

At first glance…

Nothing looked unusual.

The application normalizes the path and checks whether it starts with the configured directory.

Simple.

But one word immediately caught my attention.

startswith()

I paused for a moment.

Then I asked myself…

“Can two completely different directories still share the same prefix?”

3.A Small Test

Instead of making assumptions, I opened a Python interpreter.

I tested something simple like this.

"/data/uploads_secret".startswith("/data/uploads")

The output surprised me…

True

But from a security perspective, it was interesting.

Because:

/data/uploads

and

/data/uploads_secret

are completely different directories.

They only happen to begin with the same characters.

That was enough to make me investigate further.

4.Building a Test Environment

To verify my theory, I created a simple directory structure.

sandbox/
├── uploads/
│ └── hello.txt
└── uploads_secret/
├── flag.txt
└── deleteme.txt

The FileAdmin root was configured as:

sandbox/uploads

The goal was simple.

Everything inside uploads should be accessible.

Everything outside it should be blocked.

Now it was time to test whether that security boundary actually worked.

5.Testing the Application

I first tested the download functionality.

Instead of requesting a normal file, I requested a file from the sibling directory.

../uploads_secret/flag.txt

One thing I noticed during testing was that browsers automatically normalize traversal sequences like ../ before sending the request.

To preserve the original path, I used:

curl --path-as-is
"http://127.0.0.1:5000/admin/files/download/../uploads_secret/flag.txt"

After sending the request…

The application returned the file successfully.

At that moment, I knew my assumption was correct.

The configured FileAdmin root could be bypassed.

6.It Wasn’t Just File Read

Reading a file was only the beginning.

I wanted to understand the complete impact.

So I continued testing the remaining FileAdmin operations.

One by one.

  • Download
  • Upload
  • Rename
  • Delete
  • Create Directory

Every operation relied on the same validation logic.

Every operation trusted the same startswith() check.

Which meant they could all operate outside the configured FileAdmin root.

This wasn’t just an arbitrary file read.

The intended filesystem boundary itself had been bypassed.

7.Understanding the Root Cause

The root cause was surprisingly simple. The application assumed that if a path started with the configured directory, it must be inside it. That assumption seems reasonable at first — but it isn’t always true.

Filesystem paths don’t behave like plain strings. Two different directories can share the same prefix while existing in completely separate locations. Because of this, a simple startswith() check became the application's security boundary, and that boundary could be bypassed.

8.Responsible Disclosure

After confirming the behavior, I documented everything carefully.

My report included the root cause analysis, proof of concept (PoC), detailed reproduction steps, affected operations, and a security impact assessment.

I submitted the report through GitHub Security Advisories.

A few weeks later, I received a response from the maintainers.

The issue had already been reported by another researcher, so my advisory was closed as a duplicate.

Of course, it was disappointing 😭.

But that’s part of security research.

Duplicates happen.

And every duplicate teaches something valuable.

9.Final Thoughts

Not every report becomes a CVE.

Not every report gets accepted.

And not every finding is the first one.

But every investigation improves the way you think.

For me, this research reinforced one important lesson:

Never use string comparisons to enforce filesystem security boundaries.

Sometimes, all it takes is a single line of code to create a high-severity vulnerability.

— Written by

Aruvasaga Chithan A

Ethical Hacker & Offensive Security Researcher.

Thanks for reading — your support keeps me writing.
See you in the next article…

Linkedin — Github


How I Found a High-Severity Directory Traversal in Flask-Admin was originally published in InfoSec Write-ups on Medium, where people are continuing the conversation by highlighting and responding to this story.

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-94030 | A security vulnerability has been detected in SerenityOS up to 3d83e4509…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
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
🔖 Gespeicherte Artikel
📂 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 ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick