Skip to content

Instantly share code, notes, and snippets.

@gnyman
Created April 11, 2024 19:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gnyman/b5219f1b51a640dce08bcc1d5f3712bd to your computer and use it in GitHub Desktop.
Save gnyman/b5219f1b51a640dce08bcc1d5f3712bd to your computer and use it in GitHub Desktop.
Stupidly simple php file upload server for local networks.
<?php
/* == Minimal stupidly simple file upload script ==
* *DO NOT USE THIS IN A UNTRUSTED ENVIRONMENT*
* There very little security. I have tried to block the most obvious thing
* (uploading of php files) and directory traversal. But this was done in 30
* minutes mostly with a LLM so I wouldn't trust it at all. Use something
* better for a untrusted environment.
*
* With that said, you can run this by placing it in a folder, naming it
* index.php then running php -S 0.0.0.0:8000 in that folder. You can then
* navigate to the IP of your computer and upload the files to the same
* directory.
*
* Author: @gnyman
* Licence: CC0
*/
if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_FILES['files']['name'])) {
foreach ($_FILES['files']['tmp_name'] as $key => $tmpName) {
if (file_exists($tmpName)) {
$originalName = $_FILES['files']['name'][$key];
$baseName = pathinfo($originalName, PATHINFO_FILENAME);
$extension = pathinfo($originalName, PATHINFO_EXTENSION);
// Prevent path traversal and restrict PHP files
if (strpos($originalName, '..') !== false || strtolower($extension) === 'php') {
echo "Error: Invalid file type or path traversal attempt.\n";
continue;
}
$uploadPath = $baseName . '.' . $extension;
$counter = 1;
while (file_exists($uploadPath)) {
$uploadPath = $baseName . '_' . $counter++ . '.' . $extension;
}
move_uploaded_file($tmpName, $uploadPath);
echo htmlspecialchars($uploadPath) . "\n";
}
}
exit;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
input { font-size: 16px; }
#fileList li { color: red; }
#fileList li.success { color: green; }
</style>
</head>
<body>
<input type="file" multiple onchange="uploadFiles()">
<ul id="fileList"></ul>
<script>
function uploadFiles() {
var files = this.files;
var form = new FormData();
var list = document.getElementById('fileList');
list.innerHTML = '';
for (var i = 0; i < files.length; i++) {
form.append('files[]', files[i]);
var item = document.createElement('li');
item.textContent = files[i].name;
list.appendChild(item);
}
fetch('.', { method: 'POST', body: form })
.then(response => response.text())
.then(data => {
var uploadedFiles = data.trim().split('\n');
for (var j = 0; j < list.children.length; j++) {
if (uploadedFiles.includes(list.children[j].textContent)) {
list.children[j].classList.add('success');
} else {
list.children[j].style.color = 'red';
list.children[j].textContent += ' - Upload Failed';
}
}
});
}
document.querySelector('input[type=file]').addEventListener('change', uploadFiles);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment