How to decode a file from base64 encoding with JavaScript - javascript

My company has a very strict intranet for work related, the net has a single doorway to allow files in and out. The doorway's security does not allow special kinds of files (*.txt, *.doc etc only), and even in those specific kinds of files, it searches for patterns that approve that the file is really that kind. (You can't simply disguise a *.zip file as a *.doc file.)
As a security project, I was told to find a way to bypass this system, and insert a single C language .exe file that says 'Hello World'.
What I thought was to change the extension to .txt, and base64 encode it so that it would be more acceptable for the system. The problem is, how to decode it once it's in. It's very easy on the outside, PHP or any other decent language can do it for me. However, in there, the only real language I have access to is JavaScript (on IE6 and maybe, MAYBE, on IE8).
So the question is as follows, can I use JavaScript to read a file from the file system, decode it, and write it back? or at least display the result for me?
Note that I don't ask for decoding/encoding a message, this one is easy, I look to decode encode a file.

JSON might be the answer you are looking for. It can actually do the trick.
Encode your txt file in JSON format. It is very likely for it to pass your company's doorway security
var myJsonData = { "text" : "SGVsbG8sIHdvcmxkIQ==" }; // <-- base64 for "Hello, world!"
Import your txt file using plain html script syntax
<script src="hello.txt" type="text/javascript"> </script>
That's it! Now you can access a JSON object using the Syntax:
alert(myJsonData.text);
To complete your job, get this simple Javascript base64 decoder.
You're done. Here's the (very simple) code I've used:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=windows-1250">
<meta name="generator" content="PSPad editor, www.pspad.com">
<title></title>
<script src="base64utils.js" type="text/javascript"> </script>
<script src="hello.txt" type="text/javascript"> </script>
<script type="text/javascript">
function helloFunction() {
document.getElementById("hello").innerHTML = decode64(myJsonData.text);
}
</script>
</head>
<body onload="helloFunction();">
<p id="hello"></p>
</body>
</html>

Using only javascript (i.e. no plugins like AIR etc), browsers don't allow access to the file system. Not only is it not possible to write a file to the disk, it's not possible to even read it - browsers are very strict on that sort of thing, thank goodness.

You cannot do this with straight JS in the browser, security context and the DOM do not allow filesystem access.
You cannot do this with current versions of flash, older versions (pre 7 IIRC) had some security flaws that allowed filesystem access.
You could do this with a custom plugin, and possibly a signed Java applet, or COM (ActiveX component, IE only).
I would suggest working with IT regarding your intranet to open up the context/permissions needed in this case as that may be the shortest path to what you are wanting here. Alternative, you could create a command-line utility to easily encrypt/decrypt given files signed by a common key.

It all depends on how you can get the file in. If you have the base-64 encoded exe as a .txt, you could easily use Flash!
I'm not quite sure how you would implement this, but you can load a file into flash and as3 using flex.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import flash.net.FileReference;
import flash.net.FileFilter;
import flash.events.IOErrorEvent;
import flash.events.Event;
import flash.utils.ByteArray;
//FileReference Class well will use to load data
private var fr:FileReference;
//File types which we want the user to open
private static const FILE_TYPES:Array = [new FileFilter("Text File", "*.txt;*.text")];
//called when the user clicks the load file button
private function onLoadFileClick():void
{
//create the FileReference instance
fr = new FileReference();
//listen for when they select a file
fr.addEventListener(Event.SELECT, onFileSelect);
//listen for when then cancel out of the browse dialog
fr.addEventListener(Event.CANCEL,onCancel);
//open a native browse dialog that filters for text files
fr.browse(FILE_TYPES);
}
/************ Browse Event Handlers **************/
//called when the user selects a file from the browse dialog
private function onFileSelect(e:Event):void
{
//listen for when the file has loaded
fr.addEventListener(Event.COMPLETE, onLoadComplete);
//listen for any errors reading the file
fr.addEventListener(IOErrorEvent.IO_ERROR, onLoadError);
//load the content of the file
fr.load();
}
//called when the user cancels out of the browser dialog
private function onCancel(e:Event):void
{
trace("File Browse Canceled");
fr = null;
}
/************ Select Event Handlers **************/
//called when the file has completed loading
private function onLoadComplete(e:Event):void
{
//get the data from the file as a ByteArray
var data:ByteArray = fr.data;
//read the bytes of the file as a string and put it in the
//textarea
outputField.text = data.readUTFBytes(data.bytesAvailable);
//clean up the FileReference instance
fr = null;
}
//called if an error occurs while loading the file contents
private function onLoadError(e:IOErrorEvent):void
{
trace("Error loading file : " + e.text);
}
]]>
</mx:Script>
<mx:Button label="Load Text File" right="10" bottom="10" click="onLoadFileClick()"/>
<mx:TextArea right="10" left="10" top="10" bottom="40" id="outputField"/>
</mx:Application>
To decode it, look into http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/utils/Base64Decoder.html

If the security system scans for patterns in files, it is very unlikely that it will overlook a base64-encoded file or base64-encoded contents in files. E-mail attachments are base64-encoded, and if the system is any good it will scan for potentially harmful e-mail attachments even if they are named .txt. The base64-encoded start of an EXE file is almost certainly recognized by it. So ISTM you are asking the wrong question.

Related

Call a Java Function using Browser's Client Side JavaScript

Good morning!
I have been working on a client side browser based app using JavaScript that (all of a sudden) needs the capability to save and load files locally.
The saved files are plain text (.txt) files.
I have managed to get JavaScript to read existing text files. However, I am unable to find reliable information on how to create and edit the contents of these files.
Based on what I see online, I am under the impression that you can't do this with JavaScript alone.
I found out from another source that the best way to do this is outsource the file writing/editing to a Java file and let Java do the work.
I found a code snippet and tweaked it around a bit, but it is not working and I seem to be at a loss:
JAVASCRIPT
<!Doctype html>
<html>
<OBJECT ID="Test" height=0 width=0
CLASSID="CLSID:18F79884-E141-49E4-AB97-99FF47F71C9E" CODEBASE="JavaApplication2/src/TestJava.java" VIEWASTEXT>
</OBJECT>
<script language="Javascript">
var Installed;
Installed = false;
try
{
if (Test==null)
Installed = false;
else
Installed = true;
}
catch (e)
{
Installed = false;
}
alert ("Installed :- " + Installed);
TestStr = Test.SendStr("Basil");
alert (TestStr);
</script>
</html>
JAVA
import javax.swing.*;
public class TestJava {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
}
public String SendStr(String lStr)
{
return lStr + "!!!";
}
}
If someone could point me in the right direction or even just explain why this isn't working, I would appreciate it.
I believe the sandbox issue prevents all browsers from performing any and all local file writing, without an enormous amount of working around the access restrictions. It is easier to write files remotely on the server than to write them locally to the client. This is true across all browsers.
So while it may be possible to perform the load function, you cannot perform the 'save' function on the local machine.

Writing a javascript generated file using File API

I would like to use the File API in Javascript to be able to store generated content on the client browser's file system. I've looked at the documentation, but found no cross-browser solution (FileSystem API appears to be Chrome only).
With File API: Writer being discontinued, I don't know what options I have. Any suggestions?
You are correct that the FileSystem API is only supported in Chrome at the time of this writing, and it will probably not be implemented in other browsers.
http://caniuse.com/#feat=filesystem
Per MDN, the FileSystem API shouldn't be used in production:
This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.
At the moment better supported options to store files on the client are:
Web Storage API - http://caniuse.com/#feat=namevalue-storage
Cookies
IndexedDB - http://caniuse.com/#feat=indexeddb
WebSQL database - http://caniuse.com/#feat=sql-storage
I found the following solution that is simple and appears to solve my problem well. With this, I can generate a file and offer a download like link to the user to save. Here is the example code I use:
HTML
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<textarea id="fileContent" type="text" cols=80 rows=30>File Content!</textarea>
<a id="anchor" href="#" download="fileContent.txt">Download Me!</a>
<script src="clientfile.js"></script>
</body>
</html>
JavaScript
var fileContent = document.getElementById("fileContent");
var anchor = document.getElementById("anchor");
anchor.onclick = function () {
var fileContent_blob = new Blob([fileContent.value], {type: 'text/plain'});
if (window.navigator.msSaveBlob === undefined) {
anchor.setAttribute('href', URL.createObjectURL(fileContent_blob));
}
else {
window.navigator.msSaveOrOpenBlob(fileContent_blob, 'fileContent.txt');
}
}

iOS: Open UIWebView with local javascript files

