# Arbitrary Local-File Read from Admin - Restore From Backup due to Symlinks

Admin-crafted backup tar containing a symlink to /etc/passwd was extracted on restore, letting the admin read arbitrary local files via the uploads URL.

- Payout: $512
- Severity: high
- Program: Discourse
- Credited: ziot
- Disclosed: 2017-05-13
- Write-up quality: 6/10
- Original: https://hackerone.com/reports/213558
- Library page: https://bugbountylibrary.com/r/h1%3A213558
- Tags: domain:web impact:data-leak kind:bounty platform:hackerone sev:high tech:ruby technique:source-review vuln:info-disclosure vuln:path-traversal

**Target:** Admin backup restore (tar extraction) and uploads serving
**Root cause:** Backup restore extracts tar archives without rejecting symlink entries, so a symlink pointing outside the app directory is materialized under /uploads and then served as a file.
**Steps:**
1. Login as admin at `/admin/backups/`
2. Create a backup including files, extract it locally
3. In `uploads/default/original/1X/` create `ln -s /etc/passwd <hash>.png`
4. Repack extracted tree as `.tar.gz`
5. Enable 'Restore from Backups' setting
6. Upload crafted tar and restore
7. Request `http://try.discourse.org/uploads/default/original/1X/<hash>.png` to read `/etc/passwd`
**How found:** Recognized that backup restore is an untrusted tar extraction and that uploads are served directly, so a symlink entry would be followed on read.
**Exploitation:** Admin uploads a tampered backup tar containing a symlink entry; restore extracts it into the uploads tree, and the web server follows the symlink when serving the upload path, disclosing arbitrary readable files.
**Insight:** Any feature that extracts user-supplied archives (backup restore, plugin/theme import, zip upload) is a symlink/zip-slip candidate; check whether extracted entries are later served or read by the app.
