Let's say you have a javascript with a variable like this:
<script type="text/javascript" >
...some javascript...
var secret = 123;
...some javascript...
</script>
Assuming you're able to write this javascript on the server side. Is it possible to prevent it from being scraped using regular expressions or Xpath?
I'm already changing the variable name on the server side to a random variable name.
The goal here is not to defeat a human taking the time to digest my code and make amendments on the client side (I know I can't stop this). It's more to make it hard/impossible for automated scripts to grab variables. Humans, given enough time, are better at scraping code than machines.
The short answer is no.
The slightly longer answer is that the variable's value will always be transmitted in plaintext to the browser and, therefore, can always be scraped from the JavaScript because it will be declared (or used) in a predictable* manner.
The only bit you, as a creator, can control is making it difficult to programmatically extract. This might be by changing the location and form of the value/secret on every page load in a random manner, making any tokens single-use only, and by encrypting/encoding* things.
This doesn't prevent access to the secret, just makes it less easy to do, and by how much depends on the level of access the user has to the browser. Once you accept this, it boils down to a cost/benefit analysis of how much effort you want to put into this compared to the benefit.
*If the value is encoded in some way, there will be a decoding function within the JavaScript, enabling the encoded variable to be passed into the decoding function. Or perhaps any functions can be replaced. For further reading, have a look into the very few attempts at encryption/decryption in JavaScript.
Related
Background
I'm trying to better understand potential XSS attack scenarios. I understand if you are retrieving data component 'unknow_data' from a server and not validating it the following scenarios could allow malicious code to run.
<script src = unknow_data >
or
<a href=unknow_data></a>
Where unknow_data could be 'javascript:somethingMalicious' instead of pure data.
Question
Is there any threat of XSS when passing unknown data directly into a JavaScript object and not a script tag or html attribute? For example:
var G = unknow_data;
What javascript code, if any, would have to be injected into a plain javascript object for it to be a security risk? My thinking so far is that this is only a threat if you are calling
eval(G)
Is my understanding correct?
It would definitely be a security hole.
Example, the unknown_data could be 1; alert('xss').
However, if you JSON encoded it using your server-side language, it would be safe to print it there (however it may have encoded attacks in it - deal with it like you normally would depending on its context).
It depends on what you do with G.
Certainly eval-ing it would be problematic, but why would you do that anyway?
In addition to the attack mentioned by #alex, if you insert in into the DOM in one way or another, then that's another attack surface.
You should HTML-escape it before inserting it into the DOM, either on the server or the client. If you are using a templating language like Handlebars, then {{G}} will take care of the HTML escaping for you. You need to be cautious with the triple-mustache ({{{G}}}), which skips the HTML escaping.
This question already has answers here:
What are the common defenses against XSS? [closed]
(4 answers)
Closed 8 years ago.
while working on project open which is open source application, the url http://[host_ip]:8000/register/ includes Java Scripts which are vulnerable to cross-site scripting and Authentication Bypass Using SQL Injection.
I want to know that how can I avoid it? do I have to insert filter for that? and how should I do that?
please let me know if the problem is not clear to understand.
SQL Injection
The universal answer to SQL Injection problems is “never send any user input to the database as part of an SQL string”. Anything that can go as a parameter should do so. Thus, instead of (in some dialect that might not exactly match what you're looking at):
db eval "SELECT userid FROM users WHERE username = '$user' AND password = '$pass'"
you do:
db eval "SELECT userid FROM users WHERE username = ? AND password = ?" $user $pass
# I personally prefer to put SQL inside {braces}… but that's your call
The key is that because the database engine just understands that these are parameters, it never tries to interpret them as SQL. Injection Impossible. (Unless you're using badly-written stored procedures.)
It gets much more complex where you want to have a table or column name specified by a user. That's a case where you can't send it as a parameter; such SQL identifiers must be interpreted by the SQL engine. Your only alternatives there are to either remap from user-supplied terms to ones that you control, or to rigorously validate.
Remapping is done by having a separate trivial table that maps from user-supplied names to ones you've generated:
db eval {SELECT realname FROM namemap WHERE externalname = ?} $externalname
Because the generated name is easy to guarantee to be free of nasty characters and not to be one of SQLs keywords, it can be safely used in SQL text without further quoting. You can also try doing the mapping per request (factor out the mapping code to a procedure of course) by stripping all bad characters from it. A suitable regsub might be:
regsub -all {\W+} $externalname "" realname
but then we need additional checks to see that it isn't “evil”:
# You'll need to create an array, SQLidentifiers, first, perhaps like:
# array set SQLidentifers {UPDATE - SELECT - REPLACE - DELETE - ALTER - INSERT -}
# But you can do that once, as a global "constant"
if {[regexp {^\d} $realname] || [info exist SQLidentifiers([string toupper $realname])]} {
error "Bad identifier, $externalname"
}
As you can see, it's a good idea to factor out such transforms and checks into their own procedure so you get them right, once.
And you must test your code extensively. I cannot stress that hard enough. Your tests must try really hard to break things, to make SQL injections via every possible field that anyone could pass into the software; not one of them should ever result in anything happening that your code ever expects.
It's probably a good idea to get someone else to write at least some of the tests; experience from the security community suggests that it is relatively easy to write code that you can't break yourself, but much harder to write code that someone else can't break. Also consider doing fuzz testing, sending computer-generated random data at the interface. In all cases, either things should give a graceful error or should succeed, but never ever cause the application to outright fail.
(You might well allow highly-authenticated users — system/database administrators — to outright specify SQL to evaluate so they can do things like setting the system up, but they're the minority case.)
Cross-site Scripting
This is actually conceptually quite similar: it's caused (principally) by someone putting something in your site that unexpectedly gets interpreted as HTML (or CSS, or Javascript) rather than as human-readable text (with SQL injection, it's something getting interpreted as SQL rather than as data). Because you can't do the equivalent of parameterised queries when going back to the client, you have to use careful quoting. You're strongly recommended to do the careful quoting by using a proper templating library that constructs a DOM tree (with data coming from users or from the database being only ever inserted as text nodes).
If you want users to supply a marked up piece of text, consider either delivering it back as plain text before using Javascript to render it as, say, Markdown, or completely parsing the user-supplied text on the server to construct a model (e.g., DOM tree) of what should be delivered, before sending it back as HTML generated from that model.
You must not allow users to specify a location where you load a script or frame from. Even allowing them to specify links is worrying, but you probably have to permit that if you can't restrict things to straight plain text. (Consider adding a mechanism for listing all links that have been supplied by users. Consider marking all external links with rel=nofollow unless you can positively detect that they go to somewhere that you whitelist.)
Direct supply of HTML is a “highly-authenticated users only” operation.
(I told a lie above. You can do the equivalent of SQL parameterised queries. You write JS that the client executes to fetch the user data using an AJAX query, perhaps serialized as JSON, and then do DOM manipulations there to render it; in effect, you're moving the DOM construction from the server to the client, but you're still doing DOM construction as that's the core of how you get this right. You have to remember to never insert the things retrieved as straight HTML though. Clients must not trust the server too much.)
The comments I made above above about testing apply here too. With testing for XSS, you're looking to inject something like <script>alert("boom!")</script>; any time you can get that in and cause a popup dialog — except by being a system administrator with direct permission to edit HTML directly — you've got a massive dangerous hole to plug. (It's quite a good thing to try to inject, as it is very noticeable and yet fairly benign in itself.)
Don't try to just filter out <script> using regular expressions. It's far too hard to get that right.
I have javascript that is being generated at design time that needs to be executed to find a value at run time. The code is stored as a string in an object and I would like to be able to execute it and retrieve the value and then scrap the code. Is there a way to do this? Do I have to use eval()?
You can use eval(String)
Or use new Function (String)
Or use document.createElement
[edited]
Depend on how it was done your code
1 -
if those strings are saved in shared across different pages (with cookies or database), then SERVER-SIDE you can generate a tag <script> with the values saved in a JSON for quick access.
2 -
If the strings are saved only at runtime (ie in pagination are not recoverable values) you may not need to save these values in Strings, talves you can create a global Json in Window Object (eg. window.MyObjectGlobal), making the values accessible at any time on the page (since there is no paging) - is idea can also be reused in case of using the SERVER-SIDE, combined with Ajax (ajax only to save the data in your database), or document.cookie (but will have to use document.createElement("script") or eval)
Good luck
Yes, you can do that using eval.
However, remember evalis evil and it could potentially introduce security risks.
Anyway, if you know what you're doing, that's the way to go
im building a web app in html5.. basically a form with a time counter and questions and answers.
im looking for a way that the user cannot change the score (that is calculated from the time took to answer the question) via browser debugger or etc.
encrypting the raw data sounds like an options.. but when the data is at dom, the user can change it.
i added some "time checking" in server side.. but still i would prefer some client side protection as well.
any suggestions? thanks
I'm no web pro, but I'd say just stick all the validation on the server side. From what I know about people exploiting MMORPGs, there is always a way to access/change client side data.
What you're asking for is impossible. No matter how you implement it, the user can use debugging tools to alter how the code runs in their browser - or, ultimately, just generate the HTTP POST request themselves, independent of your code.
Well, since you're saying you're using html5, why don't you just use the storage support?
e.g:
var store = sessionStorage.question= new Array();
store[0]="10s";
store[1]="5s";
Now just set that programmatically! It will last for the whole session
Put that in a file and import it and the better-than-average user wont know where to look!
You can also check This Link for a more robust solution
As Nick says, a determined user will be able to get round any encryption scheme you use on the client machine. At most you can make it difficult for them to break. You need to do two things, 1) encrypt so as to make tampering difficult and 2) try to detect any tampering that does occur.
I don't know what is available off the shelf for Javascript, if available then use AES for encryption and HMAC to detect tampering. If you have to write your own then use RC4 for encryption (not as strong as AES but much simpler to code) and a checksum to detect tampering.
One thing you can do to make it more difficult for an attacker to find your encryption key and HMAC key is not to store them in one place. Have two arrays such that the real key is array1 XOR array2. That way the actual key is not explicitly in code anywhere.
I use DropBox and I've had some trouble reaching to my files from other computers:
I not always want to login to anything when I'm in a public computer, but I like being able to reach my stuff from wherever I am.
So I've made a simple application that when put in the public folder, ran and given the right UID, creates (still in your public folder) an HTML of all the content in the folder (including subfolders) as a tree of links.
But I didn't risk loading it anywhere, since there are slightly private things in there (yes, I know that the folder's name is "PUBLIC").
So I've came up with the idea to make it a simple login page, given the right password, the rest of the page should load. brilliant!, but how?
If I did this by redirecting to other HTML on the same folder, I'd still put the html link in the web history and the "url's accessed" history of the administrator. So I should generate itin the same page.
I've done it:
alt text http://dl.dropbox.com/u/3045472/validate.png
And currently the page is a textbox and a button, and only if you type in the right password (defined in the generator) the rest of the page (with the link-tree) loads. The fault is that everything (password, URL's) is easily reachable through the source code.
Now, assuming I only want to avoid silly people to get it all too easily, not make a bulletproof all-content-holding NSA certified website, I though about some ways to make these information a bit harder to get.
As you may have already figured, I use a streamwritter to write an html file (head, loop through links, bottom), then it's extremely configurable, and I can come up with a pretty messy-but-working c# code, though my javascript knowledge is not that good.
Public links in DropBox look like this:
Summarizing: How do I hide the URL's ande the password to show them (MAINLY the password, of course) in my source-code so that no that it should require some effort on reading ?
P.S.: It's not that personal, if someone REALLY wants it, it could never be 100% protected, and if it was that important, I wouldnt put it in the public folder, also, if the dude really wants to get it that hard, he should deserve it.
P.S. 2.: "Use the ultra-3000'tron obfuscator!!11" is not a real answer, since my javascript is GENERATED by my c# program.
P.S. 3.: I don't want other solutions as "use a serverside application and host it somewhere to redirect and bla bla" or "compress the links in a .RAR file and put a password in it" since I'm doing this ALSO to learn, and I want the thrill of it =)
Update 1:
The one answer so far gives a perfect way (according to this question) to hide my password.
Now I want a good way to hide the URL's, maby a code snippet of the example URL I gave being composed, and if it's too tricky, maby how to generate it in C#, or anything ?
Update 2:
I thought about maybe making three "obfuscating methods" and choosing them randomly in the runtime. So anyone who figures out how to read one XML, could only read about one third of them, and maybe having a hard time finding the other rest of this third..
Update 3:
Just thought about REGEX, the URL could be neatly crowded by dummy not-url-allowed characters added randomly that would be removed by something like:
regex.replace(url, ^[^\w\d/:-\.%]+$,"")
So the nosy dude should have to be pretty advanced into programming somehow, eh? could anyone tell me if it would work or not ?
Well, as it seems you already know, this is a rather poor choice of security mechanism, but if you insist...
Don't store the actual string in the source. Store, for example, its MD5 hash. Then, when the user types in a password, compute its MD5 hash and compare it with the expected one.
Check out:
MD5 in JavaScript
MD5 in C#
To elaborate on miorel's idea, you can also encrypt the whole page, using password as a key. Basically, encode all content into one big string, ask for the password and decrypt that string. If the password is wrong, it will show loads of rubbish, that is it. Like
content = "encrypted string"
function decrypt(str, key) { your algorithm of choice here }
document.write(decrypt(content, prompt('Password?')))
The only thing you need is a decrypt implementation in javascript - but that's easy to google out, for example here or here.
This also renders the separate 'login' page useless.
Granted, this is akin to asking how you can strip in public without people seeing you, but given that, I'm assuming that the password you are trying to store is the one to DropBox. I suppose you could obfuscate the password and store it in a cookie. That would at least prevent someone from simply viewing the source to see the password, but obviously wouldn't stop someone running something like Fiddler and seeing it.
[snipped server side suggestion]
EDIT: To munge the Urls, why don't you simply build the urls on the fly and have the links call a javascript function to get the url? Your server-side code would populate an array in this function with obfuscated urls and the calling code would simply pass an index into the array. Thus, on viewing the source, there would be no instances of "http" anywhere other than static unsecure links.
ADDITION Ok. now that I have a better bead on the problem, it is easier to devise solution. There are libraries for doing encryption on the net in javascript (e.g. http://point-at-infinity.org/jsaes/) but the problem comes down to key management. Since its javascript, it is going to be public but there are hoops you can devise to make it harder to determine the key. In general, those tricks involve indirection. For example, store a lengthy stream of random characters (e.g. 40-50 or more) that is generated by your C# code and stored in the HTM file. In addition, the C# code would would store into your javascript function an array numeric values that represent pointers into the long stream of text that were used by the C# code to encrypt the passwords (or just the whole url).