This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="840" viewBox="0 0 1200 840" role="img" aria-labelledby="csrf-cors-2023-field-title csrf-cors-2023-field-desc">
|
||||
<title id="csrf-cors-2023-field-title">Диагностика CORS и CSRF без ослабления защиты</title>
|
||||
<desc id="csrf-cors-2023-field-desc">Поток диагностики начинает с наблюдаемого симптома и разделяет четыре причины: origin не входит в CORS allow-list, credentials не согласованы, preflight не разрешён, либо серверная CSRF-проверка отвергла изменение. У каждого случая есть отдельная проверка и действие.</desc>
|
||||
<defs>
|
||||
<marker id="csrf-cors-2023-field-arrow" markerWidth="12" markerHeight="12" refX="10" refY="4" orient="auto"><path d="M0,0 L11,4 L0,8 Z" fill="#17324d"/></marker>
|
||||
</defs>
|
||||
<rect width="1200" height="840" fill="#f7fafc"/>
|
||||
<text x="70" y="66" font-family="Arial, sans-serif" font-size="44" font-weight="700" fill="#17324d">CORS или CSRF:</text>
|
||||
<text x="70" y="114" font-family="Arial, sans-serif" font-size="44" font-weight="700" fill="#17324d">маршрут проверки</text>
|
||||
<text x="70" y="155" font-family="Arial, sans-serif" font-size="32" fill="#425466">Симптом не указывает контроль.</text>
|
||||
|
||||
<rect x="350" y="170" width="500" height="95" rx="18" fill="#dceeff" stroke="#2176ae" stroke-width="4"/>
|
||||
<text x="600" y="215" text-anchor="middle" font-family="Arial, sans-serif" font-size="34" font-weight="700" fill="#17324d">Симптом: запрос</text>
|
||||
<text x="600" y="252" text-anchor="middle" font-family="Arial, sans-serif" font-size="34" font-weight="700" fill="#17324d">или response не работает</text>
|
||||
<line x1="600" y1="265" x2="600" y2="330" stroke="#17324d" stroke-width="5" marker-end="url(#csrf-cors-2023-field-arrow)"/>
|
||||
|
||||
<rect x="260" y="335" width="680" height="90" rx="18" fill="#ffffff" stroke="#6c7f91" stroke-width="3"/>
|
||||
<text x="600" y="375" text-anchor="middle" font-family="Arial, sans-serif" font-size="32" font-weight="700" fill="#17324d">Проверка: origin, method, headers</text>
|
||||
<text x="600" y="408" text-anchor="middle" font-family="Arial, sans-serif" font-size="32" font-weight="700" fill="#17324d">и server status реально видны?</text>
|
||||
|
||||
<line x1="420" y1="425" x2="180" y2="505" stroke="#17324d" stroke-width="5" marker-end="url(#csrf-cors-2023-field-arrow)"/>
|
||||
<line x1="530" y1="425" x2="455" y2="505" stroke="#17324d" stroke-width="5" marker-end="url(#csrf-cors-2023-field-arrow)"/>
|
||||
<line x1="670" y1="425" x2="745" y2="505" stroke="#17324d" stroke-width="5" marker-end="url(#csrf-cors-2023-field-arrow)"/>
|
||||
<line x1="780" y1="425" x2="1020" y2="505" stroke="#17324d" stroke-width="5" marker-end="url(#csrf-cors-2023-field-arrow)"/>
|
||||
|
||||
<rect x="35" y="515" width="260" height="190" rx="18" fill="#e3f4e6" stroke="#287744" stroke-width="3"/>
|
||||
<text x="165" y="555" text-anchor="middle" font-family="Arial, sans-serif" font-size="32" font-weight="700" fill="#185d31">origin не</text>
|
||||
<text x="165" y="590" text-anchor="middle" font-family="Arial, sans-serif" font-size="32" font-weight="700" fill="#185d31">разрешён</text>
|
||||
<text x="165" y="633" text-anchor="middle" font-family="Arial, sans-serif" font-size="27" fill="#17324d">сверить tuple</text>
|
||||
<text x="165" y="674" text-anchor="middle" font-family="Arial, sans-serif" font-size="27" fill="#17324d">exact allow-list</text>
|
||||
|
||||
<rect x="320" y="515" width="260" height="190" rx="18" fill="#e3f4e6" stroke="#287744" stroke-width="3"/>
|
||||
<text x="450" y="555" text-anchor="middle" font-family="Arial, sans-serif" font-size="32" font-weight="700" fill="#185d31">credentials</text>
|
||||
<text x="450" y="590" text-anchor="middle" font-family="Arial, sans-serif" font-size="32" font-weight="700" fill="#185d31">спорят</text>
|
||||
<text x="450" y="633" text-anchor="middle" font-family="Arial, sans-serif" font-size="27" fill="#17324d">exact origin + true</text>
|
||||
<text x="450" y="674" text-anchor="middle" font-family="Arial, sans-serif" font-size="27" fill="#17324d">не ставить *</text>
|
||||
|
||||
<rect x="605" y="515" width="260" height="190" rx="18" fill="#e3f4e6" stroke="#287744" stroke-width="3"/>
|
||||
<text x="735" y="555" text-anchor="middle" font-family="Arial, sans-serif" font-size="32" font-weight="700" fill="#185d31">preflight</text>
|
||||
<text x="735" y="590" text-anchor="middle" font-family="Arial, sans-serif" font-size="32" font-weight="700" fill="#185d31">отклонён</text>
|
||||
<text x="735" y="633" text-anchor="middle" font-family="Arial, sans-serif" font-size="27" fill="#17324d">OPTIONS + header</text>
|
||||
<text x="735" y="674" text-anchor="middle" font-family="Arial, sans-serif" font-size="27" fill="#17324d">narrow allow</text>
|
||||
|
||||
<rect x="890" y="515" width="260" height="190" rx="18" fill="#fff0d8" stroke="#a96c13" stroke-width="3"/>
|
||||
<text x="1020" y="570" text-anchor="middle" font-family="Arial, sans-serif" font-size="36" font-weight="700" fill="#7b4d05">CSRF: 403</text>
|
||||
<text x="1020" y="622" text-anchor="middle" font-family="Arial, sans-serif" font-size="29" fill="#17324d">origin + token</text>
|
||||
<text x="1020" y="668" text-anchor="middle" font-family="Arial, sans-serif" font-size="29" fill="#17324d">чинить flow</text>
|
||||
|
||||
<rect x="115" y="735" width="970" height="85" rx="14" fill="#e9eef4" stroke="#6c7f91" stroke-width="3"/>
|
||||
<text x="600" y="772" text-anchor="middle" font-family="Arial, sans-serif" font-size="31" font-weight="700" fill="#17324d">Не выключать CSRF и не расширять CORS,</text>
|
||||
<text x="600" y="806" text-anchor="middle" font-family="Arial, sans-serif" font-size="31" font-weight="700" fill="#17324d">пока не названо условие отказа</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.8 KiB |
@@ -0,0 +1,32 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="800" viewBox="0 0 1200 800" role="img" aria-labelledby="csrf-cors-2023-mechanism-title csrf-cors-2023-mechanism-desc">
|
||||
<title id="csrf-cors-2023-mechanism-title">Три слоя решения для cross-origin запроса</title>
|
||||
<desc id="csrf-cors-2023-mechanism-desc">Диаграмма разделяет origin как tuple scheme host port, CORS как правило доступа браузерного кода к ответу с credentials и preflight, и CSRF как серверную проверку перед изменением данных. Стрелка показывает, что preflight не заменяет CSRF.</desc>
|
||||
<defs>
|
||||
<marker id="csrf-cors-2023-mechanism-arrow" markerWidth="12" markerHeight="12" refX="10" refY="4" orient="auto"><path d="M0,0 L11,4 L0,8 Z" fill="#17324d"/></marker>
|
||||
</defs>
|
||||
<rect width="1200" height="800" fill="#f7fafc"/>
|
||||
<text x="70" y="68" font-family="Arial, sans-serif" font-size="44" font-weight="700" fill="#17324d">Cross-origin запрос:</text>
|
||||
<text x="70" y="116" font-family="Arial, sans-serif" font-size="44" font-weight="700" fill="#17324d">три разных вопроса</text>
|
||||
<text x="70" y="158" font-family="Arial, sans-serif" font-size="32" fill="#425466">Tuple → response → server action.</text>
|
||||
|
||||
<rect x="70" y="200" width="1060" height="145" rx="22" fill="#dceeff" stroke="#2176ae" stroke-width="4"/>
|
||||
<circle cx="145" cy="272" r="42" fill="#2176ae"/>
|
||||
<text x="145" y="286" text-anchor="middle" font-family="Arial, sans-serif" font-size="38" font-weight="700" fill="#ffffff">1</text>
|
||||
<text x="220" y="254" font-family="Arial, sans-serif" font-size="38" font-weight="700" fill="#17324d">Origin: scheme + host + port</text>
|
||||
<text x="220" y="298" font-family="Arial, sans-serif" font-size="30" fill="#17324d">Разный host или port — другой origin.</text>
|
||||
|
||||
<rect x="70" y="400" width="1060" height="145" rx="22" fill="#e3f4e6" stroke="#287744" stroke-width="4"/>
|
||||
<circle cx="145" cy="472" r="42" fill="#287744"/>
|
||||
<text x="145" y="486" text-anchor="middle" font-family="Arial, sans-serif" font-size="38" font-weight="700" fill="#ffffff">2</text>
|
||||
<text x="220" y="454" font-family="Arial, sans-serif" font-size="38" font-weight="700" fill="#17324d">CORS: чтение response</text>
|
||||
<text x="220" y="498" font-family="Arial, sans-serif" font-size="30" fill="#17324d">credentials: exact origin + true.</text>
|
||||
|
||||
<rect x="70" y="600" width="1060" height="145" rx="22" fill="#fff0d8" stroke="#a96c13" stroke-width="4"/>
|
||||
<circle cx="145" cy="672" r="42" fill="#a96c13"/>
|
||||
<text x="145" y="686" text-anchor="middle" font-family="Arial, sans-serif" font-size="38" font-weight="700" fill="#ffffff">3</text>
|
||||
<text x="220" y="654" font-family="Arial, sans-serif" font-size="38" font-weight="700" fill="#17324d">CSRF: server mutation</text>
|
||||
<text x="220" y="698" font-family="Arial, sans-serif" font-size="30" fill="#17324d">origin + token; preflight отдельно.</text>
|
||||
|
||||
<line x1="1050" y1="345" x2="1050" y2="400" stroke="#17324d" stroke-width="5" marker-end="url(#csrf-cors-2023-mechanism-arrow)"/>
|
||||
<line x1="1050" y1="545" x2="1050" y2="600" stroke="#17324d" stroke-width="5" marker-end="url(#csrf-cors-2023-mechanism-arrow)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.3 KiB |
@@ -0,0 +1,43 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="800" viewBox="0 0 1200 800" role="img" aria-labelledby="csrf-cors-2023-practice-title csrf-cors-2023-practice-desc">
|
||||
<title id="csrf-cors-2023-practice-title">Раздельный контракт CORS и CSRF для cookie API</title>
|
||||
<desc id="csrf-cors-2023-practice-desc">Код на доверенном origin обращается к API на другом origin. CORS-политика разрешает чтение ответа только указанному origin с credentials, а серверная CSRF-проверка отдельно требует происхождение и токен до изменения состояния.</desc>
|
||||
<defs>
|
||||
<marker id="csrf-cors-2023-practice-arrow" markerWidth="12" markerHeight="12" refX="10" refY="4" orient="auto"><path d="M0,0 L11,4 L0,8 Z" fill="#17324d"/></marker>
|
||||
</defs>
|
||||
<rect width="1200" height="800" fill="#f7fafc"/>
|
||||
<text x="70" y="68" font-family="Arial, sans-serif" font-size="44" font-weight="700" fill="#17324d">Cookie API: CORS и CSRF</text>
|
||||
<text x="70" y="116" font-family="Arial, sans-serif" font-size="44" font-weight="700" fill="#17324d">принимают разные решения</text>
|
||||
<text x="70" y="158" font-family="Arial, sans-serif" font-size="32" fill="#425466">Заголовок CORS не разрешает mutation.</text>
|
||||
|
||||
<rect x="70" y="220" width="300" height="270" rx="22" fill="#dceeff" stroke="#2176ae" stroke-width="4"/>
|
||||
<text x="220" y="278" text-anchor="middle" font-family="Arial, sans-serif" font-size="38" font-weight="700" fill="#17324d">Код страницы</text>
|
||||
<text x="220" y="328" text-anchor="middle" font-family="Arial, sans-serif" font-size="32" fill="#17324d">origin</text>
|
||||
<text x="220" y="374" text-anchor="middle" font-family="Arial, sans-serif" font-size="31" font-weight="700" fill="#17324d">app.example.test</text>
|
||||
<text x="220" y="425" text-anchor="middle" font-family="Arial, sans-serif" font-size="30" fill="#425466">credentials</text>
|
||||
|
||||
<line x1="370" y1="350" x2="530" y2="350" stroke="#17324d" stroke-width="6" marker-end="url(#csrf-cors-2023-practice-arrow)"/>
|
||||
<text x="450" y="318" text-anchor="middle" font-family="Arial, sans-serif" font-size="31" font-weight="700" fill="#17324d">запрос</text>
|
||||
<text x="450" y="392" text-anchor="middle" font-family="Arial, sans-serif" font-size="27" fill="#425466">origin + headers</text>
|
||||
|
||||
<rect x="530" y="180" width="600" height="430" rx="24" fill="#ffffff" stroke="#17324d" stroke-width="4"/>
|
||||
<text x="830" y="245" text-anchor="middle" font-family="Arial, sans-serif" font-size="38" font-weight="700" fill="#17324d">API: api.example.test</text>
|
||||
<line x1="570" y1="286" x2="1090" y2="286" stroke="#bdd0df" stroke-width="3"/>
|
||||
|
||||
<rect x="575" y="330" width="245" height="205" rx="18" fill="#e3f4e6" stroke="#287744" stroke-width="3"/>
|
||||
<text x="697" y="382" text-anchor="middle" font-family="Arial, sans-serif" font-size="38" font-weight="700" fill="#185d31">CORS</text>
|
||||
<text x="697" y="428" text-anchor="middle" font-family="Arial, sans-serif" font-size="30" fill="#17324d">чтение response</text>
|
||||
<text x="697" y="465" text-anchor="middle" font-family="Arial, sans-serif" font-size="30" fill="#17324d">exact origin</text>
|
||||
<text x="697" y="505" text-anchor="middle" font-family="Arial, sans-serif" font-size="28" fill="#425466">+ credentials</text>
|
||||
|
||||
<rect x="850" y="330" width="245" height="205" rx="18" fill="#fff0d8" stroke="#a96c13" stroke-width="3"/>
|
||||
<text x="972" y="382" text-anchor="middle" font-family="Arial, sans-serif" font-size="38" font-weight="700" fill="#7b4d05">CSRF</text>
|
||||
<text x="972" y="428" text-anchor="middle" font-family="Arial, sans-serif" font-size="30" fill="#17324d">mutation после</text>
|
||||
<text x="972" y="465" text-anchor="middle" font-family="Arial, sans-serif" font-size="30" fill="#17324d">origin + token</text>
|
||||
<text x="972" y="505" text-anchor="middle" font-family="Arial, sans-serif" font-size="28" fill="#425466">решает сервер</text>
|
||||
|
||||
<line x1="697" y1="535" x2="697" y2="665" stroke="#287744" stroke-width="5" marker-end="url(#csrf-cors-2023-practice-arrow)"/>
|
||||
<line x1="972" y1="535" x2="972" y2="665" stroke="#a96c13" stroke-width="5" marker-end="url(#csrf-cors-2023-practice-arrow)"/>
|
||||
<rect x="455" y="655" width="675" height="105" rx="16" fill="#e9eef4" stroke="#6c7f91" stroke-width="3"/>
|
||||
<text x="792" y="700" text-anchor="middle" font-family="Arial, sans-serif" font-size="32" font-weight="700" fill="#17324d">Чтение response и mutation</text>
|
||||
<text x="792" y="738" text-anchor="middle" font-family="Arial, sans-serif" font-size="32" font-weight="700" fill="#17324d">имеют разные границы</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.7 KiB |
Reference in New Issue
Block a user