В этой статье мы мак­сималь­но глу­боко изу­чим тех­нологию JSON Web Tokens (JWT): где она исполь­зует­ся, в чем ее плю­сы и минусы и какие опас­ности она может таить для все­го веб‑при­ложе­ния, если прог­раммист видит ее впер­вые. Мы так­же рас­смот­рим типич­ные уяз­вимос­ти JWT, научим­ся их экс­плу­ати­ровать и исправ­лять.
 

Аутентификация и авторизация

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

Пред­ста­вим, что мы хотим вой­ти в свой акка­унт Facebook. Веб‑при­ложе­нию нуж­но понять, что мы вла­деем этим акка­унтом. Для это­го оно про­сит нас пре­дос­тавить кор­рек­тные учет­ные дан­ные. Обыч­но это логин и пароль, которые мы вво­дим на стра­нице вхо­да.

При­ложе­ние про­веря­ет пре­дос­тавлен­ные дан­ные, и, если они вер­ны, мы вхо­дим в собс­твен­ный акка­унт. Этот про­цесс называ­ется аутен­тифика­цией.

info

Аутен­тифика­ция — про­вер­ка под­линнос­ти предъ­явленно­го поль­зовате­лем иден­тифика­тора, в про­цес­се которой поль­зователь доказы­вает, что он дей­стви­тель­но тот, за кого себя выда­ет. Срав­нение пароля, вве­ден­ного поль­зовате­лем, с паролем, который сох­ранен в базе дан­ных сер­вера, — один из при­меров аутен­тифика­ции.

Высокоуровневая схема аутентификации
Вы­соко­уров­невая схе­ма аутен­тифика­ции

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

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

info

Ав­ториза­ция — это про­цесс про­вер­ки, под­твержде­ния или пре­дос­тавле­ния раз­решений, прав дос­тупа и при­виле­гий на выпол­нение опре­делен­ных дей­ствий. При­мер авто­риза­ции: поль­зователь хочет про­читать документ на сай­те, при­ложе­ние про­веря­ет, име­ет ли он пра­во читать его.

Высокоуровневая схема авторизации
Вы­соко­уров­невая схе­ма авто­риза­ции

Аутен­тифика­ция про­ходит один раз, ког­да ты вво­дишь логин и пароль. Авто­риза­ция про­исхо­дит при каж­дом зап­росе пос­ле аутен­тифика­ции, поэто­му если допус­тить ошиб­ку в этой сис­теме, то зло­умыш­ленни­ки смо­гут выпол­нять дей­ствия от име­ни дру­гих поль­зовате­лей. Нап­ример, сде­лать покуп­ку от их име­ни или узнать кон­фиден­циаль­ную информа­цию. Важ­но знать безопас­ные и про­верен­ные спо­собы как аутен­тифика­ции, так и авто­риза­ции.

 

Куки и токены

Сес­сион­ные cookie и токены — два важ­ных и вза­имо­заме­няемых механиз­ма безопас­ности в сов­ремен­ном вебе, которые исполь­зуют­ся в про­цес­сах аутен­тифика­ции и авто­риза­ции.

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

 

Куки

Взаимодействие браузера и сервера с куками
Вза­имо­дей­ствие бра­узе­ра и сер­вера с куками

HTTP Cookie — это неболь­шие записи, которы­ми обме­нива­ются кли­ент (твой бра­узер) и сер­вер. Вся­кий раз при обра­щении к соот­ветс­тву­юще­му сай­ту эти дан­ные пересы­лают­ся сер­веру в сос­таве HTTP-зап­роса.

Ку­ки при­дума­ны дав­но, в начале девянос­тых годов. В июне 1994 года Лу Мон­тулли, сот­рудни­ку Netscape Communications, приш­ла идея исполь­зовать их при веб‑соеди­нении.

Ку­ки исполь­зуют­ся в веб‑при­ложе­ниях:

  • для управле­ния сеан­сами поль­зовате­ля и про­вер­ки его прав;
  • для отсле­жива­ния активнос­ти и пер­сонали­зации кон­тента (спе­циаль­ные «рек­ламные» куки).

