PHP WebShell

Текущая директория: /var/www/bitcardoApp/backyard/user/security

Просмотр файла: throttle.php

<?php
// backyard/user/security/throttle.php
include '../common/header.php';
if (!isset($conn)) { include_once '../../config/db_config.php'; }
require_once '../../models/security/throttle.php';
date_default_timezone_set('Africa/Lagos');

function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); }

$table   = $_GET['table'] ?? 'auth_throttle';
$allowed = th_allowed_tables();
if (!in_array($table, $allowed, true)) { $table = 'auth_throttle'; }

$filters = [
  'q' => $_GET['q'] ?? '',
  'only_locked' => isset($_GET['only_locked']) ? 1 : 0,
  'page' => (int)($_GET['page'] ?? 1),
  'per_page' => (int)($_GET['per_page'] ?? 50),
];
$data = th_list($conn, $table, $filters, $filters['page'], $filters['per_page']);

function qurl(array $add=[]){
  $qs = array_merge($_GET, $add);
  return '?'.http_build_query($qs);
}
?>
<style>
  .table td, .table th { vertical-align: middle; }
  .code-sm { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace; font-size: .825rem; }
  @media (max-width: 767.98px){
    .stack-sm>*{ margin-bottom:.5rem; }
    .table-responsive{ overflow-x:auto; }
  }
</style>

<div class="nk-content nk-content-fluid mt-5">
  <div class="container-xl wide-lg">
    <div class="nk-content-body">

      <div class="nk-block-head">
        <div class="nk-block-between-md g-3">
          <div class="nk-block-head-content">
            <h4 class="nk-block-title fw-normal">Rate-limit & Throttle Monitor</h4>
            <p class="text-soft mb-0">Inspect and clear locks across throttle tables.</p>
          </div>
          <div class="nk-block-head-content">
            <a href="../dashboard/index.php" class="btn btn-outline-secondary btn-sm">Back</a>
          </div>
        </div>
      </div>

      <div class="nk-block">
        <div class="card card-bordered">
          <div class="card-inner">

            <form class="row g-2 mb-3" method="get">
              <div class="col-12 col-md-3">
                <label class="form-label small">Table</label>
                <select class="form-select" name="table" onchange="this.form.submit()">
                  <?php foreach ($allowed as $t): ?>
                    <option value="<?= h($t); ?>" <?= $t===$table?'selected':''; ?>><?= h($t); ?></option>
                  <?php endforeach; ?>
                </select>
              </div>
              <div class="col-8 col-md-5">
                <label class="form-label small">Search (ip/token/key/user)</label>
                <input type="text" class="form-control" name="q" value="<?= h($filters['q']); ?>" placeholder="e.g. 127.0.0.1 or user id">
              </div>
              <div class="col-4 col-md-2 d-flex align-items-end">
                <div class="form-check">
                  <input class="form-check-input" type="checkbox" name="only_locked" id="only_locked" <?= $filters['only_locked']?'checked':''; ?>>
                  <label class="form-check-label small" for="only_locked">Only locked</label>
                </div>
              </div>
              <div class="col-12 col-md-2 d-flex align-items-end justify-content-end">
                <button class="btn btn-primary w-100 w-md-auto">Apply</button>
              </div>
            </form>

            <div class="d-flex justify-content-between align-items-center mb-2">
              <h6 class="mb-0"><?= h($table); ?></h6>
              <div class="small text-soft">Total: <?= number_format($data['total']); ?></div>
            </div>

            <div class="table-responsive">
              <table class="table table-striped table-sm align-middle">
                <thead class="small text-soft">
                  <tr>
                    <?php foreach ($data['columns'] as $c): ?>
                      <th><?= h($c); ?></th>
                    <?php endforeach; ?>
                    <th class="text-end">Action</th>
                  </tr>
                </thead>
                <tbody>
                  <?php if (empty($data['rows'])): ?>
                    <tr><td colspan="<?= count($data['columns'])+1; ?>" class="text-center text-muted py-4">No data.</td></tr>
                  <?php else: foreach ($data['rows'] as $row): ?>
                    <tr>
                      <?php foreach ($data['columns'] as $c):
                        $v = $row[$c] ?? '';
                        $disp = is_scalar($v) ? (string)$v : json_encode($v);
                      ?>
                        <td class="code-sm"><?= h($disp); ?></td>
                      <?php endforeach; ?>
                      <td class="text-end">
                        <button class="btn btn-xs btn-outline-danger" onclick='thDelete(<?= json_encode(['table'=>$table,'id'=>$row], JSON_HEX_TAG|JSON_HEX_APOS|JSON_HEX_AMP|JSON_HEX_QUOT); ?>)'>Clear</button>
                      </td>
                    </tr>
                  <?php endforeach; endif; ?>
                </tbody>
              </table>
            </div>

            <?php if ($data['total'] > $filters['per_page']): 
              $p = max(1,(int)$filters['page']); 
              $pages = max(1, (int)ceil($data['total'] / max(1,(int)$filters['per_page'])));
              $prev = max(1, $p-1); $next = min($pages, $p+1);
            ?>
              <div class="d-flex justify-content-between align-items-center mt-2">
                <div class="small text-soft">Page <?= $p; ?> of <?= $pages; ?></div>
                <ul class="pagination pagination-sm mb-0">
                  <li class="page-item <?= $p<=1?'disabled':''; ?>"><a class="page-link" href="<?= qurl(['page'=>1]); ?>">« First</a></li>
                  <li class="page-item <?= $p<=1?'disabled':''; ?>"><a class="page-link" href="<?= qurl(['page'=>$prev]); ?>">‹ Prev</a></li>
                  <li class="page-item disabled"><span class="page-link"><?= $p; ?></span></li>
                  <li class="page-item <?= $p>=$pages?'disabled':''; ?>"><a class="page-link" href="<?= qurl(['page'=>$next]); ?>">Next ›</a></li>
                  <li class="page-item <?= $p>=$pages?'disabled':''; ?>"><a class="page-link" href="<?= qurl(['page'=>$pages]); ?>">Last »</a></li>
                </ul>
              </div>
            <?php endif; ?>

          </div>
        </div>
      </div>

    </div>
  </div>
</div>

<script>
async function thDelete(payload){
  if(!confirm('Clear this lock/row?')) return;
  try{
    const resp = await fetch('../../models/security/throttle_actions.php', {
      method:'POST',
      headers:{'Content-Type':'application/json'},
      body: JSON.stringify({ action:'delete', table: payload.table, id: payload.id })
    });
    const txt = await resp.text();
    let data; try { data = JSON.parse(txt); } catch(e){ throw new Error('Bad JSON: '+txt.substring(0,160)); }
    if(!data.ok){ alert('Failed: '+(data.error||'Unknown')); return;}
    location.reload();
  }catch(err){
    alert(err.message || 'Network error');
  }
}
</script>

<?php include '../common/footer.php'; ?>

Выполнить команду


Для локальной разработки. Не используйте в интернете!