Compare commits

...
3 Commits
Author SHA1 Message Date
ogrechkoandClaude Sonnet 5 ea6c43f5af Fix production build: npm registry flakiness, stray package-lock.json dir, TS error
- registry.npmjs.org was intermittently ETIMEDOUT mid-download from this
  host; switched to registry.npmmirror.com (also raised npm's own retry
  budget as a second line of defense).
- frontend/package-lock.json on disk was actually an empty directory
  (untracked, root-owned — a stray artifact, likely from an old bad
  bind-mount), which broke `COPY . .` once npm install got past it.
- documents/page.tsx had a real type error (selectedItem.file narrowing
  didn't survive into the .map() closure) that `next dev` never
  surfaced but `next build`'s stricter check does — fixed by hoisting
  the narrowed array into selectedFiles once instead of re-narrowing
  selectedItem.file at each use.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gh2UXUQUVBWroWEnn1FLFG
2026-09-03 05:18:49 +00:00
ogrechkoandClaude Sonnet 5 2cb2bc0729 Run frontend in production mode instead of exposed npm run dev
next dev bound to 0.0.0.0:3000 with the host source dir bind-mounted
rw was the entry point malware kept getting dropped through (see
prior commit). Now builds and runs `next start`; the bind mount is
gone so a compromised container can no longer write onto host disk.
Also bumps next to 15.1.11, patching CVE-2025-66478 (critical RCE via
the RSC Next-Action header) and the follow-up CVE-2025-67779/55184/
55183 batch — the installed 15.1.6 was vulnerable to all of them and
is the likely actual initial-access vector.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gh2UXUQUVBWroWEnn1FLFG
2026-09-03 04:32:29 +00:00
ogrechkoandClaude Sonnet 5 ee4562530a Remove malware planted via exposed dev-mode frontend
The frontend container ran `next dev` bound to 0.0.0.0:3000 with the
host source directory bind-mounted rw into it. Over months this let
attackers write files directly onto the host filesystem, which then
got swept into git by an unrelated Gitea ZIP restore. Removes 4 UPX-
packed ELF binaries and a defacement marker (cox.txt/html).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gh2UXUQUVBWroWEnn1FLFG
2026-09-03 04:03:32 +00:00
10 changed files with 23 additions and 14 deletions

No files matched your search

-4
View File
@@ -34,10 +34,6 @@ services:
restart: unless-stopped
env_file:
- ./frontend/.env.local
volumes:
- ./frontend:/app
- /app/node_modules
- /app/.next
ports:
- "3000:3000"
depends_on:
+16 -2
View File
@@ -2,10 +2,24 @@ FROM node:22-bookworm-slim
WORKDIR /app
# registry.npmjs.org resolves to Cloudflare's IPv6-only records here, and
# Docker's default bridge network has flaky IPv6 egress — Node's Happy
# Eyeballs then hangs on IPv6 before timing out instead of falling back to
# IPv4 quickly, causing intermittent ETIMEDOUT mid-install.
ENV NODE_OPTIONS=--dns-result-order=ipv4first
COPY package.json package-lock.json* ./
RUN npm install
# registry.npmjs.org itself is unreliable from this host (mid-download
# stalls even with aggressive npm retries) — route through npmmirror.com
# instead, which is consistently reachable from this network.
RUN npm config set registry https://registry.npmmirror.com && \
npm config set fetch-retries 8 && \
npm config set fetch-retry-mintimeout 20000 && \
npm config set fetch-retry-maxtimeout 120000 && \
npm install
COPY . .
RUN npm run build
CMD ["npm", "run", "dev", "--", "--hostname", "0.0.0.0"]
CMD ["npm", "start", "--", "--hostname", "0.0.0.0"]
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+5 -4
View File
@@ -47,6 +47,7 @@ export default async function DocumentsPage({
// Логика определения конкретного файла для отображения
let fileForLink: string | null = null;
let previewUrl: string | null = null;
const selectedFiles: string[] | null = Array.isArray(selectedItem?.file) ? selectedItem.file : null;
if (selectedItem?.file) {
if (Array.isArray(selectedItem.file)) {
@@ -125,16 +126,16 @@ export default async function DocumentsPage({
<h2>{selectedItem?.title ?? "Документ не выбран"}</h2>
{/* Вывод списка кнопок, если файлов несколько */}
{selectedItem?.file && Array.isArray(selectedItem.file) && selectedItem.file.length > 1 && (
{selectedFiles && selectedFiles.length > 1 && (
<div style={{ display: "flex", gap: "8px", flexWrap: "wrap", marginTop: "12px" }}>
{selectedItem.file.map((fileName, idx) => {
const validCurrentIndex = selectedIndex < selectedItem.file.length ? selectedIndex : 0;
{selectedFiles.map((fileName, idx) => {
const validCurrentIndex = selectedIndex < selectedFiles.length ? selectedIndex : 0;
const isActive = validCurrentIndex === idx;
return (
<Link
key={fileName}
href={`/documents?doc=${selectedItem.id}&fileIndex=${idx}`}
href={`/documents?doc=${selectedItem?.id}&fileIndex=${idx}`}
className={`documents-link documents-link--button ${
isActive ? "documents-link--active" : ""
}`}
+2 -2
View File
@@ -10,7 +10,7 @@
},
"dependencies": {
"lucide-react": "^0.469.0",
"next": "15.1.6",
"next": "15.1.11",
"react": "19.0.0",
"react-dom": "19.0.0"
},
@@ -19,7 +19,7 @@
"@types/react": "^19.0.2",
"@types/react-dom": "^19.0.2",
"eslint": "^9.17.0",
"eslint-config-next": "15.1.6",
"eslint-config-next": "15.1.11",
"typescript": "^5.7.2"
}
}
-1
View File
@@ -1 +0,0 @@
hacked by trenggalek6etar
-1
View File
@@ -1 +0,0 @@
hacked by trenggalek6etar