Using Pylons global variables with JavaScript (escaping brackets) - javascript

I am trying to access a result in a dictionary held in a Python global variable within JavaScript.
var selected = jQuery('.target option:selected').text()
var list = "${c.persons_by_permission["+selected+"]}"
If I directly access the dictionary without the using the variable:
var list = "${c.persons_by_permission['stringID']}"
Then the code works.
However, when I am trying to use the variable to access the dictionary I get a syntax error (I believe its because of the curly braces).
I have tried escaping the braces with:
var list = "${{c.persons_by_permission["+selected+"]}}"
But it gives more syntax exceptions.
Any ideas?
EDIT:
This is not an issue of whether I can use Python and javascript together, it is more of a question of escaping the curly brackets
I am using pylons, so if I try:
alert("${c.persons_by_permission['Documents']}")
I will get the results I need. The issue is that I cannot find a way of passing a variable into the javascript in place of 'Documents'

I'm making a few (reasonable) assumptions hereā€¦
Your Python is running on your webserver
Your JavaScript is running on your client
As far as the Python is concerned it is outputting text. It doesn't care that the browser might interpret it as HTML, JavaScript or whatever. It just generates some text and then sends it to the browser.
With HTTP you get to make a request and have a response. You cannot stop a response half way through to get data back from the client.
You cannot pass data from client side JS back to the Python process that generated the JS. That process will have finished running.
You can either:
Send all the data to the client in the first place (and then select the bits you want in JS instead of in Python)
Have the JavaScript make a new HTTP request to the server and process the response in JS (this is known as Ajax and there are no shortage of tutorials out there for this)

I don't know what execution environment you are using,but I am almost certain that python and javascript are not executing at the same time.
${c.persons_by_permission['stringID']} looks to me like some kind of template directive. If so, this works because the directive is processed at template processing time. Your other form is just an expression in javascript that evaluates in javascript to a string.

Related

Check if a string contains executable code in JavaScript?

I have an Android app that runs my code(which is a JS bundle) in a hidden webview. I make API calls through native code using a JS interface. The response is sent back to a function through the evaluetJavascript method of the webview. The concern here is somehow a malicious response is received which might execute arbitrary JS in my webview. I am base-64 encoding the result before calling the evaluateJavascript and once it reaches the JS, I just decode it and parse the JSON and then it's just a string value which gets used further.
I have 2 questions:
(1) Since I am not using eval() anywhere in my JS code, is my understanding correct that even if a code gets through, it won't ever execute?
(2) I have been asked to still validate the data. Is there any way to detect if a given string contains executable JS code? I thought of looking for characters like ;"'() etc. but have concerns that my data may contain parentheses and that a stringified JSON will have quotes anyways. I am worried about false positives. What will be a better approach for this?

Safely pass object to client in Node.js/express

A common question is how to pass an object from Node.js/Express.js to the browser. It's possible to do that using JSON stringify, but if the object contains user-provided data, that can open the door to script-injection and possibly other attacks.
Is there a downside to the approach mentioned in this link using Base64?
https://stackoverflow.com/a/37920555/645715
Related links:
Passing an object to client in node/express + ejs?
How to pass a javascript object that contains strings with quotes from node.js to the browser?
Pass a NodeJS express object to AngularJS 1.6
Passing an object to client in node/express + ejs?
Using Base64 encoding does solve the immediate problem of passing back an injection attack, but it doesn't necessarily solve the issue of having a possible injection attack floating around out there. For example, this fiddle shows that it does prevent the immediate issue : https://jsfiddle.net/9prhkx74/
var test2 = JSON.parse(window.atob('PC9zY3JpcHQ+PHNjcmlwdD5hbGVydCgndGVzdDInKTwvc2NyaXB0PjxzY3JpcHQ+'));
This won't show an alert box, it'll just throw an error about invalid JSON. But if you change it to the literal string, it'll show the alert box (injection vulnerable)
var test2 = JSON.parse("</script><script>alert('test2')</script><script>")
Now if you are immediately parsing it to a JSON object, it'll blow up, and everything will be "safe". But if you assign it to a value because you are going to pass it around some more etc, you still have a potential issue out there.
Instead of putting a bandaid on the injection itself, I'd suggest fixing it in the first place and properly escaping data before passing it back to the client or processing it on the server side.
There are plenty of libraries that can help do this
https://www.npmjs.com/package/sanitize
https://www.npmjs.com/package/express-sanitizer
Here's a pretty good article that kind of highlights why it is important to sanitize and not just just patch over potentially malicious data : https://lockmedown.com/5-steps-handling-untrusted-node-js-data/

How to export JavaScript object as JavaScript?

