What's the security risk of having javascript access an external image? - javascript

Using javascript one cannot convert an image (hosted on a different domain than the one the javascript comes from) into a canvas.
What's the security risk with that? It can't just be to avoid phishing, right?

Same origin policy stops any remote data from being accessible by a different domain. One of the main attacks this stops is being able to circumvent a user's login by waiting for them to be logged into another site, and then piggy-back your request on their authenticated session.
Whether the data loaded is an HTML snippet, an image file or anything else, it's blocked so you can't take advantage in any way (for example, by inspecting the pixel data of an image retrieved this way)

There is one tricky attack vector connected with external images: someone can post image which will be loaded from the external resource, which they control. After some time this url can be changed to return the request for the basic http authentication. So the other users will see windows requesting their login and password. Some users, especially non-experienced ones can enter the credentials of the attacking resources which will be sent to the attacker. So be careful with external resources.

Related

What are the security implications of uploading files from an iframe?

Suppose I have a drawing html application that my users can use in their web pages. They include the widget setting its src in an iframe (with their generated key passed as query string), I send it with a frame-ancestors header to restrict use to their domain and their users can use the widget to draw.
Now suppose they want to load drawings saved on their servers and pass them to my iframe widget, and they want users to click a button (on their site) to save the current drawing on their server. In both cases, they can send a message to my iframe specifying a signed url, and my iframe can listen to the event and use fetch to, respectively, download or upload the desidered asset.
What are the security implications of my iframe downloading or uploading on their behalf? Is this setup solid or can it be abused? If it can be abused, how?
I am not sure of downloading and uploading , but it is possible to share/pass messages to and from iframe.
More details here - https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
Security concerns
If you do not expect to receive messages from other sites, do not add any event listeners for message events. This is a completely foolproof way to avoid security problems.
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.
Always specify an exact target origin, not *, when you use postMessage to send data to other windows. A malicious site can change the location of the window without your knowledge, and therefore it can intercept the data sent using postMessage.

Best way to make a request to external web service

So, I have this web application that shows network products for a specific network. The web server is not inside the network, so in order to show the visitor what network services he or she can order, I need to identify their computer inside the network.
So, I've been doing this with an iframe, which loads a specific in-network URL provided by my clients. This in-network URL will identify the visiting browser and then redirect it (inside the iframe) to a resource on my web service, with attached identification details.
For identification to occur, the in-network web server needs to receive a HTTP request from the visitor, but is this really the best way to handle this? Ajax cross domain is a bit of a mess as far as I'm aware, but I think iframe cross domain is equally shaky, or?
How would you solve this? The chain of events needs to be:
visitor visits my.web.com/services
visitor is sent to client.network.com/identify
Which redirects to my.web.com/identifier?id=XXYY
Now I can set a cookie for my.web.com on the user browser that their id is "XXYY" (or update member profile if logged in). Obviously this request needs to be asynchronous since the in-network web server may be slow to respond, so just a normal redirect is off the table.

Detect Javascript Tampering in Ajax call

We have a Javascript file that we have developed for our clients to use. The Javascript snippet takes a screenshot of the website it is run on and then sends it back to our server via jQuery.post()
The nature of our industry means that we have to ensure there is no way that the file can be tampered with by the client.
So the challenge is that we need to make sure that the screenshot was generated by the javascript file hosted on our server, and not one that's been copied or potentially tampered with in any way.
I know that I can get the script location using:
var scripts = document.getElementsByTagName("script"),
src = scripts[scripts.length-1].src;
But this won't help if a client tampers with that part of the SRC.
What methods can I employ to make sure that:
1) The post was made from the javascript file hosted on our server
2) The javascript was not tampered with in any way.
Short answer:
You can't.
You can't.
Both stem from the fact that once you hand over something to the client side, it's out of your hands. Nothing will prevent the user from putting a proxy between you and their machine, a process that intercepts content or an extension that tampers content, headers, cookies, requests, responses etc.
You could, however, harden your app by preventing XSS (prevent injection of scripts via user input), using SSL (prevent tampering of the connection), applying CSP (only allow certain content on the page), add CSRF tokens (ensure the form is authorized by the server) and other practices to make it harder for tampered content to get through.
But again, this won't prevent a determined hacker to find an opening.

Differenciate Between User Requests and AJAX/Resource Requests

I'm attempting to create an app with Node.js (using http.createServer()) which will be a single page application with requests for data via XMLHttpRequest. To do this I need to be able to differentiate between a user navigating to my domain, and AJAX requests and requests generated by the browser for linked resources.
If the request is from the user I always want to return the index.html page which will handle requesting content but if the request is browser generated or AJAX and is for CSS, Javascript or other linked files I want to serve those files. Is there any way to detect this?
Looking at the request headers for the different file types I saw the referer header appeared when the request for content was generated by the page. I figured that was the solution I was looking for but that header is also set when a user clicks on a link to the page making it useless.
The only other thing which seems to change is the accept header which could sort of work but might not be a catch all solution. Any user requests always seem to have text/html as the preferred return type regardless of which url was entered. I could detect that but I'm pretty sure AJAX requests for html files would also have that accept header which would cause problems.
Is there anything I'm missing here (any headers or properties I can look for)?
Edit: I do not need the solution to protect files and I don't care about users bypassing it with their own requests. My intention is not to hide files or make them secure, but rather to keep any data that is requested within the scope of the app.
For example, if a user navigates to http://example.com/images/someimage.jpg they are instead shown the index.html file which can then show the image in a richer context and include all of the links and functionality to go with it.
TL/DR: I need to detect when someone is trying to access the app to then serve them the index page and have that send them the content they want. I also need to detect when the browser has requested resources (JS, CSS, HTML, images, etc) needed by the app to be able to actually return the resource not the index file.
In terms of HTTP protocol there are NO difference between a user-generated-query and a browser-generated-query.
Every query is just... a query.
You can make a query with a command line, with a browser, you can click a link, send some ascii text via telnet, request a proxy which will make the query for you, the server goal is never to identify how the query was requested by the user.
See for example a request made by a user on a reverse proxy cache, this query will never reach your server (response comes from the cache), the first query made to build this response could have been made by a real user or by a browser.
In terms of security trying to control that the user is never requesting data by-himself cannot be done by detecting that the query is a real human click (and search google for clickjacking if you want to be afraid). Every query that a browser can make can also be played by the user, every one, you have no way to prevent that.
Some browsers plugins are even doing pre-fetching, detecting links on the page and making the request before you do it yourself (if it's a GET query).
For ajax, some libraries like JQuery will add an X-Requested-With: XMLHttpRequest header, and this is used on most framework to detect ajax mode.
But it is more robust to depend on a location policy for that (like making your ajax queries with a /format/ajax, which could also be used on other ways (like /format/json, /format/html, or /format/csv).
Spending time on a location policy based routing is certainly more usefull.
But one thing can make a difference, POST queries are not indempotent, it means the browser cannot make a POST query without a real user interaction, because a POST query may alter the state of the session or the state of the server data (but js can make POST queries, this is just a default behavior of browsers). The browser will never automatically retrieve a POST query, so you could make a website where all users interactions are POST queries (via forms or via some js altering link clicks to send POST ajax queries instead). But I'm not that's your real goal.
Not technically an answer to the question but I found a simple solution which does what I want: prefix all app based requests with a subdomain eg. http://data.example.com/. It's then really simple to check the host header for that subdomain: if present send the resource else send the index page.

How to restrict access to a resource based on domain

I've got a theoretical problem I'd like to solve. Imagine I want to reference an external resource from within an HTML document. However, I want the behaviour when following the link to vary depending on the domain of the referring page (the page with the link).
e.g.
A page hosted at http://somedummydomain.com/mypage.html contains a link to a resource http://someotherdummydomain.com/mydoc.pdf?key=123456789.
When a user clicks on the link to mydoc.pdf, I would only like mydoc.pdf to be returned (200 OK) if the referrer is somedummydomain.com - if it's any other domain then return 401 NOT AUTHORIZED. The significance of the key in the query params is that the application serving mydoc.pdf will, internally, have associated that key with the somedummydomain.com domain, thus stipulating that the resource can only be accessed via that domain.
Obviously I could check the referrer, but it's trivial to spoof the referrer in the HTTP headers so, were I genuinely trying to lock something down, the referrer header is not going to be satisfactory.
I'm kind of assuming that JavaScript would have to come into play in some way? I'm judging that based on things like the Google Analytics JS code that will only accept events occurring on a page hosted at a pre-registered domain.
Does anyone know how this type of behaviour could be achieved?

Categories

Resources