Про­цесс исполь­зования кук выг­лядит сле­дующим обра­зом:

  1. Бра­узер отправ­ляет при­ложе­нию зап­рос с логином и паролем.
  2. При­ложе­ние про­веря­ет логин и пароль поль­зовате­ля. Если они сов­пада­ют с теми, что хра­нят­ся в базе (вмес­то паролей срав­нива­ются их хеши), то при­ложе­ние фор­миру­ет сес­сию, генери­рует сес­сион­ную куку и отправ­ляет ее бра­узе­ру поль­зовате­ля.
  3. Бра­узер сох­раня­ет куку и отправ­ляет ее вмес­те с каж­дым зап­росом в при­ложе­ние.
  4. При­ложе­ние получа­ет куку, рас­шифро­выва­ет ее и, если она валид­ная, выпол­няет дей­ствие от име­ни авто­ризо­ван­ного поль­зовате­ля.

В ито­ге нам не нуж­но вво­дить пароль каж­дый раз. Бла­года­ря кукам сер­вер понима­ет, что мы уже прош­ли этот про­цесс.

info

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

Для прис­воения куки поль­зовате­лю сер­вер отправ­ляет такой заголо­вок:

Set-Cookie: <имя cookie>=<значение cookie>

Бра­узер в свою оче­редь — такой:

Cookie: <имя cookie>=<значение cookie>

Каж­дый из этих заголов­ков под­держи­вает мно­жес­тво атри­бутов, которые поз­воля­ют сни­зить рис­ки при воз­никно­вении уяз­вимос­тей на сто­роне при­ложе­ния.

 

Токены

В сов­ремен­ном вебе исполь­зуют­ся не толь­ко куки, но и токены. Это аль­тер­натив­ный и более сов­ремен­ный механизм, который име­ет свои плю­сы и минусы по срав­нению с при­выч­ными «печень­ками».

Нап­ример, ког­да ты хочешь аутен­тифици­ровать­ся на сай­те через дру­гой сайт, на котором ты уже аутен­тифици­рован (нап­ример, вой­ти в Facebook через Gmail), исполь­зуют­ся OAuth-токены для меж­сервер­ной аутен­тифика­ции меж­ду при­ложе­нием и про­вай­дером дан­ных.

OAuth — не единс­твен­ные токены, сущес­тву­ет мно­го дру­гих фор­матов:

  • Simple Web Token — набор пар имя — зна­чение в фор­мате кодиро­вания HTML Form, опи­сыва­ет стан­дар­тные клю­чи Issuer, Audience, ExpiresOn и HMACSHA256;
  • Security Assertion Markup Language (SAML) — опре­деля­ет токены в XML-фор­мате, вклю­чающем информа­цию об эми­тен­те и субъ­екте, а так­же усло­вия для валида­ции токена. Под­пись осу­щест­вля­ется при помощи асим­метрич­ной крип­тогра­фии. Содер­жат механизм для под­твержде­ния вла­дения токеном;
  • JSON Web Token, JWT — тре­тий вид токенов, который мы сей­час под­робно рас­смот­рим.
 

Что такое JWT

Три основополагающие части JWT
Три осно­вопо­лага­ющие час­ти JWT

Аб­бре­виату­ра JWT рас­шифро­выва­ется как JSON Web Token. Стан­дарт RFC 7519 опи­сыва­ет отправ­ку крип­тогра­фичес­ки под­писан­ных JSON дан­ных (зна­чений key-value) меж­ду сис­темами. Теоре­тичес­ки стан­дарт RFC 7519 допус­кает отправ­ку любых дан­ных, но в сов­ремен­ном вебе чаще исполь­зует­ся, что­бы переда­вать информа­цию о поль­зовате­лях для аутен­тифика­ции, обра­бот­ки сеан­сов и кон­тро­ля дос­тупа.

info

JWT (JSON Web Token) — это спе­циаль­ный фор­мат токена, который поз­воля­ет безопас­но переда­вать дан­ные меж­ду кли­ентом и сер­вером. В качес­тве кли­ента может выс­тупать бра­узер поль­зовате­ля или мобиль­ное при­ложе­ние, сер­вера — вир­туаль­ная машина или выделен­ный компь­ютер с запущен­ным веб‑при­ложе­нием.

JWT-токены были при­дума­ны гораз­до поз­же, чем куки. В 2011 году была сфор­мирова­на груп­па JOSE (JSON Object Signing and Encryption group), приз­ванная стан­дарти­зиро­вать механизм защиты целос­тнос­ти, шиф­рования, а так­же фор­мат клю­чей и алго­рит­мов иден­тифика­ции для обес­печения сов­мести­мос­ти служб безопас­ности, исполь­зующих фор­мат JSON. К 2013 году в откры­том дос­тупе появи­лись неофи­циаль­ные наб­роски и при­меры исполь­зования идей этой груп­пы. Офи­циаль­но был стан­дарти­зиро­ван груп­пой IETF в мае 2015 года.

То­кены, как и сес­сион­ные куки, соз­дают­ся сер­вером либо в начале вза­имо­дей­ствия поль­зовате­ля с сай­том или при­ложе­нием, либо пос­ле аутен­тифика­ции поль­зовате­ля в при­ложе­нии. Затем они отправ­ляют­ся поль­зовате­лю как часть отве­та сер­вера — либо в HTTP-заголов­ке Set-Cookie, либо в заголов­ке Bearer. От того, где будет записан токен, зависит, как стро­ится даль­нейшая модель безопас­ности.

Взаимодействие браузера и сервера с JWT
Вза­имо­дей­ствие бра­узе­ра и сер­вера с JWT

Аутен­тифика­ция и авто­риза­ция с исполь­зовани­ем JWT-токена устро­ена сле­дующим обра­зом:

  1. Бра­узер отправ­ляет зап­рос при­ложе­нию с логином и паролем.
  2. При­ложе­ние про­веря­ет логин и пароль и, если они вер­ны, генери­рует JWT-токен, который затем отправ­ляет бра­узе­ру. При генера­ции JWT-токена веб‑при­ложе­ние ста­вит под­пись сек­ретным клю­чом, который хра­нит­ся толь­ко в при­ложе­нии. Может исполь­зовать­ся как сим­метрич­ное шиф­рование, так и асим­метрич­ное.
  3. Бра­узер сох­раня­ет JWT-токен и отправ­ляет его вмес­те с каж­дым зап­росом в при­ложе­ние.
  4. При­ложе­ние про­веря­ет JWT-токен и, если он валид­ный (то есть он пра­виль­но сфор­мирован и дан­ные не были изме­нены), выпол­няет дей­ствие от име­ни авто­ризо­ван­ного поль­зовате­ля.

Все дан­ные, которые нуж­ны сер­веру, хра­нят­ся на сто­роне кли­ента в самом JWT. Это дела­ет JWT популяр­ным выбором для высоко­рас­пре­делен­ных веб‑сай­тов, где поль­зовате­лям необ­ходимо бес­пре­пятс­твен­но вза­имо­дей­ство­вать с нес­коль­кими внут­ренни­ми сер­верами.

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

При под­писи токена исполь­зует­ся шиф­рование. С помощью под­писи веб‑при­ложе­ние про­веря­ет, что токен дей­стви­тель­но был сге­нери­рован им. Алго­рит­мы шиф­рования могут быть раз­ными, нап­ример HS256 — HMAC с SHA-256.

 

Формат JWT

JWT-токен сос­тоит из трех час­тей, которые раз­делены точ­кой:

  • Header (заголо­вок) — информа­ция о токене, тип токена и алго­ритм шиф­рования;
  • Payload (полез­ные дан­ные) — дан­ные, которые мы хотим передать в токене. Нап­ример, имя поль­зовате­ля, его роль, исте­кает ли токен. Эти дан­ные пред­став­лены в виде JSON-объ­екта;
  • Signature (под­пись) — под­пись токена, которая поз­воля­ет про­верить, что токен не был изме­нен.

Фор­мат токена:

header.payload.signature

Каж­дая из этих час­тей обыч­но кодиру­ется в Base64 для переда­чи без пов­режде­ний по сети. Помимо это­го, исполь­зует­ся облегчен­ный вари­ант URL-кодиро­вания. Свой­ствен­ный Base64 знак равенс­тва усе­кает­ся. Плюс заменя­ется минусом, а слеш (/) — под­черки­вани­ем, что­бы не воз­никло кол­лизий.

При­мер токена:

eyJraWQiOiI5MTM2ZGRiMy1jYjBhLTRhMTktYTA3ZS1lYWRmNWE0NGM4YjUiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsImV4cCI6MTY0ODAzNzE2NCwibmFtZSI6IkNhcmxvcyBNb250b3lhIiwic3ViIjoiY2FybG9zIiwicm9sZSI6ImJsb2dfYXV0aG9yIiwiZW1haWwiOiJjYXJsb3NAY2FybG9zLW1vbnRveWEubmV0IiwiaWF0IjoxNTE2MjM5MDIyfQ.SYZBPIBg2CRjXAJ8vCER0LA_ENjII1JakvNQoP-Hw6GG1zfl4JyngsZReIfqRvIAEi5L4HV0q7_9qGhQZvy9ZdxEJbwTxRs_6Lb-fZTDpW6lKYNdMyjw45_alSCZ1fypsMWz_2mTpQzil0lOtps5Ei_z7mM7M8gCwe_AGpI53JxduQOaB5HkT5gVrv9cKu9CsW5MS6ZbqYXpGyOG5ehoxqm8DL5tFYaW3lB50ELxi0KsuTKEbD0t5BCl0aCR2MBJWAbN-xeLwEenaqBiwPVvKixYleeDQiBEIylFdNNIMviKRgXiYuAvMziVPbwSgkZVHeEdF5MQP1Oe2Spac-6IfA
 

Header

За­голо­вок обыч­но сос­тоит из JSON-объ­екта с дву­мя свой­ства­ми:

  • тип токена, в нашем слу­чае — JWT;
  • ал­горитм шиф­рования, в нашем слу­чае — HMAC SHA-256.

Да­лее этот JSON-объ­ект хеширу­ется с помощью Base64URL-кодиро­вания, что­бы пред­ста­вить его в виде ком­пак­тной стро­ки.

Та­ким обра­зом, в нашем при­мере заголо­вок JWT-токена име­ет сле­дующее зна­чение:

{
"kid": "9136ddb3-cb0a-4a19-a07e-eadf5a44c8b5",
"alg": "RS256"
}

Так­же напом­ню, что это не шиф­рование, поэто­му его мож­но рас­кодиро­вать из кон­соли Linux:

$ echo eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9 | base64 -d
{"typ":"JWT","alg":"HS256"}

Или из кон­соли JavaScript в бра­узе­ре:

>> atob("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9")
"{"typ":"JWT","alg":"HS256"}"

Ва­риант рас­шифров­ки через PowerShell:

PS C:\> [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9"))
{"typ":"JWT","alg":"HS256"}

Мож­но даже из CMD, но чуть слож­нее:

C:\>echo eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9 > file.txt && certutil -decode -f file.txt outfile.txt && type outfile.txt
Input Length = 40
Output Length = 27
CertUtil: -decode command completed successfully.
{"typ":"JWT","alg":"HS256"}
 

Payload

Вто­рая часть токена — это полез­ная наг­рузка в виде JSON-объ­екта. Она содер­жит дан­ные об авто­ризо­ван­ном поль­зовате­ле. Зна­чение этой час­ти JWT-токена раз­ное в раз­ных веб‑при­ложе­ниях. Мы можем записать здесь любые пуб­личные дан­ные, которые могут быть полез­ны при авто­риза­ции.

Как и заголо­вок JWT-токена, полез­ная наг­рузка хеширу­ется с помощью Base64URL-кодиро­вания для пред­став­ления в виде ком­пак­тной стро­ки.

В нашем при­мере полез­ная наг­рузка JWT-токена име­ет сле­дующее зна­чение:

{
"iss": "portswigger",
"exp": 1648037164,
"name": "Carlos Montoya",
"sub": "carlos",
"role": "blog_author",
"email": "carlos@carlos-montoya.net",
"iat": 1516239022
}

Наз­вания некото­рых полей могут показать­ся непонят­ными с пер­вого взгля­да. Здесь говорит­ся о том, кто выписал токен (iss), на кого он выписан (sub и name) и каков его срок жиз­ни (exp), по про­шес­твии которо­го сер­вер дол­жен счи­тать его невалид­ным. Эти дан­ные может изме­нить любой человек, затем закоди­ровать в Base64 и вста­вить на мес­то изна­чаль­ных. Поэто­му вся безопас­ность зависит нап­рямую от крип­тогра­фичес­кой под­писи.

www

При сос­тавле­нии полей полез­ной наг­рузки раз­работ­чики ста­рают­ся учи­тывать име­на из докумен­тации IANA (Internet Assigned Numbers Authority), что­бы избе­жать кон­флик­тов имен с общепри­няты­ми нор­мами.

Ос­новная при­чина, почему наз­вания полей в полез­ной наг­рузке JWT-токена пишут­ся сок­ращен­но, — это умень­шение раз­мера токена пос­ле шиф­рования.

 

Signature

Что­бы соз­дать под­пись, мы дол­жны взять закоди­рован­ный в Base64 заголо­вок, закоди­рован­ную в Base64 полез­ную наг­рузку, сек­ретную стро­ку и зашиф­ровать эти дан­ные. При этом нуж­но исполь­зовать тот же алго­ритм шиф­рования, который ука­зан в заголов­ке JWT-токена.

Вот при­мер для HS256:

HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret
)

Про­цесс соз­дания Signature пред­полага­ет наличие сек­ретно­го клю­ча под­писи. Под­пись поз­воля­ет сер­верам убе­дить­ся в том, что дан­ные, содер­жащи­еся в токене, не были под­деланы кем‑то дру­гим с момен­та его выпус­ка.

www

jwt.io — онлайн‑дебаг­гер, который авто­мати­зиру­ет декоди­рова­ние, про­вер­ку и генера­цию JWT-токенов. Его мож­но исполь­зовать для собс­твен­ных экспе­римен­тов.

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

 

JWT vs JWS vs JWE

Ис­ходная спе­цифи­кация JWT очень огра­ничен­на. Она опре­деля­ет толь­ко фор­мат пред­став­ления информа­ции в виде объ­екта JSON, который может быть передан меж­ду дву­мя сто­рона­ми. На прак­тике JWT поч­ти не исполь­зует­ся как отдель­ная сущ­ность.

Спе­цифи­кация JWT была рас­ширена спе­цифи­каци­ями JSON Web Signature (JWS) — RFC 7515 и JSON Web Encryption (JWE) — RFC 7516, которые опре­деля­ют кон­крет­ные спо­собы реали­зации JWT.

Дру­гими сло­вами, ког­да мы говорим про JWT-токены в кон­тек­сте веба, мы на самом деле име­ем в виду либо JWS-токены, либо токены JWE. Токены JWE и JWS очень похожи, пер­вые зашиф­рованы, а вто­рые закоди­рова­ны.

 

Атаки на JWT-токены

 

Зачем атаковать

Ата­ки на JWT-токены под­разуме­вают отправ­ку зло­умыш­ленни­ком изме­нен­ных токенов на сер­вер для дос­тижения сво­ей цели. Как пра­вило, эта цель зак­люча­ется в том, что­бы обой­ти аутен­тифика­цию и кон­троль дос­тупа, выдавая себя за дру­гого поль­зовате­ля, который уже про­шел аутен­тифика­цию.

 

Последствия атак

Пос­ледс­твия JWT-атак обыч­но серь­езны. Если зло­умыш­ленни­ку уда­ется соз­дать собс­твен­ные дей­стви­тель­ные токены с про­изволь­ными зна­чени­ями, он может повысить свои при­виле­гии или выдать себя за дру­гого поль­зовате­ля, получив пол­ный кон­троль над его учет­ной записью.

 

Почему токены уязвимы

Уяз­вимос­ти, поз­воля­ющие под­делывать JWT-токены, обыч­но воз­ника­ют из‑за несовер­шенной обра­бот­ки этих самых токенов в самом при­ложе­нии. Раз­ные спе­цифи­кации, свя­зан­ные с JWT-токена­ми, отно­ситель­но гиб­ки по сво­ей конс­трук­ции и поз­воля­ют раз­работ­чикам сай­тов самос­тоятель­но опре­делять мно­гие детали реали­зации. В резуль­тате раз­работ­чики могут допус­тить уяз­вимость даже при исполь­зовании биб­лиотек с уси­лен­ной защитой.

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

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

 

Burp Suite и JWT

Сей­час мы перей­дем к рас­смот­рению боль­шинс­тва уяз­вимос­тей, которые могут воз­никнуть при работе с JWT-токена­ми. Мы будем про­верять их на прак­тике, поэто­му советую зарегис­три­ровать­ся на сай­те PortSwigger и решать лабора­тории вмес­те со мной.

info

PortSwigger WebSecurity Academy — бес­плат­ная ака­демия раз­работ­чиков Burp Suite (популяр­ного инс­тру­мен­та, исполь­зуемо­го пен­тесте­рами) для обу­чения безопас­ности.

Кро­ме того, качай Burp Suite и ставь пла­гин JWT Editor, который поможет нам под­писывать JWT-токены и реали­зовать некото­рые ата­ки при про­хож­дении.

 

Неправильная проверка подписей

Вмес­то одной фун­кции выз­вать дру­гую — вот пер­вая ошиб­ка, которую мож­но допус­тить при про­вер­ке под­писи. Зву­чит нелепо, но ее дей­стви­тель­но лег­ко совер­шить — осо­бен­но если ты толь­ко что поз­накомил­ся с токена­ми и работа­ешь с ними впер­вые.

Продолжение доступно только участникам

Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

Вариант 2. Открой один материал

Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.


  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    2 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии