Securing a remote ajax method call

2019-01-26 01:27发布

问题:

I have coded some JavaScript to perform an ajax call in an asp.net application. This triggers a method that calls a URL, sending some parameters in the POST.

The receiving page processes the data and updates our database.

We will be providing this code to customers to allow them to send us the data we need in their checkout process for each transaction.

Can anyone tell me if there is a way to prevent unauthorized access to this URL? Otherwise an unscrupulous developer could use this URL to add data to our database when they shouldn't be.

Thanks for any pointers.


The issue here is that I will be providing the code to our customers and they will be adding it to their website. So I don't have the option of them performing anything much more complex than adding a few lines of code to their site.

The code though, needs to perform a sending of data to our server, somehow securely?

Is this an impossible scenario or would I need to perform some sort of auditing after the processing has occurred?

Thank you everyone for some good suggestions.

回答1:

You can use SOAP to pass a username/password with the request. SSL should be used to encrypt the data going over the wire. Here is some code that we use:

This is a class that will hold the Credentials that are sent with the request:

Imports System.Web.Services.Protocols
Public Class ServiceCredentials

Inherits SoapHeader

Private _userName As String
Public Property UserName() As String
    Get
        Return _userName
    End Get
    Set(ByVal value As String)
        _userName = value
    End Set
End Property


Private _password As String
Public Property Password() As String
    Get
        Return _password
    End Get
    Set(ByVal value As String)
        _password = value
    End Set
End Property

Public Sub New()

End Sub

Public Sub NewUserInfo(ByVal ServiceUser As String, ByVal ServicePassword As String)
    Me.UserName = ServiceUser
    Me.Password = ServicePassword

End Sub

Add an attribute to the definition of your Web Service:

    <WebMethod()> _
<SoapHeader("CredentialsHeader")> _
   Function MyWebMethod(ByVal paremetersPassed as String)
   'check permissions here
   If PermissionsValid(CredentialsHeader) then
    'ok!
       .......
   else
       'throw a permission error
  end if
 End Function

And then from there, just create a function (in my example, PermissionsValid) to check the permissions:

Function PermissionsValid(byval Credentials as ServiceCredentials) as boolean

    'check Credentials.Username and Credentials.Password here and return a boolean
End Function

This may seem like a bunch of work, but this way, when they send a request, you can check it against a database or whatever else you want. You can also turn off a username easily at your end.

A simpler way would be to restrict the IP addresses that are allowed to hit the service page. But, then you run into issues with IP addresses changing, etc.

BTW, much of this was typed as I did the post, so you may need to check over the code to make sure it compiles. :)



回答2:

Set up a user login system exactly as usual - i.e. when a user logs in, store a username and password hash in the session or cookie.

The POST page or handler can simply check for the required credentials - if missing or incorrect, you can then just return a permission error.



回答3:

You should secure you're service using SSL

Edit : I forgot the most "basic" : HTTP authentication (using login/password) I found a link but it's from 2003 : http://www-128.ibm.com/developerworks/webservices/library/ws-sec1.html

Edit 2 : As said in comments, I think the problem here fits in the purpose of REST web services... I don't know anything about asp.net but you should look forward to REST tutorials and see the security alternatives you have from HTTP authentication to full WS-Security implementation



回答4:

Could you check in your receiving page is user is logged in, ie

if User.IsAuthenticated

?



回答5:

Are all your customers on your domain?
If not you won't be able to use the XMLHttpRequest object to send data from their site. The XHR is subject to the Same Origin Policy.
You may be able to post to a page from your server in an iframe. You would need to prompt your users for their username and password so that these details aren't exposed your script and the target should be served over ssl.



回答6:

Sorry, I can't add comments as I don't have enough reupation yet.

I don't fully understand your question. Are you asking if the developer you give the username/password to decides to abuse the webservice?

If that is the case, you will probably want to include some sort of logging into the system. (In fact, you should probably do that no matter what.)

You could write an entry in to some sort of log (file, event log, sql table, etc) during the PermissionsValid function. This could show the IP address and the username passed along with the time stamp of when it was done. This way you can see if someone is trying to 'hack' in.

You could also put something in the MyWebMethod function after the permissions have been validated logging the data that the user is sending. This way you know who was sending it, when, from where and what they sent. If you want to go the extra mile, you could even record the data before any updates have been made. That would give you the ability to roll back any malicious changes.



回答7:

Assuming the follwing:

Browser <-(1)-> ASP/.NET App (`https://123.com/app`) <-(2)-> Web Service (`https://456.com/ws`)

1) Protect the web service using ssl via certificate exchange + basic auth. This way you know the only allowed consumer is the .net app.

2) Create a proxy on the .net app, say at https://123.com/webservicecall that forwards your requests to the web service.

This way, you're not making a call outside the domain of the web app, you'll know the user that is logged in and you're securing the ws endpoint from both viewing and access.

But really it sounds like you shouldn't be using a proxy and instead call the .net app using ajax and the .net app then makes the web service call directly.