I would like to open a website in an UIWebView, but I wan't to load the javascript files from the app's Documents folder (because of bandwidth). Is this possible?
Yes, you would need to create a custom NSURLProtocol as in this Post: https://stackoverflow.com/a/5573155/244160. Make an appropriate check in canInitWithRequest: and deliver your Javascript with the proper content-type according to the sample.
Update:
Here's a quick shot for a sample implementation:
#interface LocalJSURLProtocol : NSURLProtocol
#end
#implementation LocalJSURLProtocol
+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
return [request.URL.scheme caseInsensitiveCompare:#"http"] == NSOrderedSame && [request.URL.lastPathComponent hasSuffix:#"js"]);
}
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request
{
return request;
}
- (void)startLoading
{
NSURLRequest *request = self.request;
NSURLResponse *response = [[NSURLResponse alloc] initWithURL:[request URL]
MIMEType:#"text/javascript"
expectedContentLength:-1
textEncodingName:nil];
NSString *localFilePath = [[NSBundle mainBundle] pathForResource:#"sample.js" ofType:nil];
NSData *data = [NSData dataWithContentsOfFile:localFilePath];
[self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
[self.client URLProtocol:self didLoadData:data];
[self.client URLProtocolDidFinishLoading:self];
}
- (void)stopLoading
{
}
#end
And you register the protocol like this [NSURLProtocol registerClass:[LocalJSURLProtocol class]]; before starting to load. This will intercept the request in your UIWebView and you have the chance to inject your own Javascript code for the request file.
(please see my edit below - it might be possible to work with local assets and remote html files, by using custom protocol)
It is not possible to use a local js file (or any local file) on an internet file. It is similar to the fact that you cannot open a local javascript file on a website from a regular desktop browser.
What you can do is call your website's page, save the response's html as a local html file (on your documents folder), and change the js url to be local as well. The url should be relative.
For example:
documents
- myapp
-- index.html
-- scripts.js
inside index.html you can change the js src to be:
<script src="scripts.js" />
comments:
I assume that you can access and edit the webpage.
You can do a nice fallback in case the local js file was not downloaded. Similar to jQuery's cdn fallback to local file, we can do the opposite thing and do a fallback to server's file (jQuery is just for example. It can be done with any js file just by testing for namespace's existence:
<script src="jquery-2.0.0.min.js"></script>
<script>
if (typeof jQuery == 'undefined') {
document.write(unescape("%3Cscript src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-2.0.0.min.js'
type='text/javascript'%3E%3C/script%3E"));
}
Hope that helps!
EDIT:
After reviewing this post, you might be able to access local files from remote html file (in his example he is working with local html file, but it might work with a remote on as well)

Reading manifest file contents of a JAR from Javascript

Is it possible to read manifest file contents from Javascript. Requirement is to upload a jar file, read the manifest file content and then display different fields based on manifest file in browser (client side) and then send data to server.
Here is a basic example, tested in chrome.
I've never seen a JAR manifest, but the simplistic code below worked on the demo JAR files i found floating around.
That part is not tricky anyway, ripping open the zip and grabbing the file is, and here's one way:
<html>
<form><input type=file></form>
<script src="http://stuk.github.io/jszip/jszip.js"></script>
<script src="http://stuk.github.io/jszip/jszip-load.js"></script>
<script src="http://stuk.github.io/jszip/jszip-inflate.js"></script>
<script>
function getManifest(e){
var file=e.target.files[0];
var reader = new FileReader();
reader.onload = function(e) {
var zip = new JSZip(e.target.result);
var manifest = zip.files['META-INF/MANIFEST.MF']
.data
.trim()
.split(/\s*\n+\s*/)
.map(function(a,r){
r=a.split(/\s*:\s*/);
this[r[0]] = r[1];
return this;
},{})[0];
alert(JSON.stringify(manifest, null, "\t"));
};
reader.readAsArrayBuffer(file);
}
document.forms[0].elements[0].onchange=getManifest;
</script>
</html>
of course, you'll want to swap out the file input for a binary ajax call, but it's about impossible to demo such interaction in a paragraph of code like a file input allows...
it's pretty easy, thanks to jszip. about that: see http://stuk.github.io/jszip/ for general info and http://stuk.github.io/jszip/examples/get-binary-files-xhr2.html for a binary ajax demo.
Supposing you talk about Java server app:
No it's not possible.
You need to expose the info from manifest somehow, e.g. through a REST API. See [RestEasy|http://www.jboss.org/resteasy].
And then read it through XmlHttpRequest.
PS: It's not a good idea to expose whatever in META-INF or WEB-INF - it's a security risk.

Create File with Javascript

is it possible to create a file on localhost with javascript?
Not in a webpage. If you're using Windows Script Host then yes you can through ActiveX, but I presume you're not doing that. You can however, send data back to the webserver through AJAX and have it store it for you.
You can create cookies to store data on the local machine, which pretty much is the only way to create files on the local machine.
I assume you have the content of the file ready. Then you can prompt a "save as" dialog like this:
var exportText; // this variable needs to contain your content
var targetFilename = "myfilename.ext"
function presentExportFile() {
var download = document.createElement('a');
// you need to change the contenttype to your needs in the next line.
download.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(exportText));
download.setAttribute('download', targetFilename);
download.style.display = 'none';
document.body.appendChild(download);
download.click();
document.body.removeChild(download);
}
2017 addendum: Since I wrote this, I had one exotic browser (xombrero) reject it. So, I can't say for certain that this is The Way.
no, this would be a security issue.
You can create a file through a plugin, see https://developer.mozilla.org/en/Code_snippets/File_I%2F%2FO
<html>
<head>
<title>Create File</title>
<! This function will create a file named 'newfile' on the same directory as the HTML unless path is given>
<script language="javascript">
function openFile()
{ var filePath = 'c:/filename.txt';
var fileSysObj = new ActiveXObject('Scripting.FileSystemObject');
fileSysObj.CreateTextFile(filePath);
}
</script>
</head>
<body>
This will create a file called "filename.txt" on your c:\ drive.
You must accept the ActiveX control or disable prompting to create a file.
<button type=submit name=button onClick="openFile();">create file</button>
</body>
</html>

Categories

Resources