Удалить api key discord

Обновлено: 04.07.2024

API Errors Discord – это достаточно распространенная категория ошибок, возникающих во время авторизации в приложении мессенджера. И в основном они связаны со сбоем, произошедшем на стороне разработчиков и серверов. Как правило, вины пользователей в подобных неполадках нет, а появляться они могут по разным причинам. Например, из-за слишком большой нагрузки, технических работ и попросту случайного бага. Но, как показывает статистика, программисты Дискорда быстро принимают меры для устранения ошибок и возвращают сервису былую работоспособность. Однако предлагаем ознакомиться с основными проблемами и способами их решения.

API Errors в Discord – какие бывают и почему возникают?

По доступной в интернете информации становится понятно, что API Errors – это ошибки, которые возникают во время авторизации в приложении мессенджера. И, что самое интересное, столкнуться с ними можно как на компьютере, так и на мобильном устройстве.

На самом деле существует несколько категорий багов, но наиболее часто встречаются только две:




Произошла ошибка API – что делать?

И первым делом нужно отметить, что самостоятельно устранить API Errors в Discord практически невозможно – от вас они попросту не зависят.

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

  1. Пытаемся выполнить авторизацию в учетной записи посредством официального сайта, а не программы.
  2. Если ситуация не изменилась, то устанавливаем на смартфон мобильное приложение Discord. При его наличии и авторизации выполняем удаление программы, а затем повторную установку. Открываем приложение и входим в свой аккаунт.
  3. Если все работает, то авторизуемся и на компьютере. В противном случае, когда ничего не помогло, рекомендуем в настройках изменить сервер. Например, остановившись на наиболее ближайшем варианте.

Дискорд API Errors latency – что это? А под этим понимается очередная ошибка, связанная с авторизацией в приложении мессенджера. И ее уже никак не получится устранить самостоятельно – остается только ждать, пока разработчики примут меры. Если у вас не заходит в Дискорд, то API Errors latency наблюдается у многих пользователей.

Таким образом, мы рассмотрели основные Discord API Errors, встречающиеся в программе мессенджера. И, как правило, они связаны со сбоями на стороне разработчиков. Есть дополнительные вопросы по теме материала? Мы готовы на них ответить в комментариях!


Начали добавляться скамеры, полагаю, что для развода. Видимо API Key засветил где-то, как его удалить?

они ко всем добавляются у кого открыт профиль стима и инвентарь для всех

ну и кто там в доморощеных группах состоит в стиме

img

Видимо API Key засветил где-то, как его удалить?

удались из групп для трейда, скрой профиль и всё

Участник команды сайта

img

Просто скрой профиль от чужих


они ко всем добавляются у кого открыт профиль стима и инвентарь для всех

ну и кто там в доморощеных группах состоит в стиме

В группах я не состою. Но скамеры разные.
Если добавляется чел просто с 0 уровнем и не во что не играет, а потом пишет в лс по типу "Заходи на сайт y_menya_ymerla_mat.com и получай бонус 25$, которые ты можешь сразу вывести", то такие не несут никакой угрозы, ты просто удаляешь его и все.
А сейчас еще есть скамеры, которые имеют часы в доте, добавляются и пишут пасту по типу "Нам нужен мидер/кери/саппорт на турнир, наш уехал хоронить мать, не хочешь сыграть с нами?". А потом уже в Дискорде тебе вешают лапшу на уши, типо скинь свои шмотки, которые больше 1$ на твинк, там на турике нельзя и тд, ты кидаешь обмен на твинк, а они по API ключу моментально кидают трейд с таким же ником и аватаркой, а твой отклоняется. Помогает только удаление API ключа, но я не помню как это сделать.

У меня вот так буквально месяц назад знакомого развели.

удались из групп для трейда, скрой профиль и всё

Я не подписан на группы с трейдом

В группах я не состою. Но скамеры разные.
Если добавляется чел просто с 0 уровнем и не во что не играет, а потом пишет в лс по типу "Заходи на сайт y_menya_ymerla_mat.com и получай бонус 25$, которые ты можешь сразу вывести", то такие не несут никакой угрозы, ты просто удаляешь его и все.
А сейчас еще есть скамеры, которые имеют часы в доте, добавляются и пишут пасту по типу "Нам нужен мидер/кери/саппорт на турнир, наш уехал хоронить мать, не хочешь сыграть с нами?". А потом уже в Дискорде тебе вешают лапшу на уши, типо скинь свои шмотки по 1$ на твинк, там на турике нельзя и тд, ты кидаешь обмен на твинк, а они по API ключу моментально кидают трейд с таким же ником и аватаркой, а твой отклоняется. Помогает только удаление API ключа, но я не помню как это сделать.

Я не подписан на группы с трейдом

ну есть еще чувачки у которых 50+ френданов в стиме которых они знать не знают этих 50 чувачков кто то мог тоже заскамить а ты у них в друзьях и твой айди тоже в базу попадает и так в геометрической прогрессии она растет и вам срут этими инвайтами боты

  • Open with Desktop
  • View raw
  • Copy raw contents Copy raw contents Loading

