Meteor Dev Tools Auditor is marking collections as insecure - google-chrome

I use Meteor Dev Tools plugin in Chrome, and I’ve noticed a cool new feature, that is worrying me about the way I've coded my app.
The audit collection tool is telling me that some of my collections are insecure.
I am still using Meteor 1.2 with Blaze
1.
One of them is meteor_autoupdate_clientVersions
1.1. should I worry about this one?
1.2. How do I protect it?
Insert, Update and Remove are marked as insecure.
2.
Then I have a cycles collection, which has marked as insecure: update and remove
This collection is updated on the database now and then but not supposed to be accessed from the frontend, and is not meant to be related to any client interaction.
For this collection I have these allow/deny rules in a common folder (both client and server)
I've tried applying these rules only on the server side, but I didn't see a difference on the audit results.
2.1. Should these rules be only on the server side?
Cycles.allow({
insert: function () {
return false;
},
remove: function () {
return false;
},
update: function () {
return false;
}
});
Cycles.deny({
insert: function () {
return true;
},
remove: function () {
return true;
},
update: function () {
return true;
}
});
2.2. How do I protect this collection?
3.
And then, I also have another collection with an insecure check which is users, where remove is marked as insecure.
On this webapp I don't make any use of users, there is no login, etc.
I might want to implement this in the future, though.
3.1 Should I worry about this collection being insecure, since I don't use it at all?
3.2 How do I protect this collection?

You do not have to allow or deny. Just remove the insecure package from the meteor app.
Then you can use publish/subscribe and methods for data insert, update and delete.
Remove this please fo code from app:
Cycles.allow({
insert: function () {
return false;
},
remove: function () {
return false;
},
update: function () {
return false;
}
});
Cycles.deny({
insert: function () {
return true;
},
remove: function () {
return true;
},
update: function () {
return true;
}
});
For 1.1
This happens while the user is logging.
Basically, issue is not with this but with the login method.
see wait time: https://ui.kadira.io/pt/2fbbd026-6302-4a12-add4-355c0480f81d
why login method slow?
This happens when everytime, your app gets reconnected. So, after the sucessful login, it will re-run all the publications again. That's why you saw such a delay to login hence this publication.
There is no such remedy for this and but this is kind fine unless your app is having a lot of througput/subRate to this method/publication.
For 3.1 :
You do not have to worry about inscure anymore after removing allow/deny and insecure package. But make sure, you write secure methods.

Related

How to record http requests with Google Chrome extension and persist them

I want to create a Chrome extension, that records HTTP requests (to a pre-defined host) and persists them as a list in local storage so when I call a particular website again the list will be extended.
I want to go with Manifest v3 to make the extension "ready for the future". I created a background script to trigger the request that currently puts all the details into local storage like that (currently this is redundant for demonstration purposes, I also tried it seperated):
chrome.webRequest.onBeforeRequest.addListener(details => {
var urls = [];
chrome.storage.local.get(['data'], function(data){
urls = data.urls;
});
chrome.scripting.executeScript(
{
target: {tabId: details.tabId},
func: recordClick,
args: [details, urls]
},
() => {
urls.push(details);
console.log(urls.length);
chrome.storage.local.set({urls: urls});
});
}, {
urls: ['<all_urls>']
});
There's another function called recordClick() that does the same as in the callback:
function recordClick(details, urls) {
urls.push(details.url);
chrome.storage.local.set({urls: urls});
}
I tried several ways on where to load and save the result but none of them work. When I load the previous urls within the onBeforeRequest trigger, urls is not global and not known within the callback. When I put it outside the trigger definition, it's not reading the storage in realtime. I also tried to load the urls in a content script, loaded at "Document start". I tried to load the urls in the backend script at the top, and so on.
Seems like I have a timing problem: The trigger always loads an empty list or the variable is not global. I'm not able to extend the list. No matter where I put the storage functions.
Is my plan feasable at all? What am I'm doing wrong?
thanks!
Since chrome.storage.local.get is asynchronous, you should move chrome.scripting.executeScript into the callback of it.
onComplete may be suitable for your purpose, instead of onBeforeRequest.
chrome.webRequest.onBeforeRequest.addListener(details => {
chrome.storage.local.get('urls', function(data){
let urls = [];
if( data.urls ) {
urls = data.urls;
}
urls.push(details);
chrome.storage.local.set({urls: urls}, function() {
console.log('Value is set to ');
console.log(urls);
});
chrome.scripting.executeScript( {
target: {tabId: details.tabId},
func: function(details, urls){ console.log("executed script") },
args: [details, urls]
},
() => {
console.log("injected")
});
});
},
{ urls: ['<all_urls>'] }
);

