惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Troy Hunt's Blog
GbyAI
GbyAI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
月光博客
月光博客
Engineering at Meta
Engineering at Meta
The Register - Security
The Register - Security
阮一峰的网络日志
阮一峰的网络日志
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
F
Fortinet All Blogs
博客园 - 司徒正美
博客园 - 聂微东
T
Tailwind CSS Blog
MyScale Blog
MyScale Blog
Microsoft Security Blog
Microsoft Security Blog
Jina AI
Jina AI
A
About on SuperTechFans
Y
Y Combinator Blog
N
Netflix TechBlog - Medium
V
V2EX
I
InfoQ
WordPress大学
WordPress大学
小众软件
小众软件
The Cloudflare Blog
Recent Announcements
Recent Announcements
U
Unit 42
The Last Watchdog
The Last Watchdog
P
Palo Alto Networks Blog
Vercel News
Vercel News
罗磊的独立博客
H
Hackread – Cybersecurity News, Data Breaches, AI and More
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
M
MIT News - Artificial intelligence
Project Zero
Project Zero
美团技术团队
L
LangChain Blog
S
Security @ Cisco Blogs
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Last Week in AI
Last Week in AI
W
WeLiveSecurity
S
Securelist
H
Hacker News: Front Page
K
Kaspersky official blog
Martin Fowler
Martin Fowler
Know Your Adversary
Know Your Adversary
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
J
Java Code Geeks
P
Proofpoint News Feed
有赞技术团队
有赞技术团队
Google Online Security Blog
Google Online Security Blog
D
DataBreaches.Net

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Path Traversal: What It Is, Why It's Dangerous, and How to Stop Attackers from Reading Files They Shouldn't
Jer Catallo · 2026-06-14 · via DEV Community

Path traversal is a web vulnerability where an attacker reads files outside the directory your application intends to serve. It sounds simple, but the impact can be severe. One missing validation and an attacker can walk straight into your .env, your database backups, or your cloud credentials using nothing more than ../ in a URL.

The mock server used in this demonstration is available at https://github.com/jercatallo/lab-path-traversal if you want to follow along and try the vulnerability yourself.

Path traversal, also called directory traversal, happens when an application takes a filename from user input and builds a file path with it, without checking where that path actually leads. Attackers chain ../ sequences to climb up the directory tree and reach files the application was never meant to expose.

Common targets include:

  • Environment files with database credentials
  • Configuration files with cloud API keys
  • Database backups with user data and password hashes
  • Internal service credentials

Path Traversal vs LFI vs RFI

These three vulnerabilities are related but different. Here is a quick comparison:

Feature Path Traversal LFI RFI
File source Local filesystem Local filesystem Remote server
Execution Read only Can execute code Can execute code
Main goal Read sensitive files Read or execute local files Execute remote malicious code
Common payload ../ sequences ../ + file paths http://attacker.com/shell.php

Path traversal only reads files. LFI goes further and can execute them. RFI pulls code from an external server entirely. This demonstration focuses on path traversal.

Vulnerable Code Examples

Path traversal happens when developers trust user input without validating the resulting file path. Here are common patterns that cause this vulnerability.

PHP - Direct file path concatenation without validation:

<?php
$filename = $_GET['file'];
$filepath = '/var/www/files/' . $filename;
readfile($filepath);
?>

The code takes the file parameter directly from the URL and appends it to the base path. If an attacker sends ?file=../.env, the server reads /var/www/files/../.env which resolves to /var/www/.env.

Python - Missing path boundary check:

from flask import Flask, request, send_file
import os

app = Flask(__name__)
BASE_DIR = "/var/www/files"

@app.route("/files")
def serve_file():
    filename = request.args.get("file")
    filepath = os.path.join(BASE_DIR, filename)
    return send_file(filepath)

The os.path.join() function does not prevent directory traversal. When filename is ../.env, the result is /var/www/files/../.env which the server resolves to /var/www/.env.

Node.js - Unsafe path construction:

const express = require('express');
const fs = require('fs');
const path = require('path');
const app = express();

app.get('/files', (req, res) => {
  const filename = req.query.file;
  const filepath = path.join(__dirname, 'files', filename);
  res.sendFile(filepath);
});

The path.join() method preserves ../ sequences. An attacker sending ?file=../config/production.json gets the full production configuration file.

Java - File object without canonical path validation:

@WebServlet("/files")
public class FileServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
        String filename = req.getParameter("file");
        File file = new File("/var/www/files", filename);
        // Missing: check if file.getCanonicalPath() starts with base directory
        Files.copy(file.toPath(), resp.getOutputStream());
    }
}

