Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
471e811
fix(critical): prevent SQL injection via PANEL_DB_NAME by backtick-qu…
ddrayko Jul 10, 2026
e47fc40
fix(critical): remove 'unsafe-eval' from CSP to prevent XSS via code …
ddrayko Jul 10, 2026
eecd21a
fix(critical): prevent attacker-controlled lookup in WebAuthn challen…
ddrayko Jul 10, 2026
3e4bfd7
fix(high): add progressive login delay to admin login to prevent brut…
ddrayko Jul 10, 2026
ea4ef15
fix(high): bump token_version on email change to invalidate existing …
ddrayko Jul 10, 2026
1db8c9b
fix(high): apply progressive login delay only after CAPTCHA/password …
ddrayko Jul 10, 2026
1e90bc4
fix(high): add ownership verification for resources and power endpoin…
ddrayko Jul 10, 2026
e4fe548
fix(high): invalidate all sessions on logout by bumping token_version
ddrayko Jul 10, 2026
7768db8
fix(medium): sanitize activity log details to prevent log injection a…
ddrayko Jul 10, 2026
9306e1b
fix(medium): add rate limiting to all passkey endpoints to prevent br…
ddrayko Jul 10, 2026
6cb4835
fix(medium): remove verbose error messages from API responses to prev…
ddrayko Jul 10, 2026
07974d4
fix(medium): add audit logging to admin CLI operations for accountabi…
ddrayko Jul 10, 2026
fe1d247
fix(critical): restrict CORS origins in development mode to prevent c…
ddrayko Jul 10, 2026
aa592ca
fix(critical): prevent SQL injection in requireOwnership middleware b…
ddrayko Jul 10, 2026
4326fbd
Merge pull request #21 from ZeroHost-Code/security-update
ddrayko Jul 10, 2026
fd805ef
fix: add missing PANEL_DB_NAME export from services/pyrodactyl.js for…
ddrayko Jul 10, 2026
6d22f87
fix: import randomBytes from crypto instead of using crypto.randomByt…
ddrayko Jul 10, 2026
4822f5a
fix: add wasm-unsafe-eval to CSP for cap-widget WebAssembly, handle p…
ddrayko Jul 10, 2026
868d1e5
fix: suppress 4xx error logging from Pterodactyl API (callers handle …
ddrayko Jul 10, 2026
547b12f
fix: init Lucide icons on login page so passkey fingerprint SVG appea…
ddrayko Jul 10, 2026
08eef6c
fix: inline fingerprint SVG directly instead of relying on Lucide dyn…
ddrayko Jul 10, 2026
020bc32
fix: add initIcons() with fallback timeout in renderLoginPage, bump c…
ddrayko Jul 10, 2026
37a3133
fix: add 'unsafe-eval' to CSP script-src for cap-widget instrumentation
ddrayko Jul 10, 2026
cc13e71
switch GH Actions from password to SSH key auth
ddrayko Jul 10, 2026
dd4753d
chore: trigger deploy
ddrayko Jul 10, 2026
1135a12
feat: complete mobile responsive redesign
ddrayko Jul 10, 2026
8277b5b
fix: improve /create wizard and notification panel mobile layout
ddrayko Jul 10, 2026
fbea818
fix: close sidebar on mobile when opening notification panel
ddrayko Jul 10, 2026
d29ec0b
fix: hide wizard progress bar on mobile
ddrayko Jul 10, 2026
da81f35
fix: notif panel full width on phones only, fixed on tablets
ddrayko Jul 10, 2026
c106753
fix: mobile notif panel shows X close button instead of Mark all read
ddrayko Jul 10, 2026
fb9c286
fix: notif panel uses max-width to prevent overflow on all screens
ddrayko Jul 10, 2026
b27d761
fix: notif panel full width on mobile
ddrayko Jul 10, 2026
5ba929e
fix: reset notif panel left position on mobile
ddrayko Jul 10, 2026
cc57690
fix: hide wizard progress bar on mobile (override after base styles)
ddrayko Jul 10, 2026
006984e
fix: hide create page header text on mobile
ddrayko Jul 10, 2026
dcfed2c
fix: force hide create page header on mobile (inline style override)
ddrayko Jul 10, 2026
a3a84d0
fix: disable sidebar collapse on logo click on mobile
ddrayko Jul 10, 2026
0266a40
feat: add server dropdown menu in sidebar
ddrayko Jul 11, 2026
b797a6b
fix: server dropdown always fetches and navigates to /servers on click
ddrayko Jul 11, 2026
1f98d8f
feat: add resend verification email button on login error
ddrayko Jul 11, 2026
f173c7b
fix: show nav indicator on My Servers dropdown
ddrayko Jul 11, 2026
393ef2b
fix: always re-render sidebar nav on page change for correct indicator
ddrayko Jul 11, 2026
301c030
fix: preserve nav indicator element across re-renders for smooth anim…
ddrayko Jul 11, 2026
2a347b5
fix: don't re-render sidebar nav on every navigation to preserve indi…
ddrayko Jul 11, 2026
76e6226
fix: preserve nav indicator element by not calling renderSidebarNav i…
ddrayko Jul 11, 2026
ff4d28b
fix: preserve nav indicator by using .nav-items wrapper + fix dropdow…
ddrayko Jul 11, 2026
8782a82
fix: animate indicator to Notification when clicked
ddrayko Jul 11, 2026
bd0f046
fix: auto-close server dropdown when navigating away
ddrayko Jul 11, 2026
95a85e9
fix: apply active orange color to nav-parent (My Servers) tab
ddrayko Jul 11, 2026
a8e36f6
fix: force-close sidebar dropdown instantly before positioning nav in…
ddrayko Jul 11, 2026
4cf0342
fix: eagerly fetch servers on sidebar render so dropdown shows them
ddrayko Jul 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/deploy-beta.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ jobs:
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USER }}
password: ${{ secrets.SSH_PASSWORD }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
port: ${{ secrets.SSH_PORT || 22 }}
host_key_checking: false
script: |
cd ${{ secrets.BETA_PATH }}
cp .env /tmp/beta.env 2>/dev/null; cp port.txt /tmp/beta.port.txt 2>/dev/null
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/deploy-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ jobs:
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USER }}
password: ${{ secrets.SSH_PASSWORD }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
port: ${{ secrets.SSH_PORT || 22 }}
host_key_checking: false
script: |
cd ${{ secrets.MAIN_PATH }}
cp .env /tmp/main.env 2>/dev/null; cp port.txt /tmp/main.port.txt 2>/dev/null
Expand Down
3 changes: 2 additions & 1 deletion config/pyrodactyl.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export const PTERO_URL = process.env.PTERO_URL || 'https://panel.zero-host.org';
export const PTERO_API_KEY = process.env.PTERO_API_KEY || '';
export const PANEL_DB_NAME = (process.env.PANEL_DB_NAME || 'panel').replace(/[^a-zA-Z0-9_]/g, '');
const _rawPanelDb = (process.env.PANEL_DB_NAME || 'panel').replace(/[^a-zA-Z0-9_]/g, '');
export const PANEL_DB_NAME = '`' + _rawPanelDb + '`';

export const SERVER_LIMITS = {
memory: 512,
Expand Down
8 changes: 8 additions & 0 deletions middleware/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,17 @@ export function requireNotRestricted(req, res, next) {
next();
}

const ALLOWED_TABLES = new Set(['server_meta']);
const ALLOWED_COLUMNS = new Set(['ptero_server_id', 'user_id', 'id']);

export function requireOwnership(table, column, paramName, idSource = 'params') {
return async (req, res, next) => {
try {
if (!ALLOWED_TABLES.has(table) || !ALLOWED_COLUMNS.has(column)) {
console.error(`Blocked ownership check on unauthorized table/column: ${table}.${column}`);
return res.status(500).json({ error: 'Ownership verification failed' });
}

const id = parseInt(idSource === 'params' ? req.params[paramName] : req.body[paramName], 10);
if (isNaN(id)) {
return res.status(400).json({ error: 'Invalid ID' });
Expand Down
Loading
Loading