69 Commits
Author SHA1 Message Date
Jamie Curnow 66ab4b24d1 Stop non-admins injecting nginx directives through host fields
advanced_config is admin-only, but other fields are written into nginx
config as-is and the schema barely limited them. A non-admin could add
any directive through them:

- location path, forward_host and forward_path (any non-empty string)
- proxy host forward_host (a quote breaks out of set $server "...")
- redirection forward_domain_name and stream forwarding_host (their
  pattern allowed ";", e.g. "example.com; return 200; #")
- access list IPv6 addresses ("%.+" zone id allowed "::1%x; allow all")
- domain names (a newline got out of the header comment)

Validation
- New lib/nginx-values.js holds the rules. Values can't contain
  characters that end or change an nginx token: whitespace, control
  characters, ; { } " ' # \, and no $ in a host. Location paths allow a
  modifier and an unquoted or double-quoted URI, so =, ~, ~* and ^~
  locations and quoted regexes keep working.
- The API schemas use the same patterns, including the certificate
  schema's own copy of the domain rule. A test fails if they drift.
- generateConfig checks stored values again, so rows saved before these
  rules can't inject either. The check is about nginx structure only:
  a stored value the API would now reject, but which can't add
  directives, still renders. If a value is unsafe, nothing is written
  and the host is marked offline with the reason in nginx_err. The same
  check covers per-location access lists and the Let's Encrypt request
  config.
- htpasswd user names can't contain ":" or control characters, which
  corrupted the file.

Fixes along the way
- IPv6 client addresses: drop zone ids, which nginx's allow/deny
  rejects anyway, and fix broken escapes (literal "d" for digits, an
  unescaped ".").
- Rewrite the domain rule used by redirection and stream hosts so it
  can't backtrack exponentially. It accepts the same values.
- Pattern errors still say "must match pattern", but no longer quote
  the regex.

Tests
- backend/test/nginx-values.test.js, run by `yarn test` and in
  scripts/ci/test-and-build. Real request schemas reject an injection
  set and accept valid values on every endpoint. Accepted values,
  rendered through the real templates and parsed using nginx's
  tokenizer rules, keep the same statement structure. The check
  refuses unsafe stored rows.
- NginxValues.cy.js: injection attempts from a non-admin get 400, and
  hosts using valid edge-case values come up with nginx_online true.
2026-11-10 08:20:02 +10:00
Jamie Curnow 5b7e34eb67 Fix second round of review findings from PR #6029
Security
- Check advanced_config permissions before creating a certificate on
  host update (proxy, redirection and 404 hosts). A refused request
  previously requested a Let's Encrypt certificate first, leaving an
  orphan certificate and using up rate limit.
- Only trust X-NPM-Peer-Addr when it comes with a secret generated at
  container start. The admin nginx sends both headers. Any proxy host or
  stream forwarding to 127.0.0.1:3000 was also a loopback peer, so it
  could forge the header and get a fresh rate-limit bucket on every
  request. Without the secret (dev, or a mounted production.conf), the
  header is ignored.
- Add a login limit per IP across all accounts (30 failed attempts a
  minute) alongside the per-account one. Before this, one address could
  spray passwords over any number of accounts. Behind a shared proxy,
  everyone using that proxy shares this limit.
- Stop trusting X-Real-IP from loopback. It was only there for an older
  version of the rate limiter, and it let a stream host forwarding to a
  local proxy host forge the client IP and get past IP access lists.
  Loopback now behaves as it does on master.

Correctness
- Refuse to delete a certificate that hosts still use (400, with counts
  per host type). Their configs include its files, and a successful
  revoke deleted them anyway, which broke nginx -t. Otherwise the
  certificate is revoked and its files are removed even if the revoke
  fails.
- Let non-admins clear a location's advanced config. Deleting the
  location was already allowed and has the same effect, and a location
  deleted and re-added at the same path arrives with an empty config,
  which was refused.
- Clear proxy host grants (meta.proxy_host_ids) when visibility isn't
  "user" or proxy hosts are hidden, and drop ids of deleted hosts.
  Before, hidden grants came back when proxy hosts were shown again.
  The backend enforces this; the permissions modal also stops sending
  them.
- 404 host and redirection host modals now wait for the current user
  to load, so an admin's advanced config change isn't dropped if they
  submit before it loads.

Tests
- NonAdminHosts.cy.js: refused change doesn't create a certificate,
  location rename and clear rules, grant clearing.
