Repository navigation
Security hardening, HTTPS + LAN only, self-contained Windows/macOS/Linux packages, signed updates, About & Licences - #22
Merged
Conversation
- images_to_pdf: compute the image rect ourselves (PyMuPDF's keep_proportion stretched square images over the A4 box) and add a placement option: fit / fill (crop) / stretch / original size. - Tool grid: tint tools usable on the selection pastel green, move them and their groups to the front, row-major layout; user-pinned favourites row. - Shortcuts dialog: up to four columns so it fits on screen. - SchemaForm: show_if accepts a list of values. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SgNH4tzUdde2tgUEgsfWxD
- Files and jobs belong to an owner (this machine, or one paired device); other devices get 404. Owner ids are hashes, never the session cookie. - A loopback request carrying proxy forwarding headers is treated as remote, so a local reverse proxy cannot make the LAN 'local'. - Pairing: keys under 12 characters refused at start-up, a global attempt limit on top of the per-client one, bounded limiter memory, sessions expire after 30 days and are capped. - LibreOffice runs with a throwaway hardened profile: no macros or active content, links never updated, no recalculation on load, all network traffic sent to a dead proxy (tests cover SSRF and local file includes). - API responses are no-store; extra security headers; uvicorn Server header off; /api/docs off unless APT_API_DOCS=true. - Storage cap (APT_MAX_STORAGE_MB, 507) and per-owner pending job cap (429); the sweeper no longer expires inputs of running jobs. - Docker trusts only the bridge gateway (APT_TRUSTED_NETWORKS=gateway), never in LAN mode; CI token is read-only. - pdfjs-dist 6.4.299 (GHSA-hq66-cqwq-w95j). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SgNH4tzUdde2tgUEgsfWxD
Optionally rebuild the redacted document from page images only (no text, fonts, objects, annotations, attachments or metadata survive), so nothing under a treatment can be recovered by any tool. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SgNH4tzUdde2tgUEgsfWxD
- HTTPS on by default with the server's own name-constrained local CA (private addresses and local names only, so a leaked key cannot vouch for real websites); the server certificate follows LAN address changes. TLS 1.2+, ECDHE + AEAD ciphers; HSTS only for DNS names. - Clients outside the local network (public addresses) are always refused; APT_TRUSTED_NETWORKS may only list local ranges. - --trust-ca and a one-time OS trust prompt on desktop start; public /api/session/ca.crt for devices; 'Connect device' dialog on the server PC with a pairing QR code (segno) and the CA fingerprint. - Mobile: compact header, scrollable viewer modes, KVKK findings usable on phones, no keyboard hints on touch, 40 px touch targets, no iOS zoom on input focus; opaque KVKK preview boxes. - Docker health check, CI and release smoke tests over verified HTTPS. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SgNH4tzUdde2tgUEgsfWxD
The Windows package now ships Tesseract with tur/eng/osd data in ocr/, so OCR works on PCs whose network blocks downloads. Sources are pinned in scripts/ocr/sources.json (SHA-256 enforced when set) and the installer's signature is reported at build time; ocr/manifest.json records the SHA-256 of every bundled file, the app re-checks it before use and refuses a damaged or altered bundle. 'OCR Onar (Windows).bat' repairs language data only with files matching those hashes; install-ocr-windows.ps1 verifies pinned hashes too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SgNH4tzUdde2tgUEgsfWxD
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SgNH4tzUdde2tgUEgsfWxD
- AdminPDFToolkit.exe (C# 5 WinForms, built with the Windows csc): ticks off every component via python -m adminpdf.selfcheck, starts the server with no console window, shows addresses and the certificate fingerprint, network-sharing switch, notification-area icon. Version info and asInvoker manifest; Authenticode signing when the WINDOWS_SIGN_PFX secret is set. .bat files move to scripts\. - python -m adminpdf.updater: optional update check; installs only releases whose Ed25519-signed SHA256SUMS verifies, matching hash, never a downgrade, zip-slip safe; data\ is kept. Release workflow writes SHA256SUMS(.sig) and release-manifest.json (scripts/release_signing.py). - Ghostscript bundled in gs\; Tesseract and Ghostscript resolved to their newest release at build time and verified against GitHub's published SHA-256; Ghostscript's source tarball is published with the release. - CI compiles the launcher on Windows with /warnaserror. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SgNH4tzUdde2tgUEgsfWxD
- Certificates: cap the common name at 64 characters (long computer names broke certificate creation, seen on macOS runners). - Tests: no POSIX mode check on Windows; a LibreOffice that refuses the crafted documents outright also passes (nothing leaks). - Windows package: unpack the Tesseract / Ghostscript NSIS installers with 7-Zip instead of a silent install (which re-launched elevated and returned before any file existed); pin Tesseract to its newest release v5.4.0.20240606 by SHA-256. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SgNH4tzUdde2tgUEgsfWxD
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SgNH4tzUdde2tgUEgsfWxD
The start-up banner contains Turkish letters that cp1252 cannot encode; the server died before listening when started from a .bat on such a PC. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SgNH4tzUdde2tgUEgsfWxD
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SgNH4tzUdde2tgUEgsfWxD
- python -m adminpdf.launcher: the Windows launcher's window in Tk — component checklist, server without a terminal (own process group), network sharing, update notice, data in the user's folder (macOS may run downloaded apps from a read-only location). - scripts/build_unix_portable.py: python-build-standalone (SHA-256 checked) + the app; Linux x86_64 tar.gz with a menu-entry script, macOS arm64 AdminPDFToolkit.app, ad-hoc signed (no paid Apple account; 'Open Anyway' once). Release CI builds and smoke-tests both. - Updater looks for the package of the running system; in-place install stays Windows-only. Self-check shows brew / apt / dnf commands for a missing Tesseract or Ghostscript. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SgNH4tzUdde2tgUEgsfWxD
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SgNH4tzUdde2tgUEgsfWxD
- In-app "Hakkında ve Lisanslar / About & Licences" dialog with separate Turkish and English tabs: supported systems, first-start warnings, every installed Python package (direct and transitive, from metadata), web bundle npm packages, bundled tool files with SHA-256 sources, programs, runtimes, fonts, data, build tools and methods (/api/about). - scripts/third_party.py replaces python_licenses.py and writes THIRD_PARTY_LICENSES.md as a full Turkish part then a full English part. - Windows SmartScreen, certificate prompt, firewall, macOS Gatekeeper, keychain and browser/phone certificate warnings documented on the README main page, release notes, OKUBENI files and in the app. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SgNH4tzUdde2tgUEgsfWxD
- scripts/virustotal.py (standard library): uploads the packages and the launcher exe to VirusTotal with a free API key (secret VIRUSTOTAL_API_KEY), or looks them up by SHA-256; paces itself to the free 4-per-minute limit; writes a TR/EN Markdown table and virustotal.json. Skips without a key and never fails the release. - release.yml: virustotal job between the builds and publish; its table goes into the release notes and the step summary, virustotal.json is published with the release. - README: "Güvenlik / Security" badge row (VirusTotal results of the latest release via shields.io, HTTPS, LAN only, signed updates, verified bundles, CSP, code signing). SECURITY.md and CHANGELOG. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SgNH4tzUdde2tgUEgsfWxD
…ut a web build - mypy: named function instead of a lambda returning CompletedProcess; the os.startfile ignore is no longer unused on Windows. - test_stream_json_runs_the_selfcheck: CI has no web build, so the self-check is not "ready" there; assert the exit code matches the streamed result instead of requiring 0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SgNH4tzUdde2tgUEgsfWxD
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SgNH4tzUdde2tgUEgsfWxD
…Brand links - Highlights (TR/EN): extra-secure KVKK PDF, image-to-PDF page size and placement, HTTPS + LAN-only + per-device isolation, green/first tools and favourites, phone/tablet QR, in-app About & Licences. - Phones/tablets: the launcher's Network sharing switch (the old 'Baslat - Ag Paylasimi (Windows).bat' no longer exists). - English install: macOS / Linux packages; launcher row in the stack; 350+ tests, VirusTotal and signed SHA256SUMS; APT_OCR_DIR/APT_GS_DIR. - Roadmap: portable packages, HTTPS/LAN pairing, signed updates and VirusTotal done; MSI installer left open. D Brand: public sibling repos. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SgNH4tzUdde2tgUEgsfWxD
…arning - README Installation: numbered macOS steps with the exact Gatekeeper message (incl. macOS 15 wording), Done (not Move to Trash) > Privacy & Security > Open Anyway, xattr alternative, keychain password, brew; numbered Linux steps with the browser certificate import and apt/dnf. Same in the English part. - Launcher menu names as they are in the app. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SgNH4tzUdde2tgUEgsfWxD
- security.default_gateway reads /proc/net/route with Path.read_text (file always closed). - launcher: say why each ignored OSError is safe to ignore. - selfcheck: one import style for importlib. - third_party / virustotal: explicit parentheses around intentionally joined strings in lists. - test_security: requests made before the assert, not inside it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SgNH4tzUdde2tgUEgsfWxD
On a slow macOS runner the server had not printed its banner after 6 s. Read stdout line by line in a thread and wait up to 90 s for the banner (or the process ending); stderr goes to a file so the pipe cannot fill. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SgNH4tzUdde2tgUEgsfWxD
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary / Özet
Güvenlik sıkılaştırması, her zaman HTTPS ve yalnızca yerel ağ, kurulum gerektirmeyen Windows / macOS / Linux paketleri, imzalı güncellemeler, VirusTotal taraması ve uygulama içi iki dilli Hakkında ve Lisanslar sayfası.
Security hardening, HTTPS-only and local-network-only access, self-contained Windows / macOS / Linux packages, signed updates, VirusTotal scanning and a bilingual in-app About & Licences page.
Güvenlik / Security
no-store;/api/docsoff by default.--trust-ca,/api/session/ca.crt, Devices dialog with QR for phones / tablets.Özellikler / Features
AdminPDFToolkit.exelauncher (component checklist, "System ready", tray, no console window; plain .NET Framework, optional Authenticode via secrets).SHA256SUMSverifies; never downgrades./api/about): Turkish and English as separate tabs — systems, first-start warnings, every installed Python package, npm packages, bundled tool files, programs, fonts, data, methods.scripts/third_party.pywrites THIRD_PARTY_LICENSES.md the same way.Sürüm ve belgeler / Release & docs
SHA256SUMS(+.sig), the Ghostscript source (AGPL §6) and release notes with download table and first-start warnings.virustotaljob (scripts/virustotal.py, free API key asVIRUSTOTAL_API_KEY): scans the packages and the launcher exe, results in the release notes andvirustotal.jsonfor the README badges; never blocks a release.Type of change / Değişiklik tipi
Breaking: the server now serves HTTPS by default (
http://…:8000bookmarks stop working;APT_TLS=falseonly behind your own TLS proxy), public client addresses are refused, pairing keys must be ≥ 12 characters, and in the Windows package the.batfiles moved toscripts\(the launcher isAdminPDFToolkit.exe).Checklist
cd server && ruff check . && ruff format --check . && mypy adminpdf && pytest) — locally 348 passed / 11 skipped; mypy also for--platform win32anddarwincd web && npm run check && npm run build)CHANGELOG.mdunder[Unreleased]Field(tr=, en=)/t("tr", "en"))README.mdif applicable)Linked issues / Bağlı issue'lar
—
Screenshots (UI changes only)
Not attached; the UI changes are the About & Licences dialog, the Devices (QR) dialog, the green / favourite tool grid and the image-placement option.
Test plan / Test planı
ruff,mypy(linux / win32 / darwin),pytest— new tests for TLS, LAN-only, owner isolation, office sandbox, bundles, updater, launcher, About.npm run check,npm run build; About dialog checked in TR / EN on desktop and phone widths.codesign --verify, Linux and macOS packages start and serve over HTTPS; VirusTotal job skips cleanly without a key.RELEASE_SIGNING_KEY(and the public key inserver/adminpdf/updater.py) andVIRUSTOTAL_API_KEY.Generated by Claude Code