Copy raw contents

Copy raw contents

danger Some API and Gateway versions are now non-functioning, and are labeled as discontinued in the table below for posterity. Trying to use these versions will fail and return 400 Bad Request.

Version Status Default
9 Available
8 Available
7 Doesn't look like anything to me
6 Deprecated
5 Discontinued
4 Discontinued
3 Discontinued

In API v8, we've improved error formatting in form error responses. The response will tell you which json key contains the error, the error code, and a human readable error message. We will be frequently adding new error messages, so a complete list of errors is not feasible and would be almost instantly out of date. Here are some examples instead:

Authenticating with the Discord API can be done in one of two ways:

  1. Using a bot token gained by registering a bot, for more information on bots see bots vs user accounts.
  2. Using an OAuth2 bearer token gained through the OAuth2 API.

Example Bot Token Authorization Header

Example Bearer Token Authorization Header

Snowflake ID Broken Down in Binary

Snowflake ID Format Structure (Left to Right)

Field Bits Number of bits Description Retrieval
Timestamp 63 to 22 42 bits Milliseconds since Discord Epoch, the first second of 2015 or 1420070400000. (snowflake >> 22) + 1420070400000
Internal worker ID 21 to 17 5 bits (snowflake & 0x3E0000) >> 17
Internal process ID 16 to 12 5 bits (snowflake & 0x1F000) >> 12
Increment 11 to 0 12 bits For every ID that is generated on that process, this number is incremented snowflake & 0xFFF

Convert Snowflake to DateTime

Graphical representation of how a Snowflake is constructed

Snowflake IDs in Pagination

We typically use snowflake IDs in many of our API routes for pagination. The standardized pagination paradigm we utilize is one in which you can specify IDs before and after in combination with limit to retrieve a desired page of results. You will want to refer to the specific endpoint documentation for details.

It is useful to note that snowflake IDs are just numbers with a timestamp, so when dealing with pagination where you want results from the beginning of time (in Discord Epoch, but 0 works here too) or before/after a specific time you can generate a snowflake ID for that time.

Generating a snowflake ID from a Timestamp Example

There are some cases in which our API and Gateway may return IDs in an unexpected format. Internally, Discord stores IDs as integer snowflakes. When we serialize IDs to JSON, we transform bigints into strings. Given that all Discord IDs are snowflakes, you should always expect a string.

However, there are cases in which passing something to our API will instead return IDs serialized as an integer; this is the case when you send our API or Gateway a value in an id field that is not bigint size. For example, when requesting GUILD_MEMBERS_CHUNK from our gateway:

You can see in this case that the sent user_id is not a bigint ; therefore, when it is serialized back to JSON by Discord, it is not transformed into a string. This will never happen with IDs that come from Discord. But, this can happen if you send malformed data in your requests.

Discord utilizes the ISO8601 format for most Date/Times returned in our models. This format is referred to as type ISO8601 within tables in this documentation.

Nullable and Optional Resource Fields

Resource fields that may contain a null value have types that are prefixed with a question mark. Resource fields that are optional have names that are suffixed with a question mark.

Example Nullable and Optional Fields

Field Type
optional_field? string
nullable_field ?string
optional_and_nullable_field? ?string

Discord operates at a scale where true consistency is impossible. Because of this, lots of operations in our API and in-between our services are eventually consistent. Due to this, client actions can never be serialized and may be executed in any order (if executed at all). Along with these constraints, events in Discord may:

  • Never be sent to a client
  • Be sent exactly one time to the client
  • Be sent up to N times per client

Clients should operate on events and results from the API in as much of an idempotent behavior as possible.

User Agent Example

Clients may append more information and metadata to the end of this string as they wish.

Boolean Query Strings

Certain endpoints in the API are documented to accept booleans for their query string parameters. While there is no standard system for boolean representation in query string parameters, Discord represents such cases using True , true , or 1 for true and False , false or 0 for false.

Gateway (WebSocket) API

Discord's Gateway API is used for maintaining persistent, stateful websocket connections between your client and our servers. These connections are used for sending and receiving real-time events your client can use to track and update local state. The Gateway API uses secure websocket connections as specified in RFC 6455. For information on opening Gateway connections, please see the Gateway API section.

Discord utilizes a subset of markdown for rendering message content on its clients, while also adding some custom functionality to enable things like mentioning users and channels. This functionality uses the following formats:

Using the markdown for either users, roles, or channels will usually mention the target(s) accordingly, but this can be suppressed using the allowed_mentions parameter when creating a message. Standard emoji are currently rendered using Twemoji for Desktop/Android and Apple's native emoji on iOS.

Timestamps will display the given timestamp in the user's timezone and locale.

Style Example Output Description
t 16:20 Short Time
T 16:20:30 Long Time
d 20/04/2021 Short Date
D 20 April 2021 Long Date
f * 20 April 2021 16:20 Short Date/Time
F Tuesday, 20 April 2021 16:20 Long Date/Time
R 2 months ago Relative Time

