How to detect users setting do-not-track - php

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

Related

How do I ensure privilege to update record?

I received some pen tests results.
The results say that anybody can update any record by just changing a certain id.
How could I ensure that the user can only update his own record in this function?
public function actionUpdateProfile()
{
$postdata = file_get_contents("php://input");
$response = array("status" => "1", "message" => "Profile update successful.");
$data = json_decode($postdata);
$model = HosDoctors::model()->findByPk($data->doctor_id);
foreach ($data->fields1 as $field) {
$_POST[$field->name] = $field->value;
}
$enc = NEW bCrypt();
$model->attributes = $_POST;
if ($model->save()) {
$response = array("status" => "1", "message" => "Profil erfolgreich aktualisiert");
} else {
pr($model->getErrors());
}
echo json_encode($response);
die;
}
Would it be sufficient to simply check for
if (cookie == $data->doctor_id)
{
//ok
}
else
{
//we are not logged as the user id that we want to update, so deny updating
die;
}
I am assuming the person has "logged in" in some way so that you know "who they are". While security is complex and is definitely not a one-answer topic; at its simplest level, once you have identified the user, use PHP session handling to persist their identity across one or many http/s requests, then internally access any related information using the session cookie id for the duration of the session.
There are several potential issues in this function (unless you posted a heavily edited version). I'll note them as comments.
public function actionUpdateProfile()
{
$postdata = file_get_contents("php://input");
$response = array("status" => "1", "message" => "Profile update successful.");
// Never initialize responses until you really *must*. Chances that a partially prepared response might be output are slight, but why run risks?
// And actually you **do** reinitialize $response later on!
$data = json_decode($postdata);
// You are not verifying that $data *exists* (i.e. the JSON data was, indeed, JSON). You should check that $data is not NULL and that it does have **all** the required fields and that they are valid.
// This is the point where you validate $data->doctor_id, by the way. Or you check that patient_data matches with whatever you have in your $_SESSION or Session app object.
$model = HosDoctors::model()->findByPk($data->doctor_id);
// This is a bad practice. Yes, you have some code that relies on
// _POST. If necessary, wrap it in another code that will set up
// _POST from an input and then delete it. Otherwise you're leaking
// data into a superglobal. You don't want to do that.
foreach ($data->fields1 as $field) {
$_POST[$field->name] = $field->value;
}
// Why are you initialising $enc?
$enc = NEW bCrypt();
// This is not very good. $_POST could contain *other* information
// unless it's been sanitized outside the function.
// I would prepare a setter function, $model->setArray($data), that
// would verify the validity of the attributes before setting them.
$model->attributes = $_POST;
if ($model->save()) {
$response = array("status" => "1", "message" => "Profil erfolgreich aktualisiert");
} else {
pr($model->getErrors());
}
// This works in 90% of the browsers and scenarios. But I'd
// set up a function that would also send the appropriate
// Content-Type headers to satisfy the remaining 10%.
echo json_encode($response);
die;
// e.g. Utilities::jsonResponse($response);
}
Would it be sufficient to simply check for
if (cookie == $data->doctor_id) {
//ok } else {
//we are not logged as the user id that we want to update, so deny updating
die; }
try checking by user token instead of user-id because user-id can be found within some page url or body but the token is hard to get unless using network sniffing technics.
you can generate user token by any token generation method and then store it as a column in the user table in your database.
token generation method e.g
$token = bin2hex(openssl_random_pseudo_bytes(16));
# or in php7
$token = bin2hex(random_bytes(16));
Would it be sufficient to simply check for
if (cookie == $data->doctor_id)
{
//ok
}
else
{
//we are not logged as the user id that we want to update, so deny updating
die;
}
No, in principle this is actually the same as you already have: the ID is still part of the request and can be changed like you got it reported.
Instead ensure the request is first of all authorized, then fetch the related data from the identity and access management system.
If you do not have anything to manage identity and access, choose a system and integrate it first.
From the code you've posted so far it is not visible (to me) whether or not such a system exists. Therefore I can not specifically answer on that detail.
Authentication/Authorization of requests is part of the HTTP protocol and is supported at a basic level in PHP out of the box. See:
HTTP authentication with PHP Docs
If you want to roll your own completely you can consider HTTP state management with PHP sessions, but as you ask the question the way you ask it (with all due respect), my suggestion is to take something that already exists, is proven and easy for you to understand and integrate (less complexity = better software and less flaws/holes).
Take the event of the pen test and its result to address the design issues first and find a high level solution not that you need to patch multiple endpoints individually only to address the same basic flaw.
Let the system work for you.
After the pen-test I would also suggest the code is reviewed with dedication towards the found issues and the code writers are trained based on the results of both.
Would it be sufficient to simply check for ...
Yes, given the cookie is from a safe source and all its properties are secure. E.g. only the identity and access management system can add it to the HTTP request that hits the PHP SAPI.
I would rate this event very unlikely as you needed to ask the question.
And it would be very unorthodox if it would contain a concrete id. There should always be a HTTP state management and it should be rolling to protect against replay attacks with credentials or at least limit the time-frame in which they are valid.
But purely technically, with the right design and implementation I can imagine there can be systems that work this way (HTTP request with cookie as secure token).
Take care.

How to access ASP classic session variable from PHP?

