Obfuscating URL parameters to prevent users from changing them? - javascript

I am developing a fat client page based on Javascript that will allow users to carry out tasks outwith another web client application (Oracle Siebel).
The way the web page will be called from the browser will be by a simple window.open() call.
When this happens a URL will be passed which contains some parameters at the end which will change the functionality of the fat client page depending on what value they have.
e.g
userlevel=1 //normal user
userlevel=2 //advanced user
In an example full URL would be like so
www.mypage.com/index.htm?id=25215125%userlevel=2%context=full
However a user who wants to change their access only need to figure out that if they change their user level then they can change their access rights on this fat client page.
Yes, I know this is risky and before you ask why I am not using a server supported thin client with controls that cannot be altered by the user. I simply have to do it this way!
This system will be in a "trusted" environment and this users will have at best average IT skills.
So all I need to do is figure out a way to obfuscate/ scramble the URL parameters (if possible) and then decipher them at the fat client.
e.g.
www.mypage.com/index.htm?1sdf908ga90-821098650f8asdg098g0a98
I tested it out on the browser and no complaints so far so I guess I just need to develop a piece of logic to decipher it.
e.g. I could use MD5?
Any examples or ideas?
Thanks

Try Base64 encoding it. https://stackoverflow.com/a/4699739/1088652
That'll shorten it and obfuscate it, so that users can't just throw values in the URL.

Params integrity can be ensured with HMAC. You generate hash using secret key and all the params, you include this hash inside of URL, then at server side you generate hash using same params and compare values.
function generateSignature(array $params, $hmacKey)
{
// sort the array by key using SORT_STRING order
ksort($params, SORT_STRING);
$escapeFunc = function ($val) {
return str_replace(':', '\\:', str_replace('\\', '\\\\', $val));
};
// generate the signing data string
$signData = implode(':', array_map($escapeFunc, array_merge(array_keys($params), array_values($params))));
// base64-encode the binary result of the HMAC computation
$merchantSig = base64_encode(hash_hmac('sha256', $signData, pack("H*", $hmacKey), true));
return $merchantSig;
}

Related

Can I generate a transaction on the server and send it to the client for payment

I have built a smart contract method to which I pass some sensitive data that needs to be stored on the blockchain and alter the state of the contract. I, the creator of the contract don't want to be the one paying for the fees of that transaction. I want the user on the browser to approve and pay for it.
However, I do not want to generate the transaction object on the browser as I want some of the data that will be passed to the contract to be hidden from the client. If I understand the web3 syntax correctly, in the code below, I'm doing just that
web3.eth.sendTransaction({
from: walletAddressOfTheUserThatWillPayForTheTransaction,
data: myContract.methods.changeState(..sensitive data...).encodeABI()
})
However I do not want the above to happen on the browser. In my head, the sequence of events should look like this (pseudocode):
// server
let transactionObject = {
from: walletAddressOfTheUserThatWillPayForTheTransaction,
data: myContract.methods.changeState(..sensitive data...).encodeABI()
}
sendToClient(encrypt(transactionObject))
// client
let encryptedTransactionObject = await fetchEncryptedTransactionObjectFromServer()
// this should open up Metamask for the user so that they may approve and finalise the transaction on the browser
web3.eth.sendTransaction(encryptedTransactionObject)
Is this possible ? Is there some other way of achieving this? Could you provide me with some hints about the actual syntax to be used?
However, I do not want to generate the transaction object on the browser as I want some of the data that will be passed to the contract to be hidden from the client.
Then you should not be using public blockchains in the first place, as all data on public blockchains, by definition, is public. Anyone can read it.

How to prevent tracking sensitive data in URLs?