I'm looking for most elegant way of "dumping" simple JavaScript object into JavaScript source-code generated on-fly.
Purpose:
Assume we have node.js server generating HTML. We have an object x on server side. The object is simple - only strings/ints/arrays in it (so, it's JSON-able). I want to "embed" object x into HTML being generated, to be available for JavaScript code which will run on the browser. So the code:
console.log(x);
will dump exactly the same data on both server-side and browser-side.
For example - imagine I'm going to pass some additional config/data to JavaScript running on browser.
Obvious solutions:
Encoding as JSON and send as AJAX/Websocket is not a part of this question as we have to embed the object in the HTML. I don't want additional HTTP requests - everything should be passed in one go.
Encoding as JSON and simply attach to variable sounds initially good, but involves some additional escaping steps.
Using util.inspect() works for me, in this way:
var toHtml = 'var x = ' + util.inspect(theXonServer, {depth:9}) + ';';
but I'm not sure if it's "elegant" (and secure and error-prone and...)
Any better suggestions ? Standard way of doing that ?
The Wrong Way to Pass Data
It's common to get advice to just stringify some JSON and dump it into a <script> tag. This is bad advice. Don't do it.
It's important to understand why this is a bad idea.
When you string-build JavaScript, you're opening yourself up to all sorts of quirks of the language that you'd absolutely be required to understand to make sure that there are no issues.
One such quirk is that within a <script> element, the first occurrence of </script> will close the <script> element. It doesn't matter that it's in a string, the script will be closed, and the rest of the contents after that point will be treated as HTML.
HTML escaping doesn't work because JS doesn't like HTML entities.
what might start as:
<script>
window.xss = <%= JSON HERE %>
</script>
could turn into:
<script>
window.xss = {"username":"Robert Hackerman</script><script src='nefarious.js'></script>"}
</script>
Don't risk it.
The Right Way to Pass Data...
...When the Page is Rendering
The much safer way that prevents any script execution is via [data-*] attributes. You must HTML-escape the contents, but that's OK in attributes. I'm using a <script> element because it's implied that the script will be using the data.
What would start as:
<script data-foo="<%= HTML ENCODED JSON HERE %>" src="yourscript.js"></script>
Would turn into:
<script data-foo="{"username":"Robert Hackerman</script><script src=&apos;nefarious.js&apos;></script>"}" src="yourscript.js"></script>
And if you want access to that data, you can just access the attribute value, or use the dataset api (if your target browsers support it):
var fooElement = document.querySelector('[data-foo]');
var rawData = fooElement.dataset.foo;
// or
var rawData = fooElement.getAttribute('data-foo');
var data = JSON.parse(rawData);
console.log(data);
...After the Page has Rendered
If the page has already loaded, and you want to access some data, just use an AJAX request. You'll be able to safely read in a JSON data source, which can be piped through JSON.parse to access the data object.
Util.inspect vs JSON.stringify
You only need util.inspect if your object is circular. If it's JSON encodable in 99.9% of cases you can just output it to the source with JSON.stringify.
Using JSON
There are edge cases to this - not only are JS objects more expressive than JSON (functions etc), JSON objects can do things JS objects can't (in edge cases of encoding). So make sure not only is your object serializable correctly, it's also deserializable correctly. I also assume you didn't do anything crazy like override the array constructor (which would make JS objects behave differently from JSON ones).
Security
As for security, unless your object can contain sensitive data (and it really shouldn't, whitelist it first) there should not be any related issues.
Overall option 2 is a standard approach that is quite commonly used - including on this very site.
It usually works for simple data which is most data you need to share (numbers and strings).
It saves the round trip.
It's used very often in big sites and in practice.

What should be done to JSON data before it's inserted into a page via JavaScript?

I am fetching JSON data from my local server and was wondering what functions I should run my data through before printing it on the page in HTML. Just want to ensure everything is secure and any special characters like quotes are handled properly.
Thanks!
If you are using legal JSON and you are using a real JSON parser, not eval(), then your JSON is safe. It can't contain executable code, only data definitions.
You are certainly free in your client code to take the parsed JSON and run a bunch of sanity checks on the data to make sure it makes sense and passes any specific tests you might want to run on it, but you won't have to worry about code injection if you are using real JSON and a real JSON parser. That is one of the advantages of using JSON - it is a data-only format.
If you're worried about someone hijacking your server and returning bogus data, then you can try to secure the endpoint with https and run any obvious sanity checks in the client.

How to show a friendly error message using Open-flash-charts2?

If my JSON data-file comes from a database result set and that result set is empty, how do I tell OFC2 to display an error message, instead of crashing because of a malformed JSON string?
Add tags for javascript and actionscript-3 to this question and you should get a load more views and useful responses than you currently are, with more precise details than I am giving. Post the actual JSON string that is causing you the problem and that you would like to be guarded against. That way people can suggest a regexp to catch it, treating it as a string rather than as JSON data at some point before JSON.decode() happens.
In more detail:
You can catch it in two places. One route is to switch over to using the javascript interface to OFC2 and use client side javascript to detect the bad string. This allows you to modify the JSON string client side. See http://teethgrinder.co.uk/open-flash-chart-2/tutorial-5.php for that approach. One downside is that the clients must have javascript enabled for this to work.
Alternatively, since OFC2 is LGPL, you or an actionscript developer can dive into the OFC2 source code and do the same thing there. I am not an actionscript developer so you are better off ensuring you get a reply from one.
The main thing is to add those two tags to this question. 22 Views is way too low for a question with a bounty of 500. Hope this helps.
Several solution avenues are possible, depending on your level of access to the server and your knowledge of JavaScript and/or any server-side platforms.
With access to database
Depending on the kind of data you are displaying, it might be possible to add dummy records for those queries that would otherwise have returned an empty set. If you have access to the query definition, you may check for the empty set in the DB-query. For example, if you're on MS SQL Server you could check the condition with some T-SQL statements.
With access to server
If you have access to the server side script generating the dataset, add a condition that returns some default value that OFC2 will handle correctly.
With access to another server or serverlocation
If you don't have access to the specific script, you may consider creating a new script at another location that queries the original script and replaces empty results with the default value.
Client-side only
You can add the JavaScript open_flash_chart_data function (see tutorial) to replace empty datasets. OFC2 can use that function as data source.
Hope this helps.

Categories