This is an intentionally vulnerable lab to study nosql injection, the specific case of $where
Code:
let username = req.query.username;
query = { $where: `this.username == '${username}'` }
User.find(query, function (err, users) {
if (err) {
// Handle errors
} else {
res.render('userlookup', { title: 'User Lookup', users: users });
}
});
So far I managed to execute javascript code, example:
user/lookup?username=';sleep(5000);'
My next intentions are to try to collect the data inside the dbs, since $where let me execute stuff.
So, If I do for example:
user/lookup?username=';db.getMongo().getDBNames();'
I get this error:
{"ok":0,"code":139,"codeName":"JSInterpreterFailure","name":"MongoError"}
Reading the server logs:
...
cmd":{"find":"user","filter":{"$where":"this.username ==
'';db.getMongo().getDBNames();''"},"projection":{},"lsid":{"id":{"$uuid":"d910e28c-
7303-45b2-8888-2defbb220e0a"}},"$db":"vulnerablemean"}}}
node_1 | { MongoError: Executor error during find command :: caused by ::
ReferenceError: db is not defined :
...
But if in the mongo shell I run the same string, I get a result:
> db.getMongo().getDBNames()
[ "admin", "config", "local", "vulnerablemean" ]
I would like to undestand why it happens. I mean, is it not actually referenced?
How can I get the same result via injection?
Related
I'm trying to implement database population by using a migration function. The code works perfectly, it saves all the data into the database, but the test for the function is failing, and now I would like to know why?
I'm getting the "Exceeded timeout of 5000 ms" error for this particular test. I've written 166 tests for this app and all of them are passing.
Here is the function I want to test:
const doMigration = async ({ model, data }) => {
await model.collection.insertMany(data)
}
And here is the test:
const { Amodel } = require('../../../models/Amodel')
const { doMigration } = require('../../../database/migrations')
describe('Database Population', () => {
it ('Should populate the database using migrations', async () => {
const data = [{ name: 'A' }, { name: 'B' }]
const model = Amodel
const migration = { name: 'Amodel', model, data }
await doMigration(migration)
const countAfter = await Amodel.count()
expect(countAfter).toBe(2)
})
})
In this test I simply import the function, the model and create a migration object that then is passed to the function.
What did I try?
Tried using just the countAfter without using the doMigration function, and it still generates the same timeout error.
Tried increasing the time for this test to 30000, failed with error saying that the mongodb time exceeded the 10000 ms.
Here is the github repository: https://github.com/Elvissamir/Fullrvmovies
What is happening, how can I solve this error?
The problem was the way the mongodb connection was handled. When testing, the app created a connection to the db on startup, and then the jest tests used that connection, that caused some issues.
The solution was to connect to the database on startup only if the environment is set to testing, otherwise the connection will be handled by each set of tests.
In each set I added a beforeAll and afterAll to open and close the connection to the database.
Hope it helps anyone that finds the same problem or has similar issues.
The orientation is that the message reflect the actual reason, So i recommand to follow the following steps:
use the following code to check mongo state:
const { MongoMemoryServer } = require("mongodb-memory-server");
const mongoose = require("mongoose");
(async () => {
mongod = await MongoMemoryServer.create();
const mongoUri = mongod.getUri();
await mongoose.connect(mongoUri, {
useNewUrlParser: true,
useUnifiedTopology: true,
}).then((result) => {
console.log(result.connection.readyState)
console.log(result.connection.host)
}).catch((err) => {
});;
})();
if you are using mongodb-memory-server add "testTimeout" attribute:
"jest": {
"preset": "ts-jest",
"testEnvironment": "node",
"setupFilesAfterEnv": [
"./src/test/setup.ts"
],
"testTimeout": 15000
},
If all above still huppens check the time-out of all inter-test operation
Trying to get results of command that I passed in admin command,
but it throws me back a MongoError
how to/ where to set rs.slaveOk() using mongoose lib, if its ?
conn = mongoose.createConnection(`mongodb://localhost:port`)
cmd = "someCommand"
conn.db.admin().command(cmd, (err, result)=>{
if(err){
console.error(err)
}
resolve(result)
})
// MongoError: not master and slaveOk=false
Added Read Preference and Replicaset name in Connection String
https://mongoosejs.com/docs/connections.html#connection-string-options
https://mongoosejs.com/docs/api.html#query_Query-read
var options = {
"db": {
"readPreference": "secondaryPreferred"
},
"replset": {
"rs_name": "replica_name",
}
}
var connection =
mongoose.createConnection(`mongodb://localhost:27030/dbname`, options);
I'm trying to figure out what I'm doing wrong here with absolutely no luck.
db.attendances.update({ _id: 'hRs6LfAqPBmy4ZNuH' }, { $set: { absentParentOrGuardianDate: undefined } })
If I run this update command in the terminal shell using 'meteor mongo' absentParentOrGuardianDate is removed from the document, however, if I run the same code, slightly changed for meteor, on the meteor server I get an error.
Attendances.update({ _id: 'hRs6LfAqPBmy4ZNuH' }, { $set: { absentParentOrGuardianDate: undefined } });
The error is:
{isClientSafe: true, error: 500, reason: "Internal server error", details: undefined, message: "Internal server error [500]", …}
Can someone please tell me what I'm missing here.
import { _ } from 'meteor/underscore';
const updateDoc = {};
_.each(yourObj, (value, key) => { // I'm using underscore to help loop through the object
if (value) {
updateDoc.$set[key] = value;
} else {
updateDoc.$unset[key] = value;
}
});
yourCollection.update(yourSelector, updateDoc);
Per the docs, StrongLoop doesn't support running custom sql statements.
https://docs.strongloop.com/display/public/LB/Executing+native+SQL
How anyone thinks you can build an enterprise app with just simple joins is beyond me, but I did find this post which says you can do it:
Execute raw query on MySQL Loopback Connector
But this is for MySql. When I try it with Postgres I get the error: "Invalid value for argument 'byId' of type 'object': 0. Received type was converted to number." And it returns no data. Here is my code:
module.exports = function(account) {
account.byId = function(byId, cb){
var ds=account.dataSource;
var sql = "SELECT * FROM account where id > ?";
ds.connector.execute(sql, [Number(byId)], function(err, accounts) {
if (err) console.error(err);
console.info(accounts);
cb(err, accounts);
});
};
account.remoteMethod(
'byId',
{
http: {verb: 'get'},
description: "Get accounts greater than id",
accepts: {arg: 'byId', type: 'integer'},
returns: {arg: 'data', type: ['account'], root: true}
}
);
};
For the part [Number(byId)], I've also tried [byId] and just byId. Nothing works.
Any ideas? So far I really like StrongLoop, but it looks like the Postgresql connector is not ready for production. I'll be doing a prototype with Sails next if this doesn't work. :-(
Here's the thing arg is of type 'integer' which is not a valid Loopback Type. Use `Number instead. Check the corrected code below:
module.exports = function(account) {
account.byId = function(byId, cb){
var ds = account.dataSource;
var sql = "SELECT * FROM account WHERE id > $1";
ds.connector.execute(sql, byId, function(err, accounts) {
if (err) console.error(err);
console.info(accounts);
cb(err, accounts);
});
};
account.remoteMethod(
'byId',
{
http: {verb: 'get'},
description: "Get accounts greater than id",
accepts: {arg: 'byId', type: 'Number'},
returns: {arg: 'data', type: ['account'], root: true} //here 'account' will be treated as 'Object'.
}
);
};
Note: MySQL's prepared statements natively use ? as the parameter placeholder, but PostgreSQL uses $1, $2 etc.
Hope this works for you. Else try with [byId] instead of byId as per the docs.
I have this route defined, but any requests made to it get's stuck on 'pending' and runs forever.
When I log the code, I see 1 followed by 4, which means the code inside the find method never gets executed
# Calendar routes
router.get '/calendars', (req, res) ->
console.log '1'
Calendar.find (err, calendars) ->
console.log "2" + err
console.log "3" + calendars
res.send(err) if err
res.json(calendars)
return
console.log '4'
return
Model
mongoose = require("mongoose")
module.exports = mongoose.model("Calendar",
name: String
)
Any ideas on why this is?
Until you call mongoose.connect, your mongoose queries will simply be queued up.
Add code like this in your startup code to connect:
mongoose.connect('mongodb://localhost/test', function(err) {
if (err) {
console.error(err);
} else {
console.log('Connected');
}
});
In the connection string, replace test with the name of your database.