Discord uses ids and hashes to render images in the client. These hashes can be retrieved through various API requests, like Get User. Below are the formats, size limitations, and CDN endpoints for images in Discord. The returned format can be changed by changing the extension name at the end of the URL. The returned size can be changed by appending a querystring of ?size=desired_size to the URL. Image size can be any power of two between 16 and 4096.

Name Extension
JPEG .jpg, .jpg
PNG .jpg
WebP .webp
GIF .jpg
Lottie .json
Type Path Supports
Custom Emoji emojis/emoji_id.jpg PNG, JPEG, WebP, GIF
Guild Icon icons/guild_id/guild_icon.jpg * PNG, JPEG, WebP, GIF
Guild Splash splashes/guild_id/guild_splash.jpg PNG, JPEG, WebP
Guild Discovery Splash discovery-splashes/guild_id/guild_discovery_splash.jpg PNG, JPEG, WebP
Guild Banner banners/guild_id/guild_banner.jpg PNG, JPEG, WebP
User Banner banners/user_id/user_banner.jpg * PNG, JPEG, WebP, GIF
Default User Avatar embed/avatars/user_discriminator.jpg ** *** PNG
User Avatar avatars/user_id/user_avatar.jpg * PNG, JPEG, WebP, GIF
Guild Member Avatar guilds/guild_id/users/user_id/avatars/member_avatar.jpg * PNG, JPEG, WebP, GIF
Application Icon app-icons/application_id/icon.jpg PNG, JPEG, WebP
Application Cover app-icons/application_id/cover_image.jpg PNG, JPEG, WebP
Application Asset app-assets/application_id/asset_id.jpg PNG, JPEG, WebP
Achievement Icon app-assets/application_id/achievements/achievement_id/icons/icon_hash.jpg PNG, JPEG, WebP
Sticker Pack Banner app-assets/710982414301790216/store/sticker_pack_banner_asset_id.jpg PNG, JPEG, WebP
Team Icon team-icons/team_id/team_icon.jpg PNG, JPEG, WebP
Sticker stickers/sticker_id.jpg *** **** PNG, Lottie
Role Icon role-icons/role_id/role_icon.jpg * PNG, JPEG, WebP

* In the case of endpoints that support GIFs, the hash will begin with a_ if it is available in GIF format. (example: a_1269e74af4df7417b13759eae50c83dc )

*** In the case of the Default User Avatar and Sticker endpoints, the size of images returned is constant with the "size" querystring parameter being ignored.

**** In the case of the Sticker endpoint, the sticker will be available as PNG if its format_type is PNG or APNG , and as Lottie if its format_type is LOTTIE .

Image data is a Data URI scheme that supports JPG, GIF, and PNG formats. An example Data URI format is:

Ensure you use the proper content type ( image/jpeg , image/png , image/gif ) that matches the image data being provided.

Some endpoints support file attachments, indicated by the files[n] parameter. To add a file to the request, the standard application/json body must be replaced by a multipart/form-data body. The otherwise json body can instead be provided using a special payload_json parameter in addition to a number of files[n] parameters.

All files[n] parameters must include a valid Content-Disposition subpart header with a filename and unique name parameter. Each file parameter must be uniquely named in the format files[n] such as files[0] , files[1] , or files[42] . The suffixed index n is the snowflake placeholder for the attachments json parameter that is supplied in payload_json (or Callback Data Payloads).

The file upload limit applies to the entire request, not individual files in a request. This limit depends on the Boost Tier of a Guild and is 8 MiB by default.

Images can also be referenced in embeds using the attachment://filename URL. An example payload is provided below.

Editing Message Attachments

All files added to a request, as described above, will be appended to the message in a PATCH request. The attachments json parameter has a special behavior for edit, as it is used for both removing attachments from the message as well as adding descriptions for new attachments added by the request.

The attachments json parameter lists all files that should be attached to the message after the edit, including all new files added and the respective snowflake placeholders. To remove attachments, simply exclude them from this list.

Example Request Bodies (multipart/form-data)

This example demonstrates usage of the endpoint without payload_json .

This example demonstrates usage of the endpoint with payload_json and all content fields ( content , embeds , files[n] ) set.

Using Attachments within Embeds

You can upload attachments when creating a message and use those attachments within your embed. To do this, you will want to upload files as part of your multipart/form-data body. Make sure that you're uploading files that contain a filename, as you will need a filename to reference against.

warn Only filenames with proper image extensions are supported for the time being.


"The API for interacting with Gateways is complex and fairly unforgiving, therefore it's highly recommended you read all of the following documentation before writing a custom implementation." - Discord API Docs

Добрый день. Многие знают, что программисту приходится следить за развитием технологий, даже тех, которые не касаются его текущего стека. Ну, или ему это доставляет удовольствие, которое он оправдывает необходимостью держать руку на пульсе. Так обычно зарождаются разнообразные домашние проекты. Я решил свести в один пост свои наработки по написанию Node.js-бота для Discord Slash API с Serverless подходом в Yandex Cloud. Использование готовых библиотек сведено к минимуму.

Discord?

