8.7 KiB
8.7 KiB
Март 2018 — безопасная загрузка файлов: draft-review
Статус: принято в публикационный слой 31 июля 2026 после независимого audit. Эта партия существует как три ревизии из web/scripts/upgrade-2018-03.mjs --print-revisions; слой web/data/editorial-revisions.mjs сопоставляет их только по стабильным slug, не меняя даты, автора или историю Git.
| Slug | Главный вопрос | Основной текст без источников |
|---|---|---|
editorial-2018-03-practice-safe-uploads |
Как принять JPEG или PNG для аватара без доверия к имени и MIME-типу формы? | 5 666 знаков |
editorial-2018-03-mechanism-safe-uploads |
Какие признаки файла можно использовать для какой проверки? | 6 209 знаков |
editorial-2018-03-field-safe-uploads |
Как выдать владельцу приватный PDF, если файл хранится вне веб-корня? | 5 688 знаков |
1. Факты и техника — пройдено
Практика: приём аватара
- Проверены коды ошибок загрузки PHP, move_uploaded_file, finfo_file, ограничение getimagesize как валидатора и OWASP File Upload Cheat Sheet.
- Пример проверяет
UPLOAD_ERR_OK, прикладной лимит, MIME-тип через Fileinfo и размеры изображения до переноса.getimagesize()используется только для размеров, не как доказательство корректности изображения. - Ограничения названы прямо: нет антивирусной проверки, CSRF-защиты и обработки миниатюр.
Механизм: границы доверия
- Проверены RFC 7578 для multipart/form-data, коды ошибок PHP, Fileinfo, getimagesize и OWASP.
- Воспроизводимый
curl-пример не утверждает конкретный результат базы magic: он показывает разницу между заявленным клиентомtypeи типом, который определяет Fileinfo. - Статья не называет Fileinfo антивирусом и не переносит ответственность за лимит всего запроса на одну PHP-функцию.
Поле: выдача приватного PDF
- Проверены OWASP для размещения файлов вне webroot, header(), readfile() и RFC 6266 для Content-Disposition.
- В коде ID документа и текущий пользователь участвуют в одном SQL-запросе; путь строится только из ключа, прошедшего контрактное регулярное выражение.
- Ограничения не скрыты: в примере нет Range, кеширования, ограничения частоты и эффективной выдачи больших файлов.
Версионная оговорка: код ориентирован на PHP 7.2. В статьях не используются приёмы, добавленные позднее; актуальные страницы PHP Manual взяты как первичный справочник функций и их ограничений.
2. Редактура и голос — пройдено после исправления стоп-условия
- Каждая статья отвечает на один вопрос и начинает с наблюдаемой ситуации, а не с общего рассуждения о безопасности.
- Для
mechanismиfieldпервоначальный строгий audit обнаружил недостаточно явную постановку проблемы. В первые два предложения добавлены формулировкиСимптом:иЦена ошибки; сильная исходная подводка сохранена дальше в том же абзаце. - Повторный CLI-audit подтвердил: обе статьи содержат симптом и цену ошибки в первых 420 знаках; длины — 6 209 и 5 688 знаков соответственно.
- Речь соответствует 2018 году: короткие технические абзацы, «давайте» и «я бы» только там, где автор делает практический вывод; нет обещаний универсального решения, поздних инструментов и шаблонных оборотов.
- Во всех трёх ревизиях есть проблема, таблица, воспроизводимый пример, порядок действий, ограничения, один рисунок и минимум четыре первичных или нормативных источника.
3. Визуал и выпуск — пройдено для черновика
xmllint --nooutпрошёл для трёх SVG:php-upload-avatar-contract.svg,php-upload-trust-signals.svg,php-private-download-flow.svg.- В локальном рендере SVG проверены title, доступное описание, границы текста и масштаб 1280×720: 31, 26 и 20 текстовых узлов соответственно; выходов за границы нет.
- На первой схеме во время визуальной проверки найден и исправлен контраст номеров этапов: цвет изменён с белого на тёмный
rgb(46, 82, 103). - Каждый рисунок будет иметь осмысленный
altи подпись через данные ревизии. Таблицы обёрнуты вtable-scroll; текущие стили блога добавляют горизонтальную прокрутку при минимальной ширине таблицы 620px. - Production-сборка и проверка опубликованных URL не запускались намеренно: статьи ещё не интегрированы в
web/data/articles.json. Это выпускной шаг основного агента, а не основание менять архив из этой ветки.
Повторённые команды
node --check web/scripts/upgrade-2018-03.mjs
node web/scripts/upgrade-2018-03.mjs --print-revisions
xmllint --noout \
web/public/assets/editorial/2018/php-upload-avatar-contract.svg \
web/public/assets/editorial/2018/php-upload-trust-signals.svg \
web/public/assets/editorial/2018/php-private-download-flow.svg
Результат: три ревизии готовы для точечной интеграции без перезаписи остальных статей.
Приёмка основного агента
- Повторно пройден строгий
audit-quality-batch.mjs: 5 666 / 6 209 / 5 688 знаков основного текста; в каждой статье найдены рисунок сalt, таблица, код, порядок действий и отдельный раздел источников. - Проверены безопасный import модуля и CLI-вывод ровно трёх ревизий. Production build после интеграции прошёл и сгенерировал 374 статические страницы.