将.NET Web API发布限制为相同来源

Limit a .NET Web API post to same origin
2021-03-07
  •  译文(汉语)
  •  原文(英语)

我正在使用VS 2013 .NET Web API 2.

我知道使用.ajax调用必须启用跨源(CORS),但是,我将如何限制服务器端POST请求.

如果我有一个终结点/api/images,该终结点接受以Base64String形式发布的图像,那么我该如何确保某人不能POST从源域(example.com)以外的任何其他位置将该终结点提交到该终结点.

现在,我检查Request.Headers.Host,如果这不是原始域,则返回403禁止响应.

var origin = Request.Headers.Host;
if (origin != "example.com" 
   return ForbiddenResponse;

我想这很容易伪造.除了实现某种形式的oAuth之外,还有另一种方法吗?像API密钥这样简单的东西需要来回传递(或者可以通过Fiddler读取)吗?

我要解决的是有一个Flash对象,该对象将图像发送到api端点.我显然不希望其他人能够将图像发送到该终点.

速聊1:
您是指服务器端发布请求?就像您有一台可能触发发布服务器端的计算机一样?我认为通常由内部防火墙规则处理
速聊2:
您将如何设置防火墙规则以阻止帖子?难道不是全部来自端口80或443吗?
速聊3:
我不确定100%,但是在这种情况下,我认为防火墙不起作用.防火墙只能阻止来自给定IP地址的流量.如果您不知道要过滤的IP,就无法确定坏人.我可能是错的,但您也必须同时控制防火墙.
速聊4:
我想如果您知道实例所花的时间很长,可以在代码级别将请求白名单到与您的实例相关的IP.
解决过程1

当前,您可以对ASP.NET Web API 2使用CORS支持

https://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api#enable-cors

文章摘录------

启用CORS

现在,让我们在WebService应用程序中启用CORS.首先,添加CORS NuGet软件包.在Visual Studio中,从"工具"菜单中选择"库软件包管理器",然后选择"软件包管理器控制台".在"程序包管理器控制台"窗口中,键入以下命令:

Install-Package Microsoft.AspNet.WebApi.Cors

此命令将安装最新的软件包并更新所有依赖项,包括核心Web API库.使用-Version标志来定位特定版本.CORS软件包需要Web API 2.0或更高版本.

打开文件App_Start / WebApiConfig.cs.将以下代码添加到WebApiConfig.Register方法.

using System.Web.Http;
namespace WebService
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // New code
            config.EnableCors();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
}

接下来,将[EnableCors]属性添加到TestController类中:

using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Cors;
namespace WebService.Controllers
{
    [EnableCors(origins: "http://mywebclient.azurewebsites.net", headers: "*", methods: "*")]
    public class TestController : ApiController
    {
        // Controller methods not shown...
    }
}
解决过程2

无需赘述,您可以使用某种公共/专用加密密钥,该密钥与图像一起进行POST.

我刚刚进行了搜索,发现这篇文章可能会帮助您进行Flash方面的加密.本文涉及数据库,但是其中包含有关加密的信息:

http://help.adobe.com/zh_CN/as3/dev/WS8AFC5E35-DC79-4082-9AD4-DE1A2B41DAAF.html#WS61068DCE-9499-4d40-82B8-B71CC35D832C

一旦平方下来,就可以在API端进行解密.他们只需要共享某种密码即可.在.NET方面,请参阅本文:

http://blogs.msdn.com/b/shawnfa/archive/2009/03/17/authenticated-symmetric-encryption-in-net.aspx

希望这会有所帮助.如果不使用某种身份验证方法,将很难保护端点免受欺骗性帖子的攻击.

还要注意,闪存加密使用AES-CCM,因此您将必须在.NET端使用此方法进行解密.

速聊1:
显然,这必须通过SSL进行,否则有人会滥用Fiddler并看到"令牌"被传递到端点了吗?这就是我需要使用某种时间戳来停止重放攻击的地方.
速聊2:
SSL永远是一个加号.我认为您所推荐的是随机数.en.wikipedia.org/wiki/Cryptographic_nonce.

I'm using VS 2013 .NET Web API 2.

I know with .ajax calls you have to enable Cross Origin (CORS), however, how would I limit server side POST requests.

If I have an endpoint called /api/images that accepts posted images in the form of a Base64String, how do I make sure that someone can't submit a POST to that end point from anywhere other than the origin domain (example.com).

Right now I check the Request.Headers.Host and if that's not the origin domain I return a 403 Forbidden Response.

var origin = Request.Headers.Host;
if (origin != "example.com" 
   return ForbiddenResponse;

I imagine that is easy to fake. Is there another way to do this besides implemented a form of oAuth? Something simple like an API Key that needs to be passed back and forth (or is it possible that could be read via Fiddler)?

What I'm trying to solve is there is a flash object which sends an image to an api end point. I obviously don't want anyone else to be able to send an image to that end point.

Talk1:
What do you mean server side post requests? Like you have another machine that might trigger the post server side? I think typically that's handled by internal firewall rules
Talk2:
How would you setup a firewall rule to block Posts? Doesn't it all come from port 80 or 443?
Talk3:
I am not 100% sure, but i don't think a firewall would work in this case. A firewall would only be able to block traffic from a given IP address(es). If you don't know which IP's to filter you wouldn't be able to pinpoint the baddies. I could be wrong, but you would also have to be in control of the firewall as well.
Talk4:
I suppose you could whitelist requests at the code level to IPs associated with your instances if you know them ahed of time.
Solutions1

Currently you can use CORS support for ASP.NET Web API 2

https://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api#enable-cors

Article Excerpt ------

Enable CORS

Now let's enable CORS in the WebService app. First, add the CORS NuGet package. In Visual Studio, from the Tools menu, select Library Package Manager, then select Package Manager Console. In the Package Manager Console window, type the following command:

Install-Package Microsoft.AspNet.WebApi.Cors

This command installs the latest package and updates all dependencies, including the core Web API libraries. User the -Version flag to target a specific version. The CORS package requires Web API 2.0 or later.

Open the file App_Start/WebApiConfig.cs. Add the following code to the WebApiConfig.Register method.

using System.Web.Http;
namespace WebService
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // New code
            config.EnableCors();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
}

Next, add the [EnableCors] attribute to the TestController class:

using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Cors;
namespace WebService.Controllers
{
    [EnableCors(origins: "http://mywebclient.azurewebsites.net", headers: "*", methods: "*")]
    public class TestController : ApiController
    {
        // Controller methods not shown...
    }
}
Solutions2

Without going into too much detail you could use some sort of public/private encryption key that gets POST'ed along with the image.

I just did a search and came across this article that might help you with the encryption on the Flash side. The article deals with databases but the info on encryption is in there:

http://help.adobe.com/en_US/as3/dev/WS8AFC5E35-DC79-4082-9AD4-DE1A2B41DAAF.html#WS61068DCE-9499-4d40-82B8-B71CC35D832C

Once you have that squared away you could do the decryption on the API side. They would just need to share a passkey of some sort. on the .NET side refer to this article:

http://blogs.msdn.com/b/shawnfa/archive/2009/03/17/authenticated-symmetric-encryption-in-net.aspx

Hopefully this helps a little bit. Without the use of some sort of authentication method it will be quite difficult to protect your endpoint from spoofed posts.

Also notice that the flash encryption uses AES-CCM so you will have to do the decryption with this method on the .NET side.

Talk1:
And obviously this would have to be done over SSL otherwise someone could juse use Fiddler and see the "token" being passed to the end point right? This would be where I'd need to stop replay attacks using some sort of timestamp.
Talk2:
SSL is always a plus. I think what you are reffering is a nonce. en.wikipedia.org/wiki/Cryptographic_nonce.
转载于:https://stackoverflow.com/questions/23002882/limit-a-net-web-api-post-to-same-origin

本人是.net程序员,因为英语不行,使用工具翻译,希望对有需要的人有所帮助
如果本文质量不好,还请谅解,毕竟这些操作还是比较费时的,英语较好的可以看原文

留言回复
我们只提供高质量资源,素材,源码,坚持 下了就能用 原则,让客户花了钱觉得值
上班时间 : 周一至周五9:00-17:30 期待您的加入