Accessing form data inside iframe - html

Is it possible to access form data with javascript inside iframe from external source?
For example: I have a web store on example.com. If I use payment gateway stripe.com with iframe integration https://stripe.com/checkout is it possible to access input data user inserts in iframe popup on interval 1s?
I would like to be sure that i case one hacks into my website, one cannot access payment details of customers.

Is it possible to access form data with javascript inside iframe from external source?
No. This is prevented by the Same Origin Policy.
If I use payment gateway stripe.com with iframe integration https://stripe.com/checkout is it possible to access input data user inserts
Not in a straightforward JS way, but there have been a number of clickjacking attacks against content in iframes. See for example http://www.contextis.com/documents/5/Context-Clickjacking_white_paper.pdf
However in this case the point is moot, as:
I would like to be sure that i case one hacks into my website, one cannot access payment details of customers.
This is not achievable. If your site is compromised (either at the server or at the client via XSS), the attacker can change the parent page to make it pop up a fake checkout iframe instead of using the real Stripe script, one that leaks entered payment details.
This is a risk with all iframe-based checkouts: the user can't verify the origin and HTTPS details of an iframe, so they have to trust those of the parent page (merchant).

Related

Securing an iFrame form

For our ASP.NET application we have an API which users can use to send data from their website forms (e.g. a sign-up form) directly to our application.
To use this, obviously some programming is required to connect their forms to our API. Some users (or their website developers) find this too difficult. So the idea is to provide a standard webform which can be included in their website using an iFrame. The webform should be unique per user, specified by using an ID or key in the URL or in a hidden field. For example, they can link their iFrame to an URL like https://myapplication.com/webform/CustomerID-1001
My question is how can we secure this webform? For the API we use an API-key, but that is used only serverside. Since the suggested webform is hosted in our application, the user cannot set anything serverside. So how can we prevent a malicious website visitor from copying the entire form (including the complete URL or hidden fields) from a valid user's website and using it in an iFrame on their own malicious website? (or at least stop the form from working in this case)
Do you have any suggestions about securing such a webform?

web application architecture (javascript client side + ASP.NET server side)

This question comes from the following post:
OWIN cookie authentication get roles on client side
I've created a separate thread for the question since it is more general than one in the post above.
In short:
Let's say we have a web application with javascript as client side + ASP.NET web api as server side and also an identity server. Only authenticated users can access web api endpoints, some of them accessible only for specific roles of user.
Now the client side of application should show specific items based on what role user is in. For example: user in administrator role can see an extra tab: manage items. There are two approaches to achieve this:
When rendering client side application, one could call an endpoind in web api which would return what roles user have. Based on that result, show/hide items in html.
When application loads, an endpoint, which returns how the structure should look like (for example: json string) would be returned, and based on that structure client application would be rendered. No show/hide html on client side based on roles in such case.
Now regarding 1st point: some could argue that there is a security leak, since malicious user can modify html to see elements that he is not supposed to see. But in this case he will not see any content from database and will not be able to load/update it since he will not be authorized to do that based on his role which is checked in server side.
2nd point seems more valid since we keep all identity related information logic on server side. And also all unnecessary content is not in html (while in 1st point it's hidden) - so that leads to better performance? In this case though if for example developing angular application, the json structure of application should include such information as name of angular controller and route for example. Would that not add complexity to developing application?
Assume that the application itself have a lot of roles and a lot of items should be visible/not visible based on these roles.
Pros/cons between 1st and 2nd? Thanks!
I stick always with the first suggested point.
As you mentioned the second choice will add more complexity for developing. For the 1st there is no security leak. If you don't want your users to modify the html and to access forbidden areas in your application simply use ng-if instead of ng-show. If you are not familiar - ng-if will not just hide the content with display: none;. It will completely remove it from the DOM and this leading the user unable to show that content as it is not in the DOM.
Read this for more detailed explanation for ng-if and ng-show: what is the difference between ng-if and ng-show/ng-hide
I usually have an endpoint getting information about the user - including it's role and save that user into a service (factory). This gives me the flexibility to use it everywhere in the application and check if the user has access or not to certain parts of it.

Include Additional HTTPS Request Header Information in Form

Is there a way to include additional request headers in form data, other than action and method? I am hoping to send some authentication credentials cross domain without making the user re-enter their login credentials. ie I want to build an Authentication header directly from form submission.
The domain is SSL enabled, so I considered including credentials in the URL, but as explained here this is a bad idea, as those credentials may be secure over the connection, but can be accessed through the browser by other apps potentially.
Larger Picture
I have access to the cross domain username and password through an AJAX request to the client server (home domain). I want to take those credentials and submit them through a non-AJAX request, so a user can download a document securely without the URL being publicly accessible.
To the specific question, I believe the answer is no - you can't control sending any extra headers from the form itself. There are some other things you can send with a form, but they are not useful to what you want to do: W3 Form Tag Specification
What you could do is do a form POST, which is the standard way to communicate when sessions cookies are out of the question and a query string won't do; just use a hidden field with some sort of token/hash of the credentials. Avoid clear-text of passwords like the plague, and really try to avoid reversible encryption of them too. This is just one of those areas you have to be extra careful to avoid creating an easily exploitable security vulnerability.
But generally speaking it works just fine, and anything that can do an AJAX GET should be able to do an AJAX POST.

Is there a way, aside from SSL, to allow secure input on webpages?

I want to set up a project page on GitHub, so that it acts as a live site.
The site would require an API sid & token (both just long strings of text) that, in a self-hosted environment, the user would just add to the config file.
If I host this through GitHub project pages, users will supply their sid/token through a form. The page with the form will need to be served over SSL so that the sid/token aren't transferred as cleartext. The problem is that GitHub project pages don't allow SSL.
So, if I can find another secure way to take input through a form aside from using SSL, then I can host this whole thing a hosted service through GitHub project pages.
The project would be open source, so I don't expect any sort of encoding/hashing scheme to work, since the methods would be public.
The sid/token are being used in curl calls to an API which is sent over SSL. Perhaps there's a way to direct the form input directly to that SSL URL instead of having it go through the non-SSL GitHub project page...
Any ideas?
You can just give the action attribute of the form the HTTPS URL of the target script, if that's possible.
You could also use some kind of Challenge-Response encryption/hashing scheme using Javascript. The algorithm for that would be something like this:
Server generates unique, random token, saves it and sends it to the client along with the form HTML.
On the client side, Javascript intercepts the form submission and hashes the sensitive form data with the server-generated token as a salt.
Server can now check whether the hash is equal to its own calculated hash value
HOWEVER
A man-in-the-middle attacker with the ability to modify traffic (for example through ARP poisening, DHCP or DNS spoofing) could always strip all your client-side protection mechanisms from the served HTML. Have a look at SSLStrip for a tool to rewrite HTTPS URLs to unsecure HTTP URLs on the fly. The challenge-response could be defeated something like this:
Save token sent by the server, remove the Javascript from the HTML form.
As the form submission is not intercepted now, we get the raw input data.
Hash the data using the same algorithm that the Javascript would have performed.
Thank you for all the fish.
You see, an intercepting attacker can probably defeat any defense mechanism you try to make up.

How to make a cross-domain form CSRF and replay resistant?

I'm contemplating making a project, but I'm wondering if cross-site request forgery would make it impossible to secure.
Basically, I want to have a web service that generates a form using the usual tricks(JSON-P and iframes) on another domain's page. So WebService.example.com generates a form's HTML, and it's shown to the user on User.example.com
This form, I assume will have to use the injected iframe trick to submit the form from javascript. Because anyone would be able to just get the same data from WebService.example.com, how can I ensure that it's actually only coming from User.example.com? Preferably, without having to have any server-side code running on User.example.com.
Note, I'll be using ASP.Net for the WebService, but I'd like it explained in a language/framework agnostic manner
This is pretty hard to do without using server side scripts on both domains.
If you change your architecture and just use Cross-Domain Messaging (host the form etc in the top domain, use iframe for communication) then you could use the XDM to verify that it is indeed the intended domain you are talking to.
If you only target HTML5-capable browsers then use postMessage, if you want broader support, and things like RPC etc then use easyXDM, which abstracts all of the hassle with cross-domain messaging.
Actually, you can host your form in either document, you just need to use the XDM-communication in order to do a successful 'handshake', verifying the origin.