Spoofing Javascript.location.hostname - javascript

I'm developing an API where a website owner submits their website url to a database, when the user uses the API the javascript hostname gets sent to our database and gets checked against the string they submitted when registering. Is it possible for a malicious user to spoof their hostname? If so, are there safer practices?

Anyone can send an arbitrarily constructed HTTP request; the referer headers or the properties of window.location cannot be trusted (even if the user cannot change the contents of window.location in their browser -- at least not without causing a navigation -- the user can always observe what requests get generated as a result of that value, and then send an HTTP request with that altered).
If that will be an issue, then you will probably want to use digital signatures along with the domain to ensure that the domain has not been altered (i.e., changing the domain without changing the signing token will render the request invalid, and generating a signing token from the domain is not obvious and requires some server-side backend mechanism that you provide to the customers of your API).

Related

Automatically submitting form to HTTPS site, how to authenticate?

I'm hacking together a script to automate the submission of tickets to our helpdesk system. So far it's a very simple, but working system. I have a page with a form that auto-submits via JavaScript with form value based on the URL requested.
This works great when you access the page from your browser. Assuming you're already authenticated to the ticket system page, the auto-submitted form happily sends its form data and you are directed to the ticket list where you see the newly auto-submitted ticket. Unfortunately of course, the ticket system is an HTTPS secured site, so if you're not logged in you're directed to the login page and the auto-submission fails.
The idea however is to run this auto-submission on a schedule, or kick it off remotely, where the initiator won't necessarily be human and won't be following the form submission to babysit it with delicious authentication cookies.
So, being a newbie in this area, my options seem to be A) dive in and get real messy by listening for the auto-submission response, determine whether the login page is being returned and submit some credentials via JS (not a huge deal as this automation would run solely on a secured server), then resubmit the form... or B) somehow do this the proper way by authenticating beforehand. But that's where my knowledge ends.
I've read through this similar question, but am still coming up short. Is this proper automation only possible if the server in question supports some form of auth token API? Is there not a more direct way to connect and request/submit data to an HTTPS site? I've been glossing over some introductions to cURL, but have not yet dove in.
NB: I don't have direct access to the ticket database, code, nor to the web server processes/accounts running it. I probably can run processes on the same machine, which is why I'm not real concerned with the security of auto-submitting credentials, but that's probably it.
Firstly, whether your ticket system directs you to a login screen if you're not already authenticated has nothing to do with HTTPS - this will be either a username/password <form> that then sets a cookie, or it will be a WWW-Authenticate header. Each of these can be used whether you are using HTTPS or plain HTTP.
Whichever method it uses, if you're planning on doing this in a web browser, chances are you won't be able to because CORS (cross-origin resource sharing) will probably not have been set up to allow it.
If however you're doing this from a script such as Node.js, Python, PHP or anything else that can make arbitrary HTTP(S) requests, you might want to look at a flow like this:
Request the index page of the ticket system
Detect whether it gave you a login screen
If so, fetch any necessary data from the login screen (e.g. a nonce) and make a POST request as if you filled in the username/password yourself
Check that authentication was successful (based on the POST response)
Keep the cookie returned by your POST request and use it to submit the ticket.
For the simpler case where the system uses a WWW-Authenticate header it would be like this:
Request the index page of the ticket system
Detect the WWW-Authenticate header in the HTTP 401 response received
Send an Authorization header with an appropriate value
Check that authentication was successful (based on getting an HTTP 200 instead of a HTTP 401)
Send the same Authorization header again while submitting the ticket.
Using WWW-Authenticate is described at Wikipedia for basic and digest authentication.

Skip HTTP authentication with Javascript?

I have a site where user must login to access. I have some web services calls for getting datas stored in another server.
But to access to the server user must login again via a login popup. To avoid this I want to pass the user/password but not in the URL.
Is it possible to do this in Javascript adding user/password in header or something similar ?
Authorization of this type is typically done via request headers. For regular users interacting with a web page, the login credentials may be remembered using the cookies in the request. For API access, however, the standard way to do this is with bearer tokens included in the POST body of the request. See also: OAuth2.
For authenticating API access (but not the user), such authentication is typically done via API keys.
Important footnote: whenever doing any authentication, you should ensure that your requests are encrypted (and, when setting cookies, that cookies used for authentication are properly marked "secure").
Take a look at the W3C specifications for the XMLHttpRequest Object. The five-parameter version of the 'open' method allow you to specify the username and password.
EDITED
Keep in mind: this will make your password publicly accessible.

JS - How to securely use window.postMessage when the sender domain is unknown

I would like to create a secure postMessage connection (origin safe), with an Iframe that is created at runtime.
Current state:
I have a script, that generates an iframe with a specific domain (domain.b.com in the example below). I want that iframe to receive messages only from the parent domain (the page that included my script). Since the parent domain is unknown at runtime, I'm thinking of a "Handshake" process as described and illustrated below:
Wait for Iframe to be loaded.
Send postMessage from the parent domain with it's origin.
Set the allowed origin to be the 1st received origin
Edit:
More Info:
On my server I have a whitelist domains (for example domain.a.com, any.domain.com, domain.b.com)
My Goal is to integrate with some of my clients (for example domain.a.com , domain.b.com)
Once integrated I want to prevent hackers injecting Iframes that can listen to sensitive information over postMessage
I want to avoid checking the whitelist, I prefer to give some acessToken, but not sure what is the right flow.
Example 1:
Example 2:
Is that the right way to implement it?
As mentioned here, you should not expect the parent's origin to be sent to you in postMessage's parameter. Instead:
If you do expect to receive messages from other sites, always verify
the sender's identity using the origin and possibly source properties.
Any window (including, for example, http://evil.example.com) can send
a message to any other window, and you have no guarantees that an
unknown sender will not send malicious messages. Having verified
identity, however, you still should always verify the syntax of the
received message. Otherwise, a security hole in the site you trusted
to send only trusted messages could then open a cross-site scripting
hole in your site.
And once you have the main frame's URI in your iframe, you can verify its authorization with a simple AJAX call to the server. In my point of view, a server call is inevitable and one way or another you will make such a call.
There are other ways to know who is including your iframe but they are not relying on postMessage. For instance if you are using PHP, you can check $_SERVER['HTTP_REFERER'] to see who is requesting your iframe even before it is sent to the browser. Yet there are ways to referrer spoofing as well.
If your application requires a solid bullet proof solution then server to server communication is your way. In this scenario, each client of yours has a username and password and the web server who is going to serve the main page should ask for a one time pass token from the web server who is serving the iframe (this is a server to server communication). And then use the token in the iframe's URL to be sent back to the server generated it. Here's a step by step of this scenario:
End user asks for the URL http://customer.com/main.php.
While main.php is executing and populating the response, it also
connects to
http://you_website.com/generate_token.php?username=cutomer1&password=123
and gets a one time pass token token1.
The response is returned to the browser containing an iframe with URL http://your_website.com/iframe.php?token=token1.
In iframe.php you verify the token1 to see if it is valid, and
, at the same time, you are authenticating the requester without actually asking
for his username and/or password (since you know who you have
generated the token for).
Such tokens are usually deleted once used (one time pass) and they also usually come with an expiration data. But that's up to you and your application.

Accessing Pages that need authentication via JavaScript

I'm fairly new to JavaScript and I'm trying to access a page that requires user authentication before that page is displayed.
How do I access this page? (I have the required user name and Password) I'm know we can use the XML HTTPrequest object to access other URLs via the script. But I'm not aware of any option that lets me authenticate first.
How do I do this?
You should probably make a request to the authentication page, sending username and password. That would set a session cookie that the browser will handle on his own, then the session cookie will automatically be forwarded to the following requests you make, until the session expiral.
Remember however about the limits of cross-domain scripting, e.g. if the page you want to authenticate is in a different domain than the one the page the script is running in is the browser will likely refuse to make any request.
Actually this automatic cookie handling from the browser is the reason cross-domain scripting is insecure and thus forbidden for most sites.

Is it possible to restrict an API to only one web interface/app?

I have a question regarding cross-origin policies.
I have a web app that gets data, usually in JSON format, via ajax.
When the web app initialize, a unique 'key' or 'token' is created from the server via ajax and is sent to the client, as a mean to identify it. The token is sent back on every ajax call for validation purposes. If it is not validated within two hours, a PHP script deletes it, and the user is required to authenticate him/herself again.
If the user sends another ajax call (i.e. if there is activity with the associated token), the token sets its expiration for another 2 hours.
On every call, I validate the token and then process the request. Everything works well but my issue is security-oriented.
Since the token is stored client-side (very crudely, like window.token = 'YTM0NZomIzI2OTsmIzM0NTueYQ==';), won't it be possible for malicious users to inspect the code, copy the JavaScript including the token, and create another app that will access the same data?
Since the token is stored client-side (very crudely, like window.token = 'YTM0NZomIzI2OTsmIzM0NTueYQ==';), won't it be possible for malicious users to inspect the code, copy the JavaScript including the token, and create another app that will access the same data?
Yes.
And possibly even more disturbing to you may be this: it doesn't even matter how your token is stored client-side - they'd even be able to login using the same API you expose to your users for logging in. (And if you think you don't have a login API because it's a form-post or something similar, you're fooling yourself - a form post is just as much an "API" as anything else... and can easily be replicated elsewhere).
The cross-domain stuff has very little to do with anything - as that's a client-side restriction of a browser - intended for the user's protection - not yours. I can make any HTTP request I want from a desktop or a server. I can even setup a service which allows me to proxy all requests made to my service over to your service... so the cross-domain security in browsers is of no help to you.

Categories