How to hide or hash values inside a Javascript function? - javascript

I am a graphic designer working on a website for my employer. At last minute, they have asked if it is possible to hide/reveal certain parts of a page dependent on whether the user types a specific email domain. After some research—given I am not an expert web developer—I figure out this bit of Javascript:
function validate()
{
var text = document.getElementById("email_input").value;
var formslist = document.getElementById ("forms");
var regx = /^([a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]{3,20})+#(email1.com||email2.com)$/;
if (regx.test(text))
{
forms.style.display = "block";
document.getElementById("errortext").style.visibility="hidden";
}
else
{
forms.style.display = "hidden";
document.getElementById("errortext").innerHTML="Our forms section requires an approved email address.";
document.getElementById("errortext").style.visibility="visible";
document.getElementById("errortext").style.color="gray";
}
}
And it works! But common sense tells me this seems too simple to be secure... How can I hide/hash/mask "email1.com" or "email2.com"? How could I decrease the of odds of someone just going into the browser's developer view and seeing the accepted values?
(Sorry if I am repeating this question. I just can't figure out the correct search terms for what I want to do!)

you can use digest method of Crypto API, and check the hashed input against the hashed email values

What you want is probably not possible using only a client-side approach, or else a robust client-side approach is probably overkill.
A one-way hash function is a cryptographically sound approach to allow the client to check input without revealing what the desired input is. You can send a hashed value H(v1) without leaking information about v1 itself, and then have the client verify if the user's input v2 satisfies H(v1) == H(v2).
However, what is the client then to do after verifying a match? If it's going to display information to the user, that same information must be sent to the client before displaying it. Though the page may be cryptographically sound in it's decision of when to show the information on the page, any modestly savvy user may find that information using debug tools in the browser without making the page's script render it properly.
One actually cryptographically sound approach is to only grant the client access to the secret display-information in a form that has been encrypted with a symmetric-key cipher using the output of a key derivation function (KDF) like Encrypt(secretData, KDF(v1)), and attempt to perform the corresponding Decrypt(secretData, KDF(v2)) to decrypt the data using the user's input v2. It would probably be simpler to just send the input to the server and have it decide whether to send the secret data at all, but if you have no server (or no server that you trust with your secrets, or no server you believe will stay online for the useful life of your client application) then this is a viable approach.

If you want this to be completely hidden from a "clever" user - you need to implement a backend validation. I don't see other good ways of doing this.
Javascript that runs in browser can be easily read by a user and translated into a more human readable form. So, even if you encode your strings with btoa() - it can be decoded with atob(). Example - https://www.w3schools.com/jsref/met_win_atob.asp

Related

Hiding my admin login information HTML

I'm pretty new to HTML, like 1 week new. I am making a web store and I want to be able to login into an "admin panel" to make it easier for me to manage my products. Add new, remove, rename etc. My problem is, I have my login information stored in the html code and I use if-statements to check the validity.
When I was testing the code, I was curious and wanted to inspect element. Unsurprisingly, there was my entire login information and anybody can have access to it.
I need to somehow hide it, or hide the login fields from users except me. But I do not know how to approach that. I thought of a few solutions like have a hidden part on the store page and if I click it a certain amount of times then it will show the fields. But I think I'm complicating it.
Any ideas are greatly appreciated. Thanks. Below is my function for logging in.
function login()
{
var username = "test username";
var password = "testpassword";
if(document.getElementById("username field").value == username && document.getElementById("password field").value == password)
{
var btn = document.createElement("BUTTON");
document.body.appendChild(btn);
<!-- hide the user name field after login -->
document.getElementById("username field").hidden = true;
<!-- hide the password field after login -->
document.getElementById("password field").hidden = true;
<!-- hide the login button after login -->
document.getElementById("login btn").hidden = true;
<!-- show a message indicating login was successfull -->
window.alert("Login successfull! Welcome back admin!")
}
else
{
window.alert("Sorry, you are not authorized to view this page.");
}
}
And this is a screenshot of the inspect element. I don't want anything too crazy like a database because I'm the only user, just a way to be able to access the admin panel without exposing myself. Thanks again.
Inspect Element Screenshot
EDIT:
I am not using my own server, I am using Wix.com to make the initial website and then using the HTML widget to create a webstore. I don't think they allow people to have any communication with their servers whatsoever.
Username and password validation should never be done on the client side. It should always be done on the server. Do not use javascript for this task. Allow your user to enter their username and password in a form, and then submit the form to a server side script to validate their credentials. Doing it on the client side will never be secure.
There's no easy solution to your particular request, but before I oblige you with the details I'd like to stress three very important points.
1: Javascript is not Safe
Javascript is a client side language, which means every piece of data you'll ever be dealing with that comes from your user can be directly modified. These include, but are not limited too, any values or attributes of HTML tags, inline Javascript, loaded image files, etc. Essentially, anything that is cached on the user's computer can be modified and might not be what you're expecting to receive.
As such, a Javascript authentication system is absolutely not safe by any definition of the word. For a local page that only you can access, it would do the job, but that begs the question of why you need authentication in the first place. Even then, as a new developer you'd be widely encouraged to never try do it anyway. There's no point practising and learning how to do something in a completely insecure way and nobody is likely to suggest it.
2: Authentication is a tricky topic
Authenticating logins is not an easy thing to do. Yes, it's easy to make a login script but it's not easy to do it properly. I would never try to discourage anyone from making something themselves nor discourage a new developer from pursuing any goal, but authentication is not something you should be learning only a week into HTML. I'm sorry if that comes across as harsh, but there are people who have been masterminding applications for years who still don't do it securely.
3: Third Party are Best
It's possible to make your own authentication system that likely only the most determined of attackers could access, but it wouldn't involve Javascript authentication. Consider Javascript to be more of a convenience to the user than a solution for the developer. Javascript can do some remarkable things, but being a trusted source of data is something it will never do. Please understand this important point, because the source code you have provided is riddled with security flaws.
--
Now, on to what you want to do. Identifying that you're the "admin" user is something you're putting a password in to do. If you could figure out you're the owner of this site before putting in your password, you wouldn't need the password, right? In short, you can't do what you want to do; not reliably, anyway. It's possible to only show those forms if you're using a particular IP, but IPs can be masked, imitated and changed, which makes it insecure.
There are several third party authentication methods that you can use to do all the heavy lifting for you. All you do is put the fields on your page and they'll handle the rest. You can use any Social Media login (Facebook, Twitter, Google Plus, etc) or you can use O Auth, which deals with all the heavy lifting of authentication for you.
I don't mean to discourage you, nor anyone else, from pursuing their own authentication methods but if I'm honest with you I think this is something way beyond your skill level that you shouldn't be considering right now.
If you serve the pages via a server, you can enforce basic HTTP auth. Should be really simple to set up and you would have the benefit of a standard of security.
Here are the Apache docs for this, for example.

How "secure" is the ASP .NET Controller

I am still very new to the concepts and design of ASP .NET's MVC and AJAX and I was wondering how secure the Controller is to unwanted user's when webdeployed.
I ask because for fun I made a little admin panel that requires a user name and password. Once input is entered the information is AJAX submitted to a ActionResult method in the Controller that just compares the strings to see if they match, then returns the response back to the AJAX.
My question is, how easy is it for someone to get into my Controller and see the hard-coded password?
No professional-type person will ever try to break into this, as it is a free site for a university club, but I want to make sure that the average Computer Science student couldn't just "break in" if they happen to "rage" or get mad about something (you never know! haha).
Question: Is having a password validation within the Controller "decently" secure on a ASP .NET MVC web-deployed application? Why or why not?
Here is the actual code in case the use of it matters for the answer (domain is omitted for privacy)
Note: I understand this use of Javascript might be bad, but I am looking for an answer relative to AJAX and Controller security of the password check.
View (Admin/)
//runs preloadFunc immediately
window.onpaint = preloadFunc();
function preloadFunc() {
var prompting = prompt("Please enter the password", "****");
if (prompting != null) {
$.ajax({
url: "/Admin/magicCheck",
type: "POST",
data: "magic=" + prompting,
success: function (resp) {
if (resp.Success) {
//continue loading page
}
else {
//wrong password, re-ask
preloadFunc();
}
},
error: function () {
//re-ask
preloadFunc();
}
});
}
else {
// Hitting cancel
window.stop();
window.location.replace("google.com");
}
}
Controller (ActionResult Snippet)
[HttpPost]
public ActionResult magicCheck(string magic)
{
bool success = false;
if (magic == "pass")
{
success = true;
}
else
{
success = false;
}
return Json(new { Success = success });
}
Again I am new to MVC and AJAX, let alone anything dealing with security so I am just wondering how secure the Controller is, specifically on webdeploy for this simple password setup.
During normal operation, there is no concern as your code is compiled, the DLL prevented from being served, and there is no way for the browser to request the controller to divulge its own code.
However, it is not impossible (but quite rare) that unforeseen bugs, vulnerabilities, or misconfigurations of the server could lead to the server divulging compiled code, web.config, etc., whereby someone could disassemble the code (IL is easily decompiled) and reveal your secret.
More worrisome would be someone having physical access to the server just grabbing the binaries directly and disassembling to find your secret.
Another thing to consider is who, during normal situations, might see that secret and whether or not they should know it. A developer, tester, or reviewer may be allowed to write or inspect code, but you may not want them to know the secret.
One way to handle this is not store secrets in plain text. Instead, create a hash of the valid value, then update your application to hash the user's input in the same manner, and compare the results. That way if the user ever gets your source code, they can't read the original plain text value or even copy/paste it into your UI. You can roll your own code to do the hashing, use the FormsAuthentication API, or something else.
Finally, do not rely on client-side enforcement of security. You can check security on the client side to have the UI react appropriately, but all server-side requests should be doing checks to make sure the user's security claims are valid.
The question really goes out of scope from here, regarding how to manage identities, passwords, and make security assertions. Spend a little time looking through the myriad articles on the subject. Also, the Visual Studio ASP.NET project templates include a lot of the security infrastructure already stubbed out for you to give you a head start.
Never leaving things to chance is an important policy. Learning about ASP.NET and MVC's various facilities for authentication and authorization is a worthwhile effort. Plus, there are numerous APIs you can plug in to do a lot of the heavy lifting for you.
As has already been pointed out if you can get a hold of the binaries for an app (or for that matter ANY .NET application not just MVC) then it's definately game over.
Just sat in front of me here and now I have 3 applications that make it child's play to see what's inside.
Telerick - Just Decompile
IL-Spy
Are both freely downloadable in seconds, and the former of the two will take an entire compiled assembly, and actually not just reverse engineer the code, but will create me a solution file and other project assets too, allowing me to load it immediately back into Visual Studio.
Visual Studio meanwhile, will allow me to reference the binaries in another project, then let me browse into them to find out their calling structure using nothing more than the simple object browser.
You can obfuscate your assemblies, and there are plenty of apps to do this, but they still stop short of stopping you from de-compiling the code, and instead just make the reverse engineered code hard to read.
on the flip side
Even if you don't employ anything mentioned above, you can still use command line tools such as "Strings" or editors such as "Ultra Edit 32" and "Notepad++" that can display hex bytes and readable ASCII, to visually pick out interesting text strings (This approach also works well on natively compiled code too)
If your just worried about casual drive by / accidental intrusions, then the first thing you'll want to do is to make sure you DON'T keep your source code in the server folder.
It's amazing just how many production MVC sites Iv'e come accross where the developer has the active project files and development configuration actually on the server that's serving live to the internet.
Thankfully, in most cases, IIS7 is set with sensible defaults, which means that things like '*.CS' files, or 'web.config' files are refused when an attempt is made to download them.
It's by no means however an exact science, just try the following link to see what I mean!!
filetype:config inurl:web.config inurl:ftp
(Don't worry it's safe, it's just a regular Google Search link)
So, to avoid this kind of scenario of leaking documents, a few rules to follow:
Use the web publishing wizard, that will ensure that ONLY the files needed to run end up on the server
Don't point your live web based FTP root at your project root, in fact if you can don't use FTP at all
DO double check everything, and if possible get a couple of trusted friends to try and download things they shouldn't, even with a head start they should struggle
Moving on from the server config, you have a huge mountain of choices for security.
One thing I definitely don't advocate doing though, is rolling your own.
For years now .NET has had a number of very good security based systems baked into it's core, with the mainstay being "ASP.NET Membership" and the current new comer being "ASP.NET simple membership"
Each product has it's own strengths and weaknesses, but every one of them has something that the method your using doesn't and that's global protection
As your existing code stands, it's a simple password on that controller only.
However, what if I don't give it a password.
What happens if I instead, decide to try a few random url's and happen to get lucky.
eg: http://example.com/admin/banned/
and, oh look I have the banned users page up.
This is EXACTLY the type of low hanging entry point that unskilled script kiddies and web-vandals look for. They wander around from site to site, trying random and pseudo random URL's like this, and often times they do get lucky, and find an unprotected page that allows them to get just far enough in, to run an automated script to do the rest.
The scary part is, small college club sites like yours are exactly the type of thing they look for too, a lot of them do this kind of thing for the bragging rights, which they then parade in front of friends with even less skill than themselves, who then look upon them as "Hacking Heroes" because they broke into a "College Site"
If however, you employ something like ASP.NET membership, then not only are you using security that's been tried and tested, but your also placing this protection on every page in your site without having to add boiler plate code to each and every controller you write.
Instead you use simple data annotations to say "This controller is Unprotected" and "This one lets in users without admin status" letting ASP.NET apply site wide security that says "NO" to everything you don't otherwise set rules for.
Finally, if you want the last word in ASP.NET security, MVC or otherwise, then go visit Troyhunt.com I guarantee, if you weren't scared before hand, you will be afterwards.
It looks like you are sending a password via AJAX POST. To your question, my answer would be that you should consider using SSL or encrypt the password prior to sending it via POST. See this answer for an example and explanation SSL Alternative - encrypt password with JavaScript submit to PHP to decrypt
As HackedByChinese said, the actual code being stored in your compiled files (DLL) wouldn't be too big of a deal. If you want to be extra paranoid, you can also store the password in your web.config and encrypt it there. Here's an example and explanation of that How to encrypt username and password in Web.config in C# 2.0
This code is not secure at all. Your JavaScript code can be replaced with EVERYTHING user wants. So someone can just get rid of your preloadFunc. Average computer sience student will execute this code directly from console:
if (resp.Success) {
//continue loading page
//this code can be executed by hand, from console
}
And that will be all when it comes to your security.
Authentication and authorization info should go to server with every request. As a simple solution, you could use FormsAuthentication, by calling
FormsAuthentication.SetAuthCookie("admin")
in /Admin/magicCheck, only if password is correct.
Then you should decorate data retrieval methods with [Authorize] attribute to check if cookie is present.
Using SSL to secure communication between browser and server would be wise too, otherwise password travels in clear text.

Most efficient way to send ascii characters to mailto without reaching URL limit

I have a form which is submitted via mailto to a email server.
As you most know, there is a limitation to the mailto content over which it won't work because it exceeds URL characters limit.
I developed some custom data compression that are domain specific, but it is still not enough (In case all fields are filled, it will bust the limit, this is rare... but rare is bad enough for the client. Never is better.).
I found the Lempel–Ziv–Welch algorithm (http://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Welch) and concluded it would allow me to save 40% of the length average.
Unfortunately, I need of course to call encodeURIComponent to send it to mailto, and as LSW algorightm will return many URL unsupported characters this will in fact make it worse once URL encoded.
Before you tell me it would be easier to make a post to a server using server-side language, let me tell you this is a really unique situation where the form has to be submitted via email via a client-side application, because emails are the only way to connect with the outside world for the end users...
So, do you know any way to compress data efficiently without encodeURIComponent ruining it all ?
Or is there a way to send content to mailto without going through browser ?
I've seen some ways to open Outlook with ActiveX and stuff, but this is pretty browser/email client specific.
Also I checked for options where I save form info in a file using javascript... but the application users are, well let's just say they are not experts at all, and from what I've been told, they could fail to attach the email. (yes, they are that bad)
So I look for the simplest option, where user involvment is almost 0 and where the result is an email sent with the form data, all of that without server-side languages, with a compression algorithm if applicable.
Thanks a lot for your help !
You'll have a hard time getting to "never" with compression, since there will always be strings that a compressor expands instead of compresses. (Basic mathematical property of compression.)
Having said that, there are much better compressors than LZW, depending on the length of your input. You should try zlib and lzma. The binary output of those would then need to be coded using only the allowed URL characters.

Can I encrypt content so it doesn't appear in view-source, then show on pageload?

I've got a site where users extend their product trial with a registration code. They click a link (with a key in the URL) from an email, get to this site and a lightbox appears with their registration code. I'm currently displaying the registration code with HTML and hiding it with CSS. Once I check to make sure the URL has the correct key with javascript, I display the registration code. However, this means anyone can just view source on the page and copy the registration code. Is there a way to encrypt the code so it doesn't appear in view source, and then decrypt it if the URL has the correct key? It's one code per product, not per user, so I don't have to do any server side authentication.
If the computer knows it, the user knows it.
You can play obfuscation games, all of which amount to making your Javascript hard to read. But a sufficiently determined user will find it anyway, and once they do, they can easily share it with their friends.
One code per user is the only way to fix this reliably.
I check to make sure the URL has the correct key with javascript
Don't check the key client-side, validate the key on the server.
This is the only way to ensure only valid users get the registration code.
Pseudo PHP example:
if( validateKey($_GET['key']) ) {
echo 'The Registration Code';
} else {
echo 'Error';
}
Client Side Code is inherently insecure. Consider anything you send to a client machine public to the world, and don't trust anything that comes from the client until you cleanse it. A sufficiently determined user will de-obfuscate your code, regardless how much effort you put into the initial obfuscation routine.
Another tip to help you instead to show the registration code in the site you can send back an email to the user with the registration code.
And as Nemo suggest, the right way is one code for user
Hope it help
As mentioned before the client side will not cover your security needs.
Better would be to have the page send a Ajax request to the server containing the key, you can then respond with the registration code.
Even better would be to directly validate the key on the first request, then decide to return an error page or the page with the registration info.
As others have replied, doing this validation server-side is both easier and more secure.
You can have an AJAX request posting the URL key to a php page, that in turn would reply with the correct registration code.
That being said, there is always the possibility of using a client-side use encryption library (like AES), but from what i understand i don't think it would be a good approach to solving your problem.
Again, doing it on the server-side is both extremely easy and as secure as you need.
Encrypt your registration code (plus some magic cookie) with the key in the server before embedding it in your HTML. In your JavaScript, validate the key (which comes in the URL) by decrypting the registration code. If the magic cookie matches, then you get a valid key and you can display the registration code to the user.
View Source will only reveal the encrypted registration code. Without the key, the snooper has no way to extract the registration code.
This means that you'll have a unique key per registration code, which should be the case for your registration system. The key you send to the user in an email, embedded into a link which they click as you said.

Safest way to update game score from client to server database? Javascript

So I have this game that is completely run on the client. No server interaction what so ever apart from downloading the initial scripts to play the game. Anyway at the end of the game I would like for the client to send me back the scores which should be updated in the server database. Now I have come to accept the fact that there is no way on earth I can hide this from a hacker and send the scores unaltered. But I would like to know till what level can I modify the whole process that it virtually becomes pretty infeasible for the hacker manipulate the data which is being sent. For sure I would not like the score to be sent as plain text from client machine and I don't want my server to perform complex decryption algorithm. What is the best way hence to achieve considerable amount of security that every tom dick and harry doesn't hack the scores... I hope someone could provide a nice little way that I could work on... :) Thanks
So my ideal result should be -> have trusted result from a calculation (of score) made by an untrusted party (the player)!
-Edit-
Someone told me something about hiding the data in a picture get request. Like, I am implementing this game on canvas (html5). So he asked me at the end of the game to fetch a game over image from my server, and they request should contain the hashed score. I did not exactly understand the complete process but if you could explain it, would be really glad! :)
coda^ so you can mask the requests nicely
shouvik how do I do it!?
coda^ you can compose the checksum you want to submit. like 12312312a12313a232 is your md5 which contains the score. bring in an asset into the canvas like
coda^ server.com/images/md5_hash_of_score/congratulations.png
coda^ which you can rewrite server side via htaccess
You seem to know this already, but just to stress; you cannot stop someone doing this; you can only make it as hard as possible!
Assume you currently submit the score as:
/submit_score.php?score=5
Someone watching in Firebug can easily distinguish where the score is submitted, and to alter it. submit_score.php gives it away, as does the name of the parameter. The score is a easily distinguishable integer.
Change the end point: /interaction.php?score=5
Change the parameter name: /interaction.php?a=5
It's getting harder for the user to work out what is going on.
Now you can make the score harder (again, harder, not impossible), to change. First, you can encrypt it (obviously you'll need to be able to decrpt it later).
Base 64 encode it.
Numbers -> Letters (1=a, 2=b, etc).
Reverse the order of the score representation.
You name it, you do it. So you now have interaction.php?a=e.
The next thing you can do is hash the score with something else. Send the hash with the score, and recalculate it on the server. For example, md5() the score with a random string, and send the score (encoded), the string, and the hash in the request:
/interaction.php?a=e&str=abcde&hash=123456789abcefbc
When the request hits the server, do:
if (md5($_GET['a'] . $_GET['str']) !== $_GET['hash']) exit;
Obviously people can (relatively) easily go through your JavaScript code and see what's going on; so make it harder for them there. Minify and Obfuscate the code.
If you make it hard enough for someone, they're going to try understand your JavaScript, try using Firebug, not understand what's going on, and not bother; for the sake of getting a few extra points on your game.
Use something like OAuth to authorize the request from client to server.
The header contains a token which matches to the body of the request. if these two doesn't match, then discard the request. Don't need to decrypt at server side, instead encrypt the body and check if the result obtained at server side and the token matches the same to find if the body was modified
"Now I have come to accept the fact that there is no way on earth I can hide this from a hacker and send the scores unaltered."
Oh yes, there is!
You can use RSA or any other public key encryption method (also called assymetric cryptography).
Create a set of (public and private) keys for the server.
Have your client code include your server's public key.
At the end of the game, the client code, encrypts the score (with this key) and sends both (plain score and encrypted score) to server.
Server decrypts and checks if plain score and decrypted one are same.
If yes, accept score.
If not, reject (there's a hacker or network error in the middle).
-------UPDATE-----------CORRECTION--------------
As Ambrosia, pointed out, my approach fails completely with this kind of attack.
What you actually want is to have a trusted result from a calculation (of score) made by an untrusted party (the player). No easy way to achieve this.
See this: http://coltrane.wiwi.hu-berlin.de/~fis/texts/2003-profit-untrust.pdf
Also this one: http://www.cse.psu.edu/~snarayan/publications/securecomputation.pdf
And this (which needs a subscription to the ACM digital library): http://portal.acm.org/citation.cfm?id=643477.643479
Can you use ajax to send the score (and any identifiers) to the server? Unless they have something like firebug open they won't see it happening.
var url = '/savescores.asp?userID=fredsmith&score=1098';
createRequest();
request.open('GET', url, true);
etc
Make the client send you the credentials (or some sort of session information in case you don't have logon credentials) and do that over SSL (https). This way you have both authentication and integrity control. Very easy and extremely lightweight for both server and client.

Categories

Resources