fs.writeFile() and fs.readFile() strange behavior - node.js

I'm writing a desktop app using electron and react. I want to store some information in a JSON file. I've tried both web-fs and browserify-fs to accomplish this, and neither is working as expected. My setup is as follows
project/app/(react files)
project/index.html
project/js/bundle.js
project/main.js
I'm using watchify to compile all the changes in the react files to the bundle.js file (which is read by index.html).
The following is ran from app.js in project/app/ (which is also where the JSON file is stored)
import * as fs from 'browserify-fs';
...
fs.writeFile('./fileData.json', data, function(err){
if(err)console.log(err);
else console.log("success");
});
'success' is always logged to the console, however the contents of the file is not updated, regardless of how I specify the path.
I've tried './fileData.json'
'/fileData.json'
__dirname + '/fileData.json' (which tells me that __dirname couldn't be found)
(absolute path to fileData.json) (which tells me that /Users could not be found)
After doing the above, if I change the writeFile to readFile and log the contents to the console, the updated file is printed. Even if I delete the fileData.json file, the file is successfully read.
This makes me believe that fs.writeFile() is writing to a different directory, not the one the process is being ran from. Despite this, I cannot find any other fileData.json files anywhere on my computer. There's a couple other weird behaviors:
When logging __filename (which should log the entire filepath), the only thing printed is "/app.js" with no leading file path.
Calling "process.cwd()" just gives me "/"
When calling fs.writeFile() with the full file path "/Users/...." I get a folder not found error
Anyone know what could be causing this behavior and how to fix it?
Edit - I also tried getting the absolute path by adding
var path = require('path')
var appDir = path.resolve('./app');
which again only gives me /app when it should be returning an absolute path

Can you confirm the same behavior when not using browserify-fs? Just use plain old fs. (Note you can do this straight from the Chrome dev tools console).
Looking at browserify-fs's page, it looks like it implements a kind of virtual file system using a dependency called level-filesystem (which uses level db). So the files you're expecting to get created aren't. They're being created within a level db database. You could probably find a level db file somewhere that has the information you're trying to write directly to the file system in it.
For simple writing/reading of a JSON file, I'd recommend https://github.com/sindresorhus/electron-config.

Related

Nodejs Pkg - how to use an external Config file?

I am having issues attempting to properly use pkg (nodejs module) properly.
I am doing a stand alone file manager (well, it would swap video/audio files to & from preselected directories, intended to allow it without any internet connection it self to remove & add files to a syncing folder like onedrive/dropbox/googledrive/etc. using a text file.)
The issue I am having, is I am at a loss of after I package it into a binary.. I do not understand how to allow/force it to create/read the text file outside compiled binary.
-- I would love for it to be within the same folder as the executable.
I am attempting to find a way to store data without having to share the sourcecode, or require node be installed on other machines.
-- I intend to have a minimal permissions as possible, and outside reading/writing the config & 'database' [which is simply a text file with what files are in the local storage, and what files are & are not in the remote storage]
What am I missing about pkg, & if it can store data internally some how... how do I get it to read an external file?
-- Though I would greatly prefer to have the txt files outside the binary & in plain text easy to read.
As a side question, I am not understanding how to pass an argument through & use it inside the program after it's compiled. [Hell, I'm having a heck of a time, properly understanding the readme for the pkg module]
Use fs features to load config object as in this three-lines of code
filename="./config.json";
let rawdata = fs.readFileSync(filename);
let config = JSON.parse(rawdata);
config.json must be in same direcory of pkg executable
If you need to change path of config.json, you will able to specify full-path of this file using command line arguments.
These can be read at runtime using process.argv variable as explained here

FS won't create file

I want to create a simple console application that would compare two files based on their filename and output the result into a new file.
My problem is that NodeJS refuses to create a new file if it doesn't exist, and acts like it doesn't exist even if I create it manually.
compare = (data) -> # data is being read from process.stdin
fname = "#{data}_compare.txt"
stdout.write "Attempting to compare #{data}" # stdout = process.stdout
fs.writeFileSync fname, 'A test.'
NodeJS returns Error: ENOENT, no such file or directory in both cases (when I want it to create the file, as well as when the file already exists).
I want the file to be created in the same folder from where the application is run, so path shouldn't be an issue at all (and indeed is correct in the error message).
I tried to specify {flags: 'w'} too, but as far as I know, that's the default value anyways, so it changed noting.
I'm running on Windows 10, tried running command prompt under administrator too, still nothing. Any idea what could be causing this?
The data variable is read from stdin and therefore contains a newline at the end. This is probably what's causing the non-descriptive ENOENT error.
You can remove the newline (and any other whitespace that user might have accidentally entered) with data = data.trim()
This would be better than the substring solution since the newline is 2 characters only on Windows and 1 character elsewhere.
Make sure the path exists (not necessarily the file itself, but the folder structure), and that the process user has write permissions.
An ENOENT error tells you that a component of the specified pathname does not exist -- no entity (file or directory) could be found by the given path.
Make sure you are putting the 'dot':
'./path/to/file'

