- Fixed plugin table sorting order
- Cleaned up code
- Added WAF
This commit is contained in:
Nikolai X. Shadeauxs 2023-04-12 18:27:41 -04:00
parent ccbd99cf79
commit e3329f6b5d
20 changed files with 404 additions and 506 deletions

View file

@ -79,6 +79,10 @@ The second section is plugins. This lets you upload plugins or delete them. As t
3/14/23
- Improved admin styles
- Code Optimizations
4/12/23
- Fixed plugin table sorting order
- Cleaned up code
- Added WAF

### To-Do List


1
update-api/.user.ini Normal file
View file

@ -0,0 +1 @@
auto_prepend_file = '~/public_html/waf.php'

View file

@ -0,0 +1,76 @@
<?php
/*
* Project: Update API
* Author: Vontainment
* URL: https://vontainment.com
* File: form-helper.php
* Description: WordPress Update API
*/

// Check if an entry was updated
if (isset($_POST['update'])) {
$hosts_file = '../HOSTS';
$entries = file($hosts_file, FILE_IGNORE_NEW_LINES);
$line_number = $_POST['id'];
$domain = $_POST['domain'];
$key = $_POST['key'];
$entries[$line_number] = $domain . ' ' . $key;
file_put_contents($hosts_file, implode("\n", $entries) . "\n");
}

// Check if an entry was deleted
if (isset($_POST['delete'])) {
$hosts_file = '../HOSTS';
$entries = file($hosts_file, FILE_IGNORE_NEW_LINES);
$line_number = $_POST['id'];
unset($entries[$line_number]);
file_put_contents($hosts_file, implode("\n", $entries) . "\n");
}

// Check if a new entry was added
if (isset($_POST['add'])) {
$hosts_file = '../HOSTS';
$domain = $_POST['domain'];
$key = $_POST['key'];
$new_entry = $domain . ' ' . $key;
file_put_contents($hosts_file, $new_entry . "\n", FILE_APPEND | LOCK_EX);
}

if (isset($_POST['upload_plugin'])) {
$allowed_extensions = ['zip'];
$file_extension = strtolower(pathinfo($_FILES['plugin_file']['name'], PATHINFO_EXTENSION));
if ($_FILES['plugin_file']['error'] !== UPLOAD_ERR_OK) {
$_SESSION['upload_messages'][] = '<p class="error">Error uploading file.</p>';
} elseif (!in_array($file_extension, $allowed_extensions)) {
$_SESSION['upload_messages'][] = '<p class="error">Invalid file type. Only .zip files are allowed.</p>';
} else {
$plugin_path = '../plugins/' . $_FILES['plugin_file']['name'];
if (file_exists($plugin_path)) {
$_SESSION['upload_messages'][] = '<p class="error">File already exists.</p>';
} else {
// ...
$_SESSION['upload_messages'][] = '<p class="success">File uploaded successfully.</p>';
}
}
}

// Check if a plugin was deleted
if (isset($_POST['delete_plugin'])) {
$plugin_name = $_POST['plugin_name'];

if (file_exists($plugin_name)) {
if (unlink($plugin_name)) {
echo '<script>
alert("Plugin deleted successfully!");
</script>';
} else {
echo '<script>
alert("Failed to delete plugin file. Please try again.");
</script>';
}
} else {
echo '<script>
alert("Plugin file not found. Please try again.");
</script>';
}
}

View file

@ -0,0 +1,110 @@
<?php
/*
* Project: Update API
* Author: Vontainment
* URL: https://vontainment.com
* File: host-box.inc.php
* Description: WordPress Update API
*/
?>