Discord — это многим известный мессенджер, бесплатный до определённых пределов. Он позволяет без особых технических навыков построить коммьюнити по какой-то теме. В основном, конечно, это геймерские сообщества, именно так себя Discord и позиционирует — встроенная функциональность для трансляции игр и прочие навороты. Ими, впрочем, дело не ограничивается — на Хабре пробегали статьи про жизнь небольших контор в этом мессенджере, также там заседают алготрейдеры с «Реддита» и много кто ещё. В определённой степени эта популярность вызвана открытым API для написания ботов. Как правило, в любом сообществе администраторы создают 1–2 канала для совместного прослушивания музыки, игр в простые текстовые развлечения — атмосфера IRC начала нулевых.

В настоящий момент существует два API для ботов на этой платформе. Одно, ставшее классическим, основано на вебсокетах. Второе Discord открыл в конце 2020 года — и им можно пользоваться на чистом REST.

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

Discord Slash API?

Базовый сценарий:


Начнём с простого — заставим эту связку минимально работать. Нужно отвечать на команду
/дай с параметром фотку:<тип> соответствующей картинкой. Варианта будет три — котик, собакен или случайная из двух.

У Discord (в отличие от Telegram) довольно разухабистая система авторизаций, проверок и перекрёстных страниц, по которым надо пройти, чтобы все участники взаимодействия получили свои права в нужном объёме. Общением с @Botfather дело не ограничивается.

Сначала идём на портал разработчика и создаём новое приложение. На этой странице нам пригодятся поля APPLICATION ID и PUBLIC KEY. На вкладке Oauth2 нужно скопировать CLIENT SECRET, он тоже пригодится.

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

CLIENT SECRET вводим весто пароля в интерактивном режиме.
Ответом будет примерно такой JSON:

Из ответа надо запомнить уже поле access_token. Обратите внимание, что scope — тоже значащее поле. Оно определяет, какие права будут у выданного нам токена. Перечисленных в примере хватит для дальнейшей работы.

Работать она, конечно же, ещё не будет.


Знания, необходимые для этой, казалось бы, простой подготовительной части, щедро рассыпаны по документации, так что написание первой простейшей версии бота заняло у меня несколько вечеров. Кроме того — таких извращенцев просто мало, в основном эту функциональность используют вместе с основным ботом, висящим на WebSocket с помощью библиотеки discord.js (что, конечно, получается гораздо быстрее), и готовых сниппетов в интернете практически нет.

Пришла пора писать Serverless-функцию, которая будет отвечать на запросы.

Yandex Cloud Functions

Я не буду подробно останавливаться на описании интерфейса консоли Yandex Cloud. Типичный жизненный цикл Serverless-функций — это обрабатывать входящие обращения, иногда уже отсортированные Gateway API, и отдавать результат. Биллинг потом спишет копеечку за время работы функции.

Итак, в консоли Yandex Cloud создаём новую функцию, среда выполнения — Node.js 14, время выполнения — 3 секунды (про него объясню позднее), доступная память — минимальная — 128 МБ.

Начинаем писать мало-мальски работающий код:

Мы объявили функцию, которая будет вызываться при получении REST-запроса по своему случайно сгенерированному постоянному адресу. В параметр event прилетает всё описание запроса — заголовки и тело. Переменная, которую мы возвращаем, описывает, как должен выглядеть ответ, его статус, заголовки и тело.

Бот обязан проверять подпись входящих запросов. Discord при первом сохранении endpoint проверяет, как она реагирует на запрос с некорректной подписью. И если бот не сможет распознать его и ответить 401-й ошибкой — откажется с ней работать. Проверку было решено отдать на откуп готовой библиотеке, помня о первой заповеди самостоятельной реализации аутентификации — «не делай этого».

Рядом с этим файлом нужно создать package.json, положив в него описание проекта, а главное — зависимостей:

После сохранения этого файла на вкладке «Операции» появится запись о том, что все зависимости установлены. Конечно, никто не мешает писать код в любимой IDE, а затем положить его в ZIP и закинуть на сервер со всеми зависимостями — но мне было интересно, как работает этот функционал.

У проверки подписи есть побочный эффект — вы не сможете потыкать свою функцию тестовыми данными, чтобы проверить её работу. Так что при более-менее серьёзной разработке поднимайте отдельную версию функции, которая не столь радикально относится к подписи. А заниматься такой отладкой придётся, потому что Discord не расскажет вам, что пошло не так при общении с ботом. Именно ручная отладка помогла мне понять, что по умолчанию функция отдаёт заголовок text/plain вместо нужного application/json.

Итак, после сохранения можно взять URL функции, зайти в личный кабинет приложения на сайте Discord, вбить его в поле INTERACTIONS ENDPOINT URL и сохранить. Ура. Теперь начнём, наконец, что-то отвечать на саму команду:


Первая итерация закончена, бот работает, выдает одну, вторую или случайную картинку. Конечно, это абсолютно синхронная и лёгкая операция, и отдавать таким образом статику суперпросто. Теперь пойдём дальше — и сделаем нашу функцию асинхронной.

