8

我有一个网页,它在页面加载时检查加密的 cookie 以确定用户身份。但是,当我在我的开发机器上本地测试页面时,我无权访问该 cookie。

以前我使用一个 appsetting 来告诉页面它是否处于开发模式,当处于开发模式时它会加载一个固定的用户身份。然后我发现了 Request.IsLocal

我可以像这样简单地检查:

if(Request.IsLocal){
   FormsAuthentication.SetAuthCookie("testUser", false);
}else{
   FormsAuthentication.SetAuthCookie(/*EncryptedCookieValue*/, false);
}

这安全吗?恶意用户有没有办法欺骗 IsLocal?

4

4 回答 4

11

I think your actual question is, how do you have development only functionality?

You could you use: Environment.UserInteractive
http://msdn.microsoft.com/en-us/library/system.environment.userinteractive.aspx

It returns false when running in IIS or a Windows Service, true when their is a user interface i.e. Visual Studio when your developing.

I think this is better than a DEBUG pre processor variable because the behaviour is more consistent, you could accidentally upload a DEBUG version of your dll to your live environment unless you have a very tight build/release process.

As a rule of thumb it's not a good idea to trust anything from the client.
I'd also be pragmatic, what are you protecting and how much effort would someone go to hack in?

The below SO post goes into some of the reasons why you shouldn't trust it:
Can I fool HttpRequest.Current.Request.IsLocal?

Reference
You can view the source at http://referencesource.microsoft.com

public bool IsLocal { 
   get {
      String remoteAddress = UserHostAddress; 

      // if unknown, assume not local
      if (String.IsNullOrEmpty(remoteAddress))
         return false; 

      // check if localhost 
      if (remoteAddress == "127.0.0.1" || remoteAddress == "::1") 
         return true;

      // compare with local address
      if (remoteAddress == LocalAddress)
         return true;

      return false;
   } 
于 2013-09-25T16:24:43.130 回答
6

的代码IsLocal似乎很健壮-我看不出它的逻辑有任何缺陷,因此出于您的目的,它应该没问题。

但是,您应该知道,如果您的应用程序(或在同一服务器上运行的任何其他应用程序)发出的任何 HTTP 请求的目的地可能会受到最终用户的影响,那么您应该添加额外的安全层,例如密钥/过期密钥或令牌到您的请求,或者您可以在发出请求时保护 HTTP 请求,以便无法请求本地资源。

例如,假设您的网站有一个端点,例如http://www.example.com/DeleteAllUsers在处理此请求的代码中,您正在检查IsLocal以确保只有当它是本地的、受信任的请求时才能删除用户。

现在假设您的网站上有一个功能Enter a web address to view headers:并且用户http://www.example.com/DeleteAllUsers在此文本框中输入,导致您的应用程序请求DeleteAllUsers并满足IsLocal安全检查,因为 HTTP 请求是从您的应用程序发出的。这就是IsLocal可以被利用的方式,我意识到这是一个人为的例子来证明这一点,但是很多网站都做类似的事情,例如抓取要显示的 URL 的预览图像。如果您的服务器上没有任何东西可以发出本地 HTTP 请求,那么您应该很高兴。

于 2013-09-26T15:17:53.843 回答
2

由于其他答案中提到的原因,您不应将此代码放在生产服务器上。

但是,你可以做

#if DEBUG
    if (Request.IsLocal)
    {
        FormsAuthentication.SetAuthCookie("testUser", false);
    }
    else
    {
#endif
        FormsAuthentication.SetAuthCookie(/*EncryptedCookieValue*/, false);
#if DEBUG
    }
#endif

在您的开发箱上,运行调试构建。在生产中,部署发布版本。

于 2013-09-28T08:59:02.207 回答
1

确定远程 IP 很棘手,取决于正确配置服务器。

例如,配置错误的服务器可能使用 X-Forwarded-For 来确定 IP,但它可以由客户端选择。但是当使用反向代理将其设置为自己的 IP 时,这是确定 IP 的正确方法。

使用来自套接字的 IP 也可能是错误的,请考虑在机器上运行的反向代理作为网络服务器。

=> 如果可能,请使用不同的身份验证机制

于 2013-09-26T15:31:18.227 回答