- Certificates.cy.js: deleting a certificate that is in use.
2026-11-09 23:39:26 +10:00
Abdulhafiz Davlatov bc8bbf3562 feat: rate limit auth endpoints and scope user proxy host permissions
- Add in-memory sliding window rate limiter for auth token endpoints with CI/test bypass and successful request exclusion
- Add user_permission meta column migration and Objection model configuration
- Support scoping allowed proxy hosts per user when in 'Created Items Only' visibility mode
- Restrict advanced nginx configuration editing on hosts to admin users only
- Fix user permissions route ID parsing and omit id from permission update payloads
- Add allowed proxy hosts selector in permissions modal and display permissions summary badges in users table
2026-11-05 12:16:36 +05:00
mikeyheneinandClaude Opus 5.5 5aed3a5539 Reject unknown keys in PUT /api/users/:id/permissions (an extra key crashes the backend)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 20:28:37 -08:00
Jamie Curnow 2cfd3395cf Adds integration tests for per path access lists, fixes ipv6 jsv,
and enforces host-wide access list when location access list is not set
2026-09-24 12:21:49 +10:00
Dimas Rakha Wisnu 633b653f79 Merge branch 'develop' into develop 2026-09-23 18:53:06 +07:00
carlosalbertorg 4282d6c6e9 feat: Add a Logs viewer to the admin UI
Nginx Proxy Manager had no way to inspect application or nginx logs
from the web UI - admins had to shell into the container or read
`docker logs`. This adds an admin-only Logs page that can tail:

- the backend application log, now also mirrored to
  /data/logs/backend.log (in addition to stdout) and rotated by the
  logrotate timer that already runs every 2 days
- the Let's Encrypt/certbot log, which certbot already writes to
  /data/logs/letsencrypt.log via its existing --logs-dir flag
- per-host nginx access/error logs (proxy, redirection, 404 and
  stream hosts), with the file path always resolved server-side from
  a validated host_type enum + numeric host_id, never from client
  input

Reads use a reverse chunked scan (64KB chunks, capped at 5MB scanned
per request) instead of loading whole files into memory, and the
frontend polls every 5s only while the tab is focused and "Live" is
on, so this stays cheap on both CPU and memory. No new runtime
dependencies were added on either side.

Purely additive: two new admin-only endpoints
(GET /api/logs/sources, GET /api/logs/tail), no existing behaviour
changed.
2026-09-22 13:11:38 -03:00
Dimas R. Wisnu 4a0f212289 feat: per-path access lists, host logs modal, PostgreSQL support
- Per-path access lists: assign different access lists to individual
  locations on the same proxy host
- Host logs modal: view access/error logs from proxy host dropdown
- PostgreSQL JSON containment query (@>) for location regeneration
- Locale keys: action.logs, column.error
2026-08-07 16:40:32 +07:00
Jamie Curnow 03c70e3902 Fixes for upgraded debian trixie
- Adds request logging in debug mode for some endpoints
- Moves certbot version determination to the startup scripts and removes
  bash script encapsulation when installing plugins
- Revert loose domain validation, which was there for a specific reason
  addressing CVE's
- Fix Cypress suite for cert generation
- Adds Cypress test that iterates over the entire certbot plugins list
  and installs each one, ensuring at the very least that the install
  works
- Fixed some plugins based on this
- (!) Still some work to do on this, hostinger is still broken at least
- Improved cypress tests for custom certs; they will generate on each
  run instead of being baked in. The baked ones were due to expire soon
2026-05-25 07:37:24 +10:00
Jamie Curnow 7330d0441c Loose validation on certificate domain names 2026-05-18 15:34:29 +10:00
jc21 011191f645 Merge pull request #5260 from jerry-yuan/develop
Add trust_forwarded_proto option for SSL redirect handling in r…
2026-02-11 14:54:00 +10:00
Jamie Curnow c88de65d3a Fix #5274 2fa backup codes not validating properly 2026-02-05 10:51:15 +10:00
jerry-yuan 054742539f fix: Supplement Swagger documentation 2026-01-31 14:17:05 +00:00
jerry-yuan 187d21a0d5 feat: add trust_forwarded_proto option for SSL redirect handling in reverse proxy scenarios
When Nginx is behind another proxy server (like CloudFlare or AWS ALB), the force-SSL
feature can cause redirect loops because Nginx sees the connection as plain HTTP
while SSL is already handled upstream. This adds a new boolean option to trust
the X-Forwarded-Proto header from upstream proxies.

Changes:
- Add `trust_forwarded_proto` column to proxy_host table (migration)
- Update model and API schema to support the new boolean field
- Modify force-ssl Nginx template to check X-Forwarded-Proto/X-Forwarded-Scheme
- Add map directives in nginx.conf to validate and sanitize forwarded headers
- Add advanced option toggle in frontend UI with i18n support (EN/ZH)
- Set proxy headers from validated map variables instead of $scheme

This allows administrators to control SSL redirect behavior when Nginx is deployed
behind a TLS-terminating proxy.
2026-01-31 13:11:47 +00:00
Jamie Curnow c1ad7788f1 Changed 2fa delete from body to query for code
as per best practices
2026-01-14 13:24:38 +10:00
Jamie Curnow d33bb02c74 Add missing params to swagger 2026-01-14 12:46:30 +10:00
Jamie Curnow 462c134751 2fa work slight refactor
- use existing access mechanisms for validation
- adds swagger/schema and validation of incoming payload
2026-01-14 11:45:12 +10:00
kk.cheng 471b62c7fe Add option to select RSA or ECDSA key type when creating certificates 2026-01-07 19:13:12 +08:00
Jamie Curnow e5aae1f365 Fix openapi schema format 2025-11-13 11:51:13 +10:00
Jamie Curnow cf7306e766 Tweaks to showing new version available
- Added frontend translation for english
- Moved frontend api logic to hook and backend api space
- Added swagger schema for the new api endpoint
- Moved backend logic to its own internal file
- Added user agent header to github api check
- Added cypress integration test for version check api
- Added a memory cache item from github check to avoid hitting it too
  much
