feb5380b28
Fixes critical pre-existing issues found during review: bulk_action.php had no auth check at all (unauthenticated download/delete of any qrcode) and built a table name from unwhitelisted user input (SQL injection); the QR generator classes wrote files from unvalidated filename/format, allowing path traversal and arbitrary file writes. Also pins chillerlan/php-qrcode to 5.0.5 since master now requires PHP 8.4, breaking the PHP 8.3 build. - CSRF tokens on all POST forms and the bulk_action.php JSON endpoint - Login rate limiting (5 attempts / 15 min) via new login_attempts table - Hardened sessions: httponly/samesite cookies, 30 min idle timeout, session regeneration on login - Forced password change for the default superadmin/superadmin account - Server-side validation in Users/DynamicQrcode/Qrcode classes - Audit log table for auth, user, and qrcode actions - Checked-in db schema (db/init.sql, migrations/) instead of relying on an opaque prebuilt db image - Production docker-compose with Nginx + php-fpm instead of the PHP dev server Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
85 lines
2.6 KiB
PHP
85 lines
2.6 KiB
PHP
<?php
|
|
require_once 'includes/bootstrap.php';
|
|
require_once BASE_PATH . '/includes/auth_validate.php';
|
|
require_once BASE_PATH . '/lib/Users/Users.php';
|
|
|
|
$db = getDbInstance();
|
|
$users = new Users();
|
|
|
|
if ($_SESSION['type'] !== 'super')
|
|
$users->failure('Only a "super admin" account can access the admin listing page', 'Location: index.php');
|
|
|
|
$select = array('id', 'username', 'type');
|
|
$search_fields = array('username');
|
|
require_once BASE_PATH . '/includes/search_order.php';
|
|
$page = filter_input(INPUT_GET, 'page', FILTER_SANITIZE_FULL_SPECIAL_CHARS) ?? 1;
|
|
$db->pageLimit = 15;
|
|
$rows = $db->arraybuilder()->paginate('users', $page, $select);
|
|
$total_pages = $db->totalPages;
|
|
?>
|
|
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<title>Qrcode Generator</title>
|
|
<head>
|
|
<?php include './includes/head.php'; ?>
|
|
</head>
|
|
<body class="hold-transition sidebar-mini layout-fixed layout-navbar-fixed layout-footer-fixed">
|
|
<div class="wrapper">
|
|
<!-- Navbar -->
|
|
<?php include './includes/navbar.php'; ?>
|
|
<!-- /.navbar -->
|
|
|
|
<!-- Main Sidebar Container -->
|
|
<?php include './includes/sidebar.php'; ?>
|
|
<!-- /.Main Sidebar Container -->
|
|
|
|
<!-- Content Wrapper. Contains page content -->
|
|
<div class="content-wrapper">
|
|
<!-- Content Header (Page header) -->
|
|
<div class="content-header">
|
|
<div class="container-fluid">
|
|
<div class="row mb-2">
|
|
|
|
<div class="col-sm-6">
|
|
<h1 class="m-0 text-dark">Users</h1>
|
|
</div><!-- /.col -->
|
|
|
|
<div class="col-sm-6">
|
|
<ol class="breadcrumb float-sm-right">
|
|
<li class="breadcrumb-item">
|
|
<a href="user.php" class="btn btn-success"><i class="fa fa-plus"></i> Add new</a>
|
|
</li>
|
|
</ol>
|
|
</div><!-- /.col -->
|
|
</div><!-- /.row -->
|
|
</div><!-- /.container-fluid -->
|
|
</div><!-- /.content-header -->
|
|
|
|
<!-- Flash message-->
|
|
<?php include BASE_PATH . '/includes/flash_messages.php'; ?>
|
|
<!-- /.Flash message-->
|
|
|
|
<!-- Filters -->
|
|
<?php $options = $users->setOrderingValues();
|
|
include BASE_PATH . '/forms/filters.php'; ?>
|
|
<!-- /.Filters -->
|
|
|
|
<!-- Main content -->
|
|
<section class="content">
|
|
<div class="container-fluid">
|
|
|
|
<!-- Table -->
|
|
<?php include BASE_PATH . '/forms/table_users.php'; ?>
|
|
<!-- /.Table -->
|
|
|
|
</div><!-- /.container-fluid -->
|
|
</section>
|
|
</div><!-- /.content-wrapper -->
|
|
|
|
<!-- Footer and scripts -->
|
|
<?php include './includes/footer.php'; ?>
|
|
<!-- /.Footer and scripts -->
|
|
</body>
|
|
</html>
|