0

I'm designing 2 websites. The first to upload images and the second to store the images as an image hosting (both of them are using asp.net mvc 5).

The domain name of the first website is: vinachannel.com.

In the first website, I wanna send some images to the hosting via ajax:

var f = new FormData();
$.ajax({
   url: 'https://myimagehosting.com/home/upload',
   type: 'POST',
   data: f,
   processData: false,
   contentType: false
}).done(function (data) {
   // logic...
})

Action Upload in Home controller of the hosting:

[HttpPost]
public JsonResult Upload()
{
   if (Request.Files.Count > 0)
   {
      // start uploading...
   }
}

Now, my problem is: I wanna the image hosting accepts only the requests which are sent from vinachannel.com. Just like:

[HttpPost]
public JsonResult Upload()
{
   if (Request.Files.Count > 0 && Request.Url.AbsoluteUri.StartsWith("vinachannel.com"))
   {
      // start uploading...
   }
}

or using regex:

var reg = new Regex(@"^(https://)?(www\.)?(vinachannel\.com)(.+)$");
if (Request.Files.Count > 0 && reg.IsMatch(Request.Url.AbsoluteUri))
{
   // start uploading...
}

My question: How can I custom an attribute to validate all requests for action Upload?

[VinaChannel] // only requests from site vinachannel.com
[HttpPost]
public JsonResult Upload()
{
   // ...
}

UPDATE: (based on @David's comment and following the article)

public class VinaChannelFilter : ActionFilterAttribute, IActionFilter
{
    void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
    {
        var reg = new Regex(@"^(https://)?(www\.)?(vinachannel\.com)(.+)$");
        if (reg.IsMatch(HttpContext.Current.Request.Url.AbsoluteUri))
        {
           // what's next here...?
        }
        this.OnActionExecuting(filterContext);
    }
}
3
  • 1
    You need a custom ActionFilter subclassed from ActionFilterAttribute. Look at this article: asp.net/mvc/overview/older-versions/hands-on-labs/… Commented Jan 1, 2016 at 19:33
  • @DavidTansey I've just tried based on your advice but I cannot complete it. Can you help me the last part? Commented Jan 1, 2016 at 19:52
  • 2
    you want to add this.OnActionExecuting(filterContext); inside your if since that you want to execute action if it matched regex otherwise send it some where else Commented Jan 1, 2016 at 19:58

2 Answers 2

2

You may create a custom action filter which inspects the request headers and see where the request is coming from and use that values to determine, whether to allow /deny further processing. the Referer header is the one you might want to use.

public class VerifyDomain : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var expectedHost = "domainnameyouwanttocheck";
        var headers = filterContext.HttpContext.Request.Headers;

        if (!String.IsNullOrEmpty(headers["Referer"]) 
                                      && new Uri(headers["Referer"]).Host == expectedHost)
        {
            base.OnActionExecuting(filterContext);
        }
        else
        {
            filterContext.Result = new HttpUnauthorizedResult();
        }           
    }
}

And decorate your action method/controller with the action filter

[VerifyDomain]
[HttpPost]
public ActionResult Upload()
{
  // to do : return something
}

When this endpoint is being accessed from anywhere other than the value you have in the expectedHost variable, the caller will get 401 Unauthorized response. You may update the if condition to check for a list of expectedHost name's to support your local development environment as well.

Sign up to request clarification or add additional context in comments.

1 Comment

You are welcome. You should be checking the Referred , not Host . See my updated answer.
1

Upload() is on myimagehosting.com, right? Then HttpContext.Current.Request.Url.AbsoluteUri will return Uri on myimagehosting.com domain, to get source address you need to get referrer: HttpContext.Current.Request.UrlReferrer.AbsolutePath. But the problem is, it can be easily forged, so depending on your needs, you probably will have to implement more complex Authentication/Authorization logic

1 Comment

Thanks! I will remember it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.