How to resolve system directories paths independently of system locale? - node.js

TLDR
I need to get paths to system directories like "Screenshots":
On an English system. I can just use this one:
C:/Users/User/Pictures/Screenshots
How do I get the path to "Screenshots" directory on a non-English system?
C:/Users/User/Pictures/[NAME]
Description
I have a file manager app, it displays system directories and loads them on click.
The app can run system commands via Powershell and use Node.js (preferred)
Problem
The problem is, it only works if the system has English system language.
Currently, to resolve the "Screenshots" directory path, the app simply joins the User directory with the word "Screenshots"
const pictures = electronRemote.app.getPath('pictures')
const screenshots = PATH.join(pictures, 'Screenshots')
link to the line in code
Expectedly, the C:/Users/User/Screenshots path only exists on English systems.
One way to solve this is to use short names, at least on Windows, I know that system directories have short names like SCREEN~1 and WALLPA~1 for Screenshots and Wallpapers directories, but if I use these names the paths will look like this:
C:/Users/User/SCREEN~1 instead of C:/Users/User/Screenshots throughout the app.
And even if I were to run these paths through a function to convert it to readable name, how would I know which word to replace it with? I need to get the name in the system's language.
Are these translations stored somewhere on the system? Can I just retrieve the translated directory name and use that in the code above?
Question
How do I make it to get / resolve the actual path of system directories like Screenshots and Wallpapers, independently of system locale?
If you know how to do it, could you please suggest the solution for all platforms (Win, Mac, Linux)?
Should I just use the short names like SCREEN~1 and then automatically replace all the occurrences in UI and also filter all paths through a function that replaces this short name with the actual path throughout the whole app? Seems like a lot of work, this approach

Related

How to create same path to directory on different platforms in Python?

In the piece of code I have, there are many instances where I have the following line
'/home/myname/directory'
For example, I have the following lines of code
filepath = os.listdir('/home/myname/directory')
for content in filepath
# do something
In the next part of the project, I have to share the code with some one else. I know this person runs openSUSE. If I want code to create that specific directory with the same path to the directory as mine, what do I need to include?
I know its going to involve the OS module but i am not sure which functions and methods to use.
Your code can check the existence of the directory and create it if not found:
if not os.path.exists("/home/myname/directory"):
os.makedirs("/home/myname/directory")
# do something

In Windows Node.js fs.readdirSync With Users Folders etc

I've been developing an nw.js project and use node.js file system functions in it as normal. In my application there is a file manager and I list folders and files according to user navigation. In Windows, for example, if I scan drive C: I get the Turkish named folder "Kullanıcılar" as "Users". I know it's real name in operating system is "Users" and just seen on the screen according to Languages. I can replace names of such folders when dispaying in my file manager but I'm searching for better solution if exists. Thanks in advance.
There's an SO answer here that reads the localized name of a folder in C# using the SHGetFileInfo function which might help you along.
Now I know you didn't ask, but in case you want to know where the information is stored... It's within the directory, in the Desktop.ini file.
For instance, my Windows 10 installation has this in it for "Users":
[.ShellClassInfo]
LocalizedResourceName=#%SystemRoot%\system32\shell32.dll,-21813
And this for the Images folder within my user folder (bringing this up to show you the additional keys):
[.ShellClassInfo]
LocalizedResourceName=#%SystemRoot%\system32\shell32.dll,-21779
InfoTip=#%SystemRoot%\system32\shell32.dll,-12688
IconResource=%SystemRoot%\system32\imageres.dll,-113
IconFile=%SystemRoot%\system32\shell32.dll
IconIndex=-236
The #%SystemRoot%\system32\shell32.dll,-21813 points to having to read the MUI (multilingual user interface) resources, key 21813 for the given file (presumably the # means that it's in this file, not this literal value, but don't quote me on that). %SystemRoot% is an environment variable that points to the Windows directory.
The actual MUI files and their locations are handled by Windows (see the MSDN link above), but we'll just happen to handily know that the MUI file for the US English localization of shell32.dll is system32\en-US\shell32.dll.mui.
Opening up that file with Resource Hacker, we can search for 21813 -- and voila! We can find STRINGTABLE resource #1364 that contains:
[...snip...]
21812, "Extras and Upgrades"
21813, "Users"
21814, "Saved Games"
[...snip...]
I unfortunately don't have tr-TR/shell32.dll.mui available, so you'll just have to trust me that you'd find the Kullanıcılar string there.

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