Все, перед кем вставала задача радовать неугомонных пользователей фотографиями животных, наверное, знают про сервисы The Cat API и The Dog API. Это API, отдающее ссылки на фотографии, доступные для использования в проектах, похожих на наш. Большинство подобных сервисов реализуют функцию random и сами следят за актуальностью фотографий в своей базе, что снимает с разработчика множество проблем. Такие сервисы есть почти по любой тематике, и многие из них бесплатны до какого-то количества обращений. Мне вполне хватало этого лимита, так что я приступил к их использованию, всего лишь один fetch-запрос до сервиса. и сразу наступил на грабли того самого ограничения в 3 секунды, про которое говорил ранее. И проблема тут совсем не во времени исполнения функции — хотя, учитывая, что тарифицируют нас за время работы, необдуманно забивать это поле девятками — безусловно, не лучшая идея.

Я не планировал скачивать изображения и считал что «трёх секунд хватит всем»​, но нет. Во-первых, запросы в нашем несовершенном мире иногда падают по сетевым причинам. Во-вторых, сервисы эти монетизируются крайне условно и геокешинг с CDN в разных странах, как правило, не используют. Запросы отрабатывали, но за 3 секунды можно вылететь.

Кроме того, однажды я попал в ситуацию, когда изображения перестали открываться в чате. Виноват оказался Роскомнадзор: CDN сервиса с котиками попал под блокировку. Сам сервис отдавал ссылку на картинку, я передавал её в чат, а Discord не мог открыть её, так как из России адрес был недоступен. Дополнительная проверка ссылки на доступность (напомню, мы всего лишь пытаемся показывать милые фото котиков) делала перспективы уложиться в 3 секунды более призрачными, особенно в случае повторного запроса.

Решение? Очевидно — создадим ещё одну функцию.

Новый план!


Изменения в быстрой функции:

Работа с точки зрения пользователя:


Итоги

Главный вопрос, который может возникнуть при прочтении: «Зачем?».

Иногда нужен контроль, иногда страшно, что функция слишком бодро масштабируется, иногда есть виртуалка, на которой вполне хватит места на ещё-один-докер-с-js-процессом-внутри. Но рано или поздно за этим придётся следить — переносить процесс, данные, добавлять мониторинг, обновлять систему, наконец. Serverless-подход несложен в использовании, не требует ухода после деплоя и очень дёшев при небольших/нечастых нагрузках для домашних проектов.

Кстати, про «дёшево» — это, как правило, второй возникающий вопрос. Посчитаем по прайсу.

При тарификации вычислительных ресурсов (ГБ × час) учитывается объём памяти, выделенный для функции, и время выполнения функции.

На июль 2021 г. 1 миллион вызовов стоит 10 ₽, ГБ*час стоит 3,42 ₽, а исходящий трафик — 0,96 ₽ за гигабайт.

Среднее оплачиваемое время выполнения этих функций (из отчёта Yandex Cloud):

Медленная функция: 1200 мс
Быстрая: 200 мс

Итого: 1,4 с на обработку одного запроса.

Прикинем стоимость миллиона котиков:

3,42 × (128 / 1024) × (1200 / 3600 / 1000) × 1 000 000 + 10 × (1 000 000 / 1 000 000) = 152,5 ₽

Но — приятный подарок — первый миллион запросов, первые 10 ГБ × час в месяц и первые 10 ГБ исходящего трафика не тарифицируются.

Из моей личной практики (на канале в 400 человек, где у бота есть клуб преданных фанатов): он ни разу не вышел в платный режим. Даже с учётом вакханалии на 1 апреля, когда он показывал, а затем оперативно удалял чуть-чуть NSFW-шные картинки, которые «случайно» попали в его базу.

Для меня это уже не первый раз, когда Serverless-решение оказалось дешевле, но главное — гораздо проще в поддержке , чем стандартный подход.

Неважно, что вы делаете — планировщик задач, торгового бота или такой проект на коленке, — прежде чем писать ещё_один_демон_за_которым_надо_следить, подумайте, возможно Serverless подойдёт вам больше.

В статье я попытался обобщить информацию о существующих уязвимостях REST API, чтобы у читателей сложилась общая картина. На схемах представлена современная архитектура клиент-сервер и обобщенный REST API запрос с потенциальными угрозами безопасности. Далее я подробнее расскажу об этих угрозах, и как технически реализовать защиту от них.

Стандарты безопасности

Начнем со стандартов. Существует несколько стандартов, которые помогут нам сформулировать список требований к безопасности API:

OWASP (Open Web Application Security Project) известна своими списками рисков в разных программных технологиях. Нам интересен список «10 наиболее опасных уязвимостей при разработке API»:

  • API1:2019 Broken Object Level Authorization (Недостатки контроля доступа к объектам). Другое название этого риска: Insecure Direct Object References (Небезопасные прямые ссылки на объекты)
  • API2:2019 Broken User Authentication (Недостатки аутентификации пользователей)
  • API3:2019 Excessive Data Exposure (Разглашение конфиденциальных данных)
  • API4:2019 Lack of Resources & Rate Limiting (Отсутствие проверок и ограничений)
  • API5:2019 Broken Function Level Authorization (Недостатки контроля доступа на функциональном уровне)
  • API6:2019 Mass Assignment (Небезопасная десериализация)
  • API7:2019 Security Misconfiguration (Некорректная настройка параметров безопасности)
  • API8:2019 Injection (Внедрение)
  • API9:2019 Improper Assets Management (Недостатки управления API)
  • API10:2019 Insufficient Logging & Monitoring (Недостатки журналирования и мониторинга)
    (Небезопасный транспортный уровень) (Небезопасные пароли) (Использование компонент с известными уязвимостями)
  • CWE-79 Cross-site Scripting (XSS) (Межсайтовое выполнение сценариев)
  • CWE-352 Cross-Site Request Forgery (CSRF) (Межсайтовая подмена запросов)

API2:2019 — Broken User Authentication (Недостатки аутентификации пользователей)

Тема аутентификации пользователей идет на втором месте в списке OWASP, но я ее поставил на первое, т.к. с этого все начинается. Современные стандарты аутентификации и авторизации я уже рассматривал в своей статье про OAuth 2.0, OpenID Connect, WebAuthn. Здесь кратко опишу основные схемы безопасности и рассмотрим более подробно наиболее надежную на данный момент схему, основанную на токенах.

API key

API Key — это строка символов, которую передает клиент в запросах к серверу. Для успешной аутентификации строка должна совпадать у клиента и у сервера. Данная схема обеспечивает защиту от несанкционированного использования API и позволяет осуществлять, например, проверку лимитов использования API.

Basic Authentication

В Basic Authentication используется аутентификация по двум строкам, например логину/паролю.


После этого клиент автоматически будет посылать заголовок Cookie при каждом запросе:


Для реализации этого механизма необходимо на сервере организовать хранение и проверку сессий пользователей. Подробнее использование Cookies рассмотрено в разделе «Insecure Cookies and Local Storage»

Token-Based Authentication

Также называют Bearer Authentication.


При получении токена сервер должен проверять его на валидность — что пользователь существует, время использования не прошло и т.д. Token-Based Authentication может использоваться как часть OAuth 2.0 или OpenID Connect протоколов, так и сервер сам может сформировать токен.

Алгоритм Token-Based Authentication

Разберем подробнее последнюю из описанных схем. На схеме представлен упрощенный алгоритм Token-Based Authentication на примере реализации возможности «Зайти с помощью Google аккаунта»

image

  1. Пользователь заходит на сайт и нажимает кнопку «Зайти с помощью Google аккаунта»
  2. Сервер посылает запрос на Google.
  3. Google показывает пользователю свою форму логина.
  4. Пользователь вводит логин/пароль.
  5. Google проверяет логин/пароль и отправляет на наш сервер приложений access token и refresh token.
  6. Для аутентификации сервер расшифровывает token или получает информацию о пользователе по Google API.
  7. Далее сервер находит пользователя в своей базе, сообщает об успешной аутентификации и сохраняет токены в локальном хранилище пользователя для реализации возможности «Запомнить меня на этом устройстве». В каком конкретно: Local Storage, Session Storage или Cookies, решается в зависимости от требований бизнеса и безопасности. OWASP склоняется к Cookies с реализацией дополнительных механизмов безопасности: JSON Web Token Cheat Sheet. Нужно ли генерировать дополнительный «session token», где его хранить и как использовать — также должно определяться бизнесом, для которого реализуется система.
  8. После этого при каждом запросе к серверу клиент будет передавать access token в запросе, а наш сервер проверять его на валидность в Google и только после этого передавать запрошенные данные.
  9. При окончании срока действия access токена сервер использует refresh токен для получения нового.
  1. Не надо хранить пароли в базе данных на сервере, таким образом сразу избавляемся от уязвимости Insecure Passwords.
  2. В некоторых случаях можно вообще избавиться от базы данных на сервере и получать всю необходимую информацию из Google или других систем.
  3. Нет проблем с безопасностью, характерных для остальных методов:
  • При компрометации логина/пароля доступ к данным получается сразу и длится пока пользователь сам не заметит факт взлома, у токенов же есть время жизни, которое может быть небольшим.
  • Токен автоматически не уйдет на сторонний сайт, как Cookie.
  • Cookie-Based Authentication подвержена атаке Cross-Site Request Forgeries (CSRF) и, соответственно, необходимо использовать дополнительные механизмы защиты.
  • Можно не хранить сессию пользователя на сервере, а токен проверять каждый раз в Google.

API1:2019 Broken Object Level Authorization (Недостатки контроля доступа к объектам)

Другое название этого риска: Insecure Direct Object References (Небезопасные прямые ссылки на объекты). Это самая распространенная проблема с API в настоящее время. Для иллюстрации приведу API, которое в дальнейшем использую еще для нескольких примеров уязвимостей.

Получить одного пользователя с userID:


Получить всех пользователей (может только администратор):


Удалить пользователя c userID: DELETE /users/