The File constructor accepts any path string. Without calling getCanonicalPath() and verifying it stays within the allowed directory, traversal sequences pass through unchecked.

The common mistake across all these examples is the same: user input flows directly into file path construction without checking where the final path actually points.

Ethical Considerations

All credentials, tokens, and data shown here are simulated values created for this lab. The environment runs on a local machine with no real user data. Never test path traversal on systems you do not own or have written permission to test. Unauthorized file access is illegal in most jurisdictions.

Step 1: Finding Available Endpoints

Before attacking, we need to discover what endpoints exist on the target application. In real-world scenarios, attackers use fuzzing, directory brute-forcing, or source code review to find these. This lab provides an /api endpoint that lists available routes for training purposes.

curl http://localhost:8080/api | jq

The response reveals two endpoints: /api itself (which lists endpoints) and /files which serves files using a file query parameter. The /files endpoint is our target for path traversal. In a real engagement, you would not have this convenient listing and would need to discover it through reconnaissance techniques.

Step 2: Normal File Access

The application runs on localhost:8080 with a /files endpoint that serves user profile icons. We start by requesting a legitimate file to confirm normal behavior.

curl http://localhost:8080/files?file=user-1.svg

The server returns the full SVG markup for the profile icon. The endpoint works as expected when given a valid filename within the intended directory. No errors, no restrictions visible from the outside.

Step 3: Escaping the Directory with ../

Now we test if the server validates the file parameter. We use ../ to move one level up from the files directory and target an admin credentials file.

curl http://localhost:8080/files?file=../admin/credentials.txt

The server returns the credentials file without any error. You can see the fake admin email and password, three API tokens with different permission levels (read-only, read-write, admin), and internal service URLs for the payment and user services. The application accepted the ../admin/ path without any validation. This confirms path traversal is possible.

Step 4: Reading the Environment File

With directory traversal confirmed, we go after the .env file. This file typically holds database connection details that the application loads at startup.

curl http://localhost:8080/files?file=../.env

The response exposes five environment variables: DATABASE_HOST, DATABASE_PORT (5432, a PostgreSQL port), DATABASE_USER, DATABASE_PASSWORD, and DATABASE_NAME. In a real application, these details give an attacker direct access to your database server. One request, and the database is open.

Step 5: Pulling a Database Backup

Backup files are another high-value target. They are often stored on the same server and contain a full snapshot of your data.

curl http://localhost:8080/files?file=../backups/db_dump.sql

The dump includes the full schema and data for two tables. The users table has usernames, bcrypt password hashes, emails, and roles. The payments table has card numbers, CVV codes, and expiry dates. An attacker reading this file gets everything needed to attempt credential stuffing and has access to payment data that could lead to PCI DSS violations.

Step 6: Exposing Production Configuration

The last target is the production configuration file. These files often bundle multiple secrets together in one place.

curl http://localhost:8080/files?file=../config/production.json

The JSON file reveals three sections: database connection details with a separate internal hostname (fake-db-host-name.internal), AWS credentials with an access key ID and secret access key, and a JWT signing secret with a 7-day expiry. With the AWS keys, an attacker can enumerate and access cloud resources. With the JWT secret, they can forge authentication tokens and impersonate any user.

Step 7: Remediation

Path traversal is preventable. The root cause is the application trusting user input to build file paths. Here are the key fixes:

  1. Resolve the canonical path: Use realpath() or equivalent to resolve the full path before doing anything with it.
  2. Validate against an allowlist: Check that the resolved path starts with the intended base directory. Reject anything outside it.
  3. Avoid raw path construction: Use file IDs or database references instead of accepting filenames directly from users.
  4. Apply least privilege: Run the application with a user that only has read access to the files directory. Even if traversal succeeds, the process cannot read files it has no permission to access.

Secure path validation example in Python:

import os

ALLOWED_DIR = "/var/www/files"

def serve_file(filename):
    full_path = os.path.realpath(os.path.join(ALLOWED_DIR, filename))
    if not full_path.startswith(ALLOWED_DIR + os.sep):
        raise ValueError("Access denied: path traversal detected")
    return open(full_path, "rb").read()

The key line is the startswith check after realpath(). This resolves any ../ sequences before the check, so an attacker cannot bypass it by encoding or chaining traversal sequences.

Summary

Path traversal is a low-effort, high-impact vulnerability. All five steps above used a single curl command with ../ in the filename parameter. No special tools, no authentication bypass, just a missing validation check on the server side.

The attack chain here went from reading a profile icon to exposing admin credentials, database environment variables, a full database backup with payment data, and AWS cloud credentials. Each of those steps is one request. Protect your applications by resolving canonical paths, validating against a strict base directory, and running with least privilege.