I have a login protected back office website written in ASP classic running on Windows. Login status is stored in a session variable. I also have a PHP page that should be accessible only to logged in users. How do I check in PHP that the client is logged in to this website?
P.S. There may be multiple users accessing the page at the same time.
By assuming both PHP and ASP applications share the same domain name, here's a step by step guide.
1 - Create an asp file named sessionConnector.asp.
2 - In sessionConnector.asp, serialize the Session.Contents object into a format that PHP can deserialize, JSON for example. You can use JSON.asp from aspjson.
<%#Language=VBScript CodePage=65001%>
<!--#include file="JSON.asp"-->
<%
Set JSONObject = jsObject()
For Each Key In Session.Contents
If Not IsObject(Session.Contents(Key)) Then 'skip the objects cannot be serialized
JSONObject(Key) = Session.Contents(Key)
End If
Next
JSONObject.Flush
%>
3 - Create a PHP function named GetASPSessionState().
4 - In GetASPSessionState(), make an HTTP request for sessionConnector.asp by specifying the Cookie header filled with $_SERVER["HTTP_COOKIE"] which must contains identifier of the ASP Session, so ASP can identify the user and the response will vary by user.
5 - After fetching the response (string of JSON), deserialize by using json_decode and look for the ASP session variable.
function GetASPSessionState(){
if(stripos($_SERVER["HTTP_COOKIE"], "ASPSESSIONID") === false){
# since ASP sessions stored in memory
# don't make request to get ASP session state if the cookie does not contain ASPSESSIONID
# otherwise IIS will create new redundant sessions for each of your checks so it wouldn't be a memory-friendly way
# returning an empty array
return array();
} else {
$options = array('http' =>
array('method'=>"GET", 'header' => "Cookie: " . $_SERVER["HTTP_COOKIE"])
);
$cx = stream_context_create($options);
$response = file_get_contents("http://mywebsite.com/sessionConnector.asp", false, $cx);
return json_decode($response, JSON_FORCE_OBJECT);
}
}
$aspSessionState = GetASPSessionState();
if($aspSessionState["IsLoggedIn"] == true){
//user previously logged in with the ASP
}
My solution was to auto-submit a webform which works both ways regardless of whether PHP to ASP or ASP to PHP.
On the leading page simply add an OnLoad to the body tag like so:
<body onload="document.xxx.submit()">
Where "xxx" is the is the ID of your form that contains the hidden fields that you want to pass. For example:
<form id="xxx" action="example.asp" method="post">
This will work locally and across domains.

Avoid changing values in console

How can I avoid that users changing the values in the console. As example my link is:
example.com/delete.php?id=8. When I'm open my console and I change the 8 to 10 then row 10 is deleted.
How can I avoid this? Or by which way I can do it instead of the URL?
The security of an application must never be only on the client side.
You must always consider that URIs called on the client side can be called not just via a form.
If your interface offers a short list of choices, the webservice or server script must check the same reduced choice list before before any other treatment.
You can use a <form method=post action=delete.php ><button type=submit value=8 name=id>delete</button></form> and then, in the PHP, use $_POST['id'] instead of $_GET['id'].
You can also use $_SESSIONs to see if the user is logged in and if he is allowed to delete that id; For instance, when delivering the page set something as $_SESSION['allow_id'] = 8 and then, on the PHP side, you could do something as:
if ((!empty($_SESSION['allow_id'])) && (!empty($_POST)) && ($_SESSION['allow_id'] == $_POST['id'])) { // allow the deletion } else { // don't allow }

Is it possible to block cookies from being set using Javascript or PHP?

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.

login to php website using RCurl

I would like to access with R to the content of a php website
http://centralgreen.com.sg/login.php?login=9-1501&password=mypassword
I have passed an example of login + password in the url, but I don't know how to press the login button through the url.
I would like to use the R package RCurl if possible.
The form submits by post - you are using a get request at the moment by the looks of things, you need to use post.
My guess is that rcurl is based on curl - and I know curl can do this, so should be possible.
recently I've been having the same problem. In my case I solved it like this, using RCurl package (with a POST request).
In this code two requests are done one after the other. The fist one, is in order to gain a session cookie (start session in the server). The application I was calling expected the session to be started by the time it checked the login credentials (this won't happen if you send the form upfront). Otherwise some warning about not having cookie support was raised. This might be the case of the asker (though it was time ago)... or someone else's.
login <- function (xxxx_user, xxxx_pass) {
url_login <- 'http://centralgreen.com.sg/login.php'
curlhand <- getCurlHandle()
curlSetOpt(
.opts = list(cainfo = system.file("CurlSSL", "cacert.pem", package = "RCurl")),
cookiefile = "cookies.txt",
useragent = 'YOUR R-PACKAGE NAME',
followlocation = TRUE,
# might need this in case the server checks for the referer..
httpheader = "Referer: http://centralgreen.com.sg",
curl = curlhand)
# (1) first call to initializate session. you get the session cookie
getURL(url_login, curl = curlhand)
params<- list( login = xxxx_user, password = xxxx_pass )
# might need to add some other hidden form param in case there are..
# (2) second call, sends the form, along with a session cookie
html = postForm(url_login,
.params = params,
curl = curlhand,
style="POST")
# ... perform some grep logic with 'html' to find out weather you are connected
}
# you call the function...
login("yourusername", "yourpass")
The 'perform some grep logic' note takes care of the fact that since you are targeting a system not designed for this kind of programatical log in, it's not going to give you any nice hint on the result of the attempt ... so you might need to parse the raw html string you receive against some key sentences (eg: 'wrong username or password' ...)
hope it helps

Categories