I'm trying to create a chrome extension which scans a local directory for new files ...
However, if I add the file://* permission to the manifest I can access the internal file browser of chrome with
xmlhttp.open("GET","file://C:/Users/username/Desktop/",false);
xmlhttp.send();
console.log(xmlhttp.response);
From the response I could extract the file URLs and use them in my extension.
My question is now: Are there other approaches? The above way seems more like a workaround and easily breaks if chrome's file browser is changed ...
Any time I've had to do something on the local machine from a Chrome extension, I've always created a small program that accepts connections via HTTP, and does the work as a normal program, taking commands with JSON over POST. This gives you great flexibility, as it essentially allows you to write a Chrome extension that can do anything a desktop program can do.
However, there are great downsides to this, and you should only do it if absolutely necessary. For instance:
You can't do this for all operating systems, unless you're going to write an agent for every OS.
The extension cannot be installed from Google's extension hosting.
You must write your own installation program that registers the extension.
There are very real security considerations to worry about with this. You will be opening up a web service that executes commands. Be very sure that you are not exposing the user. In all reality, if you are making a file browser, you probably are exposing the user. It will be up to you to fix this security hole, as if you were creating any other web service.
Related
I have a chrome extension (intended to be used by companies internally) that needs to have user specific configurations but I want to avoid the user having to do all that and have a sysadmin configure those things for them via a script.
EDIT: Basically, I just need to read from a file that sysadmin can write.
Is this in any way possible?
You have two solutions.
First one is to ask your sysadmin to properly locate chrome's extension folder on all platforms, and edit a file in there. It might be a bit complicated if all computers at your company are not the same or use different platforms.
See: Where to find extensions installed folder for Google Chrome on Mac?
The second one, is simply to ask for the file:///* permission when you install the extension.
It will allow your extension to read files on the whole hard drive, and load the configuration file on a predetermined place.
Here is a related question:
Chrome plugin reading text file on hard drive and replacing textbox content
edit: for the second solution to work, you need your users to enable "Allow access to file URLs" in chrome's config (not sure you can do that automatically)
Assuming you have an enterprise install, you can use chrome.storage.managed (which can be easily controlled from a central location) to hold those preferences.
See Configuring Apps and Extensions by Policy for a detailed, per-OS explanation.
If an enterprise managed storage is not an option, perhaps a better one would be to have a configuration file available somewhere on an internal web server. The extension can then retrieve that pre-defined URL and configure itself accordingly.
You can differentiate between computers automatically using IP/MAC address information accessible by the server processing the request, of you can pass some query parameters yourself.
I'm working on a Chrome extension to be used as an internal tool. Its required behavior is:
As a page action, enable an address bar icon when looking at certain intranet pages.
when the user clicks the icon, identify all files of a certain media type (say, .jpg) on the page, and
silently save them all to a directory on the user's local drive.
This question has been asked before, but the answer then was "use NPAPI", and NPAPI is now derelict.
So, what is the currently available way to achieve this? The ones I've looked at are:
The chrome.FileSystem API --- but this does not save files in any user-accessible location. Instead the stored files are hidden behind obfuscated names in an undocumented directory. User requires that the files be stored under their original names in an accessible directory.
The HTML5 download attribute, by creating a data: URL and programmatically clicking it. This pops up a "save as..." dialog for each file, which is unacceptable when there are a hundred assets on a single page. User requires that the files be downloaded without further interaction beyond the single icon click.
The Chrome Download API, but that is only available in the beta and dev channels. User requires this extension work with mainstream Chrome.
Use the Native Messaging API by creating a small .exe that simply saves a file to disk, and then pass the .jpg as a blob to it. This seems very cumbersome and I am not even sure how to reliably pass large blobs to EXEs like that.
Is there another approach I can try?
You've done quite a lot of research. Indeed, regular web pages cannot write to the user's filesystem without any plugins or extensions. Also, the HTML5 Filesystem API only provides access to a virtual filesystem, as you've observed.
However, you are confusing the chrome.fileSystem API with the HTML5 FileSystem API. Unlike the HTML FileSystem API, Chrome's fileSystem (app) API can directly write to the user's filesystem (e.g. ~/Documents or %USERPROFILE%\Documents), specified by the user.
This API is only available to Chrome apps, not extensions. This is not a problem, especially since you're developing an internal tool, because you can install the app and extension, and use message passing to communicate between the extension (page action) and app (file system access) (example).
About chrome.downloads: Since your extension is internal, you can probably force users to get on the beta/dev channel in order to use this API. The only limitation of this API is that the files will be saved in (a subdirectory of) the user-defined Downloads folder.
EDIT: The chrome.downloads API is now avaiable in all channels, including the stable branch (since Chrome 31).
I am afraid that you have done your homework, meaning you looked at all possible alternatives.
The best way to achieve exactly what you want, would be (as you mentioned) using a supporting native app and communicating through Native Messaging. BTW, since bandwidth is rarely a problem on intranets, you might find it simpler to pass the resources (e.g. images) URLs and have the app download and save them.
(Yes, it will be more cumbersome than simply developing an extension, but one's got to do what they've got to do, right ?)
On the other hand, if you are willing to sacrifice a little bit of user's experience over simplicity of development, I suggest combining the HTML5 goodies (that allow you to create and download a file locally) with a JS zipping library (e.g. JSZip), so the user only has to download a single zip file (and is only prompted once). BTW, if the user wishes, he/she can choose to always download the files without prompting (but you knew that already).
Use the Native Messaging App idea.
The native app is cumbersome and a pain to write because documentation is poor, and unless you get the JSON formatting exactly correct on both ends you will not see anything in a console because stdin and stdout are taken over.
But, you will be happier when it is done because you can use standard tools (e.g., Windows Explorer, a hex editor, TeamViewer...) to view, move, and delete files, and otherwise see what is going on. Chrome's sand-boxed file system works, but seems to now be a dead-end (no other browsers have picked it up). No one is likely to develop third-party tools for it. Of course you probably don't need tools once everything is working, but until then, debugging is a nightmare because you need to write code (and quite a lot of code) just to track what files are in what directories, file versions, remaining disk space...
Another solution for internal (or may be non-internal) usage is to connect to a websocket server, local or remote.
You can put it in both background.js or content.js (use wss:// for https://)
var ws = new WebSocket('ws://echo.websocket.org');
// var ws = new WebSocket('ws://127.0.0.1:9000');
ws.onmessage = function(res) {
console.log('received data:', res.data);
};
ws.onopen = function() {
ws.send('hello');
};
I found the some strange <script/> tags on a site:
<script src="chrome-extension://lifbcibllhkdhoafpjfnlhfpfgnpldfl/document_iterator.js"></script>
<script src="chrome-extension://lifbcibllhkdhoafpjfnlhfpfgnpldfl/find_proxy.js"></script>
...
I haven't been able to find much information on this, but I highly doubt this is actually related to Google Chrome since this site in particular is still using <table>s for layout, and the source in question was retrieved with curl not a graphical web browser.
So,
What on earth is this?
What is chrome-extension://
Why is it using lifbcibllhkdhoafpjfnlhfpfgnpldfl as a directory name
Why is it pretending to be valid URL to a javascript file?
Why would I need find_proxy or document_iterator
Solved. As far as I know...
chrixian was right, It seems that only on this and a few select other pages, someone had re-saved them from Chrome's source-view with the Skype extension installed.
Thanks everyone for all your help, +1's for all! enjoy!
That is actually Skype Click to Call chrome extension.
Manage and view it using this link
chrome://extensions/?id=lifbcibllhkdhoafpjfnlhfpfgnpldfl
If you are using cURL to get the page, you're getting the HTML as it exists on the server--so I think a safe assumption would be: the author of the page initially saved the page from Chrome, he had an extension installed that inserted these script tages and lastly he didn't remove the script tags for one reason or another before putting the page on the server.
This is added by chrome as the page loads, to inject the extension's Javascript code into the page, so it can access the HTML document.
The Skype extension causes it by inserting all kinds of junk in webpages that you visit.
Do you have the Skype browser extension installed for Chrome?
Just disable the extension.
Chrome, like Firefox, provides developers with an easy API to extend the functionality of the web browser without needing to actually download and build the browser to do so.
They also provide a robust delivery system. In Google's case, it's the Google Chrome Web Store.
Extensions are installed locally on your computer, and use long strings as directory names to reduce the risk of collisions with another extension. In other words, if you and I both named our extensions "mycoolextension", then there would be a problem if a person tried to install your extension and my extension. The long string helps prevent collisions such as this.
The chrome-extension:// protocol is used by the browser to make requests to these local resources. Chrome extensions are developed using HTML5, JavaScript, and CSS, along with an API exposed to allow the local JavaScript to perform actions it would not normally be able to do on the Internet.
When you see these in the Chrome developer tools, it's just the extension doing it's thing, whatever that may be.
If you're seeing these, then you likely installed some extensions from the Chrome Web Store. To view them, go to the Tools menu and select "Extensions". This will show you a list of all installed Chrome extensions and apps.
To learn more about extension development, see the Getting Started Tutorial.
Also, as someone else mentioned, you're using the Skype Call Extension. However, an app using that directory name doesn't appear in the first page of the search results. It might be worth doing some more research to make sure you got that extension from a legitimate source, whether that be Skype or the Chrome Web Store.
If you're seeing it in Chrome developer tools for every request you make, it means it has access to all your websites, which could be benign, like if they're just making phone numbers clickable, or it could be malicious, if it's scraping your bank account info and shipping it off to some third party server. :)
It's a Chrome extension, and chrome-extension:// is a URL for extensions to address their contents via Javascript.
lifbcibllhkdhoafpjfnlhfpfgnpldfl is the unique identifier for the extension. I can't find it with a search, but apparently it might be Skype.
It's not pretending... it is a valid URL. The Javascript file is located in the extension. If you were to look on your harddrive you'd probably find that very file in the extensions folder.
The functions its calling probably are some sort of detection used by the extension to see if it needs to enable itself.
See this for some additional information:
Checking if user has a certain extension installed
I have created a Java program which takes some command line arguments to run. I need to make a browser extension to the program so that the program can be opened with data from the browser.
I know Javascript does not allow any local file access, but there are programs which doing the task I needed.
Examples are Internet Download Manager which has the browser extension for running it receiving command line arguments from the browser. Obviously extensions for most of the browsers including Chrome and Firefox are made using Javascript? Is there any way to do local program execution via JavaScript (I think there's a way surely)?
You can't directly run anything from your JS sandbox on client PC (just think about security risks!) There's other method however: Make your application register itself as protocol handler when it installs and use links with this protocol on your pages (think how e-mail clients serve mailto: or torrent clients serve magnet: links). Since you control both sending and receiving side, you can pass pretty much any information in those. You can find Windows example for registering a handle at MSDN. Should you need it for any other system, I'm pretty sure searching for "system_or_gui_name register protocol handler" will show you desired result among the first.
This has been asked a lot of times already: I need to get the full file path via a web-page. The use case is an application running on the same machine as the browser (i.e. the application starts a local HTTP server and fires up the browser.) File-paths are of course valid and the same for both client/server now. The use case it that the user selects a file and then the server process does some computation on it, and the input files are typically large (read: several GiB in size.)
The easiest thing would be to directly access the path using , but for security reasons, this is disabled. I'm looking now for the least intrusive workaround to this problem. The target browser in question is Chrome. I'm fine if the user has to click "accept" once on some security warning, as long as I can ensure that it won't appear again.
Do I have to write an extension, NSPlugin, can I use some special header magic to mark my page as "local", is there some security setting I can set? The less the client has to do the better, and I would prefer some "click here to allow access ..." solution above everything else. Can I directly install an extension from the server process that would do this (after the user clicks accept?)
Is it possible to do this with a Java applet/Flash? That would be the easiest solution, and clients are guaranteed to have Flash installed (as it is bundled in Chrome...)
You can create Java applet for tasks like this and self-sign it. User will have to allow it to run, but then you will be able to access applet's function that will return file path string via Javascript.
Clearly file io on the client's system is forbidden from JavaScript. If this wasn't the case it would be absolutely trivial to hack every web browser that visits your website.
Battlefiled 3 is controlled though the browser. To do this EA wrote a browser extension for the top three browsers. But that's resource intensive. If you just care about chrome you can use an addon, and for that i suggest using the NPAPI.
And as MOleYArd said, Java is a good solution and probably more common than an extension or addon.