
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
A js-git mixin that uses github as the data storage backend.
This allows live mounting of github repos without cloning or pushing.
It's implemented as a js-git mixin that implements the storage backend using Github's Git Data API using REST calls.
This will work in the browser or in node.js. Technically an access token isn't required to read public repositories, but you will be rate-limited to a very small amount of requests per hour. With an auth token, you will be able to do more, and depending on the access of the token you can read private repos or write to repos.
I highly reccommend using a local cache in IndexedDB or LevelDB or something available on your platform. This way you never request resources you've asked for before and can do more work without hitting the rate limit.
Here is a sample config for a chrome app that uses IDB for a local cache:
// Start out the normal way with a plain object.
var repo = {};
// This only works for normal repos. Github doesn't allow access to gists as
// far as I can tell.
var githubName = "creationix/js-github";
// Your user can generate these manually at https://github.com/settings/tokens/new
// Or you can use an oauth flow to get a token for the user.
var githubToken = "8fe7e5ad65814ea315daad99b6b65f2fd0e4c5aa";
// Mixin the main library using github to provide the following:
// - repo.loadAs(type, hash) => value
// - repo.saveAs(type, value) => hash
// - repo.listRefs(filter='') => [ refs ]
// - repo.readRef(ref) => hash
// - repo.updateRef(ref, hash) => hash
// - repo.deleteRef(ref) => null
// - repo.createTree(entries) => hash
// - repo.hasHash(hash) => has
require('js-github/mixins/github-db')(repo, githubName, githubToken);
// Github has this built-in, but it's currently very buggy so we replace with
// the manual implementation in js-git.
require('js-git/mixins/create-tree')(repo);
// Cache github objects locally in indexeddb
var db = require('js-git/mixins/indexed-db')
require('js-git/mixins/add-cache')(repo, db);
// Cache everything except blobs over 100 bytes in memory.
// This makes path-to-hash lookup a sync operation in most cases.
require('js-git/mixins/mem-cache')(repo);
// Combine concurrent read requests for the same hash
require('js-git/mixins/read-combiner')(repo);
// Add in value formatting niceties. Also adds text and array types.
require('js-git/mixins/formats')(repo);
// Browser only: we need to initialize the indexeddb
db.init(function(err) {
if (err) throw err;
});
Note that this backend does not provide loadRaw or saveRaw and can't be used
with the pack-ops mixin required for clone, push, and pull. The good news is
you don't need those since all changes are happening on github directly. If you
want to "push" a new commit, simply update the ref on the repo and it will be
live.
So, here is an example to load README.md from an existing repo, change it to
all uppercase the save it back as a new commit.
// I'm using generator syntax, but callback style also works.
// See js-git main docs for more details.
var run = require('gen-run');
run(function* () {
var headHash = yield repo.readRef("refs/heads/master");
var commit = yield repo.loadAs("commit", headHash);
var tree = yield repo.loadAs("tree", commit.tree);
var entry = tree["README.md"];
var readme = yield repo.loadAs("text", entry.hash);
// Build the updates array
var updates = [
{
path: "README.md", // Update the existing entry
mode: entry.mode, // Preserve the mode (it might have been executible)
content: readme.toUpperCase() // Write the new content
}
];
// Based on the existing tree, we only want to update, not replace.
updates.base = commit.tree;
// Create the new file and the updated tree.
var treeHash = yield repo.createTree(updates);
At this point, the new data is live on github, but not visible as it if wasn't pushed. If we want to make the change permanent, we need to create a new commit and move the master ref to point to it.
var commitHash = yield repo.saveAs("commit", {
tree: treeHash,
author: {
name: "Tim Caswell",
email: "tim@creationix.com"
},
parent: headHash,
message: "Change README.md to be all uppercase using js-github"
});
// Now we can browse to this commit by hash, but it's still not in master.
// We need to update the ref to point to this new commit.
yield repo.updateRef("refs/heads/master", commitHash);
});
I tested this on this repo. Here is the commit
FAQs
An implementation of the js-git interface that mounts a live github repo.
The npm package js-github receives a total of 25 weekly downloads. As such, js-github popularity was classified as not popular.
We found that js-github demonstrated a not healthy version release cadence and project activity because the last version was released 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
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.