【转载】【漏洞分析】One Endpoint, Two Account Takeovers

Hello everyone, last year I found an interesting account takeover on a bug bounty program named Namava, they were rather quick patching the vulnerability, but I was also able to break the patch with the help of a friend.
In this blog post, we are going to discuss the steps from the beginning until the end.

大家好,去年我在一个叫 Namava 的错误赏金计划上发现了一个有趣的账户接管,他们很快修补了漏洞,但是我也在一个朋友的帮助下破解了补丁。在这篇博文中,我们将从头到尾讨论这些步骤。

First Account Takeover


Namava is an online TV shows platform like Netflix, it has wide scope (*) and quite interesting functionalities to test for. As always, I started doing basic recon on the target and found the interesting subdomain


This web application was designed to ease the user’s login process. so instead of using TVs to log in, they can use their web application.
Users are given a QR code after clicking the “login by code” button. Here was the exact flow:

Namava 是一个类似于 Netflix 的在线电视节目平台,它具有广泛的范围(*)和相当有趣的功能需要测试。像往常一样,我开始对目标进行基本的侦察,并发现了有趣的子域名 tv.namava.ir。这个 web 应用程序的设计是为了方便用户的登录过程。所以他们可以使用他们的网络应用程序,而不是通过电视登录。用户点击“登陆”按钮后会得到一个二维码。下面是精确的流程:

  1. The 这个 user use the 用户使用“login by code” 「以密码登入」 feature, to get a QR code and a token 这个功能可以让你得到一个二维码和一个令牌 from tv.namava.ir.
  2. The user’s browser sends the request containing the previously generated 用户的浏览器发送包含以前生成的token 令牌
    to the TV application backend each 10 seconds to check the token status. 每隔10秒检查 TV 应用程序的后端,以检查令牌状态
  3. If the user who has already logged in to the main website scans the QR code and the login link will be opened on their browser. 如果用户已经登录到主网站,扫描二维码,登录链接将在他们的浏览器上打开
  4. The application backend ( 应用程序后端(namava.ir) verifies the token in a hidden channel with an API call to )通过 API 调用验证隐藏通道中的令牌tv.namava.ir, if the token is correct, then the ,如果标记是正确的,则token’s status Token 的状态
    will be changed to 将改为

    verified 核实


  5. Since the token has been verified, the user will be logged in with the subsequent request. 由于令牌已经过验证,用户将随后的请求一起登录

Here are the screenshots regarding the generated HTTP requests to make the above steps more clear. The first step, login by token feature:

下面是生成的 HTTP 请求的屏幕截图,以使上面的步骤更加清晰。第一步,按标记登录功能:

Here is an example API call to validate the token:

这里有一个 API 调用的例子来验证这个令牌:

The response, if the token is not verified (QR code is not scanned):

如果令牌没有被验证(二维码没有被扫描) ,响应:

The issued authentication token after opening the QR code link:


The flow mentioned is vulnerable by design. You may ask why? In general, one-click login without the user’s confirmation is not safe. The confirmation terms refer to an action requiring a user’s interaction. So what’s the attacking scenario here?


  1. The attacker opens the website and clicks on the “login by code” button. 攻击者打开网站,点击“代码登录”按钮
  2. The attacker scans the QR code and extracts the login link containing the 攻击者扫描二维码并提取包含token 令牌
    parameter. 参数
  3. The attacker makes a hidden iframe sourced to the login link. 攻击者将一个隐藏的 iframe 提供给登录链接
  4. If the victim visits the URL while logged in to 如果受害者在登录时访问 URLnamava.ir, then the ,然后token 令牌
    will be verified and the attacker gets access to the victim’s account. 然后攻击者就能进入受害者的账户

If the victim is lured to open the attacker’s website while logged in to the Namava application, the account takeover will be possible.

如果受害者被诱骗在登录 Namava 应用程序时打开攻击者的网站,那么帐户接管将是可能的。

The exploit code is as follows (the link is generated in



利用代码如下(链接是在 tv.namava.ir 中生成的) :

<!DOCTYPE html>
     src="https://www.namava.ir/a/nn4zqq" style="width: 0; height: 0; border: 0; border: none;">

This was enough proof of concept for the Namava team to triage the vulnerability and pay the bounty. They also patched the vulnerability rather quickly but it wasn’t a proper patch for this issue.

这对于 Namava 团队来说是足够的概念验证,可以将漏洞分类并支付赏金。他们也修补漏洞相当快,但它不是一个适当的补丁这个问题。

Bypassing the Patch – Second Account Takeover


After approximately two weeks, when I came back to the program to verify the patch. they’ve implemented a confirmation button (Arrival on TV) after opening the login link.


After clicking on the “Arrival on TV” button, there was an HTTP request to namava.ir to confirm that the request wasn’t forged (CSRF). The attacking scenario is to check CSRF bypassing methods. The confirmation request:

点击“ Arrival on TV”按钮后,会有一个 HTTP 请求到 namava.ir 来确认请求不是伪造的(CSRF)。攻击方案是检查 CSRF 绕过方法。确认要求:

There was no CSRF token on the request, although it wasn’t possible to accomplish CSRF as there were several other headers such as




that makes the browser send a preflight request as the request is not simple.

该请求上没有 CSRF 令牌,尽管不可能完成 CSRF,因为有其他几个头文件,如 X-Application-Type 和 X-Auth-Token,使浏览器发送一个飞行前请求,因为请求并不简单。

Their protections against the CSRF were to implement custom headers (




) and the JSON content type leading to a preflight request.

它们对 CSRF 的保护是实现自定义报头(X-Auth-Token 和 X-Application-Type)和导致飞行前请求的 JSON 内容类型。

When it comes to cross-site requests, there are several rules applied by the browsers, one of them is the preflight request (OPTIONS Request), and if the CORS configurations allow it, then the original request will be sent. If you are unfamiliar with this concept I’d suggest you read this link from Mozilla’s website, then this post which explains cross-site requests and browser security features.

当涉及到跨站点请求时,浏览器应用了几个规则,其中之一是飞行前请求(OPTIONS Request) ,如果 CORS 配置允许,那么将发送原始请求。如果你不熟悉这个概念,我建议你阅读 Mozilla 网站上的这个链接,这篇文章解释了跨站点请求和浏览器安全特性。

I tried several tests, one of which was to remove the




headers, to check if the user’s authentication is kept by the cookies. I was amazed that this method worked, so I was one step closer to change the request to a simple request.
The other issue was with the JSON content type. I changed the


header to


, and it worked! so the request was then a simple request with no preflights requests needed.

我尝试了几个测试,其中之一是删除 X-Application-Type 和 X-Auth-Token 头,以检查用户的身份验证是否由 cookie 保留。我很惊讶这种方法居然有效,所以我离将请求更改为简单请求又近了一步。另一个问题是 JSON 内容类型。我将 Content-type 头文件更改为 application/x-www-form-urlencoded,并且它工作了!所以请求只是一个简单的请求,不需要预飞请求。

The response:


The request was vulnerable to CSRF. The exploit code:

这个请求很容易受到 CSRF 攻击:

  <form action="https://www.namava.ir/api/v1.0/accounts/login/by-remote/verify" method="POST" target="namava">
  <input type="hidden" name="fastLoginCode" value="n27494" />
<iframe name="namava"></iframe>
  let iframe=document.getElementsByTagName("iframe")[0];

However, another protection was not discovered yet until then. After the exploit code was executed, the server responded:


The server was checking the


header and it didn’t accept external origins. The HTTP request was sent with the help of exploit code:

服务器正在检查 Origin 头部,它不接受外部起源。HTTP 请求是在利用代码的帮助下发送的:

It seemed the flaw was un-exploitable, after digging a bit more revealed that the server was accepting a


origin as a valid value.

这个缺陷似乎是不可利用的,经过深入研究后发现,服务器正在接受一个 null 原点作为一个有效值。



value as origin header may lead to different security flaws, if you are unfamiliar with the concept please visit the Portswigger’s academy labs on this topic.

作为原始标题的空值可能会导致不同的安全缺陷,如果您不熟悉这个概念,请访问 Portswigger 的学院实验室。

The response:


The final exploit code:


  <iframe src="data:text/html;base64,PHNjcmlwdD4KICAgICAgZnVuY3Rpb24gc3VibWl0UmVxdWVzdCgpCiAgICAgIHsKICAgICAgICB2YXIgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7CiAgICAgICAgeGhyLm9wZW4oIlBPU1QiLCAiaHR0cHM6Ly93d3cubmFtYXZhLmlyL2FwaS92MS4wL2FjY291bnRzL2xvZ2luL2J5LXJlbW90ZS92ZXJpZnkiLCB0cnVlKTsKICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcigiQ29udGVudC1UeXBlIiwgImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCIpOwogICAgICAgIHhoci53aXRoQ3JlZGVudGlhbHMgPSB0cnVlOwogICAgICAgIHhoci5zZW5kKCJmYXN0TG9naW5Db2RlPTdyNTdteiIpOwogICAgICB9CiAgICAgIHN1Ym1pdFJlcXVlc3QoKQo8L3NjcmlwdD4="></iframe>
    let iframe = document.getElementsByTagName("iframe")[0];
    iframe.style.display = "none";



When it comes to CSRF, there are several protections and bypassing methods, I will discuss each:

当谈到 CSRF 时,有几种保护和旁路方法,我将逐一讨论:



  • The best protection is using CSRF tokens. 最好的保护是使用 CSRF 令牌
  • If 如果 custom HTTP headers are used with the purpose of CSRF protection, then they should be compulsory. 自定义 HTTP 头是用来保护 CSRF 的,那么它们应该是强制性的
  • The common security practices should be implemented on the 常见的保安实务应在

    Content-type 内容类型

    header. The developers usually use libraries that supports different content types which makes this bypassing method possible. 开发人员通常使用支持不同内容类型的库,这使得这种旁路方法成为可能

  • The origin header should be correctly whitelisted, the 原始页眉应该正确地使用白名单,null
    value is commonly forgotten by developers. 价值通常被开发者遗忘



  • Eliminating custom headers, they could be removable with no change on the website. 消除自定义标题,它们可以在网站上不做任何更改的情况下被移除
  • Changing the 改变Content-type 内容类型
    header to common simple requests header. 通常简单的请求头
  • Using various bypassing methods for the 对象使用各种绕过方法origin 起源
    header. 集管

I’m hoping that you liked this write-up. leave me your feedback on the topics you would like to read more about.
Thanks for reading!