Аватарка пользователя Елена Капаца
Елена Капаца

Как защитить свой Python-код

Описали четыре техники увеличения безопасности кода и подобрали примеры к каждой из них. В статье вы познакомитесь не только с универсальными приемами, но и специфическими – для серверов и ботов.

203
Обложка поста kak-zashhitit-svoj-python-kod

Безопасностью кода студентов озадачивают нечасто. Нас знакомят с некоторыми устоявшимися приемами, вроде применения виртуального окружения, но в систему это складывается только во время работы.

Чтобы ускорить процесс и избавить вас от возможных проблем на старте, я собрала топ способов сделать код защищеннее от двух видов воздействия: злонамеренного (например, использование уязвимостей сайта хакерами) и непреднамеренного (ошибки разработчика, приводящей к падению прода).

Валидируйте входные данные

Стоит фильтровать пользовательский ввод на наличие определенных символов. В разработке веб-приложений это особенно важно, потому что помогает предотвратить различные атаки, такие как SQL-инъекции и межсайтовый скриптинг (XSS).

Покажу на примере.

Код ниже запускает простой веб-сервер, который при обработке GET-запроса возвращает HTML, вставляя имя сайта в приветствие:

			from http.server import HTTPServer, BaseHTTPRequestHandler
secret = 'abc123'
class Handler(BaseHTTPRequestHandler):
    name = 'xakep'
    msg = 'welcome to {site.name}'
    def do_GET(self):
        res = ('' + self.path + '\n' + self.msg).
format(site=self)
        self.send_response(200)
        self.send_header('content-type', 'text/html')
        self.end_headers()
        self.wfile.write(res.encode())
HTTPServer(('localhost', 8888), Handler).serve_forever()
		

Однако атакующий обращается к серверу и получает ключ secret, который хранится, казалось бы, в приватном репозитории:

			curl -g 'http://localhost:8888/XXX{site.do_GET.__globals__[secret]}
		

Это происходит из-за того, что self.path контролируется конечным пользователем.

Для решения проблемы подойдут f-строки. Они безопасны и работают быстрее, да и код выглядит куда опрятнее:

			res = f"{self.path}\n{self.msg}"</code>
		</pre><button class="tp-content-code__button" data-v-da581141><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" role="presentation" data-v-da581141><!----><g fill="inherit" stroke="inherit"><!--[--><!--[--><rect stroke="inherit" width="14.655" height="14.655" x="7.345" y="2.5" stroke-width="2" rx="1"></rect><path stroke="inherit" stroke-width="2" d="M4.897 6.569H4a2 2 0 0 0-2 2V20.5a2 2 0 0 0 2 2h12.655a2 2 0 0 0 2-2v-.896"></path><!--]--><!--]--></g></svg></button></div><!--]--><!--[--><p class="tp-content-paragraph" data-type="paragraph" data-v-6c80349f>Не всегда удается избежать спецсимволов в пользовательских данных. Для таких ситуаций придумали библиотеку bleach. Она может удалять нежелательные или потенциально вредоносные теги и атрибуты:</p><!--]--><!--[--><div class="tp-content-code code-toolbar" data-type="code" data-v-da581141><pre class="tp-content-code__pre" data-v-da581141>			<code class="lang-python lazy-code" data-v-da581141>import bleach

user_input = "<script>alert('XSS attack');</script>"
cleaned_input = bleach.clean(user_input)
print(cleaned_input)</code>
		</pre><button class="tp-content-code__button" data-v-da581141><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" role="presentation" data-v-da581141><!----><g fill="inherit" stroke="inherit"><!--[--><!--[--><rect stroke="inherit" width="14.655" height="14.655" x="7.345" y="2.5" stroke-width="2" rx="1"></rect><path stroke="inherit" stroke-width="2" d="M4.897 6.569H4a2 2 0 0 0-2 2V20.5a2 2 0 0 0 2 2h12.655a2 2 0 0 0 2-2v-.896"></path><!--]--><!--]--></g></svg></button></div><!--]--><!--[--><h2 class="tp-content-subtitle tp-content-subtitle--h2" data-type="header2" data-v-75e770f1>Управляйте сессиями</h2><!--]--><!--[--><p class="tp-content-paragraph" data-type="paragraph" data-v-6c80349f>Во время сессии всем событиям, помимо прочих метаданных, присваевается и идентификатор. Это позволяет сохранять данные между запросами, которые растянуты по времени.</p><!--]--><!--[--><p class="tp-content-paragraph" data-type="paragraph" data-v-6c80349f>Но злоумышленники могут угнать и перехватить cookies. Чтобы этого не произошло::</p><!--]--><!--[--><ol class="tp-content-list" style="" data-type="list" data-v-705dc74d><!--[--><li class="tp-content-list__item" data-v-705dc74d>Установите флаги Secure и HttpOnly. Первый передает только через HTTPS, второй запрещает доступ через JavaScript, что не дает внедрить скрипты</li><!--]--></ol><!--]--><!--[--><div class="tp-content-code code-toolbar" data-type="code" data-v-da581141><pre class="tp-content-code__pre" data-v-da581141>			<code class="lang-python lazy-code" data-v-da581141>from flask import session, Flask
app = Flask(__name__)
app.config.update(
    SESSION_COOKIE_SECURE=True,
    SESSION_COOKIE_HTTPONLY=True,
    SESSION_COOKIE_SAMESITE='Lax',
)</code>
		</pre><button class="tp-content-code__button" data-v-da581141><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" role="presentation" data-v-da581141><!----><g fill="inherit" stroke="inherit"><!--[--><!--[--><rect stroke="inherit" width="14.655" height="14.655" x="7.345" y="2.5" stroke-width="2" rx="1"></rect><path stroke="inherit" stroke-width="2" d="M4.897 6.569H4a2 2 0 0 0-2 2V20.5a2 2 0 0 0 2 2h12.655a2 2 0 0 0 2-2v-.896"></path><!--]--><!--]--></g></svg></button></div><!--]--><!--[--><ol class="tp-content-list" style="" data-type="list" data-v-705dc74d><!--[--><li class="tp-content-list__item" data-v-705dc74d>Регенерируйте идентификатор сессии при каждом входе и выходе пользователя из системы:</li><!--]--></ol><!--]--><!--[--><div class="tp-content-code code-toolbar" data-type="code" data-v-da581141><pre class="tp-content-code__pre" data-v-da581141>			<code class="lang-python lazy-code" data-v-da581141>@app.route('/login', methods=['POST'])
def login():
    # Проверка учетных данных
    # ...
    # Регенерация ID
    session.regenerate()
    return "Успешный вход в систему!</code>
		</pre><button class="tp-content-code__button" data-v-da581141><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" role="presentation" data-v-da581141><!----><g fill="inherit" stroke="inherit"><!--[--><!--[--><rect stroke="inherit" width="14.655" height="14.655" x="7.345" y="2.5" stroke-width="2" rx="1"></rect><path stroke="inherit" stroke-width="2" d="M4.897 6.569H4a2 2 0 0 0-2 2V20.5a2 2 0 0 0 2 2h12.655a2 2 0 0 0 2-2v-.896"></path><!--]--><!--]--></g></svg></button></div><!--]--><!--[--><ol class="tp-content-list" style="" data-type="list" data-v-705dc74d><!--[--><li class="tp-content-list__item" data-v-705dc74d>Устанавливайте тайм-аут сессии:</li><!--]--></ol><!--]--><!--[--><div class="tp-content-code code-toolbar" data-type="code" data-v-da581141><pre class="tp-content-code__pre" data-v-da581141>			<code class="lang-python lazy-code" data-v-da581141>app.permanent_session_lifetime = timedelta(minutes=15)</code>
		</pre><button class="tp-content-code__button" data-v-da581141><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" role="presentation" data-v-da581141><!----><g fill="inherit" stroke="inherit"><!--[--><!--[--><rect stroke="inherit" width="14.655" height="14.655" x="7.345" y="2.5" stroke-width="2" rx="1"></rect><path stroke="inherit" stroke-width="2" d="M4.897 6.569H4a2 2 0 0 0-2 2V20.5a2 2 0 0 0 2 2h12.655a2 2 0 0 0 2-2v-.896"></path><!--]--><!--]--></g></svg></button></div><!--]--><!--[--><h2 class="tp-content-subtitle tp-content-subtitle--h2" data-type="header2" data-v-75e770f1>Используйте виртуальное окружение</h2><!--]--><!--[--><p class="tp-content-paragraph" data-type="paragraph" data-v-6c80349f>Виртуальное окружение (virtual environment) — надстройка, которая обеспечивает две вещи.</p><!--]--><!--[--><ul class="tp-content-list" style="" data-type="list" data-v-705dc74d><!--[--><li class="tp-content-list__item" data-v-705dc74d>Изоляцию зависимостей. У каждого окружения будет собственный набор библиотек, изолированный от системного языкового пакета. Это гарантирует, что уязвимости в последних не навредят проекту.</li><li class="tp-content-list__item" data-v-705dc74d>Контроль версий. Виртуальное окружение позволит зафиксировать разновидность используемых библиотек с помощью requirements.txt или другого файла конфигурации. Код, скопированный из многолетнего треда на StackOverflow, часто выдает ошибку именно из-за этого. Если вы работаете с несколькими проектами, требующими разных версий одной и той же библиотеки, virtualenv поможет их «развести по углам».</li><!--]--></ul><!--]--><!--[--><p class="tp-content-paragraph" data-type="paragraph" data-v-6c80349f>Чтобы создать виртуальное окружение, используйте библиотеку virtualenv и команду:</p><!--]--><!--[--><div class="tp-content-code code-toolbar" data-type="code" data-v-da581141><pre class="tp-content-code__pre" data-v-da581141>			<code class="lang-bash lazy-code" data-v-da581141>python<версия> -m venv <название виртуального окружения></code>
		</pre><button class="tp-content-code__button" data-v-da581141><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" role="presentation" data-v-da581141><!----><g fill="inherit" stroke="inherit"><!--[--><!--[--><rect stroke="inherit" width="14.655" height="14.655" x="7.345" y="2.5" stroke-width="2" rx="1"></rect><path stroke="inherit" stroke-width="2" d="M4.897 6.569H4a2 2 0 0 0-2 2V20.5a2 2 0 0 0 2 2h12.655a2 2 0 0 0 2-2v-.896"></path><!--]--><!--]--></g></svg></button></div><!--]--><!--[--><p class="tp-content-paragraph" data-type="paragraph" data-v-6c80349f>Чтобы освоить установку утилиты, вход в среду и другие полезные команды, обратитесь к <a href="https://www.freecodecamp.org/news/how-to-setup-virtual-environments-in-python/">англоязычной статье на freecodecamp.org</a>.</p><!--]--><!--[--><h2 class="tp-content-subtitle tp-content-subtitle--h2" data-type="header2" data-v-75e770f1>Скачивайте только проверенные модули</h2><!--]--><!--[--><p class="tp-content-paragraph" data-type="paragraph" data-v-6c80349f>Сообщество Python отлично справляется с написанием модулей под разные задачи: от генерации игрушечных данных до внедрения GPT на сайт. В 99% случаев найти готовое решение на PyPi + GitHub вы сможете.</p><!--]--><!--[--><p class="tp-content-paragraph" data-type="paragraph" data-v-6c80349f>Но если речь заходит о других источниках, рекомендую попробовать такое скачивание в изолированной среде. Для этого подойдет дешевый покупной сервер.</p><!--]--><!--[--><h2 class="tp-content-subtitle tp-content-subtitle--h2" data-type="header2" data-v-75e770f1>Заключение</h2><!--]--><!--[--><p class="tp-content-paragraph" data-type="paragraph" data-v-6c80349f>Техник защиты кода существует еще немало, я перечислила основные, которые встречаются в моей работе при создании ботов и дата-аналитике. Как только вы почувствуете свободу в написании кода, сразу же используйте накопленный предшественниками опыт, чтобы проект реализовался с меньшим количеством проблем.</p><!--]--><!--[--><p class="tp-content-paragraph" data-type="paragraph" data-v-6c80349f>Какие еще техники защиты кода вы используете? Поделитесь в комментариях</p><!--]--><!--]--></div></div><div class="tp-post-page__end-beacon" data-v-4f64a4fb></div><div class="tp-post-page__container-tags" data-v-4f64a4fb><div class="tp-tag-subscription-banner" data-v-4f64a4fb data-v-4c97ca31><div class="tp-tag-subscription-banner__container-image" data-v-4c97ca31><div class="tp-image" style="border-radius:0;" data-v-d15050b5 data-v-4c97ca31><img class="tp-image__image" src="/images/tags-bell/tags-bell.png" srcset="undefined undefinedw,undefined undefinedw" sizes alt style="object-fit:fill;aspect-ratio:auto 1/1;object-position:50% 50%;" loading="auto" decoding="async" width="72" height="72" data-v-d15050b5></div></div><div class="tp-tag-subscription-banner__text-content" data-v-4c97ca31><span class="tp-tag-subscription-banner__title" data-v-4c97ca31>Следите за новыми постами по любимым темам </span><p class="tp-tag-subscription-banner__description" data-v-4c97ca31>Подпишитесь на интересующие вас теги, чтобы следить за новыми постами и быть в курсе событий.</p></div><button class="tp-tag-subscription-banner__close" data-v-4c97ca31><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" role="presentation" data-v-4c97ca31><!----><g fill="inherit" stroke="inherit"><!--[--><path fill-rule="evenodd" clip-rule="evenodd" d="m12 10.62 5.242-5.242a1 1 0 1 1 1.414 1.414l-5.242 5.243 5.242 5.243a1 1 0 0 1-1.414 1.414L12 13.449l-5.243 5.243a1 1 0 0 1-1.414-1.414l5.242-5.243-5.242-5.243a1 1 0 1 1 1.414-1.414L12 10.621Z" data-v-4c97ca31></path><!--]--></g></svg></button></div><div class="tp-post-page__tags" data-v-4f64a4fb><div class="tp-tags" data-v-4f64a4fb data-v-97350194><!--[--><div class="tp-tag tp-tag--primary" data-v-18ee51fb data-v-97350194><span class="tp-tag__text" data-v-18ee51fb><!--[-->Безопасность <!--]--></span><div class="tp-tag__additional-content" data-v-18ee51fb><!--[--><div class="tp-tooltip" data-v-f1909e3a data-v-97350194><!--[--><button class="tp-tags__tag-button" data-v-97350194><svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 28 28" role="presentation" data-v-97350194><!----><g fill="inherit" stroke="var(--tp-color-text-tertiary)"><!--[--><!--[--><circle cx="14" cy="14" r="12" fill="transparent" stroke="inherit" stroke-linecap="round" stroke-width="2.667"></circle><path stroke="inherit" stroke-linecap="round" stroke-width="2.667" d="M8.464 14h11.072M14 8.464v11.072"></path><!--]--><!--]--></g></svg></button><!--]--><span class="tp-tooltip__popover tp-tooltip__popover--top" style="display:none;" data-v-f1909e3a data-v-f1909e3a>Подписаться на тег</span></div><!--]--></div></div><div class="tp-tag tp-tag--primary" data-v-18ee51fb data-v-97350194><span class="tp-tag__text" data-v-18ee51fb><!--[-->Python <!--]--></span><div class="tp-tag__additional-content" data-v-18ee51fb><!--[--><div class="tp-tooltip" data-v-f1909e3a data-v-97350194><!--[--><button class="tp-tags__tag-button" data-v-97350194><svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 28 28" role="presentation" data-v-97350194><!----><g fill="inherit" stroke="var(--tp-color-text-tertiary)"><!--[--><!--[--><circle cx="14" cy="14" r="12" fill="transparent" stroke="inherit" stroke-linecap="round" stroke-width="2.667"></circle><path stroke="inherit" stroke-linecap="round" stroke-width="2.667" d="M8.464 14h11.072M14 8.464v11.072"></path><!--]--><!--]--></g></svg></button><!--]--><span class="tp-tooltip__popover tp-tooltip__popover--top" style="display:none;" data-v-f1909e3a data-v-f1909e3a>Подписаться на тег</span></div><!--]--></div></div><div class="tp-tag tp-tag--primary" data-v-18ee51fb data-v-97350194><span class="tp-tag__text" data-v-18ee51fb><!--[-->HTML <!--]--></span><div class="tp-tag__additional-content" data-v-18ee51fb><!--[--><div class="tp-tooltip" data-v-f1909e3a data-v-97350194><!--[--><button class="tp-tags__tag-button" data-v-97350194><svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 28 28" role="presentation" data-v-97350194><!----><g fill="inherit" stroke="var(--tp-color-text-tertiary)"><!--[--><!--[--><circle cx="14" cy="14" r="12" fill="transparent" stroke="inherit" stroke-linecap="round" stroke-width="2.667"></circle><path stroke="inherit" stroke-linecap="round" stroke-width="2.667" d="M8.464 14h11.072M14 8.464v11.072"></path><!--]--><!--]--></g></svg></button><!--]--><span class="tp-tooltip__popover tp-tooltip__popover--top" style="display:none;" data-v-f1909e3a data-v-f1909e3a>Подписаться на тег</span></div><!--]--></div></div><!--]--></div></div></div><div class="tp-post-page__actions" data-v-4f64a4fb><div class="tp-post-page__actions-buttons" data-v-4f64a4fb><div class="tp-reactions" data-v-d6932f57 data-v-4f64a4fb><button class="tp-button-card" style="background-color:;border-color:;" aria-label="Открыть панель реакций" data-v-8bf6fb70 data-v-d6932f57><span class="tp-button-card__icon-box" data-v-8bf6fb70><!--[--><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="presentation" data-v-d6932f57><!----><g fill="var(--tp-color-text-tertiary)" stroke="none"><!--[--><path d="M7 20.9999V7.99993L13 2.04993C13.25 1.79993 13.5457 1.65393 13.887 1.61193C14.229 1.5706 14.5583 1.63326 14.875 1.79993C15.1917 1.9666 15.425 2.19993 15.575 2.49993C15.725 2.79993 15.7583 3.10826 15.675 3.42493L14.55 7.99993H21C21.5333 7.99993 22 8.19993 22.4 8.59993C22.8 8.99993 23 9.4666 23 9.99993V11.9999C23 12.1166 22.9833 12.2416 22.95 12.3749C22.9167 12.5083 22.8833 12.6333 22.85 12.7499L19.85 19.7999C19.7 20.1333 19.45 20.4166 19.1 20.6499C18.75 20.8833 18.3833 20.9999 18 20.9999H7ZM9 8.84993V18.9999H18L21 11.9999V9.99993H12L13.35 4.49993L9 8.84993ZM4 20.9999C3.45 20.9999 2.97933 20.8043 2.588 20.4129C2.196 20.0209 2 19.5499 2 18.9999V9.99993C2 9.44993 2.196 8.97893 2.588 8.58693C2.97933 8.1956 3.45 7.99993 4 7.99993H7V9.99993H4V18.9999H7V20.9999H4ZM9 18.9999V8.84993V18.9999Z" data-v-d6932f57></path><!--]--></g></svg><!--]--></span><span class="tp-button-card__text" data-v-8bf6fb70><!--[-->2<!--]--></span></button><!----></div><div class="tp-tooltip" data-v-f1909e3a data-v-4f64a4fb><!--[--><button class="tp-button-card" style="" data-v-8bf6fb70 data-v-4f64a4fb><span class="tp-button-card__icon-box" data-v-8bf6fb70><!--[--><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="presentation" data-v-4f64a4fb><!----><g fill="var(--tp-color-text-tertiary)" stroke="none"><!--[--><path d="m21.851 5.569-2.377-2.377a.978.978 0 0 0-1.38 0L12.637 8.65a.978.978 0 0 0-.283.695v2.367a.978.978 0 0 0 .978.978h2.367a.977.977 0 0 0 .695-.283l5.458-5.459a.979.979 0 0 0 0-1.38Zm-6.564 5.165h-.978v-.978l4.48-4.48.979.978-4.48 4.48ZM19.2 12.69a.978.978 0 0 0-.978.979 6.847 6.847 0 0 1-6.848 6.847H5.906l.626-.616a.978.978 0 0 0 0-1.39 6.848 6.848 0 0 1 4.842-11.689.978.978 0 0 0 0-1.956 8.804 8.804 0 0 0-6.847 14.301L2.854 20.8a.979.979 0 0 0-.205 1.066.979.979 0 0 0 .9.607h7.825a8.804 8.804 0 0 0 8.804-8.804.978.978 0 0 0-.978-.979Z" data-v-4f64a4fb></path><!--]--></g></svg><!--]--></span><!----></button><!--]--><span class="tp-tooltip__popover tp-tooltip__popover--top" style="display:none;" data-v-f1909e3a data-v-f1909e3a>Комментарии</span></div><div class="tp-tooltip" data-v-f1909e3a data-v-4f64a4fb><!--[--><button class="tp-button-card" style="" data-v-8bf6fb70 data-v-4f64a4fb><span class="tp-button-card__icon-box" data-v-8bf6fb70><!--[--><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="presentation" data-v-4f64a4fb><!----><g fill="var(--tp-color-text-tertiary)" stroke="none"><!--[--><path fill-rule="evenodd" clip-rule="evenodd" d="M9 4a1 1 0 0 0-1 1v14.259l5-2.917 5 2.917V5a1 1 0 0 0-1-1H9ZM6 5a3 3 0 0 1 3-3h8a3 3 0 0 1 3 3v15.826a1.1 1.1 0 0 1-1.654.95L13 18.658l-5.346 3.118A1.1 1.1 0 0 1 6 20.826V5Z" data-v-4f64a4fb></path><!--]--></g></svg><!--]--></span><span class="tp-button-card__text" data-v-8bf6fb70><!--[-->2<!--]--></span></button><!--]--><span class="tp-tooltip__popover tp-tooltip__popover--top" style="display:none;" data-v-f1909e3a data-v-f1909e3a>В закладки</span></div><div class="tp-share" data-v-4f64a4fb data-v-8b417359><button class="tp-share-button" data-v-8b417359 data-v-12935963><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="presentation" data-v-12935963><!----><g fill="inherit" stroke="none"><!--[--><path d="M18.898 15.696a3.24 3.24 0 0 0-2.64 1.369l-6.837-3.11a3.24 3.24 0 0 0 .21-1.045 3.352 3.352 0 0 0-.08-.705l5.88-4.212a3.24 3.24 0 1 0-.81-2.146c.002.237.029.473.08.704l-5.88 4.212a3.24 3.24 0 1 0-2.43 5.387 3.24 3.24 0 0 0 2.155-.81l7.112 3.272v.324a3.24 3.24 0 1 0 3.24-3.24ZM17.86 4.226a1.62 1.62 0 1 1 0 3.24 1.62 1.62 0 0 1 0-3.24ZM6.39 14.53a1.62 1.62 0 1 1 0-3.24 1.62 1.62 0 0 1 0 3.24Zm12.507 6.026a1.62 1.62 0 1 1 0-3.24 1.62 1.62 0 0 1 0 3.24Z" data-v-12935963></path><!--]--></g></svg><!--[--><!--]--></button><!----></div></div><!----><span class="tp-chip" data-v-59e87408 data-v-4f64a4fb><span class="tp-chip__icon-box" data-v-59e87408><!--[--><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="presentation" data-v-4f64a4fb><!----><g fill="transparent" stroke="var(--tp-color-text-tertiary)"><!--[--><!--[--><g clip-path="url(#tp-icon-eye-a)"><g clip-path="url(#tp-icon-eye-b)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5.501 11.762s2.363-4.727 6.5-4.727c4.135 0 6.499 4.727 6.499 4.727s-2.364 4.726-6.5 4.726-6.499-4.726-6.499-4.726Z"></path><path d="M12 13.534a1.773 1.773 0 1 0 0-3.545 1.773 1.773 0 0 0 0 3.545Z"></path></g></g><defs><clipPath id="tp-icon-eye-a"><path fill="#fff" transform="translate(0 .035)" d="M0 0h24v24H0z"></path></clipPath><clipPath id="tp-icon-eye-b"><path fill="#fff" transform="translate(4.5 4.535)" d="M0 0h15v15H0z"></path></clipPath></defs><!--]--><!--]--></g></svg><!--]--></span><span class="tp-chip__text" data-v-59e87408><!--[--> 203<!--]--></span></span></div></div><div class="tp-post-page__container-listok-end-content" data-v-4f64a4fb><span data-v-4f64a4fb></span></div><div class="tp-post-page__container-comments" data-v-4f64a4fb><div id="tproger-comments" class="tp-comments" data-v-4f64a4fb data-v-de1b3714><div class="tp-comments__title" data-v-de1b3714>Что думаете?</div><div class="tp-comments-input" data-v-de1b3714 data-v-9fc13c82><!----><div class="tp-avatar tp-avatar--own tp-avatar--circle tp-comments-input__action-avatar" style="width:48px;height:48px;" data-v-6e456a49 data-v-9fc13c82><img class="tp-avatar__image tp-avatar__image--cover" src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTYiIGhlaWdodD0iOTYiIHZpZXdCb3g9IjAgMCA5NiA5NiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9Ijk2IiBoZWlnaHQ9Ijk2IiByeD0iMTgiIGZpbGw9IiNGNUVFRTUiLz4KPGc+CjxwYXRoIGQ9Ik0zNy4wNjQ5IDY0LjQ4MjJWNTAuMzQ1TDUwLjM3MDUgNDQuNTIzOFYxMDUuMjMxSC01LjUzNzQxQy04LjMwOTQxIDEwMC4yNDEgLTIuNzA5OTUgODguNTk4NiA1LjI3MzQyIDgxLjk0NThDMTEuMDc4IDc4LjQ2MTQgMzcuMDY0OSA2OC42NDAyIDM3LjA2NDkgNjQuNDgyMloiIGZpbGw9IiNFNkMxOUMiLz4KPHBhdGggZD0iTTU4LjY4NyA2NC40ODIyQzU3LjI2ODkgNjEuNDczMiA1OC42ODcgNTMuNjcxNCA1OC42ODcgNTAuMzQ1TDQ1LjM4MTQgNDQuNTIzOFYxMDUuMjMxTDEwMC4zNTEgMTAzLjU5MkMxMDMuMTIzIDk4LjYwMjggMTAwLjM1MSA4Ni43NjkxIDg5LjU0MDIgODAuMzA3NkM4MC4zMDk0IDc3LjUzODMgNjAuOTI0OCA2OS4yMzA2IDU4LjY4NyA2NC40ODIyWiIgZmlsbD0iI0U2QzE5QyIvPgo8cGF0aCBkPSJNNTguNjg2MSA2NS4zMTRDNDkuMzcyMSA3MS45NjY4IDQwLjM5MDkgNjguMDg2IDM3LjA2NDUgNjUuMzE0VjU2LjE2NjRMNTguNjg2MSA1MS4xNzY4VjY1LjMxNFoiIGZpbGw9IiNENUIxOEQiLz4KPHBhdGggZD0iTTI3LjkzNDEgMzMuNjQ1MUMyNy4wMjkgMjIuNDgyMSAzNS44NDQyIDEyLjkyMzEgNDcuMDQzOSAxMi45MjMxVjEyLjkyMzFDNTguMjQzNiAxMi45MjMxIDY3LjA1ODkgMjIuNDgyMSA2Ni4xNTM4IDMzLjY0NTFMNjUuNTQ3MiA0MS4xMjY4QzY1LjQwODggNDIuODMzIDY1LjEwMjkgNDQuNTIxNSA2NC42MzM5IDQ2LjE2NzhMNjIuMDkxMyA1NS4wOTI0QzYwLjIyNzYgNjEuNjMzOCA1NC4yNTEgNjYuMTQ1NSA0Ny40NDkyIDY2LjE0NTVWNjYuMTQ1NUM0MC45OTU5IDY2LjE0NTUgMzUuMjQzNiA2Mi4wNzcgMzMuMDk0IDU1Ljk5MjJMMjkuODUgNDYuODA5OEMyOS4xMTg5IDQ0Ljc0MDIgMjguNjU4OSA0Mi41ODQ2IDI4LjQ4MTUgNDAuMzk2OEwyNy45MzQxIDMzLjY0NTFaIiBmaWxsPSIjRjJDRUE1Ii8+CjwvZz4KPC9zdmc+Cg==" alt data-v-6e456a49></div><div class="tp-textarea tp-textarea--primary tp-textarea--elastic tp-textarea--actions-right tp-textarea--actions tp-comments-input__textarea" data-v-14c4c8fc data-v-9fc13c82><label class="tp-textarea__label tp-textarea__label--extra-small" data-v-14c4c8fc> <span class="tp-textarea__textarea-container" data-v-14c4c8fc><textarea cols="20" maxlength="none" minlength="none" placeholder="Комментировать..." rows="1" class="tp-textarea__textarea" data-v-14c4c8fc></textarea><span class="tp-textarea__actions" data-v-14c4c8fc><!--[--><div class="tp-comments-input__actions" data-v-9fc13c82><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="presentation" class="tp-comments-input__actions-icon" data-v-9fc13c82><!----><g fill="inherit" stroke="none"><!--[--><path fill-rule="evenodd" clip-rule="evenodd" d="M3.31775 19.6578C3.31775 20.3006 3.99052 20.7215 4.56856 20.4405L20.5102 12.6899C21.1632 12.3724 21.1632 11.442 20.5102 11.1245L4.56856 3.37385C3.99052 3.09281 3.31775 3.51379 3.31775 4.15653L3.31775 9.79016C3.31775 10.2344 3.65235 10.6073 4.09399 10.6553L11.1265 11.4197C11.3752 11.4468 11.5637 11.6569 11.5637 11.9071C11.5637 12.1573 11.3752 12.3674 11.1265 12.3944L4.09399 13.1588C3.65235 13.2068 3.31775 13.5798 3.31775 14.024L3.31775 19.6578Z" fill-color="inherit" data-v-9fc13c82></path><!--]--></g></svg></div><!--]--></span></span></label></div></div><div class="tp-comments__container" data-v-de1b3714><div class="tp-comments__actions" data-v-de1b3714><div class="tp-comments__count" data-v-de1b3714>0 комментариев</div><div class="tp-comments-filter" data-v-de1b3714 data-v-6f113051><div class="tp-comments-filter__current" data-v-6f113051>Сначала интересные <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="presentation" fill="none" class="tp-comments-filter__current-icon" data-v-6f113051><!----><g fill="inherit" stroke="inherit"><!--[--><path d="M9 11L12.5 14L16 11" stroke="inherit" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" data-v-6f113051></path><!--]--></g></svg></div><!----></div></div><div class="tp-comments__box" data-v-de1b3714><div class="tp-comments-list" data-v-de1b3714 data-v-eb0ae267><!--[--><!--]--><!----></div></div></div></div></div><div class="tp-post-page__widgets" data-v-4f64a4fb><!--[--><div class="tp-base-widget" widget-index="0" data-v-4f64a4fb data-v-c561b83a data-v-5cd01b80><span class="tp-base-widget__title" data-v-5cd01b80>Курсы</span><div class="tp-base-widget__content" data-v-5cd01b80><!--[--><div class="tp-widget-courses" data-v-c561b83a><!--[--><div class="tp-base-widget-item" data-v-c561b83a data-v-de6c2611><!----><div class="tp-base-widget-item__logo" data-v-de6c2611><div class="tp-avatar tp-avatar--own tp-avatar--circle tp-comments-input__avatar" style="width:28px;height:28px;" data-v-6e456a49 data-v-de6c2611><img class="tp-avatar__image tp-avatar__image--cover" src="https://media.tproger.ru/uploads/2023/05/9530afe0-ad8e-49df-ac17-d827a82599c3.png" alt="Логотип компании Result School" loading="auto" decoding="async" srcset="https://tproger.ru/signed_image/H_tEKm9zVWLX5z4yeVJfWOuWENl-XI3VbM43P7TQKAw/rs:fill:48:48:true/cb:vimg_1/f:webp/aHR0cHM6Ly9tZWRpYS50cHJvZ2VyLnJ1L3VwbG9hZHMvMjAyMy8wNS85NTMwYWZlMC1hZDhlLTQ5ZGYtYWMxNy1kODI3YTgyNTk5YzMucG5n 48w,https://tproger.ru/signed_image/h989f4kTcGC_3q3D9p-bpft6fXWGaXQtjyLaB7__Ao0/rs:fill:96:96:true/cb:vimg_1/f:webp/aHR0cHM6Ly9tZWRpYS50cHJvZ2VyLnJ1L3VwbG9hZHMvMjAyMy8wNS85NTMwYWZlMC1hZDhlLTQ5ZGYtYWMxNy1kODI3YTgyNTk5YzMucG5n 96w" sizes="(min-width: 0px) 48px" data-v-6e456a49></div></div><div class="tp-base-widget-item__info" data-v-de6c2611><div class="tp-base-widget-item__name" data-v-de6c2611><a href="/away?to=aHR0cHM6Ly9yZXN1bHQuc2Nob29sL3Byb2R1Y3RzL2dpdD91dG1fc291cmNlPXRwcm9nZXImdXRtX21lZGl1bT1wYXJ0bmVycyZ1dG1fY2FtcGFpZ249Y3BhJnV0bV9jb250ZW50PWdpdA==" rel="noopener noreferrer" target="_blank" class="tp-base-widget-item__link" data-v-de6c2611>Курс «Продвинутый GIT»</a></div><div class="tp-base-widget-item__tags" data-v-de6c2611><!----><span class="tp-base-widget-item__tag tp-base-widget-item__tag--access" data-v-de6c2611>набор еще идет</span><span class="tp-base-widget-item__tag" data-v-de6c2611>онлайн</span><span class="tp-base-widget-item__tag" data-v-de6c2611>7590₽</span></div></div></div><div class="tp-base-widget-item" data-v-c561b83a data-v-de6c2611><!----><div class="tp-base-widget-item__logo" data-v-de6c2611><div class="tp-avatar tp-avatar--own tp-avatar--circle tp-comments-input__avatar" style="width:28px;height:28px;" data-v-6e456a49 data-v-de6c2611><img class="tp-avatar__image tp-avatar__image--cover" src="https://media.tproger.ru/uploads/2023/05/9530afe0-ad8e-49df-ac17-d827a82599c3.png" alt="Логотип компании Result School" loading="auto" decoding="async" srcset="https://tproger.ru/signed_image/H_tEKm9zVWLX5z4yeVJfWOuWENl-XI3VbM43P7TQKAw/rs:fill:48:48:true/cb:vimg_1/f:webp/aHR0cHM6Ly9tZWRpYS50cHJvZ2VyLnJ1L3VwbG9hZHMvMjAyMy8wNS85NTMwYWZlMC1hZDhlLTQ5ZGYtYWMxNy1kODI3YTgyNTk5YzMucG5n 48w,https://tproger.ru/signed_image/h989f4kTcGC_3q3D9p-bpft6fXWGaXQtjyLaB7__Ao0/rs:fill:96:96:true/cb:vimg_1/f:webp/aHR0cHM6Ly9tZWRpYS50cHJvZ2VyLnJ1L3VwbG9hZHMvMjAyMy8wNS85NTMwYWZlMC1hZDhlLTQ5ZGYtYWMxNy1kODI3YTgyNTk5YzMucG5n 96w" sizes="(min-width: 0px) 48px" data-v-6e456a49></div></div><div class="tp-base-widget-item__info" data-v-de6c2611><div class="tp-base-widget-item__name" data-v-de6c2611><a href="/away?to=aHR0cHM6Ly9say5yZXN1bHQuc2Nob29sL3N0YXJ0LWluLWl0P3V0bV9zb3VyY2U9dHByb2dlciZ1dG1fbWVkaXVtPXBhcnRuZXJzJnV0bV9jYW1wYWlnbj1jcGEmdXRtX2NvbnRlbnQ9c3RhcnRfaXQ=" rel="noopener noreferrer" target="_blank" class="tp-base-widget-item__link" data-v-de6c2611>Воркшоп для начинающих «Перспективы в IT»</a></div><div class="tp-base-widget-item__tags" data-v-de6c2611><!----><span class="tp-base-widget-item__tag tp-base-widget-item__tag--access" data-v-de6c2611>набор еще идет</span><span class="tp-base-widget-item__tag" data-v-de6c2611>онлайн</span><span class="tp-base-widget-item__tag" data-v-de6c2611>бесплатно</span></div></div></div><div class="tp-base-widget-item" data-v-c561b83a data-v-de6c2611><!----><div class="tp-base-widget-item__logo" data-v-de6c2611><div class="tp-avatar tp-avatar--own tp-avatar--circle tp-comments-input__avatar" style="width:28px;height:28px;" data-v-6e456a49 data-v-de6c2611><img class="tp-avatar__image tp-avatar__image--cover" src="https://media.tproger.ru/uploads/2023/05/9530afe0-ad8e-49df-ac17-d827a82599c3.png" alt="Логотип компании Result School" loading="auto" decoding="async" srcset="https://tproger.ru/signed_image/H_tEKm9zVWLX5z4yeVJfWOuWENl-XI3VbM43P7TQKAw/rs:fill:48:48:true/cb:vimg_1/f:webp/aHR0cHM6Ly9tZWRpYS50cHJvZ2VyLnJ1L3VwbG9hZHMvMjAyMy8wNS85NTMwYWZlMC1hZDhlLTQ5ZGYtYWMxNy1kODI3YTgyNTk5YzMucG5n 48w,https://tproger.ru/signed_image/h989f4kTcGC_3q3D9p-bpft6fXWGaXQtjyLaB7__Ao0/rs:fill:96:96:true/cb:vimg_1/f:webp/aHR0cHM6Ly9tZWRpYS50cHJvZ2VyLnJ1L3VwbG9hZHMvMjAyMy8wNS85NTMwYWZlMC1hZDhlLTQ5ZGYtYWMxNy1kODI3YTgyNTk5YzMucG5n 96w" sizes="(min-width: 0px) 48px" data-v-6e456a49></div></div><div class="tp-base-widget-item__info" data-v-de6c2611><div class="tp-base-widget-item__name" data-v-de6c2611><a href="/away?to=aHR0cHM6Ly9yZXN1bHQuc2Nob29sL3Byb2R1Y3RzL2h0bWwtY3NzP3V0bV9zb3VyY2U9dHByb2dlciZ1dG1fbWVkaXVtPXBhcnRuZXJzJnV0bV9jYW1wYWlnbj1jcGEmdXRtX2NvbnRlbnQ9aHRtbF9jc3M=" rel="noopener noreferrer" target="_blank" class="tp-base-widget-item__link" data-v-de6c2611>«Бесплатный модуль курса-профессии» HTML&CSS</a></div><div class="tp-base-widget-item__tags" data-v-de6c2611><!----><span class="tp-base-widget-item__tag tp-base-widget-item__tag--access" data-v-de6c2611>набор еще идет</span><span class="tp-base-widget-item__tag" data-v-de6c2611>онлайн</span><span class="tp-base-widget-item__tag" data-v-de6c2611>бесплатно</span></div></div></div><div class="tp-base-widget-item" data-v-c561b83a data-v-de6c2611><!----><div class="tp-base-widget-item__logo" data-v-de6c2611><div class="tp-avatar tp-avatar--own tp-avatar--circle tp-comments-input__avatar" style="width:28px;height:28px;" data-v-6e456a49 data-v-de6c2611><img class="tp-avatar__image tp-avatar__image--cover" src="https://media.tproger.ru/uploads/2023/05/9530afe0-ad8e-49df-ac17-d827a82599c3.png" alt="Логотип компании Result School" loading="auto" decoding="async" srcset="https://tproger.ru/signed_image/H_tEKm9zVWLX5z4yeVJfWOuWENl-XI3VbM43P7TQKAw/rs:fill:48:48:true/cb:vimg_1/f:webp/aHR0cHM6Ly9tZWRpYS50cHJvZ2VyLnJ1L3VwbG9hZHMvMjAyMy8wNS85NTMwYWZlMC1hZDhlLTQ5ZGYtYWMxNy1kODI3YTgyNTk5YzMucG5n 48w,https://tproger.ru/signed_image/h989f4kTcGC_3q3D9p-bpft6fXWGaXQtjyLaB7__Ao0/rs:fill:96:96:true/cb:vimg_1/f:webp/aHR0cHM6Ly9tZWRpYS50cHJvZ2VyLnJ1L3VwbG9hZHMvMjAyMy8wNS85NTMwYWZlMC1hZDhlLTQ5ZGYtYWMxNy1kODI3YTgyNTk5YzMucG5n 96w" sizes="(min-width: 0px) 48px" data-v-6e456a49></div></div><div class="tp-base-widget-item__info" data-v-de6c2611><div class="tp-base-widget-item__name" data-v-de6c2611><a href="/away?to=aHR0cHM6Ly9yZXN1bHQuc2Nob29sL3Byb2R1Y3RzL2Jhc2UtcHJvZ3JhbW1pbmc/dXRtX3NvdXJjZT10cHJvZ2VyJnV0bV9tZWRpdW09cGFydG5lcnMmdXRtX2NhbXBhaWduPWNwYSZ1dG1fY29udGVudD1iYXNlX3Byb2dyYW1taW5n" rel="noopener noreferrer" target="_blank" class="tp-base-widget-item__link" data-v-de6c2611>Основы программирования</a></div><div class="tp-base-widget-item__tags" data-v-de6c2611><!----><span class="tp-base-widget-item__tag tp-base-widget-item__tag--access" data-v-de6c2611>набор еще идет</span><span class="tp-base-widget-item__tag" data-v-de6c2611>онлайн</span><span class="tp-base-widget-item__tag" data-v-de6c2611>2790₽</span></div></div></div><!--]--></div><!--]--></div><a href="/courses" class="tp-base-widget__link" data-v-5cd01b80>Все курсы <span class="tp-base-widget__link-icon" data-v-5cd01b80><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="presentation" data-v-5cd01b80><!----><g fill="transparent" stroke="var(--tp-color-brand)"><!--[--><path d="M9 11L12.5 14L16 11" stroke="inherit" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" data-v-5cd01b80></path><!--]--></g></svg></span></a></div><!----><!--]--><!----></div></div><!--]--></main><aside class="tp-layout-default__aside-right"><div class="tp-layout-default__widget-container" data-v-18cca497><div class="tp-layout-default__listok-container" data-v-18cca497><span data-v-18cca497></span></div><span data-v-18cca497></span></div></aside></div><!--teleport start--><!--teleport end--><span></span><span></span><!--teleport start--><!--teleport end--></div></div><script>window.__NUXT__=(function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,_,$,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,aA,aB,aC,aD,aE,aF,aG,aH,aI,aJ,aK,aL,aM,aN,aO,aP,aQ,aR,aS,aT,aU,aV,aW,aX,aY){T[0]="popup";T[1]="fix";T[2]="after_post";aa.RightSidebar={isEntity:b,isSubEntity:b,widgets:[{name:ab,position:z,entityId:a,settings:{order:c,isVisible:d,widgetSettings:{feed:{repeat:b,perPosts:y}}},data:[],error:{status:b,message:a}},{name:ac,position:z,entityId:a,settings:{order:D,isVisible:d,widgetSettings:{feed:{repeat:b,perPosts:y}}},data:{courses:[{id:ad,isPermanent:b,isHiddenDate:d,dateStart:j,dateEnd:k,isOpen:d,availablePlaces:g,complexity:ae,hasEmployment:b,duration:a,lessons:a,hoursPerWeek:a,speed:l,hasCert:b,pricePerMouth:a,fullPrice:af,discount:a,promoCode:a,placeAddress:a,currencyCode:h,regLink:ag,regButtonText:ah,regFormLink:a,views:ai,shows:aj,title:ak,description:al,settings:{showForm:b,directTransition:b,straightToTheLanding:b},ordToken:a,classFormat:m,name:am,publish_date:a,tags:[{id:an,name:ao},{id:ap,name:aq}],company:{id:n,name:o,link:p,logo:{original:q,alt:r,dimensions:{width:e,height:e},additionalSizes:{srcSet:[{url:s,dpr:c,width:e},{url:t,dpr:c,width:u}],sizes:[{media:i,size:v}]}}},currency:{code:h,name:w,symbol:x},logo:a,thumbnail:a,link:ar},{id:as,isPermanent:b,isHiddenDate:d,dateStart:j,dateEnd:k,isOpen:d,availablePlaces:g,complexity:A,hasEmployment:b,duration:a,lessons:a,hoursPerWeek:a,speed:l,hasCert:b,pricePerMouth:a,fullPrice:a,discount:a,promoCode:a,placeAddress:a,currencyCode:h,regLink:at,regButtonText:E,regFormLink:a,views:K,shows:au,title:av,description:aw,settings:{showForm:b,directTransition:b,straightToTheLanding:b},ordToken:a,classFormat:m,name:ax,publish_date:a,tags:[],company:{id:n,name:o,link:p,logo:{original:q,alt:r,dimensions:{width:e,height:e},additionalSizes:{srcSet:[{url:s,dpr:c,width:e},{url:t,dpr:c,width:u}],sizes:[{media:i,size:v}]}}},currency:{code:h,name:w,symbol:x},logo:a,thumbnail:a,link:ay},{id:az,isPermanent:b,isHiddenDate:d,dateStart:j,dateEnd:k,isOpen:d,availablePlaces:g,complexity:A,hasEmployment:b,duration:a,lessons:a,hoursPerWeek:a,speed:l,hasCert:b,pricePerMouth:a,fullPrice:a,discount:a,promoCode:a,placeAddress:a,currencyCode:h,regLink:aA,regButtonText:E,regFormLink:a,views:aB,shows:aC,title:aD,description:aE,settings:{showForm:b,directTransition:b,straightToTheLanding:b},ordToken:a,classFormat:m,name:aF,publish_date:a,tags:[{id:F,name:G},{id:aG,name:L},{id:aH,name:aI}],company:{id:n,name:o,link:p,logo:{original:q,alt:r,dimensions:{width:e,height:e},additionalSizes:{srcSet:[{url:s,dpr:c,width:e},{url:t,dpr:c,width:u}],sizes:[{media:i,size:v}]}}},currency:{code:h,name:w,symbol:x},logo:a,thumbnail:a,link:aJ},{id:aK,isPermanent:b,isHiddenDate:d,dateStart:j,dateEnd:k,isOpen:d,availablePlaces:g,complexity:A,hasEmployment:b,duration:a,lessons:a,hoursPerWeek:a,speed:l,hasCert:b,pricePerMouth:a,fullPrice:aL,discount:a,promoCode:aM,placeAddress:a,currencyCode:h,regLink:aN,regButtonText:aO,regFormLink:a,views:aP,shows:aQ,title:aR,description:aS,settings:{showForm:b,directTransition:b,straightToTheLanding:b},ordToken:a,classFormat:m,name:aT,publish_date:a,tags:[{id:aU,name:aV},{id:F,name:G}],company:{id:n,name:o,link:p,logo:{original:q,alt:r,dimensions:{width:e,height:e},additionalSizes:{srcSet:[{url:s,dpr:c,width:e},{url:t,dpr:c,width:u}],sizes:[{media:i,size:v}]}}},currency:{code:h,name:w,symbol:x},logo:a,thumbnail:a,link:aW}]},error:{status:b,message:a}},{name:"jobs",position:z,entityId:a,settings:{order:I,isVisible:d,widgetSettings:{feed:{repeat:b,perPosts:y}}},data:{vacancies:[{id:240383,title:"Специалист техподдержки системы электронного документооборота",link:"\u002Fjobs\u002Fspecialist-tehpodderzhki-sistemy-elektronnogo-dokumentooborota",logo:{original:N,alt:O,dimensions:{width:f,height:f},additionalSizes:{srcSet:[{url:P,dpr:c,width:f},{url:Q,dpr:c,width:B}],sizes:[{media:i,size:C}]}}},{id:240265,title:"Программист АСУТП",link:"\u002Fjobs\u002Fprogrammist-asutp",logo:{original:N,alt:O,dimensions:{width:f,height:f},additionalSizes:{srcSet:[{url:P,dpr:c,width:f},{url:Q,dpr:c,width:B}],sizes:[{media:i,size:C}]}}},{id:240391,title:"Специалист по информационной безопасности",link:"\u002Fjobs\u002Fspecialist-po-informacionnoj-bezopasnosti-g-novosibirsk",logo:{original:N,alt:O,dimensions:{width:f,height:f},additionalSizes:{srcSet:[{url:P,dpr:c,width:f},{url:Q,dpr:c,width:B}],sizes:[{media:i,size:C}]}}}]},error:{status:b,message:a}},{name:"discussion_now",position:z,entityId:a,settings:{order:Y,isVisible:d,widgetSettings:{feed:{repeat:b,perPosts:y}}},data:{comments:[{post_title:"Dunder-методы: зачем они нужны и что могут",content:"++++ у меня ушел не один год, чтобы понять и принять концепцию Dunder-методов. +++\r\nОбычное ООП , как в любом \"нормальном\" языке программирования с возможность перекрыть операции. Мне непонятно другое - зачем, при определении методов класса передавать, self в качестве первого параметра? Self   и так есть \"внутри\" экземпляра ( в других языках это this или me), при этом в вызове экземпляра self писать не надо.  Зачем эта избыточность, как вы считаете?",date:"2023-09-22T19:34:55.000+03:00",user:{avatar:{original:"https:\u002F\u002Favatars.yandex.net\u002Fget-yapic\u002F45848\u002FMS3Hw9SdO9JTpWaSjElMFHdg0-1\u002Fislands-200",alt:"Аватарка пользователя Михаил Боровиков",dimensions:{width:f,height:f},additionalSizes:{srcSet:[{url:"https:\u002F\u002Ftproger.ru\u002Fsigned_image\u002Fbv_Hx7mMI1dodY6ZPObZUR3ulsz9FXAWvIJguEzIo58\u002Frs:fill:30:30:true\u002Fcb:vimg_1\u002Ff:webp\u002FaHR0cHM6Ly9hdmF0YXJzLnlhbmRleC5uZXQvZ2V0LXlhcGljLzQ1ODQ4L01TM0h3OVNkTzlKVHBXYVNqRWxNRkhkZzAtMS9pc2xhbmRzLTIwMA=",dpr:c,width:f},{url:"https:\u002F\u002Ftproger.ru\u002Fsigned_image\u002FvhLJ-nFoDPHWyUqwXd3qU8FNm6c7gMXLGNRLKd7D94A\u002Frs:fill:60:60:true\u002Fcb:vimg_1\u002Ff:webp\u002FaHR0cHM6Ly9hdmF0YXJzLnlhbmRleC5uZXQvZ2V0LXlhcGljLzQ1ODQ4L01TM0h3OVNkTzlKVHBXYVNqRWxNRkhkZzAtMS9pc2xhbmRzLTIwMA=",dpr:c,width:B}],sizes:[{media:i,size:C}]}},name:"Михаил Боровиков"},link:"\u002Farticles\u002Fdunder-metody-zachem-oni-nuzhny-i-chto-mogut?scrollTo=tproger-comments-11966&openComments=yes"},{post_title:"За что ненавидят язык программирования JavaScript",content:"Ага, а вот питон со своим уродливым мусорным синтаксисом, прямо ппц какой классный",date:"2023-09-22T18:58:11.000+03:00",user:{avatar:{original:"https:\u002F\u002Favatars.yandex.net\u002Fget-yapic\u002F51381\u002Fenc-9a6e01bd4477651b0a76f7a72ed010d7ef2225aff6a621016f4dccad990b5d3e\u002Fislands-200",alt:"Аватарка пользователя Евгений Туз",dimensions:{width:f,height:f},additionalSizes:{srcSet:[{url:"https:\u002F\u002Ftproger.ru\u002Fsigned_image\u002FY82k8dY_LzUrGwlbT-6qFftGfiEY4Xoj2musWhOakHM\u002Frs:fill:30:30:true\u002Fcb:vimg_1\u002Ff:webp\u002FaHR0cHM6Ly9hdmF0YXJzLnlhbmRleC5uZXQvZ2V0LXlhcGljLzUxMzgxL2VuYy05YTZlMDFiZDQ0Nzc2NTFiMGE3NmY3YTcyZWQwMTBkN2VmMjIyNWFmZjZhNjIxMDE2ZjRkY2NhZDk5MGI1ZDNlL2lzbGFuZHMtMjAw",dpr:c,width:f},{url:"https:\u002F\u002Ftproger.ru\u002Fsigned_image\u002FamzkqYx0gXKiovV9LqdlyvW4FiAm83hh6tiFUb_yIQs\u002Frs:fill:60:60:true\u002Fcb:vimg_1\u002Ff:webp\u002FaHR0cHM6Ly9hdmF0YXJzLnlhbmRleC5uZXQvZ2V0LXlhcGljLzUxMzgxL2VuYy05YTZlMDFiZDQ0Nzc2NTFiMGE3NmY3YTcyZWQwMTBkN2VmMjIyNWFmZjZhNjIxMDE2ZjRkY2NhZDk5MGI1ZDNlL2lzbGFuZHMtMjAw",dpr:c,width:B}],sizes:[{media:i,size:C}]}},name:"Евгений Туз"},link:"\u002Farticles\u002Fza-chto-nenavidyat-yazyk-programmirovaniya-javascript?scrollTo=tproger-comments-11965&openComments=yes"},{post_title:"YandexGPT против ChatGPT: сравнение возможностей",content:"\"Хорошо, давайте разложим все по полочкам, шаг за шагом.\r\n\r\nМы начали с восьми качелей.\r\n\r\nТри из этих качелей были покрашены.\r\n\r\nПоскольку качели уже кто-то использовал, мы больше не можем считать их \"покрашенными\".\r\n\r\nПоэтому из общего количества качелей вычитаем количество покрашенных качелей, которые уже нельзя использовать.\r\n\r\nТаким образом, у нас остается пять неиспользованных, неокрашенных качелей.\r\n\r\nТаким образом, в парке осталось пять качелей.\"",date:"2023-09-22T06:00:13.000+03:00",user:{avatar:{original:"https:\u002F\u002Flh3.googleusercontent.com\u002Fa\u002FACg8ocKG0QkhQHGjBy6PcsWQL-H_zSDeS5mjukgnBY54Bjdv=s96-c",alt:"Аватарка пользователя ayano",dimensions:{width:f,height:f},additionalSizes:{srcSet:[{url:"https:\u002F\u002Ftproger.ru\u002Fsigned_image\u002F4h3eZv2oUOwJ3HpiEF3zoqT_guW1of2OUh2HsnCAy9Y\u002Frs:fill:30:30:true\u002Fcb:vimg_1\u002Ff:webp\u002FaHR0cHM6Ly9saDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL2EvQUNnOG9jS0cwUWtoUUhHakJ5NlBjc1dRTC1IX3pTRGVTNW1qdWtnbkJZNTRCamR2PXM5Ni1j",dpr:c,width:f},{url:"https:\u002F\u002Ftproger.ru\u002Fsigned_image\u002Fb2iDIyiVXF906gU-JLtdvMu3sO5RvHsB2O0a-gblG5g\u002Frs:fill:60:60:true\u002Fcb:vimg_1\u002Ff:webp\u002FaHR0cHM6Ly9saDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL2EvQUNnOG9jS0cwUWtoUUhHakJ5NlBjc1dRTC1IX3pTRGVTNW1qdWtnbkJZNTRCamR2PXM5Ni1j",dpr:c,width:B}],sizes:[{media:i,size:C}]}},name:"ayano"},link:"\u002Farticles\u002Fyandexgpt-protiv-chatgpt-sravnenie-vozmozhnostej?scrollTo=tproger-comments-11963&openComments=yes"}]},error:{status:b,message:a}},{name:"reading_now",position:z,entityId:a,settings:{order:Z,isVisible:d,widgetSettings:{feed:{repeat:b,perPosts:y}}},data:{posts:[{title:"10 логических задач с собеседований, которые заставят застрелиться",comments:113,view:{all:382851,new:148},link:"\u002Farticles\u002F10-logicheskih-zadach-s-sobesedovanij-kotorye-zastavjat-zastrelitsja"},{title:"История C++ с 1953 года от FLOW-MATIC и Fortran до языка Си и Cfront",comments:g,view:{all:566,new:298},link:"\u002Farticles\u002Fistoriya-cpp-s-1953-goda"},{title:"10 логических задач с собеседований, которые заставят задуматься",comments:16,view:{all:13436,new:118},link:"\u002Farticles\u002Fzadachi-s-sobesedovanij-kotorye-zastavyat-krepko-zadumatsya"}]},error:{status:b,message:a}}],position:z};aa.PostFooter={isEntity:b,isSubEntity:b,widgets:[{name:ac,position:R,entityId:a,settings:{order:D,isVisible:d,widgetSettings:{feed:{repeat:b,perPosts:y}}},data:{courses:[{id:ad,isPermanent:b,isHiddenDate:d,dateStart:j,dateEnd:k,isOpen:d,availablePlaces:g,complexity:ae,hasEmployment:b,duration:a,lessons:a,hoursPerWeek:a,speed:l,hasCert:b,pricePerMouth:a,fullPrice:af,discount:a,promoCode:a,placeAddress:a,currencyCode:h,regLink:ag,regButtonText:ah,regFormLink:a,views:ai,shows:aj,title:ak,description:al,settings:{showForm:b,directTransition:b,straightToTheLanding:b},ordToken:a,classFormat:m,name:am,publish_date:a,tags:[{id:an,name:ao},{id:ap,name:aq}],company:{id:n,name:o,link:p,logo:{original:q,alt:r,dimensions:{width:e,height:e},additionalSizes:{srcSet:[{url:s,dpr:c,width:e},{url:t,dpr:c,width:u}],sizes:[{media:i,size:v}]}}},currency:{code:h,name:w,symbol:x},logo:a,thumbnail:a,link:ar},{id:as,isPermanent:b,isHiddenDate:d,dateStart:j,dateEnd:k,isOpen:d,availablePlaces:g,complexity:A,hasEmployment:b,duration:a,lessons:a,hoursPerWeek:a,speed:l,hasCert:b,pricePerMouth:a,fullPrice:a,discount:a,promoCode:a,placeAddress:a,currencyCode:h,regLink:at,regButtonText:E,regFormLink:a,views:K,shows:au,title:av,description:aw,settings:{showForm:b,directTransition:b,straightToTheLanding:b},ordToken:a,classFormat:m,name:ax,publish_date:a,tags:[],company:{id:n,name:o,link:p,logo:{original:q,alt:r,dimensions:{width:e,height:e},additionalSizes:{srcSet:[{url:s,dpr:c,width:e},{url:t,dpr:c,width:u}],sizes:[{media:i,size:v}]}}},currency:{code:h,name:w,symbol:x},logo:a,thumbnail:a,link:ay},{id:az,isPermanent:b,isHiddenDate:d,dateStart:j,dateEnd:k,isOpen:d,availablePlaces:g,complexity:A,hasEmployment:b,duration:a,lessons:a,hoursPerWeek:a,speed:l,hasCert:b,pricePerMouth:a,fullPrice:a,discount:a,promoCode:a,placeAddress:a,currencyCode:h,regLink:aA,regButtonText:E,regFormLink:a,views:aB,shows:aC,title:aD,description:aE,settings:{showForm:b,directTransition:b,straightToTheLanding:b},ordToken:a,classFormat:m,name:aF,publish_date:a,tags:[{id:F,name:G},{id:aG,name:L},{id:aH,name:aI}],company:{id:n,name:o,link:p,logo:{original:q,alt:r,dimensions:{width:e,height:e},additionalSizes:{srcSet:[{url:s,dpr:c,width:e},{url:t,dpr:c,width:u}],sizes:[{media:i,size:v}]}}},currency:{code:h,name:w,symbol:x},logo:a,thumbnail:a,link:aJ},{id:aK,isPermanent:b,isHiddenDate:d,dateStart:j,dateEnd:k,isOpen:d,availablePlaces:g,complexity:A,hasEmployment:b,duration:a,lessons:a,hoursPerWeek:a,speed:l,hasCert:b,pricePerMouth:a,fullPrice:aL,discount:a,promoCode:aM,placeAddress:a,currencyCode:h,regLink:aN,regButtonText:aO,regFormLink:a,views:aP,shows:aQ,title:aR,description:aS,settings:{showForm:b,directTransition:b,straightToTheLanding:b},ordToken:a,classFormat:m,name:aT,publish_date:a,tags:[{id:aU,name:aV},{id:F,name:G}],company:{id:n,name:o,link:p,logo:{original:q,alt:r,dimensions:{width:e,height:e},additionalSizes:{srcSet:[{url:s,dpr:c,width:e},{url:t,dpr:c,width:u}],sizes:[{media:i,size:v}]}}},currency:{code:h,name:w,symbol:x},logo:a,thumbnail:a,link:aW}]},error:{status:b,message:a}},{name:ab,position:R,entityId:a,settings:{order:I,isVisible:d,widgetSettings:{feed:{repeat:b,perPosts:y}}},data:[],error:{status:b,message:a}}],position:R};return {data:{"/v1/options{\"method\":\"GET\",\"query\":{\"link\":\"L2FydGljbGVzL2thay16YXNoaGl0aXQtc3Zvai1weXRob24ta29k\"}}":{isShowAd:d,availableBannerPositions:T},"/v1/post/single/{\"method\":\"GET\",\"params\":{\"name\":\"kak-zashhitit-svoj-python-kod\",\"tag\":\"articles\"}}":{id:245553,title:U,status:"publish",authorId:V,link:W,linkV2:W,linkIsExternal:b,excerpt:X,view:203,bookmarks:{count:D,added:b},content:"{\"blocks\":[{\"type\":\"paragraph\",\"data\":{\"text\":\"Безопасностью кода студентов озадачивают нечасто. Нас знакомят с некоторыми устоявшимися приемами, вроде применения виртуального окружения, но в систему это складывается только во время работы.\"}},{\"type\":\"paragraph\",\"data\":{\"text\":\"Чтобы ускорить процесс и избавить вас от возможных проблем на старте, я собрала топ способов сделать код защищеннее от двух видов воздействия: злонамеренного (например, использование уязвимостей сайта хакерами) и непреднамеренного (ошибки разработчика, приводящей к падению прода).\"}},{\"type\":\"header2\",\"data\":{\"level\":2,\"text\":\"Валидируйте входные данные\"}},{\"type\":\"paragraph\",\"data\":{\"text\":\"Стоит фильтровать пользовательский ввод на наличие определенных символов. В разработке веб-приложений это особенно важно, потому что помогает предотвратить различные атаки, такие как SQL-инъекции и межсайтовый скриптинг (XSS).\"}},{\"type\":\"paragraph\",\"data\":{\"text\":\"Покажу на примере.\"}},{\"type\":\"paragraph\",\"data\":{\"text\":\"Код ниже запускает простой веб-сервер, который при обработке GET-запроса возвращает HTML, вставляя имя сайта в приветствие:\"}},{\"type\":\"code\",\"data\":{\"code\":\"from http.server import HTTPServer, BaseHTTPRequestHandler\\r\\nsecret = 'abc123'\\r\\nclass Handler(BaseHTTPRequestHandler):\\r\\n    name = 'xakep'\\r\\n    msg = 'welcome to {site.name}'\\r\\n    def do_GET(self):\\r\\n        res = ('\u003Ctitle\u003E' + self.path + '\u003C\u002Ftitle\u003E\\\\n' + self.msg).\\r\\nformat(site=self)\\r\\n        self.send_response(200)\\r\\n        self.send_header('content-type', 'text\u002Fhtml')\\r\\n        self.end_headers()\\r\\n        self.wfile.write(res.encode())\\r\\nHTTPServer(('localhost', 8888), Handler).serve_forever()\",\"language\":\"python lazy-code\"}},{\"type\":\"paragraph\",\"data\":{\"text\":\"Однако атакующий обращается к серверу и получает ключ secret, который хранится, казалось бы, в приватном репозитории:\"}},{\"type\":\"code\",\"data\":{\"code\":\"curl -g 'http:\u002F\u002Flocalhost:8888\u002FXXX{site.do_GET.__globals__[secret]}\",\"language\":\"python lazy-code\"}},{\"type\":\"paragraph\",\"data\":{\"text\":\"Это происходит из-за того, что self.path контролируется конечным пользователем.\"}},{\"id\":\"cb4e4f62-3c4e-4252-96a7-2e367e0016fe\",\"type\":\"banner-blank\",\"data\":{}},{\"type\":\"paragraph\",\"data\":{\"text\":\"Для решения проблемы подойдут f-строки. Они безопасны и работают быстрее, да и код выглядит куда опрятнее:\"}},{\"type\":\"code\",\"data\":{\"code\":\"res = f\\\"\u003Ctitle\u003E{self.path}\\\\n{self.msg}\\\"\",\"language\":\"python lazy-code\"}},{\"type\":\"paragraph\",\"data\":{\"text\":\"Не всегда удается избежать спецсимволов в пользовательских данных. Для таких ситуаций придумали библиотеку bleach. Она может удалять нежелательные или потенциально вредоносные теги и атрибуты:\"}},{\"type\":\"code\",\"data\":{\"code\":\"import bleach\\r\\n\\r\\nuser_input = \\\"\u003Cscript\u003Ealert('XSS attack');\u003C\u002Fscript\u003E\\\"\\r\\ncleaned_input = bleach.clean(user_input)\\r\\nprint(cleaned_input)\",\"language\":\"python lazy-code\"}},{\"type\":\"header2\",\"data\":{\"level\":2,\"text\":\"Управляйте сессиями\"}},{\"type\":\"paragraph\",\"data\":{\"text\":\"Во время сессии всем событиям, помимо прочих метаданных, присваевается и идентификатор. Это позволяет сохранять данные между запросами, которые растянуты по времени.\"}},{\"type\":\"paragraph\",\"data\":{\"text\":\"Но злоумышленники могут угнать и перехватить cookies. Чтобы этого не произошло::\"}},{\"type\":\"list\",\"data\":{\"items\":[\"Установите флаги Secure и HttpOnly. Первый передает только через HTTPS, второй запрещает доступ через JavaScript, что не дает внедрить скрипты\"],\"style\":\"ordered\"}},{\"type\":\"code\",\"data\":{\"code\":\"from flask import session, Flask\\r\\napp = Flask(__name__)\\r\\napp.config.update(\\r\\n    SESSION_COOKIE_SECURE=True,\\r\\n    SESSION_COOKIE_HTTPONLY=True,\\r\\n    SESSION_COOKIE_SAMESITE='Lax',\\r\\n)\",\"language\":\"python lazy-code\"}},{\"type\":\"list\",\"data\":{\"items\":[\"Регенерируйте идентификатор сессии при каждом входе и выходе пользователя из системы:\"],\"style\":\"ordered\"}},{\"type\":\"code\",\"data\":{\"code\":\"@app.route('\u002Flogin', methods=['POST'])\\r\\ndef login():\\r\\n    # Проверка учетных данных\\r\\n    # ...\\r\\n    # Регенерация ID\\r\\n    session.regenerate()\\r\\n    return \\\"Успешный вход в систему!\",\"language\":\"python lazy-code\"}},{\"type\":\"list\",\"data\":{\"items\":[\"Устанавливайте тайм-аут сессии:\"],\"style\":\"ordered\"}},{\"type\":\"code\",\"data\":{\"code\":\"app.permanent_session_lifetime = timedelta(minutes=15)\",\"language\":\"python lazy-code\"}},{\"type\":\"header2\",\"data\":{\"level\":2,\"text\":\"Используйте виртуальное окружение\"}},{\"type\":\"paragraph\",\"data\":{\"text\":\"Виртуальное окружение (virtual environment) — надстройка, которая обеспечивает две вещи.\"}},{\"type\":\"list\",\"data\":{\"items\":[\"Изоляцию зависимостей. У каждого окружения будет собственный набор библиотек, изолированный от системного языкового пакета. Это гарантирует, что уязвимости в последних не навредят проекту.\",\"Контроль версий. Виртуальное окружение позволит зафиксировать разновидность используемых библиотек с помощью requirements.txt или другого файла конфигурации. Код, скопированный из многолетнего треда на StackOverflow, часто выдает ошибку именно из-за этого. Если вы работаете с несколькими проектами, требующими разных версий одной и той же библиотеки, virtualenv поможет их «развести по углам».\"],\"style\":\"unordered\"}},{\"type\":\"paragraph\",\"data\":{\"text\":\"Чтобы создать виртуальное окружение, используйте библиотеку virtualenv и команду:\"}},{\"type\":\"code\",\"data\":{\"code\":\"python\u003Cверсия\u003E -m venv \u003Cназвание виртуального окружения\u003E\",\"language\":\"bash lazy-code\"}},{\"type\":\"paragraph\",\"data\":{\"text\":\"Чтобы освоить установку утилиты, вход в среду и другие полезные команды, обратитесь к \u003Ca href=\\\"https:\u002F\u002Fwww.freecodecamp.org\u002Fnews\u002Fhow-to-setup-virtual-environments-in-python\u002F\\\"\u003Eанглоязычной статье на freecodecamp.org\u003C\u002Fa\u003E.\"}},{\"type\":\"header2\",\"data\":{\"level\":2,\"text\":\"Скачивайте только проверенные модули\"}},{\"type\":\"paragraph\",\"data\":{\"text\":\"Сообщество Python отлично справляется с написанием модулей под разные задачи: от генерации игрушечных данных до внедрения GPT на сайт. В 99% случаев найти готовое решение на PyPi + GitHub вы сможете.\"}},{\"type\":\"paragraph\",\"data\":{\"text\":\"Но если речь заходит о других источниках, рекомендую попробовать такое скачивание в изолированной среде. Для этого подойдет дешевый покупной сервер.\"}},{\"type\":\"header2\",\"data\":{\"level\":2,\"text\":\"Заключение\"}},{\"type\":\"paragraph\",\"data\":{\"text\":\"Техник защиты кода существует еще немало, я перечислила основные, которые встречаются в моей работе при создании ботов и дата-аналитике. Как только вы почувствуете свободу в написании кода, сразу же используйте накопленный предшественниками опыт, чтобы проект реализовался с меньшим количеством проблем.\"}},{\"type\":\"paragraph\",\"data\":{\"text\":\"Какие еще техники защиты кода вы используете? Поделитесь в комментариях\"}}]}",comments:g,reactions:[{count:g,key:"angry",order:c,is_selected:b},{count:g,key:"surprised",order:D,is_selected:b},{count:g,key:"thinking",order:I,is_selected:b},{count:g,key:"laugh",order:Y,is_selected:b},{count:D,key:"like",order:Z,is_selected:b}],user:{id:_,wp:V,name:"Елена Капаца",photo:{original:"https:\u002F\u002Flh3.googleusercontent.com\u002Fa-\u002FACB-R5Q1s2fkLfoZw6ktV49kpDskWCJ-8b3PjS5qlKBbJEwYkJp1aXX5ogGIKDXufJGuwq1iwYSSOzrU2JKrGUS0hjzPKPb14SU5zUDSlUdnEvIIPlBg59rd06gyg7O1cVK4TdJEfsQFUvgnOYM99Wm_ZU2BM5kLeCjc3iscb65XN6uD0p0kLixUXWvtorPh9K82dW_SSMhCctcA9-ygmKeVCrkI_DHjKKFKQIigIx1QLiTGd8KPPuc4ZcDlC-sZmXKwXDob1br8Hy6FoiZQj_4Afxe3bytmugrZvI4zYxx1Gq-dHqY43cSGS05JqysekFN-qxDtkhxi0in6KAnebJ_X2aKNiBR4aPYHhRXqaPjhi9yhgJGYZhkSLlvN-YUfOdw5kpNVss7FRATz7kayuyB0SP2yZNWOH4bYlz7xIjGsMmp141VfkVUplfqTK2h_UPH7oWfhcGEzEJT6nM3X65gCL2POHH5c-utSddQdoqc3IkBvksAjY4i3kGgjYLmE_HQcpUUs26Rcg8f6uoaCvkUEnuAdMAjU7-Zg-rKg07knvuTJNGOionxJqOy9WfsY-NIAcmsYrYucNxQ5DLUIYZxz3WX6Z9w6BsyX-4-JQrsyw_6VjM-Ilw9rAftOauvbyEM8S2ojCSsfjw9cyPUrcUXtRRWDLln_ahq-EMW9nw4Wtgq5C0EPlJuC7Zvo9lwiSVyIzwgCIVKxqlX45t8YPfThDZmLgMmoMDlBOrue6gH0PPuv1zBCbv4w9JQAFplDXDODujOLdPwT9QA1AWIW54GmVKtfZ9GeGfK8T1Ex16XfBtxjycpRERFmKC6ZYEyJxDjrQb0yyiRARqAVmcmBmvl98RqEF4mInsrUBzVI1xIdwkRRxYsr5CWocjMDiMqhFvJdU18dUaXUbWylGNq5MvKmmDbBXGCWgaJeBC1nCYN3vHQUbnULlDN19ughD36N=s96-c",alt:"Аватарка пользователя Елена Капаца",dimensions:{width:J,height:J},additionalSizes:{srcSet:[{url:"https:\u002F\u002Ftproger.ru\u002Fsigned_image\u002FHBfJiQ_ObvbGgoNi1m_XoA_U8OpwkIt8eHHwQ7PehRg\u002Frs:fill:40:40:true\u002Fcb:vimg_1\u002Ff:webp\u002FaHR0cHM6Ly9saDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL2EtL0FDQi1SNVExczJma0xmb1p3Nmt0VjQ5a3BEc2tXQ0otOGIzUGpTNXFsS0JiSkV3WWtKcDFhWFg1b2dHSUtEWHVmSkd1d3ExaXdZU1NPenJVMkpLckdVUzBoanpQS1BiMTRTVTV6VURTbFVkbkV2SUlQbEJnNTlyZDA2Z3lnN08xY1ZLNFRkSkVmc1FGVXZnbk9ZTTk5V21fWlUyQk01a0xlQ2pjM2lzY2I2NVhONnVEMHAwa0xpeFVYV3Z0b3JQaDlLODJkV19TU01oQ2N0Y0E5LXlnbUtlVkNya0lfREhqS0tGS1FJaWdJeDFRTGlUR2Q4S1BQdWM0WmNEbEMtc1ptWEt3WERvYjFicjhIeTZGb2laUWpfNEFmeGUzYnl0bXVnclp2STR6WXh4MUdxLWRIcVk0M2NTR1MwNUpxeXNla0ZOLXF4RHRraHhpMGluNktBbmViSl9YMmFLTmlCUjRhUFlIaFJYcWFQamhpOXloZ0pHWVpoa1NMbHZOLVlVZk9kdzVrcE5Wc3M3RlJBVHo3a2F5dXlCMFNQMnlaTldPSDRiWWx6N3hJakdzTW1wMTQxVmZrVlVwbGZxVEsyaF9VUEg3b1dmaGNHRXpFSlQ2bk0zWDY1Z0NMMlBPSEg1Yy11dFNkZFFkb3FjM0lrQnZrc0FqWTRpM2tHZ2pZTG1FX0hRY3BVVXMyNlJjZzhmNnVvYUN2a1VFbnVBZE1BalU3LVpnLXJLZzA3a252dVRKTkdPaW9ueEpxT3k5V2ZzWS1OSUFjbXNZcll1Y054UTVETFVJWVp4ejNXWDZaOXc2QnN5WC00LUpRcnN5d182VmpNLUlsdzlyQWZ0T2F1dmJ5RU04UzJvakNTc2ZqdzljeVBVcmNVWHRSUldETGxuX2FocS1FTVc5bnc0V3RncTVDMEVQbEp1Qzdadm85bHdpU1Z5SXp3Z0NJVkt4cWxYNDV0OFlQZlRoRFptTGdNbW9NRGxCT3J1ZTZnSDBQUHV2MXpCQ2J2NHc5SlFBRnBsRFhET0R1ak9MZFB3VDlRQTFBV0lXNTRHbVZLdGZaOUdlR2ZLOFQxRXgxNlhmQnR4anljcFJFUkZtS0M2WllFeUp4RGpyUWIweXlpUkFScUFWbWNtQm12bDk4UnFFRjRtSW5zclVCelZJMXhJZHdrUlJ4WXNyNUNXb2NqTURpTXFoRnZKZFUxOGRVYVhVYld5bEdOcTVNdkttbURiQlhHQ1dnYUplQkMxbkNZTjN2SFFVYm5VTGxETjE5dWdoRDM2Tj1zOTYtYw=",dpr:c,width:J},{url:"https:\u002F\u002Ftproger.ru\u002Fsigned_image\u002FaiXHaugr0zdeJz5PPkua1v7Leu9dWoADQE38DTBq_p8\u002Frs:fill:80:80:true\u002Fcb:vimg_1\u002Ff:webp\u002FaHR0cHM6Ly9saDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL2EtL0FDQi1SNVExczJma0xmb1p3Nmt0VjQ5a3BEc2tXQ0otOGIzUGpTNXFsS0JiSkV3WWtKcDFhWFg1b2dHSUtEWHVmSkd1d3ExaXdZU1NPenJVMkpLckdVUzBoanpQS1BiMTRTVTV6VURTbFVkbkV2SUlQbEJnNTlyZDA2Z3lnN08xY1ZLNFRkSkVmc1FGVXZnbk9ZTTk5V21fWlUyQk01a0xlQ2pjM2lzY2I2NVhONnVEMHAwa0xpeFVYV3Z0b3JQaDlLODJkV19TU01oQ2N0Y0E5LXlnbUtlVkNya0lfREhqS0tGS1FJaWdJeDFRTGlUR2Q4S1BQdWM0WmNEbEMtc1ptWEt3WERvYjFicjhIeTZGb2laUWpfNEFmeGUzYnl0bXVnclp2STR6WXh4MUdxLWRIcVk0M2NTR1MwNUpxeXNla0ZOLXF4RHRraHhpMGluNktBbmViSl9YMmFLTmlCUjRhUFlIaFJYcWFQamhpOXloZ0pHWVpoa1NMbHZOLVlVZk9kdzVrcE5Wc3M3RlJBVHo3a2F5dXlCMFNQMnlaTldPSDRiWWx6N3hJakdzTW1wMTQxVmZrVlVwbGZxVEsyaF9VUEg3b1dmaGNHRXpFSlQ2bk0zWDY1Z0NMMlBPSEg1Yy11dFNkZFFkb3FjM0lrQnZrc0FqWTRpM2tHZ2pZTG1FX0hRY3BVVXMyNlJjZzhmNnVvYUN2a1VFbnVBZE1BalU3LVpnLXJLZzA3a252dVRKTkdPaW9ueEpxT3k5V2ZzWS1OSUFjbXNZcll1Y054UTVETFVJWVp4ejNXWDZaOXc2QnN5WC00LUpRcnN5d182VmpNLUlsdzlyQWZ0T2F1dmJ5RU04UzJvakNTc2ZqdzljeVBVcmNVWHRSUldETGxuX2FocS1FTVc5bnc0V3RncTVDMEVQbEp1Qzdadm85bHdpU1Z5SXp3Z0NJVkt4cWxYNDV0OFlQZlRoRFptTGdNbW9NRGxCT3J1ZTZnSDBQUHV2MXpCQ2J2NHc5SlFBRnBsRFhET0R1ak9MZFB3VDlRQTFBV0lXNTRHbVZLdGZaOUdlR2ZLOFQxRXgxNlhmQnR4anljcFJFUkZtS0M2WllFeUp4RGpyUWIweXlpUkFScUFWbWNtQm12bDk4UnFFRjRtSW5zclVCelZJMXhJZHdrUlJ4WXNyNUNXb2NqTURpTXFoRnZKZFUxOGRVYVhVYld5bEdOcTVNdkttbURiQlhHQ1dnYUplQkMxbkNZTjN2SFFVYm5VTGxETjE5dWdoRDM2Tj1zOTYtYw=",dpr:c,width:80}],sizes:[{media:i,size:"40px"}]}},link:"\u002Fauthor\u002F79101",countPosts:42,countSubscribers:12,isSubscribed:b},isPin:b,publishDate:1694285803,tags:[{id:85,slug:"security",name:"Безопасность",isSubscribe:b},{id:K,slug:"python",name:"Python",isSubscribe:b},{id:227,slug:"html",name:L,isSubscribe:b}],meta:{disableAds:b},seo:{title:U,description:X},sandbox:a,thumbnail:{original:"https:\u002F\u002Fmedia.tproger.ru\u002Fuploads\u002F2023\u002F09\u002F1f0e48a0-f226-4ec6-862c-45deac001779-autoconverted.jpeg",alt:"Обложка поста kak-zashhitit-svoj-python-kod",dimensions:{width:M,height:g},additionalSizes:{srcSet:[{url:$,dpr:c,width:M},{url:"https:\u002F\u002Ftproger.ru\u002Fsigned_image\u002FTY8qh3tcl5K5rC4u0dEpPboBA9cwKT7pwVvco1rbxRs\u002Frs:fill:1500:0:true\u002Fcb:vimg_1\u002Fq:100\u002Ff:webp\u002FaHR0cHM6Ly9tZWRpYS50cHJvZ2VyLnJ1L3VwbG9hZHMvMjAyMy8wOS8xZjBlNDhhMC1mMjI2LTRlYzYtODYyYy00NWRlYWMwMDE3NzktYXV0b2NvbnZlcnRlZC5qcGVn",dpr:c,width:1500},{url:"https:\u002F\u002Ftproger.ru\u002Fsigned_image\u002F2ONEtWR_CUwk2BLvRiSsBDZnC2ZHZWbBMrArALcNLJU\u002Frs:fill:840:0:true\u002Fcb:vimg_1\u002Fq:100\u002Ff:webp\u002FaHR0cHM6Ly9tZWRpYS50cHJvZ2VyLnJ1L3VwbG9hZHMvMjAyMy8wOS8xZjBlNDhhMC1mMjI2LTRlYzYtODYyYy00NWRlYWMwMDE3NzktYXV0b2NvbnZlcnRlZC5qcGVn",dpr:c,width:840},{url:"https:\u002F\u002Ftproger.ru\u002Fsigned_image\u002FFdGbVeONqUHmdH7MMxhyp5hsEfEM95_dpctVG4ViqtM\u002Frs:fill:1680:0:true\u002Fcb:vimg_1\u002Fq:100\u002Ff:webp\u002FaHR0cHM6Ly9tZWRpYS50cHJvZ2VyLnJ1L3VwbG9hZHMvMjAyMy8wOS8xZjBlNDhhMC1mMjI2LTRlYzYtODYyYy00NWRlYWMwMDE3NzktYXV0b2NvbnZlcnRlZC5qcGVn",dpr:c,width:1680},{url:"https:\u002F\u002Ftproger.ru\u002Fsigned_image\u002Fo17Vmg0ZDwmGZRT47hfa20kqdROQXUcO0xA2iqpCFsE\u002Frs:fill:910:0:true\u002Fcb:vimg_1\u002Fq:100\u002Ff:webp\u002FaHR0cHM6Ly9tZWRpYS50cHJvZ2VyLnJ1L3VwbG9hZHMvMjAyMy8wOS8xZjBlNDhhMC1mMjI2LTRlYzYtODYyYy00NWRlYWMwMDE3NzktYXV0b2NvbnZlcnRlZC5qcGVn",dpr:c,width:910},{url:"https:\u002F\u002Ftproger.ru\u002Fsigned_image\u002FFjhZ9UuotGySCSffu7W6j3W5nC94tdsUIJ_O-VeW5Do\u002Frs:fill:1820:0:true\u002Fcb:vimg_1\u002Fq:100\u002Ff:webp\u002FaHR0cHM6Ly9tZWRpYS50cHJvZ2VyLnJ1L3VwbG9hZHMvMjAyMy8wOS8xZjBlNDhhMC1mMjI2LTRlYzYtODYyYy00NWRlYWMwMDE3NzktYXV0b2NvbnZlcnRlZC5qcGVn",dpr:c,width:1820},{url:"https:\u002F\u002Ftproger.ru\u002Fsigned_image\u002FGD7lbgYGCoiaVz04wt20m1uLHTIsBfBMah0Aqghs418\u002Frs:fill:718:0:true\u002Fcb:vimg_1\u002Fq:100\u002Ff:webp\u002FaHR0cHM6Ly9tZWRpYS50cHJvZ2VyLnJ1L3VwbG9hZHMvMjAyMy8wOS8xZjBlNDhhMC1mMjI2LTRlYzYtODYyYy00NWRlYWMwMDE3NzktYXV0b2NvbnZlcnRlZC5qcGVn",dpr:c,width:718},{url:"https:\u002F\u002Ftproger.ru\u002Fsigned_image\u002FgO6aGsGchCUqPRU3zbEt-yMIYvpf7WpXenji2ofSLWI\u002Frs:fill:1436:0:true\u002Fcb:vimg_1\u002Fq:100\u002Ff:webp\u002FaHR0cHM6Ly9tZWRpYS50cHJvZ2VyLnJ1L3VwbG9hZHMvMjAyMy8wOS8xZjBlNDhhMC1mMjI2LTRlYzYtODYyYy00NWRlYWMwMDE3NzktYXV0b2NvbnZlcnRlZC5qcGVn",dpr:c,width:1436},{url:"https:\u002F\u002Ftproger.ru\u002Fsigned_image\u002FFPWAL3aHT7i_MQgnNxIBRYgnMBLASWdGB8kCjiZmNjM\u002Frs:fill:375:0:true\u002Fcb:vimg_1\u002Fq:100\u002Ff:webp\u002FaHR0cHM6Ly9tZWRpYS50cHJvZ2VyLnJ1L3VwbG9hZHMvMjAyMy8wOS8xZjBlNDhhMC1mMjI2LTRlYzYtODYyYy00NWRlYWMwMDE3NzktYXV0b2NvbnZlcnRlZC5qcGVn",dpr:c,width:375},{url:$,dpr:c,width:M},{url:"https:\u002F\u002Ftproger.ru\u002Fsigned_image\u002FkiQ057gjbJbibhNZHffKWixcX1Za5BpSP6kigyvHHNs\u002Frs:fill:325:0:true\u002Fcb:vimg_1\u002Fq:100\u002Ff:webp\u002FaHR0cHM6Ly9tZWRpYS50cHJvZ2VyLnJ1L3VwbG9hZHMvMjAyMy8wOS8xZjBlNDhhMC1mMjI2LTRlYzYtODYyYy00NWRlYWMwMDE3NzktYXV0b2NvbnZlcnRlZC5qcGVn",dpr:c,width:325},{url:"https:\u002F\u002Ftproger.ru\u002Fsigned_image\u002FmOj4I2R41UM9ZjZiE6nHk8z0nylCB9CgIJPev4d2x7Y\u002Frs:fill:650:0:true\u002Fcb:vimg_1\u002Fq:100\u002Ff:webp\u002FaHR0cHM6Ly9tZWRpYS50cHJvZ2VyLnJ1L3VwbG9hZHMvMjAyMy8wOS8xZjBlNDhhMC1mMjI2LTRlYzYtODYyYy00NWRlYWMwMDE3NzktYXV0b2NvbnZlcnRlZC5qcGVn",dpr:c,width:650}],sizes:[{media:"(min-width: 1281px)",size:"750px"},{media:"(max-width: 1280px)",size:"840px"},{media:"(max-width: 960px)",size:"910px"},{media:"(max-width: 768px)",size:"718px"},{media:"(max-width: 425px)",size:"375px"},{media:"(max-width: 375px)",size:"325px"}]}}},"/v1/widgets/{\"lazy\":true,\"server\":false,\"method\":\"POST\",\"key\":\"[{\\\"position\\\":\\\"RightSidebar\\\",\\\"options\\\":{\\\"entityId\\\":\\\"post\\\",\\\"widgetOptions\\\":{\\\"recommended_posts\\\":{\\\"slug\\\":\\\"kak-zashhitit-svoj-python-kod\\\"}}}},{\\\"position\\\":\\\"PostFooter\\\",\\\"options\\\":{\\\"entityId\\\":\\\"post\\\",\\\"widgetOptions\\\":{\\\"recommended_posts\\\":{\\\"slug\\\":\\\"kak-zashhitit-svoj-python-kod\\\"}}}}]\",\"body\":{\"filters\":[{\"position\":\"RightSidebar\",\"options\":{\"entityId\":\"post\",\"widgetOptions\":{\"recommended_posts\":{\"slug\":\"kak-zashhitit-svoj-python-kod\"}}}},{\"position\":\"PostFooter\",\"options\":{\"entityId\":\"post\",\"widgetOptions\":{\"recommended_posts\":{\"slug\":\"kak-zashhitit-svoj-python-kod\"}}}}]}}":aa,"/v1/comments/post/245553{\"lazy\":true}":{postAuthor:_,count:g,comments:[]},"/v1/auth/company{\"key\":\"/v1/auth/company: \"}":a},state:{},_errors:{"/v1/options{\"method\":\"GET\",\"query\":{\"link\":\"L2FydGljbGVzL2thay16YXNoaGl0aXQtc3Zvai1weXRob24ta29k\"}}":a,"/v1/post/single/{\"method\":\"GET\",\"params\":{\"name\":\"kak-zashhitit-svoj-python-kod\",\"tag\":\"articles\"}}":a,"/v1/widgets/{\"lazy\":true,\"server\":false,\"method\":\"POST\",\"key\":\"[{\\\"position\\\":\\\"RightSidebar\\\",\\\"options\\\":{\\\"entityId\\\":\\\"post\\\",\\\"widgetOptions\\\":{\\\"recommended_posts\\\":{\\\"slug\\\":\\\"kak-zashhitit-svoj-python-kod\\\"}}}},{\\\"position\\\":\\\"PostFooter\\\",\\\"options\\\":{\\\"entityId\\\":\\\"post\\\",\\\"widgetOptions\\\":{\\\"recommended_posts\\\":{\\\"slug\\\":\\\"kak-zashhitit-svoj-python-kod\\\"}}}}]\",\"body\":{\"filters\":[{\"position\":\"RightSidebar\",\"options\":{\"entityId\":\"post\",\"widgetOptions\":{\"recommended_posts\":{\"slug\":\"kak-zashhitit-svoj-python-kod\"}}}},{\"position\":\"PostFooter\",\"options\":{\"entityId\":\"post\",\"widgetOptions\":{\"recommended_posts\":{\"slug\":\"kak-zashhitit-svoj-python-kod\"}}}}]}}":a,"/v1/comments/post/245553{\"lazy\":true}":a,"/v1/auth/company{\"key\":\"/v1/auth/company: \"}":{message:"[GET] \"https:\u002F\u002Ftproger.ru\u002Fwp-node\u002Fv1\u002Fauth\u002Fcompany\": 401 Unauthorized",statusCode:401,statusMessage:"Unauthorized",data:{status:b,message:"E_UNAUTHORIZED: You are not authorized"}}},serverRendered:d,path:"\u002Farticles\u002Fkak-zashhitit-svoj-python-kod",pinia:{user:{auth:b,user:a,company:a,token:H,authModelOpen:b,authCallbacks:[],settingsMode:b,authPlace:"other"},options:{isShowAd:d,availableListokPositions:T},notifications:{notifications:[]},modals:{isShowModalBugReport:b},subscriptions:{loaded:b,subscriptions:[],subscriptionsView:[],countSubscriptions:a,page:c,perPage:18,isFirst:d,isCropped:b},posts:{feeds:{},posts:{},postsPortions:{},isLoadPortion:{},isMainLoading:{},isError:{},feedRequestInfo:{}},widgets:{widgets:aa,widgetsOptions:{RightSidebar:{entityId:S,widgetOptions:{recommended_posts:{slug:aX}}},PostFooter:{entityId:S,widgetOptions:{recommended_posts:{slug:aX}}}},firstLoaded:d,resolver:a,entityId:S,subEntityId:a,entityIdIsChanged:b,subEntityIdIsChanged:b,loadingProgress:b}},config:{public:{IS_PROD:d,SENTRY_CLIENT_DNS:"https:\u002F\u002F5878ab4ef73649a6a0584650f853dad0@o413944.ingest.sentry.io\u002F4504649713385472",ENV:H,API_BACKEND_BASE_URL:aY,API_FRONT_BASE_URL:aY,API_QUIZ_BASE_URL:"https:\u002F\u002Ftproger.ru\u002Ftp-quiz\u002Fapi\u002F",AUTH_TELEGRAM_CALLBACK:H,SOCIAL_VK_MAIN:"https:\u002F\u002Fvk.com\u002Ftproger",SOCIAL_VK_WEB:"https:\u002F\u002Fvk.com\u002Ftproger_web",SOCIAL_VK_TNULL:"https:\u002F\u002Fvk.com\u002Ftnull",SOCIAL_ZEN_MAIN:"https:\u002F\u002Fzen.yandex.ru\u002Ftproger",SOCIAL_TWITTER_MAIN:"https:\u002F\u002Ftwitter.com\u002Ftproger",SOCIAL_TELEGRAM_MAIN:"https:\u002F\u002Ft.me\u002F+ANGj_G5y1AE3YjFi",ANALYTIC_SEND:d,ANALYTIC_DEBUG:b,WIDGET_TELEGRAM_MAIN:"https:\u002F\u002Ft.me\u002F+LpLVNzPUnmNkMmZi",SHORTCODE_URL:"https:\u002F\u002Ftproger.ru\u002Fiframe-loader\u002F",siteUrl:"https:\u002F\u002Ftproger.ru",ANALYTICS_ENABLE:b,SPECIALS_STATIC_URL:"https:\u002F\u002Fspecials.tproger.ru",device:{enabled:d,defaultUserAgent:"Mozilla\u002F5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit\u002F537.36 (KHTML, like Gecko) Chrome\u002F64.0.3282.39 Safari\u002F537.36",refreshOnResize:b},vk:{cdnURL:"https:\u002F\u002Fproxy.tproger.ru\u002Fvk-openapi.js",id:"VK-RTRG-271723-bcLdk"},ym:{noscript:d,cdnURL:"https:\u002F\u002Fproxy.tproger.ru\u002Fyandex-metrika.js",initParams:{defer:d,clickmap:d,trackLinks:d,accurateTrackBounce:d,webvisor:b,ecommerce:d},id:"27485085"}},app:{baseURL:"\u002F",buildAssetsDir:"\u002F_nuxt\u002F",cdnURL:H}}}}(null,false,1,true,48,30,0,"RUB","(min-width: 0px)","2023-09-05T00:00:00.000+03:00","2023-10-05T00:00:00.000+03:00","FREE","ONLINE",240737,"Result School","\u002Fcompany\u002Fresult-school","https:\u002F\u002Fmedia.tproger.ru\u002Fuploads\u002F2023\u002F05\u002F9530afe0-ad8e-49df-ac17-d827a82599c3.png","Логотип компании Result School","https:\u002F\u002Ftproger.ru\u002Fsigned_image\u002FH_tEKm9zVWLX5z4yeVJfWOuWENl-XI3VbM43P7TQKAw\u002Frs:fill:48:48:true\u002Fcb:vimg_1\u002Ff:webp\u002FaHR0cHM6Ly9tZWRpYS50cHJvZ2VyLnJ1L3VwbG9hZHMvMjAyMy8wNS85NTMwYWZlMC1hZDhlLTQ5ZGYtYWMxNy1kODI3YTgyNTk5YzMucG5n","https:\u002F\u002Ftproger.ru\u002Fsigned_image\u002Fh989f4kTcGC_3q3D9p-bpft6fXWGaXQtjyLaB7__Ao0\u002Frs:fill:96:96:true\u002Fcb:vimg_1\u002Ff:webp\u002FaHR0cHM6Ly9tZWRpYS50cHJvZ2VyLnJ1L3VwbG9hZHMvMjAyMy8wNS85NTMwYWZlMC1hZDhlLTQ5ZGYtYWMxNy1kODI3YTgyNTk5YzMucG5n",96,"48px","Российский рубль","₽",6,"RightSidebar","NEWBIES",60,"30px",2,"Приступить к обучению",992,"Фронтенд","",3,40,107,"HTML",750,"https:\u002F\u002Fmedia.tproger.ru\u002Fuploads\u002F2023\u002F04\u002Favatar.jpg","Логотип компании АО «Гринатом»","https:\u002F\u002Ftproger.ru\u002Fsigned_image\u002FpR3bNBj0vbkxZpI7Nu5AKkicuA0EOzIqYei90wnPVE4\u002Frs:fill:30:30:true\u002Fcb:vimg_1\u002Ff:webp\u002FaHR0cHM6Ly9tZWRpYS50cHJvZ2VyLnJ1L3VwbG9hZHMvMjAyMy8wNC9hdmF0YXIuanBn","https:\u002F\u002Ftproger.ru\u002Fsigned_image\u002F57rk8xr-AxGbLrRq56MRz9Tjevr8TJrFnzQub1189_A\u002Frs:fill:60:60:true\u002Fcb:vimg_1\u002Ff:webp\u002FaHR0cHM6Ly9tZWRpYS50cHJvZ2VyLnJ1L3VwbG9hZHMvMjAyMy8wNC9hdmF0YXIuanBn","PostFooter","post",Array(3),"Как защитить свой Python-код",64052,"#","Описали четыре техники увеличения безопасности кода и подобрали примеры к каждой из них. В статье вы познакомитесь не только с универсальными приемами, но и специфическими – для серверов и ботов.",4,5,79101,"https:\u002F\u002Ftproger.ru\u002Fsigned_image\u002FYv8ufz0GD121SiktDQi6JqKq0vQbzRxE6yrfXh5iScQ\u002Frs:fill:750:0:true\u002Fcb:vimg_1\u002Fq:100\u002Ff:webp\u002FaHR0cHM6Ly9tZWRpYS50cHJvZ2VyLnJ1L3VwbG9hZHMvMjAyMy8wOS8xZjBlNDhhMC1mMjI2LTRlYzYtODYyYy00NWRlYWMwMDE3NzktYXV0b2NvbnZlcnRlZC5qcGVn",{},"events","courses_v2",494,"MEDIUM",7590,"https:\u002F\u002Fresult.school\u002Fproducts\u002Fgit?utm_source=tproger&utm_medium=partners&utm_campaign=cpa&utm_content=git","Купить курс",84,"251930","Курс «Продвинутый GIT»","За 14 дней вы научитесь вести разработку через Git самостоятельно и сможете работать в команде, используя лучшие практики крупных компаний.","kurs-prodvinutyj-git-ljn8kaaru",1003,"Веб-разработка",1056,"Git","\u002Fcourses\u002Fkurs-prodvinutyj-git-ljn8kaaru",448,"https:\u002F\u002Flk.result.school\u002Fstart-in-it?utm_source=tproger&utm_medium=partners&utm_campaign=cpa&utm_content=start_it","261686","Воркшоп для начинающих «Перспективы в IT»","Изучите рынок IT, создайте первый проект и освойте базу, которая поможет вам сменить сферу работы и устроиться в IT.","vorkshop-dlja-nachinajushhih-perspektivy-v-it-ljn8k2hxu","\u002Fcourses\u002Fvorkshop-dlja-nachinajushhih-perspektivy-v-it-ljn8k2hxu",447,"https:\u002F\u002Fresult.school\u002Fproducts\u002Fhtml-css?utm_source=tproger&utm_medium=partners&utm_campaign=cpa&utm_content=html_css",191,"242473","«Бесплатный модуль курса-профессии» HTML&CSS","Во время всего модуля вы работаете над полноценный проектом — сайтом-резюме, на котором будет информация о вас.","besplatnyj-modul-kursa-professii-html-css-ljn8jybg2",1046,1047,"CSS","\u002Fcourses\u002Fbesplatnyj-modul-kursa-professii-html-css-ljn8jybg2",446,2790,"TPROGER60","https:\u002F\u002Fresult.school\u002Fproducts\u002Fbase-programming?utm_source=tproger&utm_medium=partners&utm_campaign=cpa&utm_content=base_programming","Начать за 2790 ₽ ",135,"242567","Основы программирования","Освойте базу за 7 дней и подготовьтесь к следующему шагу в получении IT-профессии под руководством опытного разработчика.","osnovy-programmirovanija-ljn8jtdy8",656,"Бэкенд","\u002Fcourses\u002Fosnovy-programmirovanija-ljn8jtdy8","kak-zashhitit-svoj-python-kod","https:\u002F\u002Ftproger.ru\u002Fwp-node"))</script>
<script src="https://proxy.tproger.ru/vk-openapi.js" defer></script>
<script type="application/ld+json" id="schema-org-graph" data-hid="3437552">{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@id": "https://tproger.ru/#website",
      "@type": "WebSite",
      "name": "Tproger",
      "url": "https://tproger.ru",
      "publisher": {
        "@id": "https://tproger.ru/#identity"
      }
    },
    {
      "@id": "https://tproger.ru/#identity",
      "@type": "Organization",
      "email": "sales@tproger.ru",
      "name": "Tproger",
      "telephone": "+7 916 559-71-10",
      "url": "https://tproger.ru",
      "address": {
        "@type": "PostalAddress",
        "postalCode": "129085",
        "addressCountry": "RU",
        "addressLocality": "Москва",
        "streetAddress": "Москва, Деловой Центр «Калибр»"
      },
      "image": {
        "@id": "https://tproger.ru/#/schema/image/0dc3723"
      },
      "logo": {
        "@id": "https://tproger.ru/#logo"
      }
    },
    {
      "@id": "https://tproger.ru/articles/kak-zashhitit-svoj-python-kod/#article",
      "@type": "Article",
      "description": "Описали четыре техники увеличения безопасности кода и подобрали примеры к каждой из них. В статье вы познакомитесь не только с универсальными приемами, но и специфическими – для серверов и ботов.",
      "headline": "Как защитить свой Python-код",
      "author": {
        "@id": "https://tproger.ru/#identity"
      },
      "publisher": {
        "@id": "https://tproger.ru/#identity"
      }
    },
    {
      "@id": "https://tproger.ru/articles/kak-zashhitit-svoj-python-kod/#breadcrumb",
      "@type": "BreadcrumbList",
      "itemListElement": [
        {
          "@type": "ListItem",
          "name": "Главная",
          "item": "https://tproger.ru",
          "position": 1
        },
        {
          "@type": "ListItem",
          "name": "Статьи",
          "item": "https://tproger.ru/articles",
          "position": 2
        },
        {
          "@type": "ListItem",
          "name": "Как защитить свой Python-код",
          "position": 3
        }
      ]
    },
    {
      "@id": "https://tproger.ru/#/schema/image/0dc3723",
      "@type": "ImageObject",
      "contentUrl": "https://cdn.tproger.ru/android-chrome-32x32.png",
      "url": "https://cdn.tproger.ru/android-chrome-32x32.png"
    },
    {
      "@id": "https://tproger.ru/#logo",
      "@type": "ImageObject",
      "caption": "Tproger",
      "contentUrl": "https://cdn.tproger.ru/android-chrome-32x32.png",
      "height": 32,
      "url": "https://cdn.tproger.ru/android-chrome-32x32.png",
      "width": 32
    }
  ]
}</script></body>
</html>