<div class="section">
<h2>Allowed Hosts</h2>
<?php
// Display the table of entries
$hosts_file = '../HOSTS';
$entries = file($hosts_file, FILE_IGNORE_NEW_LINES);
?>
<div class="row">
<div class="column">
<table>
<thead>
<tr>
<th>Domain</th>
<th>Key</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php
$i = 0;
foreach ($entries as $line_number => $entry) {
$fields = explode(' ', $entry);
$domain = isset($fields[0]) ? $fields[0] : '';
$key = isset($fields[1]) ? $fields[1] : '';
if ($i % 2 == 0) {
?>
<tr>
<form method="post">
<input type="hidden" name="id" value="<?php echo $line_number; ?>">
<td><input type="text" name="domain" value="<?php echo $domain; ?>"></td>
<td><input type="text" name="key" value="<?php echo $key; ?>"></td>
<td>
<input type="submit" name="update" value="Update">
<input type="submit" name="delete" value="Delete">
</td>
</form>
</tr>
<?php
}
$i++;
}
?>
</tbody>
</table>
</div>
<div class="column">
<table>
<thead>
<tr>
<th>Domain</th>
<th>Key</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php
$i = 0;
foreach ($entries as $line_number => $entry) {
$fields = explode(' ', $entry);
$domain = isset($fields[0]) ? $fields[0] : '';
$key = isset($fields[1]) ? $fields[1] : '';
if ($i % 2 != 0) {
?>
<tr>
<form method="post">
<input type="hidden" name="id" value="<?php echo $line_number; ?>">
<td><input type="text" name="domain" value="<?php echo $domain; ?>"></td>
<td><input type="text" name="key" value="<?php echo $key; ?>"></td>
<td>
<input type="submit" name="update" value="Update">
<input type="submit" name="delete" value="Delete">
</td>
</form>
</tr>
<?php
}
$i++;
}
?>
</tbody>
</table>
</div>
</div>
<div class="section">
<h2>Add Entry</h2>
<form method="post">
<div class="form-group">
<label for="domain">Domain:</label>
<input type="text" name="domain" id="domain" required>
</div>
<div class="form-group">
<label for="key">Key:</label>
<input type="text" name="key" id="key" required>
</div>
<div class="form-group">
<input type="submit" name="add" value="Add Entry">
</div>
</form>
</div>
</div>

View file

@ -0,0 +1,96 @@
<?php
/*
* Project: Update API
* Author: Vontainment
* URL: https://vontainment.com
* File: plugins-box.inc.php
* Description: WordPress Update API
*/
?>

<div class="section">
<h2>Plugins</h2>
<div id="plugins_table">
<?php
$plugins_dir = "../plugins";
$plugins = glob($plugins_dir . "/*.zip");

function generateTableRow($plugin, $plugin_name)
{
return '<tr>
<td>' . $plugin_name . '</td>
<td>
<form name="delete_plugin_form" action="' . htmlspecialchars($_SERVER["PHP_SELF"]) . '" method="POST">
<input type="hidden" name="plugin_name" value="' . $plugin . '">
<input type="submit" name="delete_plugin" value="Delete">
</form>
</td>
</tr>';
}

// Reverse the plugins array
$plugins = array_reverse($plugins);

if (count($plugins) > 0) {
// Split plugins array into two halves
$half_count = ceil(count($plugins) / 2);
$plugins_column1 = array_slice($plugins, 0, $half_count);
$plugins_column2 = array_slice($plugins, $half_count);

$table_html = '<div class="row"><div class="column">
<table>
<thead>
<tr>
<th>Plugin Name</th>
<th>Delete</th>
</tr>
</thead>
<tbody>';
foreach ($plugins_column1 as $plugin) {
$plugin_name = basename($plugin);
$table_html .= generateTableRow($plugin, $plugin_name);
}
$table_html .= '</tbody></table></div><div class="column"><table>
<thead>
<tr>
<th>Plugin Name</th>
<th>Delete</th>
</tr>
</thead>
<tbody>';
foreach ($plugins_column2 as $plugin) {
$plugin_name = basename($plugin);
$table_html .= generateTableRow($plugin, $plugin_name);
}
$table_html .= '</tbody></table></div></div>';
} else {
$table_html = "No plugins found.";
}

echo $table_html;

?>

</div>

<div class="section">
<h2>Upload Plugin</h2>
<form name="upload_plugin_form" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="POST" enctype="multipart/form-data">
<input type="file" name="plugin_file">
<input type="submit" name="upload_plugin" value="Upload">
</form>
<?php
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
if (isset($_SESSION['upload_messages'])) {
echo '<div class="upload-messages">';
foreach ($_SESSION['upload_messages'] as $message) {
echo '<p>' . $message . '</p>';
}
echo '</div>';
unset($_SESSION['upload_messages']);
}
?>
</div>
</div>

View file

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 134 KiB

Before After
Before After

View file

