I realised that I don't know how variables are injected into JavaScript in HTML.
I would like to test overriding a clickTag variable which is simply a var in the main body of a JavaScript ( a default value ), but to override it with the injected variable.
Something like this >
somewhere.com/index.html?{"clickTag":"http://www.something.com"}
What's the best way to do that ?
Pretty basic, but I've been used to having the DoubleClick Enabler handling that for me and I have not thought about how the data actually gets in, and how I could test it.
( for a basic php file, passing variables the simplest way, it would be work.php?play=good&balance=true etc but I'm not finding a question here for what I have asked )
Please also correct my terminology if it is bad or misleading. Thanks.
Variables aren't injected into JavaScript.
A JavaScript program defines variables. It might get values to assign to them by accessing APIs (such as location in a web browser which would give you details of the URL of the page).
If you want to override the value of a variable in an existing program then you would need to change the source code of that program to write a new value to that variable between the point where it would normally be assigned and the point where it gets read back and used.
Related
I have made a math formula editor which allows the user to enter a math formula. This will then be converted to a JavaScript equation in a string, which will be executed using eval(). The user will also be able to submit it so that other users can view his function. The big problem with this is that it would be possible to enter JavaScript code in the formula, which would then be executed by the browsers of other users viewing it. I unfortunately can't just escape the formula because I am converting things like Sinus to a Math.sin() function. I am open to any suggestions how I can prevent the user from putting JavaScript code into the Math formula, here are my ideas:
Somehow check the code. The problem is that as said I can't just scan for any JavaScript function because I am using things like Math.sin() or Math.log(). So I would like to allow any method of the Math object and also normal math using standard operators. Another problem with this is that JavaScript can be disabled and modified, which could be a security concern. It would therefore be great if I could do this scanning using PHP.
Execute the equation in a "safe environment". Now I don't know if this is possible in JavaScript, but I am basically looking for something where the function that is being executed can't access or modify any functions (except any methods of the Math object) and can't change any of the global variables, including the document variable. I don't know whether this is possible or not but maybe somebody knows something.
Thanks for your help, Moritz
UPDATE: I have found a way. I made a function which shadows all global variables and functions with a local variable. This is the function:
function safeEval(string,banned) {
for(var i=0;i<banned.length;i++) {
eval('var '+banned[i]);
}
return eval(string);
}
Where banned is an array of strings which will be shadowed. To block all global variables, you can call it like this:
safeEval('document.write("test")',Object.keys(window))
This will throw an error, which is exactly what I want. Object.keys(window) will return an array of all global variables (and functions), including safeEval.
ANOTHER UPDATE: As Rainer Plumer pointed out, this is not safe as you can use this as follows: safeEval('this.document.write("test")',Object.keys(window))
Hope I could help. Moritz
The "safe environment" is a good idea; It can achieve by Iframe.
According to your description, you need a "safe environment" to run a JavaScript equation, I think Iframe is very good to do that. This process runs a JavaScript equation can be done in Iframe, and it is safe because the page and Iframe are independency document.
Then you can use postMessage or something else to get result from Iframe, show it to users. You have to use another domain in Iframe that can ensure nobody can get users cookie or something else important, one of the famous website is codepen.io doing that.
I would like to be able to expose a function-scoped variable that is part of a website's (not mine) javascript.
Here's a simplified example:
function addHooks(e, t, n, i) {
var props = { // Would like to expose this
update: function() { ... },
remove: function() { ... },
find: function() { ... },
};
...
}
In the above example, I would like to expose the props variable so that my webextension can then access this to modify the behavior of the website. Please note, that the website that serves this JS file isn't under my control and thus, I cannot simply modify the source file to export this variable. However, I'm fully open to modifying the final code that the browser runs (I just don't know how to). The javascript file containing the addHooks function appears to be added dynamically via XHR.
Although I have no idea on how to accomplish this programmatically, I have had some success setting a breakpoint and then issuing window.siteController = props in the browser's developer console. Unfortunately, manual user-intervention is not something I can package and distribute.
One method that I have been toying with is the idea of making an AJAX request for the JS file, modifying its script contents and appending it to the page.
Is there a canonical, programmatic way in which a function-scoped variable can be exposed?
if it's the props object variable that you want exposed, you could return he entire object from the functin, like in closures.
Or , you could, simple declare a the enclosing function as a constructor function, set props as this.props and then, invoke the same function elsewhere, using the new keyword.
Let me know if this helps
EDIT:
Thanks to Makyen who pointed out my error.
Apparently you might be able to do it if you re-define the function in a page script and insert it as a script element. (See the comment for two references).
Just be sure that your <script> element is inserted after the original definition and then you can either return props at the end of the function, or use this.props and use the function either as a constructor or using thecallfunction, passing an object that will get the props property added.
Old answer ( __ wrong__ apparently)
Short answer: you can't.
Full explanation: if you can't change the code of the function and you can only use the function (call it) you cannot alter its variable's scope (and good thing you can't, too. There's a reason why the variable was limited to its current scope).
And you can't change the website's JavaScript. As a Firefox or Chrome extension (and possibly the same fires to other browsers I'm not sure) you can't even access the function (let alone it's inner variables). I mean to say you can't even call it from the extension of it's in the website's code.
content scripts cannot see JavaScript variables defined by page scripts
More info and source
Firefox/Chrome runs your JavaScript code in a parallel environment, isolated from the website's environment. This is of course for security reasons. It also helps for you to be able to develop without knowing the exact inner workings of each website your code might be injected into, as you don't need to bother regarding naming conflicts (which would be impossible if it weren't for the separation environments).
The only thing you do have access to is the DOM, through which you can gather information, alter the website and even talk with the website in some cases (the website should follow a protocol you decide upon as well).
I am developing a JS game and wish to prevent cheating as much as possible. I understand that this is near impossible but I would like to prevent users from going into the console and changing their lives by saying something like game.lives = 99;
Is there a way I can detect if a variable such as lives has been changed from the console thus marking the game hacked and stopping the execution of my code? I understand I could do server side checking but I want to avoid lag. I am looking for a JS answer if there is one.
You won't be able to completely stop a user from changing the javascript code or variable values. You only can make it more difficult. Fisch mentioned using closure so as all variables will be private. Look into the immediately invoked function expression (IIFE) pattern. It's used in a lot of plugin style code and helps prevent modifications.
If a user wants to change a variables value, nothing will stop them from running the game in debug mode and modifying values at breakpoints.
You could use a closure which would essentially make all your variables private and thus not accessible from the console. If you need to have some public variables and methods, you could use a revealing module pattern. you can read more about them here: http://www.joezimjs.com/javascript/javascript-closures-and-the-module-pattern/
My question basically refers to this example:
https://github.com/vlandham/vlandham.github.com/blob/master/vis/gates/coffee/vis.coffee
At the end of this script (on line 202) it calls the (view_type) parameter from the front end and based on the view type ('year' or 'all') renders the exact method. I need to implement the a similar strategy, but within the show_details() method of this script (on line 176)..What I precisely need is to retrieve the view_type in the show_details() method and based on the view type ('year' or 'all') decide what the content variable (in show_details() method) should display..any ideas or help will be really helpful. Thank you.
So cofeescript automatically inserts local var statements for any variable referenced inside a function (precisely to prevent global leakage that JavaScript causes by default). This means you have to explicitly pollute some global namespace which in a browser would be the window object. Nothing in CofeeScript will prevent you from assigning a field of your choice with what ever value you need and reading it back any time you need. Note that this is messy and prevented for a reason (its hard to keep this kind of code clean, also there is no window object in a server side envrionment like node.js), but it will work.
I have a ajax form that populates select lists with values based on the previous selected select list item. This form is used in 3 different views with each view adding an extra select list. I have written some basic validation code that keeps the form process in sync and doesn't confuse the user.
I have written one function that handles all 3 forms in an external script file.
My Question:
Is it acceptable or is there anything I need to worry about if some of my variables are undefined based on the form and view?
Here is some sample code that illustrates my question:
Note: These are not the actual names of my variables.
(function ($){
var objects = {sl1:$('#SelectList1'),sl2:$('#SelectList2'),sl3:$('#SelectList3'),lbl1:$('#Label1'),lbl2:$('#Label2'),lbl3:$('#Label3')};
objects.sl1.change(function(){
mapValues();
}
function mapValues(){
objects.lbl1.text(objects.sl1.val());
objects.lbl2.text(objects.sl2.val());
objects.lbl3.text(objects.sl3.val());//What if this select list is undefined for View1?
}
})(jQuery);
To summarize, View #1 has SelectList1 & SelectList2. View #2 has all 3. Is there a performance issue or is it bad practice to call a function where some of the variables are undefined?
Thanks.
This is more of a jQuery issue, not a JS one. jQuery simply does nothing (it does not even fail!) if you execute a method such as .text() or .val() on an empty result from a selector. For the performance issue, test it yourself. If the element is not found, I expect the performance to be a little better compared to when an element exists.
So, it's valid to use such code.
Note that you're mixing up "undefined variables" with "non-available elements" which are totally different matters. Using undefined variables is strongly discouraged and often lead to unexpected behavior.
I think it's more about readability and maintainability at this point. I mean would it be clear to another developer just by looking at your JS that View #1 has SelectList1 & SelectList2 ? Looking at the code you would think it has all three since all the forms use the same JS. Maybe making it more flexible to where individual forms can specify which selectLists are contained within the respective form, this way the global script is only using the selectLists specified in the forms and not assuming all at available.
Yes it is bad practice. And is source of bugs.
For good practice, define default value, and/or check for it in your function.
thats why you should use the || operator
e.g. :
( $('#SelectList1').length || '0')
The issue is that you will introduce a level of uncertainty, and hence hard to trace bugs, if you do so. Different JS parsers will respond differently - some are more forgiving and will do nothing, others will just crash. So right away you have potential cross-browser issues.
Further, as those variables get passed around inside your code, if you do not know their values, you'll have a difficult time predicting how the rest of your code will interact with them. So now you also have potential logic/program bugs.
So do yourself a favor and a) check that any required parameters are passed, and do some error handling if it is not and b) make sure optional parameters are handled as soon as you receive them (eg assign them a default value, make sure they don't get passed on to other functions if they are not defined, whatever is most appropriate for your application logic).