Some URLs in my single-page-app (SPA) contain sensitive information like an access token, user information, etc.
Examples:
/callback#access_token=HBVYTU2Rugv3gUbvgIUY
/?email=username#example.com
I see that hotjar allows suppressing DOM elements and images from tracked data. Is it possible to hide params in URL or at least disable tracking for some pages?
Since you are saying that it is your SPA, you might solve the problem by switching from GET requests (which have the parameters inside the URL) to POST requests. I do not know hotjar, but if you tell the tracking service to analyze URLs only, that would be an option worth considering.
Another option frequently used is to obfuscate your parameters in the URL, see e.g. Best way to obfuscate an e-mail address on a website? However, that is never a really safe solution for sensitive data, since the de-ciphering step is too easy, in particular if your man-in-the-middle has all requests ever send to your SPA.
Edit. I just found in the Hotjar allows RegEx. Assuming you could enter a regular expression of URL-parts to exclude.
The general syntax /foo/bar/ means that foo should be replaced by bar, in our case, we want to delete the given snippet, that why it is /foo//.
For the given case of the access token, the regular expression would be
/callback#access_token=[a-zA-Z0-9]{15}//
and respectively for the email part of the URL
/\?email=(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")#(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])//
This second RegEx partially taken from How to validate an email address using a regular expression?
It seems to me that it's reasonable to assume that tracking scripts will try to access window.location.href or similar to get the current url which they will store.
So a possible solution would be create a dynamic scope which has a different value for window.location.href (with all sensitive info filtered out)
This is how it might work:
// get the tracker script as a string, so you can eval it in a dynamic scope
let trackerScript = 'console.log("Tracked url:", window.location.href)';
// now lets lock it up
function trackerJail(){
let window = {
location: {
// put your filtered url here
href: "not so fast mr.bond"
}
}
eval(String(trackerScript))
}
trackerJail()
If the tracking snippet is wrapped in a function it might be possible to create a dynamic scope for it without running eval by overriding it's prototype instead. But I'm not sure you can count on tracker scripts being wrapped in a neat function you can modify.
Also, there are a couple more ways the script might try to access the URL, so make sure to cover all the exits
If you control the page and order of scripts, you could read the data from the url then delete it before anything else can get to it.
proofOfConcept.html
<script id="firstThingToLoad.js">
console.log(window.location.href);
const keyRegex = /key=[^&]*/;
const key = window.location.href.match(keyRegex);
console.log("I have key", key);
const href = window.location.href.replace(keyRegex, "");
history.replaceState({}, "", href);
</script>
<script id="someSnoopyCode.js">
console.log("I'm snooping: ", window.location.href);
</script>
<body>
Link to private
</body>
Of course the Link to private should not exist as is. Also, this does break refresh and most navigation in general, though there are ways to catch and save that.

Best way to prevent parameter tampering and send values with Javascript?

I am posting a form to the controller and making it asynchronous. I am storing values in input form hidden. When a button is clicked, a javascript function is called. It both fetches the value from an input field, as well as a value from input form hidden. It then sends a json string to the controller to handle this request.
Controller:
[HttpPost, Authorize]
public ActionResult DoSomeStuff (string leagueName, string doSomething) {
var service = new Service(_db);
var league = service.GetLeague(leagueName);
if (league != null) {
// validate doSomething
league.Action = doSomething;
_db.SaveChanges();
}
return new EmptyResult();
}
Javascript:
$(document).on("click", "#submitForm", function () {
var json = {
"leagueName": $("input[name=leagueName]").val(),
"doSomething": $("input[name=doSomething]").val()
};
$.post("/Home/DoSomeStuff/", json, function () {
// async display something
});
}
Html:
<input type="text" name="doSomething">
<button type="submit" id="submitForm"</button>
<input type="hidden" name="leagueName" value="#item.League.LeagueName" />
What is the best way to let javascript fetch a stored value (more secure way then input type hidden)?
How can I prevent some user from altering the value from the input type
hidden field?
How can I prevent some user from altering the value from the input
type hidden field?
You cannot!
What is the best way to let javascript fetch a stored value (more
secure way then input type hidden)?
The general rule is, do not trust data coming from client. You should always validate it on server before doing anything.
If you are worried about a user update the league name field value in the form to some other users league name and post it, What you should be doing is, explicitly checking whether the user has proper permission to do something on the posted league in your server code.
[HttpPost, Authorize]
public ActionResult DoSomeStuff (string leagueName, string doSomething) {
var service = new Service(_db);
var league = service.GetLeague(leagueName);
// Now check whether the current user has access/permission
// to perform some operation on this league.
// Ex : if(!service.IsUserAuthorizedToDoSomething(league))
// {
// return View("NotAuthorized");
// }
//to do: Return something
}
If the value needs to come from the client (and be part of the HTTP request) then there's absolutely nothing you could do to prevent the client from modifying its contents. If the client is not supposed to modify the contents of some fields then those fields have nothing to do in your markup and be part of the postback HTTP requests (be it as hidden fields or whatever markup element comes to your mind). They should safely reside on your server (database?) and be retrieved using some identifier coming from the client. Obviously whether the client can access the information related to this identifier is subject to something called authorization. Basically you should first know who your client is (authentication) and then verify in your data model if this client has access to the corresponding records. It's as simple as that.
[HttpPost]
[Authorize]
public ActionResult DoSomeStuff (string id, string doSomething)
{
var service = new Service(_db);
var league = service.GetLeagueById(id);
if (!HasAccessToLeague(User.Identity.Name, league))
{
// you are not suppose to modify the contents of this league
// throw him a 404 or something
}
else
{
if (league != null)
{
// validate doSomething
league.Action = doSomething;
_db.SaveChanges();
}
}
return new EmptyResult();
}
obviously the implementation of the HasAccessToLeague(string username, string leagueId) method will greatly depend on your data model and how your authorization logic.
Also you used XSS in your question title but here your problem is not about XSS or javascript but rather designing authorization layer in your web application.
of course its possible to do this! After all, your server app manages to track who the currently logged on user is using insecure client storage.
When a user logs on, the server will generate a secret message and store it in an encrypted token that's passed to the client and bak in a cookie (which is just another piece of unsecured client data storage). When you send requests to the server, it gets the cookie, decrypts it, and checks the data inside to tell who the user is.
You can do the same - for the hidden fields, encrypt them, put them in a hidden input (or a cookie if you prefer) and send them back to the server. However, you can only use them in your client javascript if you send them plain text as well, which means you need to still perform some checking on the server, but that checking can be as simple as comparing the encrypted values with the hidden form values, if any do not match, reject the request.
things to bear in mind though, encrypion is slow. It can be quicker to fetch the values from a DB instead, though you might use a cache for these. YMMV.
An alternative option is to generate a javascript file with the values in and ensure that the client browser cannot edit them using security features such as content-security-policy. The disadvantage is an inability to use these values in html (as obviously the user can edit them there) so you'll have to pass data back to the server via js calls.

Concern with Facebook's login decoding sign_request performance

I am completely new to the Facebook API. I would like to incorporate Facebook login into my application. I am using the Javascript SDK on the front-end to log the user in and retrieve the user_id and signed_request from Facebook. I then plan to send these two pieces of information via AJAX to my server (either php/hack (hhvm), node, java, or whichever language I can determine is quickest for decoding) every time my logged in user does an action on my application to validate if the user is indeed logged in and is the person they say they are. For me to accomplish this, I need to decode the signed_request, for example in php:
function parse_signed_request($signed_request) {
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$secret = "appsecret"; // Use your app secret here
// decode the data
$sig = base64_url_decode($encoded_sig);
$data = json_decode(base64_url_decode($payload), true);
// confirm the signature
$expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
if ($sig !== $expected_sig) {
error_log('Bad Signed JSON signature!');
return null;
}
return $data;
}
function base64_url_decode($input) {
return base64_decode(strtr($input, '-_', '+/'));
}
which then I will be able to extract the following JSON object:
{
"oauth_token": "{user-access-token}",
"algorithm": "HMAC-SHA256",
"expires": 1291840400,
"issued_at": 1291836800,
"user_id": "218471"
}
to be able to compare if the user_id the user sent over matches the one in the JSON object. Then if it matches I can complete my business logic (DB manipulation).
My big concern here is a user will be sending many requests to my server, so every time I will need to decode this signed_request which can really kill my server performance. I was thinking I maybe could call Facebook from my server, pass the user_id, and receive the signed_request string, which I can then match with the signed_request string the user sent over from the client_side and see if they match. This would be more efficient, but it does not seem Facebook offers anything like this. Is there any other methods besides the heavy performing decoding to validate a user? I have gone through quite a bit of the Facebook SDK's information but could not find a solution. If I must decode, which language/library would be the best performing at this type of operation?
PS. I plan on using cordova later to create a mobile app so I must use only Javascript on the front end and can't use a server language such as php to create html for the client.
Decoding the signed request will not kill your server. It's way fast than making an external request.
If you're using php you should look into the Facebook SDK for PHP and use this helper: https://developers.facebook.com/docs/php/FacebookJavaScriptLoginHelper/4.0.0

How can Java and JavaScript work together?

I'll preface this by stating that I know Java is not JavaScript and vice versa.
I've got a project where I need to count occurrences of words for each of 1750 document names and document contents. I've got some awesome JavaScript from a colleague that does exactly what I want from a form input on a web page.
I want to use Java's FileReader, BufferedReader, walkFileTree, etc. to traverse the directories in which the documents live.
I'm not sure if this is the most efficient or effective approach, but both the Java and JavaScript parts of the code are working independently of one another now, and I'd like to see if I can get them to pass data between them before I start re-inventing the wheel.
Here's where I am so far. I'm stuck at the CLParse method & have inserted pseudocode:
public static void main(String... aArgs) throws FileNotFoundException {
File startingDirectory= new File("CGT");
List<File> files = FileListing.getFileListingNoSort(startingDirectory);
for(File file : files ) {
CLParse(file.toString());
} }
static private List<File> getFileListingNoSort(File aDirectory) throws FileNotFoundException {
List<File> result = new ArrayList<File>();
File[] filesAndDirs = aDirectory.listFiles();
List<File> filesDirs = Arrays.asList(filesAndDirs);
for(File file : filesDirs) {
result.add(file); //always add, even if directory
if ( ! file.isFile() ) {
List<File> deeperList = getFileListingNoSort(file);
result.addAll(deeperList);
} }
return result;
}
/* is something like this doable and how would I do it?
*/
public static void CLParse(String fn) {
pass fn to JavaScript counter
return an array of {word,occurences} for the string
write array to file
}
I'll be creating another set of methods to extract and pass the document CONTENTS as a string as well. I'd love to know if anyone has any practical experience passing values back and forth between Java and JavaScript, and advice on a good/better way to do it.
You got 2 Options to let them interact with each other, which i know:
1.Applet <-> javascript
2.Serlvet <-> javascript
With option 1, you have to build a Communication with a JSObject: JSObject
or you cann call the Applets Method instanstly with document.appletname.methodname();
with this you can even Parse same simply Formats to each other.
With Option 2 you have to build a communication with a Servlet.
in here you have to send an Ajax request to the the Servlet:
$.post('login',{name:"Peter", pw:"123456"},function()
{
//do whatever
})
JavaServlet class
the first comment, has to written as an Servlet in your web.xml, it´s the servlet pattern.
the second ones, are the parameters which can be read in the servlet. the function describes the stuff, which can be done in the request.
The differences between these two Options are:
1.the Applets runs on the users Computer, so you can access his files. But for this your applet has to be signed.
2.the Servlet runs on the Server. Here you have got full file access(if the system allows you too have it).
I would try to investigate Mozilla Rhino.
http://en.wikipedia.org/wiki/Rhino_%28JavaScript_engine%29
Check out Rhino https://developer.mozilla.org/en-US/docs/Rhino
You can create java objects and use them in javascript. Integration is straightforward
You can use AJAX to send and receive values to server. You can send parameters or JSON to server and get response.
You can use JSONP to serve the data, or if you have no control of the second server, use a reverse proxy to proxy requests to the second server through the first.

Categories

Resources