Redirect issues when using MySQL as session storage

I have set up a Node.js app where I use sessions and store them in MySQL. When using MemoryStorage, redirections work fine, but when using MySQL, req.session doesn't update until you reload or you move to a different page, and I'm forced to replace every single res.redirect('/...') by res.render() of that same page to display anything in req.session immediately.
I've tried using both return res.redirect() and not, as well as using setTimeout, neither work. I can't figure it out and I need sessions to be stored in DB
router.get('/student-sign-up', function (req, res, next) {
res.render('student/signUp', {
title: 'Sign up',
errors: req.session.errors
});
req.session.errors = null; //to flush them on reload
}).post('/student-sign-up', function (req, res, next) {
//Some form checks
let errors = req.validationErrors();
if (errors) {
req.session.errors = errors;
req.session.signUpSuccess = false;
return res.redirect('/student-sign-up');
}
//...
}
The above should redirect to the same page, and display the error (I use Handlebars as my view engine) if there were one, but it simply redirects, and if you refresh manually or submit a faulty from again, then it displays it. Same thing for logins (both success not going into the platform's home, and failure not showing errors either). It's like everything's lagging behind by 1 step...
OK, I found the solution. According to the express-session docs, all I had to do was force a save and then redirect, as so:
req.session.save((err) => {
if (err) {
req.locals.error = err;
return res.redirect('/');
}
return res.redirect('/next-section');
});
I'll leave this here for anyone that might have the same issue!

Returning promise from reflux store

I'm working on my first react/reflux app so I may be approaching this problem in completely the wrong way. I'm trying to return a promise from a reflux store's action handler. This is the minimum code that represents how I'm trying to do this. If I display this in the browser, I get an error saying that the promise is never caught, because the result of the onLogin function is not passed back when the action is initiated. What is the best way to do this?
var Reflux = require('reflux');
var React = require('react/addons')
const Action = Reflux.createAction();
const Store = Reflux.createStore({
init: function() {
this.listenTo(Action, this.onAction);
},
onAction: function(username, password) {
var p = new Promise((resolve, reject) => {
reject('Bad password');
});
return p;
}
});
var LoginForm = React.createClass({
mixins: [Reflux.connect(Store, 'store')],
login: function() {
Action('nate', 'password1').catch(function(e) {
console.log(e); // This line is never executed
});
},
render: function() {
return (
<a onClick={this.login} href="#">login</a>
)
}
});
React.render(<LoginForm />, document.body);
Several things seem a bit confused here.
Reflux.connect(Store, 'store') is a shorthand for listening to the provided store, and automatically set the "store" property of your component state to whatever is passed in your store's this.trigger() call. However, your store never calls this.trigger so "store" in your component's state will never be updated. Returning a value from your store's action handlers doesn't trigger an update.
Stores should listen to actions to update their internal state, and typically then broadcast this state update by calling this.trigger. No component is going to get your returned promise from the store's onAction unless it explicitly calls Store.onAction (and then it doesn't matter if the actual action was invoked or not).
Async work should typically happen in the action's preEmit hook, not in the store. You should then also declare the action as async in createAction by setting the asyncResult option to true to automatically create "completed" and "failed" child actions. Check out the Reflux documentation here to learn about async events. Async actions automatically return promises, whose resolve and reject are called when the "completed" and "failed" sub-actions are called respectively. This is a bit opinionated, but that is definitely what I perceive is the intended Reflux way.

chrome.storage.sync.set won't update the storage anymore

I am using chrome.storage.sync for some of my chrome extensions, great tool!
But I have an issue now, after updating the storage like 10 times. It blocks and does not update anymore... No error or anything so I do not know where the problem is.
FYI: I still have space in the storage.
The code:
Storage.get_all = function(callback) {
STORAGE_SYNC.get('key', function(items) {
callback(items.gifs_v2);
});
};
Storage.post = function(id, item, callback) {
var THIS = this;
THIS.get_all(function(items) {
if(items) {
items[id] = item;
STORAGE_SYNC.set({'key': items}, callback);
} else {
THIS.post_all({}, function() {
THIS.post(id, item, callback);
});
}
})
};
There are several quotas published in the official documentation. Look it up. You probably run out of one of them. Remember that sync also goes into google's sync servers so abusing them will block you for a while. If you dont need to sync among devices use the regular local storage instead of sync.

How do you detect that a script was loaded *and* executed in a chrome extension?

I've been tracking down a bug for days... then I realized the bug was me. :/
I had been using webRequest.onComplete, filtered for scripts. My error was that I made the incorrect association between the scripts being loaded and being executed. The get loaded in a different order than they get executed, and thus the timing of the events is not in the order I need them in. I need to inject between certain scripts so I need an event right after a file has been executed and before the next one.
The only solution I can think of at the moment is to alter the JS being loaded before it gets executed. But it makes my stomach turn. And the bfcache would wreak even more havoc, so not a great solution either.
I would use the HTML5 spec's afterscriptexecute, but that is not implemented in Chrome. Is there another API, perhaps an extension API that I can use?
Note: This method no longer works as of Chrome 36. There are no direct alternatives.
Note: The answer below only applies to external scripts, i.e. those loaded with <script src>.
In Chrome (and Safari), the "beforeload" event is triggered right before a resource is loaded. This event allows one to block the resource, so that the script is never fetched. In this event, you can determine whether the loaded resource is a script, and check whether you want to perform some action
This event can be used to emulate beforescriptexecute / afterscriptexecute:
document.addEventListener('beforeload', function(event) {
var target = event.target;
if (target.nodeName.toUpperCase() !== 'SCRIPT') return;
var dispatchEvent = function(name, bubbles, cancelable) {
var evt = new CustomEvent(name, {
bubbles: bubbles,
cancelable: cancelable
});
target.dispatchEvent(evt);
if (evt.defaultPrevented) {
event.preventDefault();
}
};
var onload = function() {
cleanup();
dispatchEvent('afterscriptexecute', true, false);
};
var cleanup = function() {
target.removeEventListener('load', onload, true);
target.removeEventListener('error', cleanup, true);
}
target.addEventListener('error', cleanup, true);
target.addEventListener('load', onload, true);
dispatchEvent('beforescriptexecute', true, true);
}, true);
The dispatch times are not 100% identical to the original ones, but it is sufficient for most cases. This is the time line for the (non-emulated) events:
beforeload Before the network request is started
beforescriptexecute Before a script executes
afterscriptexecute After a script executes
onload After the script has executed
Here's an easy way to see that the events are working as expected:
window.addEventListener('afterscriptexecute', function() {
alert(window.x);
});
document.head.appendChild(document.createElement('script')).src = 'data:,x=1';
document.head.appendChild(document.createElement('script')).src = 'data:,x=2';
The demo can be seen live at http://jsfiddle.net/sDaZt/
I'm not familiar with Chrome Extensions (only browser javascript), but I think that you will unfortunately have to edit your loaded JS so that is calls a function of your choice when it is executed, if you want to do this nicely. This it what Google does for asynchronously loading its Maps Javascript file:
function loadScript() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://maps.googleapis.com/maps/api/js?sensor=false&callback=executed";
document.body.appendChild(script);
}
function executed() {
/* Google maps has finished loading, do awesome things ! */
}
If you really don't want to edit your loaded JS files, you could have a setInterval (or a recursive function with setTimeout) checking regularly if some functions or variables are initialized.
Have you tried script loading using Modernizr.js?
I had a similar issue, where the timing of script loading was causing conflict. I used Modernizr.js, which includes the library yepnope.js by default. Below is an example of some scripts I loaded conditionally. You can include a test clause, or simply load them in the order you prefer, with the guarantee that they will load and execute in the order you wish due to the callback.
Here is an example with a conditional clause:
Modernizr.load({
test: false, //Or whatever else you'd like. Can be conditional, or not so conditional
yep: {
'script1': 'MyJavascriptLibrary1.js'
},
nope: {
'script2': 'MyJavascriptLibrary2.js',
'script3': 'MyJavascriptLibrary3.js'
},
callback: {
'script1': function (url, result, key) {
console.log('MyJavascriptLibrary1.js loaded'); //will not load in this example
},
'script2': function (url, result, key) {
console.log('MyJavascriptLibrary2.js loaded first');
},
'script3': function (url, result, key) {
console.log('MyJavascriptLibrary3.js loaded second');
}
}
});
If triggering false, MyJavascriptLibrary2.js and MyJavascriptLibrary3.js will load in the appropriate order, no matter what elements influence how they would behave normally (file size, connection speed, etc.). In these callbacks, you may fire additional javascript as well, in the order you wish to do so. Example:
'script2': function (url, result, key) {
alert('anything in here will fire before MyJavascriptLibrary3.js executes');
},
Note this can be done without Modernizr.load({...
but using simply yepnope({...
For more documentation, check out the yepnope.js API