From fc5bd544268918403b1a08cdb55cb53251b91fa2 Mon Sep 17 00:00:00 2001 From: Sergey Konstantinov Date: Sun, 10 Jul 2022 13:28:00 +0300 Subject: [PATCH] New chapter: Technical Means of Preventing ToS Violations --- .../02-Section I. The API Design/05.md | 6 ++ .../04-Section III. The API Product/09.md | 74 ++++++++++++++++++- .../02-Раздел I. Проектирование API/05.md | 8 +- .../04-Раздел III. API как продукт/09.md | 74 +++++++++++++------ src/templates.js | 2 +- 5 files changed, 138 insertions(+), 26 deletions(-) diff --git a/src/en/clean-copy/02-Section I. The API Design/05.md b/src/en/clean-copy/02-Section I. The API Design/05.md index 222f510..802b16f 100644 --- a/src/en/clean-copy/02-Section I. The API Design/05.md +++ b/src/en/clean-copy/02-Section I. The API Design/05.md @@ -990,6 +990,12 @@ You are not obliged to actually generate those exceptions, but you might stipula It is extremely important to leave a room for multi-factored authentication (such as TOTP, SMS, or 3D-secure-like technologies) in case it's possible to make payments through the API. In this case, it's a must have from the very beginning. +##### Don't provide endpoints for mass downloading of sensitive data + +If it's possible to get through the API users' personal data, bank card numbers, private messages, or any other kind of information, exposing of which might seriously harm users, partners, and/or you — there must be *no* methods of bulk getting the data, or at least there must be rate limiters, page size restrictions, and, ideally, multi-factored authentication in front of them. + +Often, making such offloads on an ad-hoc basis, e.g. in bypass of the API, is a reasonable practice. + ##### No results is a result If a server processed a request correctly and no exceptional situation occurred — there must be no error. Regretfully, an antipattern is widespread — of throwing errors when zero results are found. diff --git a/src/en/drafts/04-Section III. The API Product/09.md b/src/en/drafts/04-Section III. The API Product/09.md index f35814b..2d62350 100644 --- a/src/en/drafts/04-Section III. The API Product/09.md +++ b/src/en/drafts/04-Section III. The API Product/09.md @@ -1,5 +1,73 @@ -### Technical Means of +### Technical Means of Preventing ToS Violations -As we have mentioned several times, API serves as a multiplier to *any* possibility, including illegal ones: having a severe API vulnerability means that *every* client application is vulnerable, and that is a much greater threat level than a security flaw in a single service. So the informational security of the API service must be of the highest possible priority. +Implementing the paradigm of a centralized system of preventing partner endpoints-bound fraud, which we described in the previous chapter, in practice faces non-trivial difficulties. + +The task of filtering out illicit API requests generally comprises three steps: + * identifying suspicious users; + * optionally, asking for an additional authentication factor; + * making decisions and applying the access restrictions. + +##### Identifying suspicious users + +Generally speaking, there are two approaches we might take, the static one and the dynamic (behavioral) one. + +*Statically* we monitor suspicions activity surges, as described in the previous chapter, marking an unusually high density of requests coming from specific networks or Referers (actually, *any* piece of information suits if it divides users into more or less independent groups: for example, OS version or system language if you can gather those). + +*Behavioral* analysis means we're examining the history of requests made by a specific user, searching for non-typical patterns, such as ‘unhuman’ order of traversing endpoints or too small pauses between requests. + +**Importantly**, when we talk about ‘user’, we will have to make a second analytical contour to work with IP addresses, as malefactors aren't obliged to preserve cookies or other identification tokens, or will keep a pool of such tokens to impede their exposure. + +##### Asking for an additional authentication factor + +As both static and behavioral analyses are heuristic, it's highly desirable to not make decisions based solely on their outcome, but rather ask the suspicious users to additionally prove they're making legitimate requests. If such a mechanism is in place, the quality of an anti-fraud system will be dramatically improved, as it allows for increasing system sensitivity and enabling pro-active defense, e.g. asking users to pass the tests in advance. + +In the case of services for end users, the main method of acquiring the second factor is redirecting to a captcha page. In the case of the API it might be problematic, especially if you initially neglected the [‘Stipulate restrictions’](#chapter-11-paragraph-19) advice. In many cases, you will have to impose this responsibility on partners (e.g. it will be partners who show captchas and identify users based on the signals received from the API endpoints). This will, of course, significantly impair the convenience of working with the API. + +**NB**. Instead of captcha, there might be any other actions introducing additional authentication factors. It might be the phone number confirmation or the second step of the 3D-Secure protocol. The important part is that requesting an additional authentication step must be stipulated in the program interface, as it can't be added later in a backwards-compatible manner. + +Other popular mechanics of identifying robots include offering a bait (‘honeypot’) or employing the execution environment checks (starting from rather trivial like executing JavaScript on the webpage and ending with sophisticated techniques of checking application integrity). + +##### Restricting access + +The illusion of having a broad choice of technical means of identifying fraud users should not deceive you as you will soon discover the lack of effective methods of restricting those users. Banning them by cookie / Referer / User-Agent makes little to no impact as this data is supplied by clients, and might be easily forged. In the end, you have four mechanisms for suppressing illegal activities: + * banning users by IP (networks, autonomous systems); + * requiring mandatory user identification (maybe layered: login / login with confirmed phone number / login with confirmed identity / login with confirmed identity and biometrics / etc.); + * returning fake responses; + * filing administrative abuse reports. + +The problem with option number one is the collateral damage you will inflict, especially if you have to ban subnets. + +The second option, though quite rational, is usually inapplicable to real APIs, as not every partner will agree with the approach, and definitely not every end user. This will also require being compliant with the existing personal data laws. + +The third option is the most effective one in technical terms as it allows to put the ball in the malefactor's court: it is now them who need to invent how to learn if the robot was detected. But from the moral point of view (and from the legal perspective as well) this method is rather questionable, especially if we take into account the probability of false-positive signals, meaning that some real users will get the fake data. + +Thereby, you have only one method that really works: filing complaints to hosting providers, ISPs, or law enforcement authorities. Needless to say, this brings certain reputational risks, and the reaction time is rather not lightning fast. + +In most cases, you're not fighting fraud — you're actually increasing the cost of the attack, simultaneously buying yourself enough time to make administrative moves against the perpetrator. Preventing API misusage completely is impossible as malefactors might ultimately employ the expensive but bulletproof solution — to hire real people to make the requests to the API. + +An opinion exists, which the author of this book shares, that engaging into this sword-against-shield confrontation must be carefully thought out, and advanced technical solutions are to be deployed only if you are one hundred percent sure it is worth it (e.g. if they steal real money or data). By introducing elaborate algorithms, you rather conduct an evolutional selection of the smartest and most cunning cybercriminals, counteracting whom will be way harder than those who just naively call API endpoints with `curl`. What is even more important, in the final phase — e.g. when filing the complaint to authorities — you will have to prove the alleged ToS violation, and doing so against an advanced fraudster will be problematic. + +#### Dealing with stolen keys + +Let's now move to the second type of unlawful API usage, namely using keys stolen from conscientious partners in the malefactor's applications. As the requests are generated by real users, captcha won't help, though other techniques will. + + 1. Maintaining metrics collection by IP addresses and subnets might help in this case as well. If the malefactor's app isn't a public one but rather targeted to some close audience, this fact will be visible in the dashboards (and if you're lucky enough, you might also find suspicious Referers, public access to which is restricted). + + 2. Allowing partners to restrict the functionality available under specific API keys: + + * setting the allowed IP address range for server-to-server APIs, allowed Referers and application ids for client APIs; + + * white-listing only allowed API functions for a specific key; + + * other restrictions that make sense in your case (in our coffee API example, it's convenient to allow partners prohibiting API calls outside of countries and cities they work in). + + 3. Introducing additional request signing: + + * for example, if on the partner's website there is a form displaying the best lungo offers, for which the partners call the API endpoint like `/v1/search?recipe=lungo&api_key={apiKey}`, then the API key might be replaced with a signature like `sign = HMAC("recipe=lungo", apiKey)`; the signature might be stolen as well, but it will be useless for malefactors as they will be able to find only lungo with it; + + * instead of API keys, time-based one-time passwords (TOTP) might be used; these tokens are valid during a short period of time (usually, one minute) only, which makes working with stealing keys much more sophisticated. + + 4. Filing complaints to the administration (hosting providers, app store owners) in case the malefactor distributes their application through stores or uses a diligent hosting service that investigates abuse filings. Legal actions are also an option, and even much so compared to countering user fraud, as illegal access to the system using stolen credentials is unambiguously outlawed in most jurisdictions. + + 5. Banning compromised API keys; the partners' reaction will be, of course, negative, but ultimately every business will prefer temporary disabling of some functionality over getting a multi-million bill. -Every contemporary IT service under the hood uses the internal APIs that are usually a main target of cybercriminals. In that sense, the sets of attack vectors against a public API and against an internal API of some service are almost identical. We won't be discussing there \ No newline at end of file diff --git a/src/ru/clean-copy/02-Раздел I. Проектирование API/05.md b/src/ru/clean-copy/02-Раздел I. Проектирование API/05.md index cb80413..d90fbb3 100644 --- a/src/ru/clean-copy/02-Раздел I. Проектирование API/05.md +++ b/src/ru/clean-copy/02-Раздел I. Проектирование API/05.md @@ -980,10 +980,16 @@ POST /v1/orders С ростом популярности API вам неизбежно придётся внедрять технические средства защиты от недобросовестного использования — такие, как показ капчи, расстановка приманок-honeypot-ов, возврат ошибок вида «слишком много запросов», постановка прокси-защиты от DDoS перед эндпойнтами и так далее. Всё это невозможно сделать, если вы не предусмотрели такой возможности изначально, а именно — не ввели соответствующей номенклатуры ошибок и предупреждений. -Вы не обязаны с самого начала такие ошибки действительно генерировать — но вы можете предусмотреть их на будущее. Например, вы можете описать ошибку `429 Too Many Requests` или редирект на показ капчи, но не имплементировать возврат таких ответов, пока не возникнет такая необходимость. +Вы не обязаны с самого начала такие ошибки действительно генерировать — но вы можете предусмотреть их на будущее. Например, вы можете описать ошибку `429 Too Many Requests` или перенаправление на показ капчи, но не имплементировать возврат таких ответов, пока не возникнет такая необходимость. Отдельно необходимо уточнить, что в тех случаях, когда через API можно совершать платежи, ввод дополнительных факторов аутентификации пользователя (через TOTP, SMS или технологии типа 3D-Secure) должен быть предусмотрен обязательно. +##### Не предоставляйте endpoint-ов массового получения чувствительных данных + +Если через API возможно получение персональных данных, номер банковских карт, переписки пользователей и прочей информации, раскрытие которой нанесёт большой ущерб пользователям, партнёрам и/или вам — методов массового получения таких данных в API быть не должно, или, по крайней мере, на них должны быть ограничения на частоту запросов, размер страницы данных, а в идеале ещё и многофакторная аутентификация. + +Часто разумной практикой является предоставление таких массовых выгрузок по запросу, т.е. фактически в обход API. + ##### Отсутствие результата — тоже результат Если сервер корректно обработал вопрос и никакой внештатной ситуации не возникло — следовательно, это не ошибка. К сожалению, весьма распространён антипаттерн, когда отсутствие результата считается ошибкой. diff --git a/src/ru/drafts/04-Раздел III. API как продукт/09.md b/src/ru/drafts/04-Раздел III. API как продукт/09.md index c402732..7cdcf5f 100644 --- a/src/ru/drafts/04-Раздел III. API как продукт/09.md +++ b/src/ru/drafts/04-Раздел III. API как продукт/09.md @@ -1,40 +1,72 @@ ### Технические способы борьбы с несанкционированным доступом к API -Реализация парадигмы, описанной в предыдущей главе — централизованной борьбы с фродом, осуществляемым через клиентские API партнёра — на практике сталкивается с достаточно нетривиальными проблемами. Допустим, с помощью каких-то признаков и/или поведенческого анализа мы определили, что запрос с большой вероятностью выполнен не реальным человеком, а роботом. Что мы можем с этим сделать? +Реализация парадигмы, описанной в предыдущей главе — централизованной борьбы с фродом, осуществляемым через клиентские API партнёра — на практике сталкивается с достаточно нетривиальными проблемами. -В случае сервисов для конечных пользователей мы могли бы показать капчу; но в случае API это весьма проблематично, особенно если вы пренебрегли советом [«Предусмотрите ограничения»](#chapter-11-paragraph-19). Если полная отработка сценария (идентификация пользователя — показ капчи или honeypot-а — пометка результатов прохождения теста) на вашем уровне невозможна или не была предусмотрена, вам придётся переложить её на партнёра (т.е. это партнёр должен будет показывать капчу и идентифицировать пользователя, основываясь на сигналах, поступающих от эндпойнтов API) что, конечно, сильно снижает комфортность работы с таким API. +Задача отсеивания нежелательных запросов, в общем случае, состоит из трёх шагов: + * идентификация подозрительных пользователей; + * опционально, запрос дополнительного фактора аутентификации; + * вынесение и применение решения об ограничении доступа. -**NB**. Вместо капчи здесь могут быть любые другие действия, вводящие дополнительные факторы аутентификации. Это может быть, например, подтверждение номера телефона или второй шаг протокола 3D-Secure. Важно здесь то, что запрос второго шага аутентификации должен быть предусмотрен в API, поскольку добавить его его обратно совместимым образом нельзя. +##### Идентификация подозрительных пользователей -Другой способ борьбы с роботами — это попытка идентифицировать среду атаки. Программная оболочка, через которую выполняются запросы, не идентична реальному пользовательскому устройству, и этот факт можно попытаться определить — особенно это касается веб-страниц, которые часто обрабатываются не эмулятором браузера, а каким-то фреймворком, который будет не способен, например, исполнять JavaScript или не поддерживает последние дополнения к WebAPI браузеров. +По большому счёту, здесь есть всего два подхода, которые мы можем применить — статический и динамический (поведенческий). -Немаловажен и вопрос, а что вы будете делать, если вы всё же смогли идентифицировать злонамеренного пользователя, но не можете сделать так, чтобы он прекратил слать запросы. В какой-то момент придётся прибегнуть к одной из двух стратегий: - * бан пользователя по ip (подсети, автономной системе), Referer-у или идентификатору приложения (если они передаются), либо какому-то частному правилу (например, по заголовку User-Agent, если злоумышленник забыл его подменить); - * отдача ложного ответа. +*Статически* мы отслеживаем подозрительную концентрацию активности (как описано в предыдущей главе), отмечая нехарактерно высокое количество запросов из определённых подсетей или Referer-ов (на самом деле, нам подойдёт *любая* информация, которая как-то делит пользователей на более-менее независимые группы — такая как, например, версия ОС или язык системы, если такие данные нам доступны). -С точки зрения эффективности противоборства атаке второй вариант куда предпочтительнее, поскольку перекидывает мяч на ту сторону: теперь уже злоумышленнику нужно каким-то образом определять, был ли он пойман. Но с точки зрения морали (и буквы закона) этот способ весьма сомнителен — особенно если учесть, что всегда возможны ложположительные срабатывания, и некорректные данные будут отданы честному пользователю. +При *поведенческом* анализе мы анализируем историю запросов одного конкретного пользователя и отмечаем нетипичное поведение — «нечеловеческий» порядок обхода эндпойнтов, слишком быстрый их перебор, etc. + +**Важно**: когда мы здесь говорим о «пользователе», нам почти всегда придётся дублировать анализ для работы по ip-адресу, поскольку злоумышленник вовсе не обязан будет сохранять cookie или другой идентификационный токен, или будет ротировать набор таких токенов, чтобы затруднить идентификацию. + +##### Запрос дополнительного фактора аутентификации + +Поскольку и статический, и поведенческий анализ эвристические, очень желательно не просто выносить решение на их основе, но предлагать подозрительным пользователям дополнительно доказать, что они совершают легитимные запросы. Если такие механизмы есть, качество работы анти-фрод системы существенно возрастает, поскольку тогда допустимо будет снизить порог срабатывания или вовсе включить проактивную защиту, т.е. предлагать пользователям пройти дополнительную проверку превентивно. + +В случае сервисов для конечных пользователей основным методом дополнительной аутентификации является перенаправление на страницу с капчей. В случае API это может быть весьма проблематично, особенно если вы пренебрегли советом [«Предусмотрите ограничения»](#chapter-11-paragraph-19) — во многих случаях вам придётся переложить имплементацию этого сценария на партнёра (т.е. это партнёр должен будет показывать капчу и идентифицировать пользователя, основываясь на сигналах, поступающих от эндпойнтов API) что, конечно, сильно снижает комфортность работы с таким API. + +**NB**. Вместо капчи здесь могут быть любые другие действия, вводящие дополнительные факторы аутентификации. Это может быть, например, подтверждение номера телефона или второй шаг протокола 3D-Secure. Важно здесь то, что запрос второго шага аутентификации должен быть предусмотрен в API, поскольку добавить его его обратно совместимым образом к существующим endpoint-ам нельзя. + +Другие популярные способы распознать робота — предложить ему приманку (honeypot) или использовать методы проверки среды исполнения (начиная от достаточно простых вроде исполнения JavaScript на странице и заканчивая технологиями проверки целостности приложения). + +##### Ограничение доступа + +Видимость богатства способов технической идентификации пользователей, увы, разбивается о суровую реальность наличия у вас очень скромных средств ограничения доступа. Бан по cookie / Referer-у / User-Agent-у практически не работает по той причине, что эти данные передаёт клиент, и он же легко может их подменить. По большому счёту, способов ограничения доступа у вас четыре: + * бан пользователя по ip (подсети, автономной системе); + * требование обязательной идентификации пользователя (возможно, прогрессивной: логин в системе / логин с подтверждённым номером телефона / логин с подтверждением личности / логин с подтверждением личности и биометрией); + * отдача ложного ответа; + * борьба административными методами. + +Вариант номер один плох тем, что наносит огромный сопутствующий ущерб, особенно если вам придётся банить подсети. + +Второй вариант, при всём его удобстве, мало применим в случае реальных API, поскольку на него будут согласны далеко не все партнёры и уж точно далеко не все пользователи, и к тому же потребует от вас дополнительных мер по соблюдению требований законодательства о персональных данных. + +Третий вариант с точки зрения эффективности противоборства атаке является наиболее предпочтительным, поскольку перекидывает мяч на ту сторону: теперь уже злоумышленнику нужно каким-то образом определять, был ли он пойман. Но с точки зрения морали (и буквы закона) этот способ весьма сомнителен — особенно если учесть, что всегда возможны ложноположительные срабатывания, и некорректные данные будут отданы честному пользователю. + +Поэтому по факту у вас есть только один действительно работающий метод борьбы с фродом — жалоба провайдеру, хостеру или правоохранительным органам. Излишне уточнять, что способ этот несёт репутационные издержки и при этом реакция наступает отнюдь не молниеносно. + +В большинстве случаев вы на самом деле не боретесь с фродом — вы повышаете атакующему стоимость атаки, выигрывая себе время на принятие решения о преследовании нарушителя в административном порядке. Предотвратить атаку полностью невозможно, поскольку у злоумышленника всегда есть в запасе дорогой, но работающий способ: посадить реальных людей с реальными приложениями, чтобы они выполняли нужные запросы к API и были неотличимы от обычных пользователей. + +Существует мнение, разделяемое автором настоящей книги, что, ввязываясь в эту борьбу щита с мечом, нужно очень аккуратно использовать технически продвинутые методы борьбы — только в том случае, когда вы уверены, что оно того стоит (читай — если злоумышленники воруют реальные деньги или данные). Вводя сложные алгоритмы, вы тем самым проводите своеобразный «эволюционный отбор», направленный на выявление самых умных и хитрых злоумышленников, противодействовать которым будет гораздо сложнее, чем наивным попыткам вызывать методы API curl-ом. Что ещё важнее, в финальной фазе — т.е. при обращении в контролирующие инстанции — вам придётся предъявить доказательства нарушения, и сделать это в отношении продвинутого противника будет не в пример сложнее. #### Противодействие краже ключей Рассмотрим теперь второй вариант несанкционированного использования, когда злоумышленник крадёт API-ключ добросовестного партнёра и вставляет его в своё приложение. Запросы при этом генерируются настоящими пользователями, а значит капча никак не поможет — но помогут другие методы. - 1. Вести иерархическую статистику доступа по сетям, как было рекомендовано в предыдущей главе. Если приложение злоумышленника всё-таки не обычное приложение для честных потребителей, а какой-то закрытый сервис для ограниченного круга пользователей, этот факт будет виден по аномальной плотности запросов с определённых ip / подсетей / автономных систем (а если повезёт — то ещё и по подозрительным referer-ам, которые закрыты для внешнего доступа). + 1. Ведение статистики по ip-адресам и сетям может помочь и здесь. Если приложение злоумышленника всё-таки не обычное приложение для честных потребителей, а какой-то закрытый сервис для ограниченного круга пользователей, этот факт будет виден на приборах (а если повезёт — то вы увидите ещё и подозрительные Referer-ы, закрытые для внешнего доступа). + + 2. Предоставление возможности партнёрам ограничивать функциональность, которая доступна по ключу: - 2. Дать возможность партнёрам ограничивать функциональность, которая доступна по ключу: * устанавливать диапазон допустимых IP-адресов для серверных API, идентификаторов приложений и хостов в клиентских API; + * разрешать использование конкретного ключа только для конкретных методов API; + * вводить иные разумные ограничения (например, для ключа нашего кофейного API можно установить ограничения по странам и городам, в которых работает партнёр). - 3. Вводить дополнительное подписывание запроса: - * например, если на странице вебсайта партнера осуществляется поиск лучших предложений лунго, для чего клиент обращается к URL вида `/v1/search?recipe=lungo&api_key={apiKey}`. В этом случае API-ключ может быть заменён на сгенерированную сервером подпись вида `sign = HMAC("recipe=lungo", apiKey)`. Такая подпись может быть украдена, но будет бесполезна для злоумышленника, так как позволяет найти только лунго; + 3. Дополнительное подписывание запроса: + + * например, если на странице вебсайта партнера осуществляется поиск лучших предложений лунго, для чего клиент обращается к URL вида `/v1/search?recipe=lungo&api_key={apiKey}`, то API-ключ может быть заменён на сгенерированную сервером подпись вида `sign = HMAC("recipe=lungo", apiKey)`; такая подпись может быть украдена, но будет бесполезна для злоумышленника, так как позволяет найти только лунго; + * вместо API-ключа можно использовать одноразовые пароли (Time-Based One-Time Password, TOTP); такие токены действительны, как правило, в течение короткого времени, порядка минуты, что чрезвычайно затрудняет злоумышленнику работу с украденными ключами. - 4. Банить ключи. Эта операция почти всегда вызовет негативную реакцию партнёра, но, в конце концов, для многих бизнесов лучше временно лишиться какой-то функциональности в приложении, чем получить многомиллионный счёт. - -#### Щит и меч - -Описанные выше методы — по сути, вариации существующих алгоритмов защиты авторских прав (DRM, Digital Rights Management), поскольку конечная цель защиты та же: не допустить несанкционированного использования данных, доступных клиенту. И, как и в случае DRM, недостаток этого подхода — это усложнение использования сервиса для абсолютно законопослушных партнёров и конечных пользователей. Это первая причина, по которой совершенствование и усложнение защиты может привести к неконкурентоспособности продукта и накоплению негативной репутации в глазах потребителей. - -Вторая причина состоит в том, что любые технологии подобного рода — всегда эвристические и не дают стопроцентных гарантий. По большому счёту их цель — сделать атаку на API настолько затратной, чтобы пропала целесообразность атаковать. Предотвратить атаку полностью невозможно, поскольку у злоумышленника всегда есть в запасе дорогой, но работающий способ посадить реальных людей с реальными приложениями, чтобы они выполняли нужные запросы к API и были неотличимы от обычных пользователей. Вводя сложные алгоритмы, вы тем самым проводите своеобразный «эволюционный отбор», направленный на выявление самых умных и хитрых злоумышленников, противодействовать которым будет гораздо сложнее, чем наивным попыткам украсть ключи. - -В конечном итоге, когда наивные злоумышленники закончились, а умные научились обходить все технические препоны, бороться с выявленным нарушением вам придётся административными методами, т.е. путём написания жалоб хостерам «пиратских» сайтов и обращений в магазины приложений и в суд. Для этого важно, чтобы доказательства нарушения были просты и очевидны, в то время как продемонстрировать факт взлома сложных DRM-алгоритмов может быть далеко не тривиальной задачей. С нашей точки зрения лучшей политикой борьбы с фродом является пассивный мониторинг нарушений (с последующим принятием административных мер) плюс возможность партнерам по их желанию установить дополнительные технические ограничения плюс административное преследование наиболее вопиющих случаев. (Уточнение «вопиющих» важное: судебные действия против таких «предпринимателей» обязательно вызовут напряженность со стороны бизнеса и разработчиков, которые могут иметь совсем другое мнение относительно тяжести нарушения; важно, чтобы деяние заслуживало строгости наказания и в глазах незаинтересованных сторон.) + 4. Обращаться к администрации (хостерам и владельцам магазинов приложений) — в случае, если нарушитель распространяет своё приложение легально или пользуется услугами добросовестного хостера, рассматривающего такого рода обращения. Обращение в правоохранительные органы и суды тоже вполне осмысленно, и даже более разумно, чем в случае фрода от имени пользователей, так как несанкционированный доступ к компьютерным системам с использованием украденных ключей в большинстве юрисдикций чётко подпадает под уголовный кодекс. + + 5. Банить скомпрометированные ключи; эта операция почти всегда вызовет негативную реакцию партнёра, но, в конце концов, для многих бизнесов лучше временно лишиться какой-то функциональности в приложении, чем получить многомиллионный счёт. diff --git a/src/templates.js b/src/templates.js index 21b8495..738bbcc 100644 --- a/src/templates.js +++ b/src/templates.js @@ -35,7 +35,7 @@ const templates = (module.exports = { - + ${l10n.author}. ${l10n.title}