@ -7,7 +7,7 @@ body {
width: 100%;
overflow-x: hidden;
background-color: #f1f1f1;
background-image: url("../img/background.png");
background-image: url("../assets/background.png");
background-repeat: repeat;
margin: 0;
font-size: 16px;
@ -136,7 +136,6 @@ width: 100%;
}

form > input[type="submit"] {
margin-top: 20px;
width: 100%!important;
}

View file

Before

Width:  |  Height:  |  Size: 235 KiB

After

Width:  |  Height:  |  Size: 235 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Before After
Before After

View file

@ -1,13 +1,15 @@
<?php
/*
index.php
Version: 1.1
Author: Vontainment
Author URI: https://vontainment.com
* Project: Update API
* Author: Vontainment
* URL: https://vontainment.com
* File: index.php
* Description: WordPress Update API
*/

session_start();
require_once "../app/auth-helper.php";
require_once "../app/form-helper.php";
?>


@ -19,222 +21,20 @@ require_once "../app/auth-helper.php";
<meta name="viewport" content="width=device-width, user-scalable=no" />
<meta name="robots" content="noindex, nofollow">
<title>API Admin Page</title>
<link rel="stylesheet" href="./static/css/index.css">
<link rel="stylesheet" href="./assets/index.css">
<script src="/assets/scripts.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>

<body>
<header>
<img src="./static/img/logo.png" alt="Lego" width="200px" height="40px">
<img src="./assets/logo.png" alt="Lego" width="200px" height="40px">
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="POST">
<button class="logout-btn" type="submit" name="logout">Logout</button>
</form>
</header>
<div class="section">
<h2>Allowed Hosts</h2>
<?php
// Check if an entry was updated
if (isset($_POST['update'])) {
$hosts_file = '../HOSTS';
$entries = file($hosts_file, FILE_IGNORE_NEW_LINES);
$line_number = $_POST['id'];
$domain = $_POST['domain'];
$key = $_POST['key'];
$entries[$line_number] = $domain . ' ' . $key;
file_put_contents($hosts_file, implode("\n", $entries) . "\n");
}

// Check if an entry was deleted
if (isset($_POST['delete'])) {
$hosts_file = '../HOSTS';
$entries = file($hosts_file, FILE_IGNORE_NEW_LINES);
$line_number = $_POST['id'];
unset($entries[$line_number]);
file_put_contents($hosts_file, implode("\n", $entries) . "\n");
}

// Check if a new entry was added
if (isset($_POST['add'])) {
$hosts_file = '../HOSTS';
$domain = $_POST['domain'];
$key = $_POST['key'];
$new_entry = $domain . ' ' . $key;
file_put_contents($hosts_file, $new_entry . "\n", FILE_APPEND | LOCK_EX);
}

// Display the table of entries
$hosts_file = '../HOSTS';
$entries = file($hosts_file, FILE_IGNORE_NEW_LINES);
?>
<div class="row">
<div class="column">
<table>
<thead>
<tr>
<th>Domain</th>
<th>Key</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php
$i = 0;
foreach ($entries as $line_number => $entry) {
$fields = explode(' ', $entry);
$domain = $fields[0];
$key = $fields[1];
if ($i % 2 == 0) {
?>
<tr>
<form method="post">
<input type="hidden" name="id" value="<?php echo $line_number; ?>">
<td><input type="text" name="domain" value="<?php echo $domain; ?>"></td>
<td><input type="text" name="key" value="<?php echo $key; ?>"></td>
<td>
<input type="submit" name="update" value="Update">
<input type="submit" name="delete" value="Delete">
</td>
</form>
</tr>
<?php
}
$i++;
}
?>
</tbody>
</table>
</div>
<div class="column">
<table>
<thead>
<tr>
<th>Domain</th>
<th>Key</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php
$i = 0;
foreach ($entries as $line_number => $entry) {
$fields = explode(' ', $entry);
$domain = $fields[0];
$key = $fields[1];
if ($i % 2 != 0) {
?>
<tr>
<form method="post">
<input type="hidden" name="id" value="<?php echo $line_number; ?>">
<td><input type="text" name="domain" value="<?php echo $domain; ?>"></td>
<td><input type="text" name="key" value="<?php echo $key; ?>"></td>
<td>
<input type="submit" name="update" value="Update">
<input type="submit" name="delete" value="Delete">
</td>
</form>
</tr>
<?php
}
$i++;
}
?>
</tbody>
</table>
</div>
</div>
<div class="section">
<h2>Add Entry</h2>
<form method="post">
<div class="form-group">
<label for="domain">Domain:</label>
<input type="text" name="domain" id="domain" required>
</div>
<div class="form-group">
<label for="key">Key:</label>
<input type="text" name="key" id="key" required>
</div>
<div class="form-group">
<input type="submit" name="add" value="Add Entry">
</div>
</form>
</div>
</div>
<div class="section" id="delete">
<h2>Plugins</h2>
<div id="plugins_table">
<?php include('plugins-table.php'); ?>
</div>