2025-11-13 11:20:31 +10:00
Jamie Curnow 95957a192c Re-add dns_provider_credentials to swagger schema 2025-10-30 12:24:17 +10:00
Jamie Curnow 906ce8ced2 Swagger/openapi schema mega fixes and Cypress validation/enforcement 2025-10-30 11:50:51 +10:00
Jamie Curnow 5b7013b8d5 Moved certrbot plugin list to backend
frontend doesn't include when building in react version
adds swagger for existing dns-providers endpoint
2025-10-26 00:28:03 +10:00
Jamie Curnow 4866988772 Fix stream creation with new ssl cert 2025-10-02 08:12:37 +10:00
Jamie Curnow 18537b9288 404 hosts add update complete, fix certbot renewals
and remove the need for email and agreement on cert requests
2025-10-02 08:12:37 +10:00
Jamie Curnow efcefe0c17 Fix custom cert writes, fix schema 2025-10-02 08:12:33 +10:00
Jamie Curnow fb2708d81d Fix cypress tests following user wizard changes 2025-10-02 08:12:09 +10:00
Jamie Curnow 330993f028 Convert backend to ESM
- About 5 years overdue
- Remove eslint, use bomejs instead
2025-10-02 08:10:18 +10:00
Jamie Curnow 8c9d2745e2 Fix remote execution bug where email address can contain malicious code
also convert almost all cmd execs for certificates to properly escape arguments
2025-08-20 10:57:24 +10:00
Jamie Curnow 97dbbdd60f Fix incorrect swagger for streams list 2025-06-30 13:00:25 +10:00
Sander Jochems a6af5ec2c7 Remove certificate as required from proxy host 2025-02-05 18:18:50 +01:00
Sander Jochems 14d7c35fd7 Fix whitespaces 2025-02-05 17:31:09 +01:00
Sander Jochems cfcf78aaee Set bearer auth security component 2025-02-05 17:29:40 +01:00
jc21 e1c84a5c10 Merge pull request #4338 from Sander0542/fix/token-expires-type
Fix type for token.expires
2025-02-05 20:35:33 +10:00
Jamie Curnow 6a60627833 Cypress test for Streams
and updated cypress + packages
2025-02-05 16:02:17 +10:00
Jamie Curnow 68a7803513 Fix api schema after merging latest changes 2025-02-04 17:55:28 +10:00
Sander Jochems 57cd2a1919 Fix type for token.expires 2025-02-03 21:47:41 +01:00
Jasper Stubbe 87998a03ce Fix bootloop if stream is used for http/https port 2024-11-14 11:39:48 -08:00
Chris Maffey 2e9a4f1aed Update put.json
Password can be left blank for updates.  Otherwise you have to reenter the password every time you save the auth list
2024-10-24 17:29:16 +13:00
Jamie Curnow edbed1af90 Adds tests for settings endpoints
and reenables dns cert test
and fixes problems with schema
2024-10-17 08:48:47 +10:00
Nephiel fa2c814fcb Fix schema validation in Default Site
Should solve error `data/value must match exactly one schema in oneOf` when setting the Default Site to 404 or 444. #4074
2024-10-16 19:09:14 +00:00
Nephiel d96a3987c0 Fix forward_scheme validation in Redirection Host
Should solve error `data/forward_scheme must be equal to one of the allowed values` when configuring a Redirection Host with scheme set to `auto`. #4074
2024-10-16 19:04:50 +00:00
Jamie Curnow fe2d8895d6 Cypress test for http and dns cert provision 2024-10-16 14:53:57 +10:00
Jamie Curnow 351ba8dacd More tests for certificates, fixed schema problems 2024-10-16 08:32:49 +10:00
Jamie Curnow c39d5433bc Fix CVE-2024-46256 and CVE-2024-46257
- Schema validate against bad domain characters
- Integration test for CVE POC examples
- Cypress rewrite of plugins for file upload
2024-10-11 11:31:57 +10:00
Jamie Curnow 4572b205c9 Openapi Schema improvements
- Return proper booleans in api responses
- Update jsonschemavalidation to latest draft
2024-10-10 15:53:11 +10:00
Jamie Curnow dfe2588523 Refactor API Schema and validation
- /schema now returns full openapi/swagger schema
- That schema is used to validate incoming requests
- And used as a contract in future integration tests
- Moved route files up one level
- Fixed incorrect 404 reponses when getting objects
- Fixed saving new objects and passing jsonschemavalidation
2024-10-09 18:05:15 +10:00
David Indra 1fb9a75a33 Fix: increase max number of domains to 100 2024-02-23 15:37:32 +01:00
Renan Duarte 1975e4a151 fix: updating maxItems (schema/definitions) to 30 2023-12-12 12:45:35 +01:00
Julian Reinhardt c55476b196 Adds buttons to test availability of server from public internet 2021-10-31 00:19:18 +02:00