TGViewer
Искусство. Код... ИИ? Искусство. Код... ИИ? @art_code_ai · 706 subscribers
Post #40 1.56K
🧩 Принципы и паттерны безопасной разработки: OCP и fail-closed

Часть 1.

(Open/Closed Principle) — классы и функции открыты для расширения, но закрыты для модификации. Говоря проще: проектируем приложение так, чтобы для новых фичей требовались минимальные изменения в уже существующем (протестированном и стабильном, ну... как правило) коде.

С точки зрения безопасности, это снижает риски сломать уже существующие защитные меры и получить на ровном месте регрессии вроде:

• CWE-840 — логическая уязвимость из-за изменения условий
• CWE-489 — ослабление проверки при модификации кода

... и охапки прочих, на правах их прямых последствий.

🐛 Жизненное

В Apache HTTPD (CVE-2021-41773) разработчики изменили ядро обработки путей — и открыли обход директорий ../. Если бы новую логику добавили отдельным модулем, а не правили существующую, старая проверка осталась бы нетронутой.

Та же история с Dirty Pipe (CVE-2022-0847) в Linux: неаккуратная «оптимизация» существующего кода pipe нарушила старые гарантии → повышение локальных привилегий.

💡 Пример: PEP-750, t-строки и шаблоны

По мотивам предыдущего поста: t"..." создаёт объект Template, а его части (Interpolation) форматируются по format_spec. Здесь напрашивается типичная ошибка — дописывать в обработчике if/elif для новых форматов (HTML, SQL, shell). Каждый раз приходится лезть в уже написанный код, и, тем самым, нарушать OCP.

Плохой пример:
def render(t):
for part in t:
if spec == "html":
out.append(html_escape(v))
elif spec == "sql":
out.append(sql_param(v))
else:
out.append(format(v))


Новый формат → новая ветка → новый риск сломать там что-то ранее работавшее (вспоминаем goto fail;).

Хороший пример:
_handlers = []

def register(h): _handlers.append(h); return h

def render(t):
for it in t:
if isinstance(it, str): yield it
elif h := next((h for h in _handlers if h.supports(it)), None):
yield h.apply(it)
else:
raise ValueError(f"Unsupported spec: {it.format_spec}")

@register
class HtmlHandler:
def supports(self, it): return it.format_spec.startswith("html")
def apply(self, it): return html_escape(str(it.value))


Ядро неизменно — добавляем только новые обработчики, неизвестные спецификации блокируются (fail-closed*): безопаснее, предсказуемее, тестируется в разы проще.

*️⃣ Fail-closed (безопасный отказ) — принцип проектирования, при котором система в случае ошибки или неопределённости выбирает безопасное поведение, даже если это мешает работе.

Примеры:

• парсер не знает формат входных данных → отклоняет запрос;
• фильтр не смог проверить токен → доступ запрещён;
• обработчик t-строк встретил неизвестный `format_spec` → бросает исключение вместо неэкранированного вывода.

Такой подход предотвращает «тихие» обходы проверок и делает поведение системы предсказуемым даже при сбоях.


⚠️ OCP — не догма


«Модификация» в OCP не про рефакторинг, баги или уязвимости. Если в существующем коде нашли нашли проблему, то нужно править. Безопасность и здравый смысл приоритетнее. OCP всё же — не тотальный запрет на изменения, а гигиена расширяемости: добавление фичей, без изменения того, что уже защищено и протестировано.

Часть 3.

TL;DR:
• Стоит разумно следовать OCP, чтобы не сломать защиту, добавляя фичи.
• Расширять, а не модифицировать, если речь не идёт о рефакторинге, багах или уязвимостях.
• Из-за нарушений OCP «увидели свет» многие, в том числе именитые, CVE.

#безопасность_кода #гайд
  • 👍 7
  • ❤ 2
  • 🔥 2
  • 💯 1
More from @art_code_ai
  1. Sep 29, 2026Объяснили с Раддой Юрьевой на Хабре, почему смешивать формальные и ИИшные подходы в задача…
  2. Sep 27, 2026🔗 Старый добрый аппсек, часть 2 Продолжаем вспоминать ключевые вехи аппсека и смежных обл…
  3. Sep 26, 2026Post #155
  4. Sep 24, 2026🔗 Старый добрый аппсек, часть 1 ...совершенно незаслуженно задвинутый на второй план ИИ-х…
  5. Sep 23, 2026Post #153
  6. Sep 21, 2026👨‍💻 Продуктивные выходные Как-то незаметно (и неожиданно) для себя с удовольствием провё…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →