how to protect an ID in the url with php? - php

For a simple mailinglist, i use flat-file (.txt) files for storing the date from subscribers.
The name of the .txt files is the same as the id i assign to a subscriber.
A .txt file with the data inside (name and email) looks so something like this:
id-8759874589.txt
In every email i send, i send an unsubscribe link so that the subscriber can unsubscribe from receiving mails. I encode the unsubscribe link with base64_encode. Only for the mask of the eye.
An unsubscribe-link looks something like this:
http://example.com/unsubscribe.php?id=aWQtMjAxOTEyMjMNDUyMTQ%3D&email=amNtZy5tYWVzc2VuQGdtYWlsLmNvbQ%3D%3D
For unsubscribing, i use this code:
<?php
$id = $_GET['id'];
$email = $_GET['email'];
// decode the id and email string
$id_decode = base64_decode($id);
$email_decode = base64_decode($email);
if( isset($id_decode) ) {
$filename = 'subscribers/'.$id_decode.'.txt';
// delete subscribers entry
if(file_exists($filename)) {
unlink($filename);
echo '<div class="alert alert-success"><b>'.$email_decode.'</b> is successfully removed from our mailinglist!</div>';
}
else {
echo '<div class="alert alert-danger">Email not found or you already have unsubscribed from our mailinglist!</div>';
}
}
?>
As you can see: the id, which is assigned to the .txt file, will be unlinked. The subscriber is deleted from the mailinglist.
My worries:
Lets say: you were a subscriber and you did unsubscribe, then you know how the url is created.
You can start guessing: How will the subscriber be unsubscribed? Lets say: you know that every subscriber has his data in a .txt file with the name of the id. You can let a robot guess the identities in the url string and execute this url. In worse case scenario, he found an id that really exists and the file will be deleted. A random subscriber is removed from the list without doing itself.
How can i protect this better?

Create a unique code and store this code in the file, also provide this code in unsubscribe url:
http://example.com/unsubscribe.php?id=aWQtMjAxOTEyMjMNDUyMTQ%3D&email=amNtZy5tYWVzc2VuQGdtYWlsLmNvbQ%3D%3D&token=WHATEVER
In this case you can also get a token from url as $_GET['token'] and check if it is the same as one in the file. If it is the same (and no one except you knows the algorithm with which token is created) - you can unsubscribe the user. In case of failure you can consider that someone is cheating)

You should worry when you only encode your parameters.
As you already expected gives Base64 no security, also the fact that you expect an Id and a email gives information to hack you.
The third risk is your response, there you als give information away, just inform your that the request is processed.
You should use encryption see to be safe.

Related

Script/bot to open a link inside an email

I want download a report that I'm receiving every day on my inbox.
This email contains a link to a platform (where I have to be logged-in on the platform to open the link correctly, otherwise I will be redirected to login page) and finally there is another link that downloads the report to my computer.
My question is: It's possible to make a PHP script that can do this automatically?. All the process to read the email and identify the link it's easy, I want some guidelines to continue working.
Thanks!
This may be harder than you anticipate and PHP may not be the best language to achieve what you are after as it can not run on top of Outlook or any other desktop based email client. To do this you would have to run the PHP code from the command line, and have it set to regularly intercept all your emails and check to see if the email is from a specific user, and if it is parse the email for the two necessary links. Once you have the links you can have the code establish a cURL connection to the login form and pass the username and password, ensuring to pass any cookies defined from the authenticated session, and then establish a new cURL link to the download link to download the file to the local file system, after which you can send a new email to yourself attaching the file as a native attachment, dependant on file size.
Information on sending cookies with cURL can be found at How can I send cookies using PHP curl in addition to CURLOPT_COOKIEFILE?
The net result though is that this would have to run in the background continuously and would have to be set to regularly connect to your email server and check all emails for the existence of emails from the automated email sender.
An easier solution would be to find out if the automated tool can be setup to simply send the file as an email attachment so that you don't have to run the excess code. In addition any time the initial email structure changes or the download or login links change you would have to update the code to deal with the associated changes.
Main point is that PHP isn't the most ideal solution for what you are trying to do and what you are trying to do, in any language, is going to be a complex task to achieve.
When you already have the email link you could login to the platform using a curl request and afterwards make the same call again. the second time you'd be logged in and curl would download your report.
You could use the cURL library.
How does your platform identifies you ? If you can use cookies, look for
CURLOPT_COOKIE
curl_setopt($ch, CURLOPT_COOKIE, session_name() . '=' . session_id());
i have the a similar issue, i want to open on googlesheets a series of reports from my email, managed to do it when its attached evenif is a zip, but when its only a link o cannot do it, heres the script i use, maybe someone could upgraded to open links and import the csv
function importCSV() {
// Change the report name Report
var threads = GmailApp.search("subject:XXXXXX has:attachment from:XXXXX#google.com newer_than:1d");
var message = threads[0].getMessages()[threads[0].getMessages().length-1];
var allAttachment = message.getAttachments();
var attachment = allAttachment[0];
var contentType = attachment.getContentType();
var name = attachment.getName();
if (attachment.getContentType() === "text/csv") {
// Change the sheet name, where you want the data to appear
var sheetActive = SpreadsheetApp.openById("1slVepI8s2Ekdiha0u4NpqFLZ4NnJrhyc8in9hYNzJA0");
var sheet = sheetActive.getSheetByName("Youtube");
var csvData = Utilities.parseCsv(attachment.getDataAsString(), ",");
// This clears the document from previous data
sheet.clearContents().clearFormats();
// Import the CSV file to the spreadsheet
sheet.getRange(1, 1, csvData.length, csvData[0].length).setValues(csvData);
}
else if (attachment.getContentType() === "application/zip") {
attachment.setContentTypeFromExtension();
// Unzip Attachment Change the sheet name, where you want the data to appear
var sheetActive = SpreadsheetApp.openById("1slVepI8s2Ekdiha0u4NpqFLZ4NnJrhyc8in9hYNzJA0");
var sheet = sheetActive.getSheetByName("Youtube");
try {
var unzip = Utilities.unzip(attachment)[0];
var csv = unzip.getDataAsString();
var csvData2 = Utilities.parseCsv(csv, ",");
// This clears the document from previous data
sheet.clearContents().clearFormats();
// Import the CSV file to the spreadsheet
sheet.getRange(1, 1, csvData2.length, csvData2[0].length).setValues(csvData2);
} catch (e) {
// Logs an ERROR message.
console.error('myFunction() yielded an error: ' + e);
}
}}

A secure enough way of identifying and activating a user in MySQL PHP with a URL

Is checking against my table with the user's email and dedicated hash enough to verify and activate an account if a match is found against those two values?
A user is asked to register themselves with user data and their email id. They are then sent a URL to their email which they are asked to click on to confirm and activate their account.
This is my current setup:
<?php //The user-account-creation processing page
$email_id = taken from user input;
$randomnessWhateverItsCalled = "lots-of-randomness-here";
UPDATE advert SET advert_hash = SHA1(CONCAT($email_id, $randomnessWhateverItsCalled))
//For simplicity's sake I omitted the PDO stuff
INSERT INTO table_name (..., user_email, hash, account_activated, ...) VALUES (..., usersEmail, advert_hash, NO, ...)
/**
Send an email with some php code with the URL that would look like this
URL to click on attached to email body:
*/
$attachStringToEmailBody = "http://www.domainname.com/activate-user?email_id=" . $usersEmail . "&hash=" . $randomnessWhateverItsCalled;
enter code here
//Send email from this process page with a little email php code
//Redirect user to a page informing the user to activate the account by visiting their email and clicking on the url
?>
Then in the activate-user.php page I have the following:
<?ph
$user_email = $_GET['email_id'];
$hash = $_GET['hash'];
/**
search database and return a row if there is a match containing both the $user_email and the $hash
if(match){
Update database and set the `account_activated` column to `YES`
}
else{
//Tell if there was no match then activation failed
//Let the user know that we do not recognise the link they used to try and activate their account.
}
*/
?>
It seems secure enough, as long as you made the "randomness" part hard to guess. You can put there the email, username, password, etc. and mix them up with another key - all encrypted - that's what I usually do.
But I would advise you to use 0/1 for active/inactive - why using strings, when you can do the same with smallint (1) - and save some space, thus making the database a bit lighter ?

how to delete mysql table row from mail inbox

I want to delete mysql table row from mail inbox , Is it possible !, If yes how can i delete the table row in my server database from any mail inbox account, please tell me the solution
Table Structure:
id usrname password status usercat
1 xxxxxxx xxxxxxx new 1
2 uuuuuuu uuuuuuu new 5
$del_qry= mysql_query("DELETE FROM table_name WHERE some_column=some_value")
In my site after Registration, the registered person get alert mail and also site admin get registered user detail's mail. So if the admin want to delete the second user(username - uuuuuu) from his mail account.
How can i do this, Please tell me i am new here...
The email you send to the admin will have to contain a link like this:
http://www.example.org/admin/remove_account.php?id=123
Where 123 is the user that was registered and remove_account.php is the script that will be loaded when the link is clicked.
Within the script you would have something like this:
mysql_query("DELETE FROM table_name WHERE id=" . mysql_real_escape_string($_GET['id']));
CAUTION
A few words of caution. The above link should be protected by one of the following:
User & password protection (either using Apache or PHP)
Signature protection (example below)
The signature protection prevents tampering / forging link parameters by adding a signature. Works like this:
$secret = "some reasonably long string of random data";
$id = "123"; // like above, the user id
$sig = hash_hmac('sha1', $id, $secret);
$link = 'http://www.example.org/admin/remove_account.php?' . http_build_query(array(
'id' => $id,
'sig' => $sig,
));
To verify the signature:
$secret = "some reasonably long string of random data";
if (isset($_GET['id'], $_GET['sig'])) {
$calc_sig = hash_hmac('sha1', $_GET['id'], $secret);
if ($calc_sig === $_GET['sig']) {
// your delete query here
}
}
Please note that, although the link protects against someone trying to access your administrative script, if it falls in the wrong hands you're still pretty much screwed. Don't underestimate security :)
I think you must add a link of a page of your site in email of delete with respect of user list. and when user click on link it will redirect to particular page where it will get that user id from url of link and then you can perform delete action. It is necessary to redirect to site page from mail because in mail you can not direct connect with database.
thanks

giving users invites?

I want people to request invites to use my app, they fill in their email address, but how can generate an url for them to go to register? Presumably only to be used once! I was thinking some sort of md6 code using php!
P.S. If there is a tutorial for this, please give a the link. Thanks.
In the email you use a random code, for example (a part of) the session-id of the user
<?php
$code = session_id();
You save this code somewhere in your database and when the user hits your register page (for example, http://mydomain.tld/register?code=here-register-code), you do something like this:
<?php
$code = $_GET['code'];
if (my_code_is_valid($code) {
echo 'Hey, you are able to register now!';
} else {
echo 'Sorry friend, you need an invite first!';
}
You need to define your my_code_is_valid() function, but that's depending on your own code (framework, database system etc).

Open txt files from a directory, compare the values, and output the top 15 in PHP

I recently designed a referral game website for the fun of it.
There's a simple MySQL user system with a email verification. It's using the UserCake user management system.
On top of this i added a php page that the user could give to "victims" that when they visit it they get "infected" and can infect other users or "victims". This page uses GET to get the username from the url. I have a folder that when a user registers it creates a file with 4 digits and then the username. (ex; 0000Username.txt) All the numbers are the same, it's just so that if a user discovers the folder they won't be able to find the files. There is also a txt file in the same format with IPS in the name. (ex; 0000IPSUsername.txt) The file when visited gets the username from the url, then checks if the text file for that username exists. If the username is present in the url, and a valid user it opens the IPS file and adds the IP of the visitor, then opens the user text file, takes the value and adds one to it, and saves. At the end it makes the difference between saying "You are infected, Username has infected (amount) people." or just you have been infected.
Now to what i need!
I need to add a hi-scores to the website so people can compete to be the one with the most "infections".
I thought i could use readdir to get a list of the files and open them with the value in an array, but i need it to also strip the username from the file name. It would be best if it just saves to a text file like "Username | value" because then i can add echo's of the html tags and have it include the file in the page i want it to be one.
Many thanks in advance.
Try using an array and count($array) to count the files.
Stripping the values out is as simple as using PHP's str_replace function. More here: http://php.net/manual/en/function.str-replace.php
With the 0000Username.txt file try using json.
// Get
$contents = file_get_contents('0000Username.txt');
$data = json_decode($contents); // PHP > 5.2.0
// Put
$data['username'] = 'Username';
$data['infectious'] = $data['infectious'] + 1;
$contents = json_encode($data); // PHP > 5.2.0
file_put_contents($contents);

Categories