<div class="section">
<h2>Upload Plugin</h2>
<form method="post" enctype="multipart/form-data" name="upload_plugin_form" action="upload-plugin.php">
<input type="file" name="plugin_file">
<input type="submit" name="upload_plugin" value="Upload">
</form>
<div id="message"></div>
</div>
<script>
function updatePluginsTable() {
$.ajax({
url: 'plugins-table.php',
success: function(data) {
$('#plugins_table').html(data);
},
error: function() {
$('#plugins_table').html('<p>Error loading plugins table.</p>');
}
});
}

$(document).ready(function() {

updatePluginsTable();

$('form[name="delete_plugin_form"]').submit(function(event) {
event.preventDefault();
var form = $(this);
$.ajax({
url: form.attr('action'),
type: form.attr('method'),
data: form.serialize(),
success: function(data) {
$('#message').html(data);
updatePluginsTable();
},
error: function() {
$('#message').html('<p>Error deleting plugin.</p>');
}
});
event.stopPropagation(); // Prevent any other event handlers from executing
return false; // Prevent default form submission behavior
});


$('form[name="upload_plugin_form"]').submit(function(event) {
event.preventDefault();
var form = $(this);
var formData = new FormData(form[0]);
$.ajax({
url: form.attr('action'),
type: form.attr('method'),
data: formData,
cache: false,
contentType: false,
processData: false,
success: function(data) {
$('#message').html(data);
updatePluginsTable();
},
error: function() {
$('#message').html('<p>Error uploading plugin.</p>');
}
});
event.stopPropagation(); // Prevent any other event handlers from executing
return false; // Prevent default form submission behavior
});
});
</script>
</div>
<?php require_once "../app/host-box.inc.php"; ?>
<?php require_once "../app/plugins-box.inc.php"; ?>
<div class="section">
<h2>Access Logs</h2>
<div class="log-box">

View file

@ -19,12 +19,12 @@ require_once '../app/auth-helper.php';
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex, nofollow">
<title>API Update Admin Login</title>
<link rel="stylesheet" href="./static/css/login.css">
<link rel="stylesheet" href="./assets/login.css">
</head>

<body>
<div class="login-box">
<img src="./static/img/logo.png" alt="Logo" class="logo">
<img src="./assets/logo.png" alt="Logo" class="logo">
<h2>API Admin Login</h2>
<form method="post">
<label>Username:</label>

View file

@ -1,95 +0,0 @@
<?php

session_start();

// Check if user is logged in
if (!isset($_SESSION['logged_in']) || $_SESSION['logged_in'] !== true) {
header("Location: login.php");
exit;
}

// Define plugins directory
$plugins_dir = "../plugins";

// Check if delete plugin form was submitted
if (isset($_POST['delete_plugin'])) {
// Get plugin name from hidden input field
$plugin_name = $_POST['plugin_name'];

// Check if plugin exists in plugins directory
if (file_exists($plugin_name)) {
// Attempt to delete the plugin file
if (unlink($plugin_name)) {
// Success message
$message = "Plugin deleted successfully!";
} else {
// Error message
$message = "Failed to delete plugin file. Please try again.";
}
} else {
// Error message
$message = "Plugin file not found. Please try again.";
}
}

// Get all plugin files from plugins directory
$plugins = glob($plugins_dir . "/*.zip");

