Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Are you fed up with that annoying FileNotFoundError when your working directory turns out to be something different from what you expected? Or, maybe, you are looking for an easy and robust way of declaring paths to configs and any data files in your project? Yeah, that drives us all crazy.
The package is really tiny, there are two function:
from_root
helps with declaring absolute paths relative to your project rootfrom_here
comes in handy when you want to declare a path relative to the current fileThey are dead simple to use.
Let's assume we have a project with the next structure:
├── .git # OPTIONAL. See explanation below
├── .project-root # OPTIONAL. See explanation below
├── config.json
├── assets
│ ├── animation.gif
│ └── logo.png
└── package
├── __init__.py
├── data.csv
├── script.py
├── FROM_HERE_DEMO.py
└── inner_package
├── FROM_ROOT_DEMO.py
├── __init__.py
└── insanely
└── deep
└── dir
└── file.txt
from_root
examples:# <PROJECT_ROOT>/package/inner_package/FROM_ROOT_DEMO.py
from from_root import from_root
CONFIG_PATH = from_root('config.json')
PACKAGE_DATA_PATH = from_root('package', 'data.csv')
# `from_root` returns pathlib.Path object
# so we can take advantage of its fantastic "/" syntax
ASSETS_DIR = from_root('assets')
ANIMATION_PATH = ASSETS_DIR / 'animation.gif'
LOGO_PATH = ASSETS_DIR / 'logo.png'
# no matter how deep it's located
FILE_TXT_PATH = from_root('package', 'inner_package', 'insanely', 'deep', 'dir', 'file.txt')
# If `mkdirs` is set to True (False by default), all *args will be treated as dir names
# and created for you.
# If a directory already exists, nothing happens.
import pickle
RESULTS_DIR = from_root('package', 'deep', 'results', 'dir', mkdirs=True)
results = {
'ones': [1, 1, 1],
'zeros': [2, 2, 2]
}
for name, data in results.items():
path = RESULTS_DIR / f'{name}.pkl'
# `FileNotFoundError` is not raised because `from_root` has created all non-existing directories
with path.open('wb') as file:
pickle.dump(data, file)
# WARNING: don't do this, you'll end up with data.json directory:
with from_root('results', 'data.json', mkdirs=True).open('w') as file:
...
# Do this instead:
with (from_root('results', mkdirs=True) / 'data.json').open('w') as file:
...
from_here
examples:# <PROJECT_ROOT>/package/FROM_HERE_DEMO.py
from from_root import from_here
# The only difference from `from_root` is that `from_here` allows you to declare relative paths
# I think the examples speak for themselves quite good.
# Take a look at tree above and compare with `from_root` examples
CONFIG_PATH = from_here('data.csv')
FILE_TXT_PATH = from_here('inner_package', 'insanely', 'deep', 'dir', 'file.txt')
When from_root
is called, folders in the current traceback are looked through one by one in order to find .git
directory or .project-root
file (might be empty; you have to create it on your own). The first one that contains at
least one of them are considered as a root directory.
FAQs
Forget about working directory errors
We found that from-root demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.