I have question regarding accessing all browser cookies using javascript, i was able to do this in shell script but i want to access the cookie information stored in local machine which needs to pass to server.
Regards
You can access them using
document.cookies
You cannot access all browser cookies. Only cookies set for the current domain and not marked 'http-only' (or 'secure' if you are on a non-SSL page).
In javascript use document.cookies
Update
The browser has built in functionality, as a security feature, to prevent you from reading cross domain cookies. As long as the javascript runs in the browser, there is no method to access those cookies, let alone execute a shell command. Google for: same origin policy.
What you basically are looking for has so many security/privacy implications, I don't even know where to start explaining the dangers.
Imagine that was possible. You browse to an arbitrary site that loads third-party ads, a rogue ad reads all your browser cookies and, voilá!, some guy from the Russian Mafia has the "Remember me" cookies and session IDs for all your sites. He can read your e-mail, see your pics on Facebook and retrieve money from your PayPal account.
function getCookie(name) {
// Split cookie string and get all individual name=value pairs in an array
var cookieArr = document.cookie.split(";");
// Loop through the array elements
for (var i = 0; i < cookieArr.length; i++) {
var cookiePair = cookieArr[i].split("=");
/* Removing whitespace at the beginning of the cookie name
and compare it with the given string */
if (name == cookiePair[0].trim()) {
// Decode the cookie value and return
return decodeURIComponent(cookiePair[1]);
}
}
// Return null if not found
return null;
}
function listCookies() {
var theCookies = document.cookie.split(';');
var aString = '';
for (var i = 1 ; i <= theCookies.length; i++) {
aString += i + ' ' + theCookies[i-1] + "\n";
}
return aString;
}
Related
I was looking through some Google articles and some Firefox developer areas and found that there was an option you can set to not let some sites track your information.
I looked into this and did some google searches for Developers and couldn't manage to find any information on how to detect whether or not a user has set this in their browser.
Is it sent in a POST request or in any type of request? Does it come in the User agent? I just wanted to know how to manage this and not store their ips for login as an example.
It's sent as an HTTP header:
function dnt_enabled()
{
return (isset($_SERVER['HTTP_DNT']) && $_SERVER['HTTP_DNT'] == 1);
}
if dnt_enabled() {
// do stuff...
}
Or, if you're using PHP 7:
function dnt_enabled(): bool
{
return (bool)$_SERVER['HTTP_DNT'] ?? false;
}
Navigator.doNotTrack
If you want to use client-side JavaScript to check whether or not a user has the dnt request header set, you can use navigator.doNotTrack.
This property returns the value of the dnt HTTP header (i.e., "1", "0", or "unspecified").
You can access this value via PHP by POSTing this value via AJAX.
const is_not_trackable = navigator.doNotTrack === '1';
console.log(is_not_trackable); // True if user has requested privacy via DNT
console.log(navigator.doNotTrack); // Current value of DNT header
Note: At the time of posting, navigator.doNotTrack is still considered experimental technology. Expect behavior to change in the future, and proceed with caution before using it in your application. See Browser Compatibility.
$do_not_track_requested = ! empty( $_SERVER[ 'HTTP_DNT' ] );
All HTTP headers are present in $_SERVER, prefixed with HTTP_.
https://www.php.net/manual/en/reserved.variables.server.php#89567
For added security our server keeps track of the browser fingerprint. At the moment we use the following headers:
HTTP_CLIENT_IP, HTTP_X_FORWARDED_FOR, HTTP_X_FORWARDED, HTTP_X_CLUSTER_CLIENT_IP, HTTP_FORWARDED_FOR, HTTP_FORWARDED, REMOTE_ADDR (take the first non-empty as the client-IP)
HTTP_ACCEPT_* headers
HTTP_USER_AGENT
Are there any more (optional) headers that can be used?
What in general is the best 'algorithm' to calculate the client fingerprint?
you can use a unique browser fingerprint (user agent, web browser, canvas, etc) and after get the hash.
/* Generate a fingerprint string for the browser */
function generateFingerprint(){
//Generate a string based on "stable" information taken from the browser
//We call here "stable information", information that normally don't change during the user
//browse the application just after authentication
var fingerprint = [];
//Take plugins
for(var i = 0; i < navigator.plugins.length; i++){
fingerprint.push(navigator.plugins[i].name);
fingerprint.push(navigator.plugins[i].filename);
fingerprint.push(navigator.plugins[i].description);
fingerprint.push(navigator.plugins[i].version);
}
//Take User Agent
fingerprint.push(navigator.userAgent);
//Take Screen resolution
fingerprint.push(screen.availHeight);
fingerprint.push(screen.availWidth);
fingerprint.push(screen.colorDepth);
fingerprint.push(screen.height);
fingerprint.push(screen.pixelDepth);
fingerprint.push(screen.width);
//Take Graphical card info
//See http://output.jsbin.com/ovekor/3/
try {
//Add a Canvas element if the body do not contains one
if ( $("#glcanvas").length == 0 ){
$(document.body).append("<canvas id='glcanvas'></canvas>");
}
//Get ref on Canvas
var canvas = document.getElementById("glcanvas");
//Retrieve Canvas properties
gl = canvas.getContext("experimental-webgl");
gl.viewportWidth = canvas.width;
gl.viewportHeight = canvas.height;
fingerprint.push(gl.getParameter(gl.VERSION));
fingerprint.push(gl.getParameter(gl.SHADING_LANGUAGE_VERSION));
fingerprint.push(gl.getParameter(gl.VENDOR));
fingerprint.push(gl.getParameter(gl.RENDERER));
fingerprint.push(gl.getSupportedExtensions().join());
} catch (e) {
//Get also error because it's will be stable too..
fingerprint.push(e);
}
//Last and, in order to made this browser unique, generate a random ID that we will store
//in local storage (in order to be persistent after browser close/reopen)
//Add this ID because, in Enterprise, most of the time browser have the same configuration
var browserUniqueID = localStorage.getItem("browserUniqueID");
if (browserUniqueID === null) {
localStorage.setItem("browserUniqueID", CryptoJS.lib.WordArray.random(80));
browserUniqueID = localStorage.getItem("browserUniqueID");
}
fingerprint.push(browserUniqueID);
return fingerprint.join();
}
And finally get the hash and sent to the server.
//Call the fingerprint dedicated function
var fingerprint = generateFingerprint();
//Use CryptoJS library ot generate a hex encoded string of the hash of the fingerprint
var fingerprintHash = CryptoJS.SHA256(fingerprint);
Source: https://www.owasp.org/index.php/JSON_Web_Token_(JWT)_Cheat_Sheet_for_Java#Token_sidejacking
https://browserleaks.com/canvas
To answer the question of which naming for the header:
I used on my side X-Fingerprint but I didn't find any standard way. You can make it more "obscure" so people don't guess that's a field to tamper.
At the end from what I saw headers like X-... are supposed to be free of use (less chance to conflict), but the last years more and more tools use them, and this kind of naming appears to become "standard" or a "convention" (like x-request-id for example).
A lot of you are probably aware of the new EU privacy law, but for those who are not, it basically means no site operated by a company resident in the EU can set cookies classed as 'non-essential to the operation of the website' on a visitors machine unless given express permission to do so.
So, the question becomes how to best deal with this?
Browsers obviously have the ability to block cookies from a specific website built in to them. My question is, is there a way of doing something similar using JS or PHP?
i.e. intercept any cookies that might be trying to be set (including 3rd party cookies like Analytics, or Facebook), and block them unless the user has given consent.
It's obviously possible to delete all cookies once they have been set, but although this amounts to the same thing as not allowing them to be set in the first place, I'm guessing that it's not good enough in this case because it doesn't adhere to the letter of the law.
Ideas?
I'm pretty interested in this answer too. I've accomplished what I need to accomplish in PHP, but the JavaScript component still eludes me.
Here's how I'm doing it in PHP:
$dirty = false;
foreach(headers_list() as $header) {
if($dirty) continue; // I already know it needs to be cleaned
if(preg_match('/Set-Cookie/',$header)) $dirty = true;
}
if($dirty) {
$phpversion = explode('.',phpversion());
if($phpversion[1] >= 3) {
header_remove('Set-Cookie'); // php 5.3
} else {
header('Set-Cookie:'); // php 5.2
}
}
Then I have some additional code that turns this off when the user accepts cookies.
The problem is that there are third party plugins being used in my site that manipulate cookies via javascript and short of scanning through them to determine which ones access document.cookie - they can still set cookies.
It would be convenient if they all used the same framework, so I might be able to override a setCookie function - but they don't.
It would be nice if I could just delete or disable document.cookie so it becomes inaccessible...
EDIT:
It is possible to prevent javascript access to get or set cookies.
document.__defineGetter__("cookie", function() { return '';} );
document.__defineSetter__("cookie", function() {} );
EDIT 2:
For this to work in IE:
if(!document.__defineGetter__) {
Object.defineProperty(document, 'cookie', {
get: function(){return ''},
set: function(){return true},
});
} else {
document.__defineGetter__("cookie", function() { return '';} );
document.__defineSetter__("cookie", function() {} );
}
I adapted Michaels codes from here to come up with this.
Basically it uses the defineGetter and defineSetter methods to set all the cookies on the page and then remove the user specified ones, this role could of course also be reversed if this is what you are aiming for.
I have tested this with third party cookies such as Google Analytics and it appears to work well (excluding the __utmb cookie means I am no longer picked up in Google Analytics), maybe you could use this and adapt it to your specific needs.
I've included the part about if a cookies name is not __utmb for your reference, although you could easily take these values from an array and loop through these that way.
Basically this function will include all cookies except those specified in the part that states if( cookie_name.trim() != '__utmb' ) { all_cookies = all_cookies + cookies[i] + ";"; }
You could add to this using OR or AND filters or pull from an array, database, user input or whatever you like to exclude specific ones (useful for determining between essential and non-essential cookies).
function deleteSpecificCookies() {
var cookies = document.cookie.split(";");
var all_cookies = '';
for (var i = 0; i < cookies.length; i++) {
var cookie_name = cookies[i].split("=")[0];
var cookie_value = cookies[i].split("=")[1];
if( cookie_name.trim() != '__utmb' ) { all_cookies = all_cookies + cookies[i] + ";"; }
}
if(!document.__defineGetter__) {
Object.defineProperty(document, 'cookie', {
get: function(){return all_cookies; },
set: function(){return true},
});
} else {
document.__defineGetter__("cookie", function() { return all_cookies; } );
document.__defineSetter__("cookie", function() { return true; } );
}
}
You can not disable it completely but you can override the default setting with .htaccess
Try
SetEnv session.use_cookies='0';
If it is optional for some users don't use .htaccess
if(!$isAuth)
{
ini_set('session.use_cookies', '0');
}
A little bit old but I think you deserve a answer that works:
Step 1: Don't execute the third party script code.
Step 2: Show the cookie banner.
Step 3: Wait until user accepts, now you can execute the third party script code..
Worked for me.
How about not paying attention to hoaxes?
Aside from the fact that this is old news, the text clearly says that it only applies to cookies that are not essential to the site's function. Meaning session cookies, a shopping basket, or anything that is directly related to making the site work is perfectly fine. Anything else (tracking, stats, etc.) are "not allowed" without permission.
I'm writing a multi-user, JavaScript based drawing app as a learning project. Right now it's one way: the "transmitter" client at transmitter.html sends the data as the user draws on the HTML5 canvas element, the "receiver" client at receiver.html replicates it on their own canvas.
The transmitter just draws a line between (previousX, previousY) and (currentX, currentY) in response to a mouseMove event. It sends those two sets of coordinates to transmitter.php via AJAX. They sit in a session var until the receiver collects them by calling receiver.php, also via AJAX. At least that's how it should work.
This is transmitter.php:
<?php
session_start();
if (!isset($_SESSION['strokes'])) $_SESSION['strokes'] = '';
$_SESSION['strokes'] .= $_GET['px'] . "," . $_GET['py'] . "," . $_GET['x'] . "," . $_GET['y'] . ';';
?>
This is receiver.php:
<?php
session_start();
echo($_SESSION['strokes']);
$_SESSION['strokes'] = "";
?>
In case you're wondering why I'm using a session var, it's because it's the fastest way I could think of to store the data in such a way that it could be accessed by the other script. I tried googling for alternatives but couldn't find anything. If there's a better way, I'd love to hear about it.
Anyway, the problem is that not all of the data is making it through. This manifests itself by gaps in the lines drawn on the receiver's canvas. I also set up a little counter in the transmitter's and receiver's JavaScript files, to check exactly how many "strokes" were being sent/received. There are invariably less received than sent, so the data is being lost server-side, it seems.
At the risk of giving you more code than you need to see, this is the code in transmitter.js that sends the data to the server (n is the counter that I mentioned):
function mouseMoveHandler(e)
{
var x = e.pageX - canvasX;
var y = e.pageY - canvasY;
if (mouseDown)
{
canvas.moveTo(prevX, prevY);
canvas.lineTo(x, y);
canvas.stroke();
sendToServer(prevX, prevY, x, y);
n++;
}
prevX = x;
prevY = y;
}
This is the code in receiver that gets it back and draws it (again, n is the counter):
function responseHandler()
{
if (xhr.readyState == 4)
{
var strokes = xhr.responseText.split(';');
n += strokes.length - 1;
for (var i = 0; i < strokes.length - 1; i++)
{
stroke = strokes[i].split(',');
canvas.moveTo(stroke[0], stroke[1]);
canvas.lineTo(stroke[2], stroke[3]);
canvas.stroke();
}
setTimeout("contactServer()", 500);
}
}
If I read your question correctly; you're trying to access the same session from different clients? If this is the case, this isn't possible, sessions are bound to a client/user.
If you want something realtime, multi-user you probably should take a look at NodeJS and specifically at NodeJS Events. Which is JS based, so I think that will integrate nicely in your application.
This is a PHP script I use to get the referring website for each new visitor to my site.
If the visitor came from Google, I get the keyword they used to find the site.
This data is stored in the session then included along with the data from the contact form when an enquiry is sent. This allows clients with little knowledge of analytics to track converting keywords.
I need to convert this PHP to work on a site that uses .aspx pages. After researching asp.net for several hours, I feel like I still don't have a clue where to start!
<code>
<?php
session_start(); // start up your PHP session!
if (empty($_SESSION['google'])) {
// if session is empty, take the referer
$thereferer = strtolower($_SERVER['HTTP_REFERER']);
// see if it comes from google
if (strpos($thereferer,"google")) {
// delete all before q=
$a = substr($thereferer, strpos($thereferer,"q="));
// delete q=
$a = substr($a,2);
// delete all FROM the next & onwards
if (strpos($a,"&")) {
$a = substr($a, 0,strpos($a,"&"));
}
// we have the key phrase
$_SESSION['google'] = urldecode($a);
$_SESSION['referer'] = 'Google';
}
}
if (empty($_SESSION['referer'])) {
$_SESSION['referer'] = $_SERVER['HTTP_REFERER'];
}
?>
</code>
I'd really appreciate a point in the right direction with this.
Thanks.
You need to read up on the HttpRequest and HttpResponse classes. More specifically, the Request.ServerVariables collection, the Request.Cookies object, and the Response.Cookies object.