ENOENT no such file on Express Endpoint for readFileSync

I've been going slightly crazy trying to figure this out. I have some certs that I need to pass through to an authentication client from my api; however, the application continues to throw ENOENT exceptions even though the file clearly exists within the same directory (I've fiddled with this to make sure). I'm using readFileSync, effectively doing the following:
key: fs.readFileSync('./privateKey.pem'),
Strangely, if I run this on a standalone Node server not as a part of an api, the file is able to be found without a problem. Is there some consideration I'm not aware of when trying to use readFileSync in such a scenario?
Thanks!
In node you need to be very careful with relative file paths. The only place where I'd ever really use them is in require('./_____') statements, where ./ to mean "relative to this file". However, require is kind of a special case because it is a function that node automatically creates per-file, so it knows the path of the current file.
In general, standard functions have no way of knowing the directory containing the script that happened to call a function, so in almost all cases, ./ means relative to the current working directory (the directory you were in when you ran node <scriptname>.js). The only time that is not the case is if your script or a module you use explicitly calls process.chdir to set the working directory to something else. The correct way to reference files relative to the current script file is to explicitly use an absolute path by using __dirname + '/file.js'.

Exploiting and Correcting Path Traversal Vulnerability

I have a Java Web App running on Tomcat on which I'm supposed to exploit Path traversal vulnerability. There is a section (in the App) at which I can upload a .zip file, which gets extracted in the server's /tmp directory. The content of the .zip file is not being checked, so basically I could put anything in it. I tried putting a .jsp file in it and it extracts perfectly. My problem is that I don't know how to reach this file as a "normal" user from browser. I tried entering ../../../tmp/somepage.jsp in the address bar, but Tomcat just strips the ../ and gives me http://localhost:8080/tmp/ resource not available.
Ideal would be if I could somehow encode ../ in the path of somepage.jsp so that it gets extracted in the web riot directory of the Web App. Is this possible? Are there maybe any escape sequences that would translate to ../ after extracting?
Any ideas would be highly appreciated.
Note: This is a school project in a Security course where I'm supposed to locate vulnerabilities and correct them. Not trying to harm anyone...
Sorry about the downvotes. Security is very important, and should be taught.
Do you pass in the file name to be used?
The check that the server does is probably something something like If location starts with "/tmp" then allow it. So what you want to do is pass `/tmp/../home/webapp/"?
Another idea would be to see if you could craft a zip file that would result in the contents being moved up - like if you set "../" in the filename inside the zip, what would happen? You might need to manually modify things if your zip tools don't allow it.
To protect against this kind of vulnerability you are looking for something like this:
String somedirectory = "c:/fixed_directory/";
String file = request.getParameter("file");
if(file.indexOf(".")>-1)
{
//if it contains a ., disallow
out.print("stop trying to hack");
return;
}
else
{
//load specified file and print to screen
loadfile(somedirectory+file+".txt");
///.....
}
If you just were to pass the variable "file" to your loadfile function without checking, then someone could make a link to load any file they want. See https://www.owasp.org/index.php/Path_Traversal

Escape spaces in File Path

I am wondering how I can programmatically add \ in front of spaces that appear in file paths. I am using fs.readdir to get the contents of directories and if I don't escape the spaces out of the path then I get an ENOENT error because unescaped paths are invalid in UNIX. I'd like get below result :
/path/with\ spaces/in/them/
However, I am running into a problem with a REGEX in the NODE REPL. When I do :
var path = '/path/with spaces/in/them/';
var escapedPath = path.replace(/(\s)/, "\\ ");
I get as result :
'/path/with\\ spaces/in/them/'
When I try to run this same code inside of the Chrome console I get :
"/path/with\ spaces/in/them/"
Which is the desired effect.
I am not sure if I am missing something or if this is a bug. I am confused because Node runs on the same Javascript engine as Chrome so I would think that these expressions would be interpreted the same.
Please let me know if anyone knows a way to do get around this. Maybe I am missing something. I just need to be able to escape the paths before passing them into fs.readdir so that I can avoid these errors.
Thanks!
try either this
var path = "'file:///Users/kevin/folder with space'";
or this
var path = "\"file:///Users/kevin/folder with space\"";
fs.readdir doesn't require you to escape paths. I was able to recursively pass fs.readdir output directories back into fs.readdir without any issues.
The issue above with the REGEX was only occuring in the Node REPL. Once I tested the above code inside of a file I was able to run it through Node and get the same output I saw in the Chrome console.
I ended up finding a bug in my code that was a little hard to track down. I first thought that it came from not escaping the path I was sending into fs.readdir but it was actually an issue where I was fs.stat the output of fs.readdir and then checking if the output was a file or a directory and treating it accordingly.
It turns out that a few results from the stat were neither Files or Directories and my function didn't have any way to deal with this so it just returned. Since I had no handlers for this my node program just stopped abrubtly. All I had to do was add an extra else condition to catch the non-file/directories cases (which I don't care about anyway).
Now its working fine!

Resources