Simple template engine for user-edited files - javascript

I am using nodeJS (server) and Dojo (client). I am writing a system that should allow users to create user-defined messages (they could be text-only email or SMS). I want to give a lot of flexibility. I would like to:
Pass the users a number of variables
Give the user a Web form
Allow the user to cycle through the data in the variables, print it, etc
The result of the script execution is a text file
This could even be used to allow them to create invoices. However, at this stage I am more focused on text.
I am thinking of allowing straight Javascript, and then eval() whatever they wrote in it. But... I am not sure.
What's the best practice solution for such a problem?

Don't use eval, read the following for why.
Why is using the JavaScript eval function a bad idea?
For JavaScript templating see the following list.
https://github.com/joyent/node/wiki/modules#wiki-templating

Related

How to create a truly hidden variable in Javascript

I am trying to build a puzzle game using HTML & JS. This is going to be a standalone HTML page. There isn't going to be a server side for this application.
Obviously, the game has an answer which the application will create at start time. Now, I wish to make this variable completely hidden i.e., not just hidden from user's view but also inaccessible to the user, even if he tries to read the page through Chrome's Developer Tools or such debug tools.
I'm looking for a solution using HTML5, JS ECMAScript 5+ & jQuery.
I remember reading something about Native HTML code (used for HTML File elements) which cannot be rendered/read even through Dev Tools. Is this any help?
Is there any way or strategy to achieve this?
NOTE: I am aware of <input type="hidden">. But that doesn't serve my purpose.
EDIT: As part of the game, the user makes attempts and the application needs to validate the user's input against this somehow-user-hidden answer variable. At this point, I believe there is no solution that's going to be completely airtight in the given constraints. Hence, I'm pursuing this from an academic interest. Does anyone have any other answers ?
Prehash your answer, hard code that into your page.
Then, when they submit their answer, run through whatever hashing pattern you did before hand, and compare the result.
It could theoretically be brute forced, of course.... if you had a few hundred years.
Javascript implementations of:
SHA-1: http://www.webtoolkit.info/javascript-sha1.html
SHA-256: http://www.webtoolkit.info/javascript-sha256.html
MD5: http://www.webtoolkit.info/javascript-md5.html
Edit:
An example would be:
Pattern: SHA-1(SHA-1(SHA-1(answer + salt)))
Salt: 982qx17wef7ddsbtxaewnsdufs (make something up, load it as an input type='hidden')
Result: (load it as an input type='hidden')
Request the answer
If SHA-1(SHA-1(SHA-1(attempt + salt))) === Result, they got it correct
Your can hash your values using MD5.
https://github.com/blueimp/JavaScript-MD5#client-side

Angular $sce vs HTML in external locale files

A question regarding ng-bind-html whilst upgrading an Angular app from 1.0.8 to 1.2.8:
I have locale strings stored in files named en_GB.json, fr_FR.json, etc. So far, I have allowed the use of HTML within the locale strings to allow the team writing the localized content to apply basic styling or adding inline anchor tags. This would result in the following example JSON:
{
"changesLater": "<strong>Don't forget</strong> that you can always make changes later."
"errorEmailExists": "That email address already exists, please sign in to continue."
}
When using these strings with ng-bind-html="myStr", I understand that I now need to use $sce.trustAsHtml(myStr). I could even write a filter as suggested in this StackOverflow answer which would result in using ng-bind-html="myStr | unsafe".
Questions:
By doing something like this, is my app now insecure? And if so, how might an attacker exploit this?
I can understand potential exploits if the source of the displayed HTML string was a user (ie. blog post-style comments that will be displayed to other users), but would my app really be at risk if I'm only displaying HTML from a JSON file hosted on the same domain?
Is there any other way I should be looking to achieve the marking-up of externally loaded content strings in an angular app?
You are not making your app any less secure. You were already inserting HTML in your page with the old method of ng-bind-html-unsafe. You are still doing the same thing, except now you have to explicitly trust the source of the HTML rather than just specifying that part of your template can output raw HTML. Requiring the use of $sce makes it harder to accidentally accept raw HTML from an untrusted source - in the old method where you only declared the trust in the template, bad input might make its way into your model in ways you didn't think of.
If the content comes from your domain, or a domain you control, then you're safe - at least as safe as you can be. If someone is somehow able to highjack the payload of a response from your own domain, then your security is already all manner of screwed. Note, however, you should definitely not ever call $sce.trustAsHtml on content that comes from a domain that isn't yours.
Apart from maintainability concerns, I don't see anything wrong with the way you're doing it. Having a ton of HTML live in a JSON file is maybe not ideal, but as long as the markup is reasonably semantic and not too dense, I think it's fine. If the markup becomes significantly more complex, I'd consider splitting it into separate angular template files or directives as needed, rather than trying to manage a bunch of markup wrapped in JSON strings.

Run inputted text as javascript in a javascript application?

My goal is to write a javascript application that will take text as an input and compile/run that text as code.
For example, say the JS application has a light that can turn red or green. The user inputted text could be lightRed(); to turn it red, and lightGreen(); to turn it green. I think the standard way to solve this kind of issue is to implement some kind of lexer/parser, like what Jison does.
However, I'm fairly new to JS programming and that seems like a daunting task - especially when I later plan to add more complex functionality to it like if/else statements. So I was wondering if it was possible to have the inputted text treated as javascript, essentially using the browser's ability to process javascript. So the javascript application will have a light, and it will have functions called lightRed() and lightGreen(). Text inputted to the javascript will be treated as javascript, so writing lightRed() as text will directly execute the lightRed() function in the application. Is this possible? Would this be more complicated than just using something like Jison? Thanks!
The easiest way to compile the inputted JavaScript would be to use the eval function. This will evaluate and execute any code passed in as a string.
Example:
eval(document.getElementById('code').value)
JSFiddle
Be aware though that this does give the user the potential to execute any code that he wants without restriction, so think carefully before allowing this.
To help mitigate any security risk, you could execute the code in the global scope, as shown in this answer, preventing the code from accessing any of your local variables, and this would be just like if the user ran the code from their browser's developer console.
More Secure Example:
(function(){eval.apply(this,[document.getElementById('code').value])})()
More Secure JSFiddle
eval() will evaluate a string expression as JavaScript. Most people (including myself) will warn you about security holes; but if you think about it, the user could open up the javascript console and type and run all the same code.. So go for it :)

releasing content by role within a D2L topic

I'm trying to release content by role within a topic in D2L's LMS. Is this possible using Javascript? Something like, "if {RoleName}=Student, then display this, else display that"...? I realize I can restrict/release content by role on a topic level, but I'm trying to do so within a topic and thus can't use release conditions. Any ideas?
You can control that functionality directly through the Content tool interface without needing to add in JavaScript. If you don't have access to that in Content, talk to your site administrator.
A roundabout way to do this would be to parse the QueryString to get the OU, then make a Valence request to find out the user role in the course. It would take a lot of work to get all the pieces connected for what seems like a really simple use case. This is the strategy I'm using for tools I've made that get embedded right in D2L pages.
If Replacement Strings worked properly then you could use a combination of them and JavaScript. But since the replacement happens at save time rather than render time in most places, they're really not usable for your scenario.
Desire2Learn Replace Strings in Content
Another option would be to create your own custom widget and put it on the course home page. Since Replacement Strings work properly in widgets, you could read the value of the {rolename} replacement string and store it in a cookie. Then, in your pages you would read the value of the cookie to create your conditionals.

How do I enable or disable scripts based on a condition?

This seems like it would be fairly simple. But I have no idea.
For example, if the user was an Admin, extra functionality would be available. If the user was not, some actions would no longer be possible because the code was not generated.
Do I actually put Ruby inside the scripts and end the filename with .erb?
OK so from your comment above, I now get a feel for what you want.
It's a question of which side of the server to do things on. User credentials, of course, are handled server-side. Therefore, this would need to be communicated to the client, i.e. JS.
How you do that very much depends on your set-up. One conceivable model would be that your JS calls, via AJAX, a server-side script that reports back on whether the user is an admin or normal user. Perhaps the server-side script simply returns a string - user or admin.
Based on the response, you could load the admin-only functionality - i.e. JS scripts - that you need.
You could do this manually or, more easily, use one of the many JS loaders out there. AMD (asynchronous module definition) loads are very much the zeitgeist at the mo, so look into something like require.js or curl.js. A simply (non-AMD) option would be LABS.js.

Categories

Resources