// Check if any plugins were found
if (count($plugins) > 0) {
$table_html = '<div class="row"><div class="column">
<table>
<thead>
<tr>
<th>Plugin Name</th>
<th>Delete</th>
</tr>
</thead>
<tbody>';
$i = 0;
foreach ($plugins as $plugin) {
$plugin_name = basename($plugin);
if ($i % 2 == 0) {
$table_html .= '<tr>
<td>' . $plugin_name . '</td>
<td>
<form method="post" name="delete_plugin_form" action="index.php#delete">
<input type="hidden" name="plugin_name" value="' . $plugin . '">
<input type="submit" name="delete_plugin" value="Delete">
</form>
</td>
</tr>';
}
$i++;
}
$table_html .= '</tbody></table></div><div class="column"><table>
<thead>
<tr>
<th>Plugin Name</th>
<th>Delete</th>
</tr>
</thead>
<tbody>';
$i = 0;
foreach ($plugins as $plugin) {
$plugin_name = basename($plugin);
if ($i % 2 != 0) {
$table_html .= '<tr>
<td>' . $plugin_name . '</td>
<td>
<form method="post" name="delete_plugin_form" action="index.php#delete">
<input type="hidden" name="plugin_name" value="' . $plugin . '">
<input type="submit" name="delete_plugin" value="Delete">
</form>
</td>
</tr>';
}
$i++;
}
$table_html .= '</tbody></table></div></div>';
} else {
$table_html = "No plugins found.";
}

// Output table HTML
echo $table_html;

View file

@ -1,160 +0,0 @@
/* Global styles */
body {
max-width: 100%;
overflow-x: hidden;
background-color: #f1f1f1;
background-image: url("../img/background.png");
background-repeat: repeat;
margin: 0;
font-size: 16px;
padding-bottom: 40px;
}

/* Header */
header {
display: flex;
align-items: center;
justify-content: space-between;
background-color: #0078d7;
border-bottom: 2px solid #2ecc71;
color: white;
font-size: 24px;
font-weight: bold;
padding: 10px;
}

.logout-btn {
background-color: white;
color: #0078d7;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
font-weight: bold;
padding: 6px 16px;
}

.logout-btn:hover {
background-color: #0078d7;
color: white;
}

/* Section */
.section {
background-color: #ffffff;
border: 2px solid #2ecc71;
margin: 20px;
padding: 20px;
}

.section .section {
background-image: linear-gradient(120deg, #fdfbfb 0%, #ebedee 100%);
border: 2px solid #2ecc71;
box-shadow: rgba(0, 0, 0, 0.15) 1.95px 1.95px 2.6px;
max-width: 400px;
}

/* Form */
.form-group {
margin-bottom: 10px;
}

label {
display: block;
font-weight: bold;
margin-bottom: 5px;
}

input[type="text"] {
width: 100%;
padding: 5px;
border: 1px solid #ccc;
border-radius: 5px;
box-sizing: border-box;
}

input[type="submit"] {
background-color: #4caf50;
border: none;
border-radius: 5px;
color: white;
cursor: pointer;
padding: 8px 20px;
box-shadow: rgba(0, 0, 0, 0.15) 1.95px 1.95px 2.6px;
}

input[type="submit"]:hover {
background-color: #3e8e41;
box-shadow: rgba(0, 0, 0, 0.07) 1.5px 1.5px 2.2px;
}

/* Grid */
.row {
display: flex;
}

.column {
flex: 50%;
padding: 10px;
}

/* Table */
table {
width: 100%;
border-collapse: collapse;
}

th,
td {
padding: 8px;
text-align: left;
border-bottom: 1px solid #ddd;
}

th {
background-color: #f2f2f2;
}
/* For screens up to 767px wide */

/* Styles for smaller screens */
@media (max-width: 767px) {
header > img {
margin: 0 auto 10px 0;
}

.section {
border: 2px solid #ffffff;
margin: 0px;
padding: 0 20px;
}

thead > tr th:nth-child(3) {
width: 80px;
}

#plugins-table-wrapper thead > tr th:nth-child(2) {
width: 80px;
}

.row {
flex-direction: column;
margin-right: -35px;
margin-left: -35px;
}

.column {
flex-basis: 100%;
margin-bottom: 20px;
}

.logout-btn {
margin: 10px 0 10px auto;
}

input[type="submit"] {
margin-top: 5px;
margin-bottom: 5px;
width: 6em;
padding: 4px 10px;
}
}

View file

@ -1,36 +0,0 @@
<?php

session_start();

// Check if user is logged in
if (!isset($_SESSION['logged_in']) || $_SESSION['logged_in'] !== true) {
header("Location: login.php");
exit;
}

$allowed_extensions = ['zip'];
$file_extension = strtolower(pathinfo($_FILES['plugin_file']['name'], PATHINFO_EXTENSION));

if ($_FILES['plugin_file']['error'] !== UPLOAD_ERR_OK) {
echo '<p class="error">Error uploading file.</p>';
} elseif (!in_array($file_extension, $allowed_extensions)) {
echo '<p class="error">Invalid file type. Only .zip files are allowed.</p>';
} else {
$plugin_path = '../plugins/' . $_FILES['plugin_file']['name'];
if (file_exists($plugin_path)) {
echo '<p class="error">File already exists.</p>';
} else {
move_uploaded_file($_FILES['plugin_file']['tmp_name'], $plugin_path);
echo '<p class="success">File uploaded successfully.</p>';
}
}

// Output messages within the upload-messages div
if (isset($_SESSION['upload_messages'])) {
echo '<div class="upload-messages">';
foreach ($_SESSION['upload_messages'] as $message) {
echo '<p>' . $message . '</p>';
}
echo '</div>';
unset($_SESSION['upload_messages']);
}

103
update-api/waf.php Normal file
View file

@ -0,0 +1,103 @@
<?php

// Define the list of disallowed characters and patterns
$disallowed_chars = array("<?", "?>", "<%", "%>", "<script", "</script>");
$disallowed_patterns = array("/bin/sh", "exec(", "system(", "passthru(", "shell_exec(", "phpinfo(");

// Function to check if a string contains a disallowed character
function contains_disallowed_chars($str) {
global $disallowed_chars;
foreach ($disallowed_chars as $char) {
if (strpos($str, $char) !== false) {
return true;
}
}
return false;
}

// Function to check if a string contains a disallowed pattern
function contains_disallowed_patterns($str) {
global $disallowed_patterns;
foreach ($disallowed_patterns as $pattern) {
if (strpos($str, $pattern) !== false) {
return true;
}
}
return false;
}

function sanitize_input($data)
{
// Remove any disallowed characters or patterns
if (contains_disallowed_chars($data) || contains_disallowed_patterns($data)) {
$data = "";
}

// Check if the IP is blacklisted
$ip = $_SERVER['REMOTE_ADDR'];
if (is_blacklisted($ip)) {
http_response_code(403); // Forbidden
exit("Access denied");
}

return $data;
}

function blacklist_ip($ip)
{
$blacklist_file = "../blacklists/BLACKLIST";
$content = file_get_contents($blacklist_file);
$content .= "$ip," . strval(time()) . "\n";
file_put_contents($blacklist_file, $content);
}


function is_blacklisted($ip)
{
$blacklist_file = "../storage/waf/BLACKLIST";
$blacklist = file($blacklist_file, FILE_IGNORE_NEW_LINES);
foreach ($blacklist as $line) {
list($blacklisted_ip, $timestamp) = explode(",", $line); // Get the IP address and timestamp
if ($ip == $blacklisted_ip) {
// Check if the timestamp is older than three days
if (time() - $timestamp > (3 * 24 * 60 * 60)) {
// Remove the IP address from the blacklist
$blacklist = array_diff($blacklist, [$line]);
file_put_contents($blacklist_file, implode("\n", $blacklist));
} else {
return true;
}
}
}
return false;
}

// Sanitize GET, POST, and COOKIE data
foreach ($_GET as $key => $value) {
$_GET[$key] = sanitize_input($value);
}
foreach ($_POST as $key => $value) {
$_POST[$key] = sanitize_input($value);
}
foreach ($_COOKIE as $key => $value) {
$_COOKIE[$key] = sanitize_input($value);
}

// Check if the user failed to log in three times
if (isset($_POST['username']) && isset($_POST['password'])) {
$username = sanitize_input($_POST['username']);
$password = sanitize_input($_POST['password']);
$ip = $_SERVER['REMOTE_ADDR'];
$ip_filename = str_replace(':', '_', $ip);
$login_attempts_file = "../blacklists/$ip_filename";
if (file_exists($login_attempts_file)) {
$login_attempts = (int) file_get_contents($login_attempts_file);
if ($login_attempts >= 3 && !is_blacklisted($ip)) {
blacklist_ip($ip);
} else {
file_put_contents($login_attempts_file, $login_attempts + 1);
}
} else {
file_put_contents($login_attempts_file, 1);
}
}