Where/How to save a preferences file in a *nix command line utility?

I am writing a small command line utility. It should hopefully be able to run on OSX, UNIX and Linux.
It needs to save a few preferences somewhere, like in a small YAML config file.
Where would one save such a file?
Language: Python 2.7
OS: *nix
Commonly, these files go somewhere like ~/.rc (eg: ~/.hgrc). This could be the path to a file, or to a directory if you need lots of configuration settings.
For a nice description see http://www.linuxtopia.org/online_books/programming_books/art_of_unix_programming/ch10s03.html
I would avoid putting the file in the ~ directory only because it has gotten totally flooded with crap. The recent trend, at least on ubuntu, is to use ~/.config/<appname>/ for whatever dot files you need. I really like that convention.
If your application is named "someapp" you save the configuration in a file such as $HOME/.someapp. You can give the config file an extension if you like. If you think your app may have more than one config file you can use the directory $HOME/.someapp and create regular-named (not hidden) files in there.
Many cross-platform tools use the same path on OS X as on linux (and other POSIX/non-Windows platforms). The main advantage of using the POSIX locations isn't saving a few lines of code, but saving the need for Mac-specific instructions, and allowing Mac users to get help from the linux users in the community (without any need to translate their suggestions).
The other alternative is to put them in the "Mac-friendly" locations under ~/Library instead. The main advantage of using the Mac locations is basically "Apple says so"—unless you plan to sandbox your code, in which case the main advantage is that you can do so.
If you choose to use the Library locations, you should read About the OS X File System and OS X Library Directory Details in the File System Programming Guide, but here's the short version:
Almost everything: Create a subdirectory with your app's name or bundle ID (unless you're going out of your way to set a bundle ID, you'll get org.python.python, which you don't want…) under ~/Library/Application Support. Ideally you should use APIs like -[NSFileManager URLForDirectory:inDomain:appropriateForURL:create:error:] to get the path; if not, you have to deal with things like localization, sandbox containers, etc. manually.
Anything that can be easily re-created (so it doesn't need to be backed up, migrated, etc.): An identically-named subdirectory of ~/Library/Caches.
Preferences: Use the NSUserDefaults or CFPreferences APIs instead. If you use your own format, the "old" way of doing things is to create a subdirectory under ~/Library/Preferences named with your app's name or bundle ID, and put your files in that. Apple no longer recommends that, but doesn't really recommend an alternative (short of "use CFPreferences, damnit!"); many apps (e.g., Aquamacs) still do it the old way, but others instead pretend they're not preferences and store them under Application Support.
In Python, this works as follows (leaving out the error handling, and assuming you're going by name instead of setting a bundle ID for yourself):
from Foundation import *
fm = NSFileManager.defaultManager()
appsupport = (fm.URLForDirectory_inDomain_appropriateForURL_create_error_(
NSApplicationSupportDirectory, NSUserDomainMask, None, True, None)[0].
URLByAppendingPathComponent_isDirectory_(
appname, True))
caches = (fm.URLForDirectory_inDomain_appropriateForURL_create_error_(
NSCachesDirectory, NSUserDomainMask, None, True, None)[0].
URLByAppendingPathComponent_isDirectory_(
appname, True))
prefs = NSUserDefaults.persistentDomainForName_(appname)

saving to /home/user/Documents in different locales / languages

In my linux python app for Fedora I want to save user's work to /home/user/Documents/MyCoolApp/TheirGreatWork.txt
But I am not sure how to find the "Documents" folder if the user is not using English as their default language.
What is the right way to determine the right path so that files go in their "Documents" folder.
EDIT
Here is a which comes up if you change locales... showing how paths can get easily changed.
I'd use the subprocess module to get the output of the command xdg-user-dir DOCUMENTS. For example:
import subprocess
documents_dir = subprocess.check_output(["xdg-user-dir", "DOCUMENTS"])
print documents_dir # This is what you're looking for.
There is no right way as the user may have changed their locale, which (fortunately) does not rename the directory. If you want a fixed place for files managed by your app, use ~user/.MyCoolApp or let the user specify the directory.

Resources