Итак, если вызывается команда удаления пользователя:


То необходима проверка, что эту команду может вызвать только сам пользователь 1 или администратор, а не, например, пользователь 2 от своего имени, просто изменив значение ID в вызове команды. Чтобы избежать подобных проблем нужно:

  • Проверять права доступа к объектам при каждом запросе.
  • Проверять, что залогиненный пользователь имеет доступ только к разрешенным объектам.
  • ID объектов должны быть сложными для подбора, например в виде UUID, а не простая последовательность 1, 2, 3.
  • Role-Based Access Control (RBAC)
  • Discretionary Access Control (DAC)
  • Mandatory Access Control (MAC)
  • Permission Based Access Control

API5:2019 Broken Function Level Authorization (Недостатки контроля доступа на функциональном уровне)

Должна быть разработана четкая система разграничения доступа между ролями пользователей API. Например, есть роль: обычные пользователи и роль: администраторы. Команду по просмотру всех пользователей может вызвать только администратор:


При каждом вызове команды необходима проверка прав доступа, чтобы обычный пользователь не мог вызвать команду, только изменив формат.

API3:2019 Excessive Data Exposure (Разглашение конфиденциальных данных)


может вернуть не только имя / возраст, но и ответ на секретный вопрос, который пользователь задал во время регистрации:


Это и называется излишняя передача данных. Проблема усугубляется тем, что лишних данных может быть еще и просто много по объёму. При больших нагрузках это приведет к сетевым проблемам. Соответственно, при разработке API нельзя полагаться на фильтрацию данных в клиенте — все данные должны фильтроваться на сервере.

API6:2019 Mass Assignment (Небезопасная десериализация)

В данном случае ситуация обратная предыдущему пункту Excessive Data Exposure — лишние данные передаются на сервер с целью несанкционированной замены значений. Как это понимать? Предположим у нас есть пользователь-хакер с ID 1 со следующими данными:


Некоторые поля записей пользователь может легитимно менять сам, например, свой возраст. А поля, такие как balance должны устанавливать внешние системы.

После этого баланс увеличится без внесения реальных денег. Чтобы предотвратить данную атаку необходимо:

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

API4:2019 Lack of Resources & Rate Limiting (Отсутствие проверок и ограничений)

Необходимо защитить сервер от атак по подбору пароля (brute force attack). Для этого нужно реализовать следующие ограничения:

  • Ограничить число неудачных попыток авторизации одного пользователя. Как вариант использовать reCapture или аналогичный механизм.
  • Блокировать IP, если число неудачных попыток с него превысило определенное значение по всем пользователям.

Необходимо защитить сервер и от отказа в обслуживании (DoS-атаки)

  • Ограничить число запросов от одного пользователя или по одному ресурсу в течении определенного времени.
  • Также атаки по отказу в обслуживании могут основываться на передаче заведомо больших значений.


Если на сервере отсутствует проверка size на максимальное значение, то передача в параметре злоумышленником, например, 1 000 000 может привести к исчерпанию памяти на сервере и отказу в обслуживании. Поэтому нужно проверять на сервере все значения параметров на допустимые, даже если на нашем клиенте есть такие проверки. Ведь никто не помешает вызвать API напрямую.

API7:2019 Security Misconfiguration (Некорректная настройка параметров безопасности)

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

  • Для пользователей устанавливать только необходимые права доступа.
  • Открывать только необходимые сетевые порты.
  • Устанавливать безопасные версии патчей OS и приложений (подробно рекомендации рассмотрены в разделе «Using Components with Known Vulnerabilities»).

API8:2019 Injection (Внедрение)

Внедрение — это выполнение программного кода, не предусмотренного системой. Разделяют внедрения:

Если сервер выполняет команды без проверки, то злоумышленник может послать следующую команду с большой вероятностью вывода сервера из строя:

Для предотвращения подобных атак:

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

API9:2019 Improper Assets Management (Недостатки управления API)

API может иметь несколько точек входа (endpoints) с разными версиями и функциональными назначениями. Например:


Необходимо обеспечить учет и контроль версий API:

  • Нужно вести список имеющихся API, их версий, назначение (production, test, development) и кто имеет к ним доступ (public, internal, partners).
  • Необходимо управлять жизненным циклом API и своевременно запускать новые версии, снимать с поддержки старые.
  • В открытом доступ выставлять только актуальные версии API.
  • Не оставлять в открытом доступе endpoints, предназначенные для отладки.

API10:2019 Insufficient Logging & Monitoring (Недостатки журналирования и мониторинга)

Чтобы выявить атаку или подозрительное поведение пользователей, систему надо мониторить, а события логировать с достаточным уровнем подробности:

  • Логировать все неудачные попытки аутентификации, отказы в доступе, ошибки валидации входных данных.
  • Обеспечить целостность логов, чтобы предотвратить возможность их подделки.
  • Мониторить надо не только приложения и вызовы API, но и инфраструктуру, сетевую активность, загрузку OS.
  • Необходимо обеспечить не только мониторинг, но и оперативное оповещение о нарушениях штатной работы системы.
  • Общие советы по мониторингу можно посмотреть в статье Monitoring Done Right

