Files
admin/.wiki/concepts/webconfig-password-xml-escape.md

72 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Web.config — XML escape для спецсимволов в connection-string паролях
type: concept
tags: [iis, webconfig, encoding, xml, gotcha]
sources: [../sources/iis-host-migration-2026-05-19.md]
updated: 2026-05-19
---
# Web.config: XML-escape для `&` (и других reserved chars) в пароле
## Симптом
После patch Web.config с новым connection-string'ом ASP.NET-сайт отдаёт **HTTP 500** на любой запрос. В Event Viewer / IIS logs — `System.Configuration.ConfigurationErrorsException: Configuration system failed to initialize` или `Unrecognized escape sequence`. На уровне XML парсера — error при чтении Web.config.
## Корень
`Web.config` — это **XML-документ**. Атрибуты в нём (`<add connectionString="..." />`) проходят через XML-парсер до того, как .NET runtime увидит сам connection string. Если в пароле есть **XML-зарезервированный символ**, парсер ломается.
XML reserved chars (в значениях атрибутов):
| Символ | XML-entity escape | Когда обязателен |
|---|---|---|
| `&` | `&amp;` | **всегда** (в attribute value и в text content) |
| `<` | `&lt;` | **всегда** |
| `"` | `&quot;` | если значение в `"..."` (наш кейс — атрибуты обычно в двойных кавычках) |
| `'` | `&apos;` | если значение в `'...'` |
| `>` | `&gt;` | формально не обязателен, но safer |
В именно нашем кейсе из [[iis-host-migration-2026-05-19]]: пароль `^I9D)LB)DK)8J#xBDG$t}W&_ioaT!M!LF` содержит `&` — XML-парсер начинал интерпретировать `&_ioaT...` как entity reference (`&_ioaT;` — невалидное имя entity) → exception → IIS 500.
## Правильный способ
```xml
<!-- WRONG (literal &) -->
<add name="MoreThenCmsEntities"
connectionString="...Password=^I9D)LB)DK)8J#xBDG$t}W&_ioaT!M!LF;..."
providerName="System.Data.SqlClient" />
<!-- RIGHT (& -> &amp;) -->
<add name="MoreThenCmsEntities"
connectionString="...Password=^I9D)LB)DK)8J#xBDG$t}W&amp;_ioaT!M!LF;..."
providerName="System.Data.SqlClient" />
```
После XML-парсинга .NET runtime получит литеральный `&` в значении атрибута и передаст в SqlConnection — там пароль уже текст, всё ок.
## Что НЕ требует escape
- `^`, `$`, `(`, `)`, `{`, `}`, `[`, `]`, `*`, `+`, `?`, `\`, `/`, `.`, `,`, `;`, `:`, `=`, `#`, `@`, `%`, `!`, `~`, `|` — все безопасны в XML attribute value.
- Особое: `;` в пароле в ADO.NET conn-string'е требует обёртки пароля в `'...'` или `"..."` внутри connection-string'а — но это отдельная история.
## PowerShell-подсказка для patch
При программной замене conn-string'а**сразу escape `&` в значение**, не оставляй на потом:
```powershell
# 💻 Windows host
$plainPassword = '^I9D)LB)DK)8J#xBDG$t}W&_ioaT!M!LF'
$xmlSafePassword = $plainPassword -replace '&', '&amp;'
# и потом подставлять $xmlSafePassword в Web.config
# или комбинированный escape всех 5 reserved chars:
function Xml-EscapeAttr($s) {
$s -replace '&','&amp;' -replace '<','&lt;' -replace '>','&gt;' -replace '"','&quot;' -replace "'",'&apos;'
}
```
## Связанные паттерны
- [[cms-config-rewrite-pattern]] — UTF-8 BOM ловушка при `Set-Content` без `-Encoding utf8` (другая XML/IIS гнойная тема).
- При генерации паролей для DB-логинов CMS — лучше **запретить `&`, `<`, `"`** в генераторе, чтобы не словить эту проблему в будущем (особенно при автоматизированных patches Web.config через CI).