Insecure Transport (Небезопасный транспортный уровень)

Insecure Passwords (Небезопасные пароли)

С этой темой все просто:

  • Пароли пользователей должны быть достаточно сложными и длинными. В настоящее время не существует единых требований к паролям, все определяется бизнесом.
  • На сервере нельзя хранить пароли пользователей в открытом виде.
  • На сервере храним только хеши паролей, вычисленные надежным алгоритмом, например, Argon2.

Insecure Cookies and Local Storage (Небезопасные Cookies и данные в Local Storage)

Cookies должны использоваться безопасно:

  • Нельзя использовать дефолтные имена.
  • При создании Cookies следует устанавливать следующие опции:
  • Европейские сайты должны явно спрашивать разрешение у пользователя о применении Cookies. Так как, например, если в Cookies записать последовательность действий пользователя на сайте, то это уже считается персональной информацией.
  • Нельзя хранить важную информацию с сервера, т.к. она доступна пользователю.
  • Нельзя хранить персональную информацию пользователя, т.к. она может стать доступна другим пользователям компьютера.
  • Соответственно, можно хранить только зашифрованные данные или служебную информацию.

Using Components with Known Vulnerabilities (Использование компонент с известными уязвимостями)

Компоненты, такие как библиотеки и framework-и выполняются с теми же привилегиями, что и приложение. Поэтому если среди используемых библиотек окажется небезопасный компонент, то это может привести к захвату или выводу из строя сервера. Для проверки безопасности компонент используются специальные приложения, например, для JavaScript можно использовать Retire.

CWE-79 Cross-site Scripting (XSS) (Межсайтовое выполнение скриптов)

CWE-352 Cross-Site Request Forgery (CSRF) (Межсайтовая подмена запросов)

Для понимания сути атаки приведу пример: предположим, есть финансовая организация с онлайн кабинетом. В Cookies запоминается пользователь, чтобы при входе ему не надо было каждый раз вводить свой логин/пароль. Пользователь случайно заходит на сайт злоумышленника, который отправляет в финансовую организацию транзакцию на перевод денег, в которую браузер автоматически помещает данные из запомненных Cookies.

Финансовый сайт успешно проверяет валидность Cookies и выполняет несанкционированную транзакцию. Для защиты от атак CSRF надо:

  • На сервере реализовать механизм «CSRF токенов». Это такой механизм, когда для каждой сессии пользователя генерируется новый токен и сервер проверяет его валидность при любых запросах с клиента.
  • На сервере проверять заголовки Origin и Referer, в которых содержится адрес источника запроса. Но эти заголовки могут отсутствовать.
  • Также можно всегда требовать от пользователя подтверждать критические действия вводом пароля или вторым фактором аутентификации, но возможность таких мер зависит от бизнеса.
  • При создании Cookies выставлять параметр SameSite, но этот механизм поддерживают не все браузеры.

Cross-origin resource sharing (CORS) (Кросс-доменное использование ресурсов)

CORS — это механизм безопасности, который позволяет серверу задать правила доступа к его API. Например, если на сервере установить заголовок:


то это позволит использовать API без ограничения. Если это не публичное API, то для безопасности надо явно устанавливать Origin-ы, с которых разрешен доступ к API, например:


И задать список заголовков, которые сервер может принимать:

X-Powered-By

Этот заголовок автоматически вставляется некоторыми серверами, что дает понять злоумышленнику, с каким сервером он имеет дело, например:


Отсутствие этого заголовка, конечно, никого не остановит, но сразу давать такую подсказку не стоит. Поэтому передачу этого заголовка надо запретить.

X-Frame-Options (защита от Clickjacking)

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


или разрешить использование только в нашем домене:


А лучше для предотвращения атаки Clickjacking использовать более современный механизм и установить правильную политику безопасности Content-Security-Policy

Content-Security-Policy

Позволяет защититься от атаки Cross-site scripting и других кросс-сайтовых инъекций, в том числе Clickjacking. Требует вдумчивого конфигурирования, т.к. параметров много. Но надо хотя бы поставить дефолтную политику, что предотвратит возможность атаки Cross-site Scripting:


Подробно значения заголовка Content-Security-Policy разбираются, например, по ссылке.

X-Content-Type-Options

Установка данного заголовка запрещает браузеру самому интерпретировать тип присланных файлов и принуждает использовать только тот, что был прислан в заголовке Content-Type. Без этого возможна ситуация, когда, например, посылается безобидный на вид txt файл, внутри которого вредоносный скрипт и браузер его выполняет как скрипт, а не как текстовой файл. Поэтому устанавливаем:

Cache-Control

Cache-Control позволяет управлять кешом на стороне клиента, рекомендуется запретить кеширование, чтобы в кеше случайно не оставались приватные данные:

Заключение

В статье мы рассмотрели угрозы, которые подстерегают API при его эксплуатации и способы борьбы с ними. В заключении приведу несколько общих выводов:

Читайте также: