Prevents bots, and stay in current URL if User is real - php

I have a script on my website, to prevents bots, it works fine but since i modified it to make changes i had a lot of errors, i'm not good at php.
<?php
error_reporting();
session_start();
$config_antibot['apikey'] = '________________________';
$config_antibot['bot'] = 'https://google.com';
$config_antibot['real'] = 'https://mywebsite.com';
class Antibot
{
function apikey($api_key){
$this->apikey = $api_key;
}
function get_client_ip()
{
if (isset($_SERVER["HTTP_CF_CONNECTING_IP"])) {
$_SERVER['REMOTE_ADDR'] = $_SERVER["HTTP_CF_CONNECTING_IP"];
$_SERVER['HTTP_CLIENT_IP'] = $_SERVER["HTTP_CF_CONNECTING_IP"];
}
$client = #$_SERVER['HTTP_CLIENT_IP'];
$forward = #$_SERVER['HTTP_X_FORWARDED_FOR'];
$remote = $_SERVER['REMOTE_ADDR'];
if(filter_var($client, FILTER_VALIDATE_IP))
{
$ip = $client;
}
elseif(filter_var($forward, FILTER_VALIDATE_IP))
{
$ip = $forward;
}
else
{
$ip = $remote;
}
return $ip;
}
function httpGet($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
return $response;
}
function check(){
$ip = $this->get_client_ip();
$respons = $this->httpGet("https://antibot.pw/api/v2-blockers?ip=".$ip."&apikey=".$this->apikey."&ua=".urlencode($_SERVER['HTTP_USER_AGENT']));
$json = json_decode($respons,true);
if($json['is_bot'] == 1 || $json['is_bot'] == true){
return true;
}else{
return false;
}
}
}
$Antibot = new Antibot;
$Antibot->apikey( $config_antibot['apikey'] );
if($Antibot->check() == true){
die(header("location: ".$config_antibot['bot']));
}else{
die(header("location: ".$config_antibot['real']));
}
?>
The lines that i tried to change
Line 7
$config_antibot['real'] = 'https://mywebsite.com';
Line 63
die(header("location: ".$config_antibot['real']));
Line 7 If the visitor is real not a bot it redirected to my website, but this redirect is causing a problem and affecting the nature of my website
Because when users sign up and get link mywebsite.com/user/02331/index?ref=02331 via email to activate their account, the user is redirected to mywebsite.com the user cannot not check mywebsite.com/user/02331/index?ref=02331 to complete registration
i change in line 63 to
die( header("HTTP/1.1 401 Unauthorized") );
exit();
}
But that doesn't seem to work for me, is there a way to let the user stay on the current url that the user is browsing if the user is real and not a bot?

What you're trying to create is a middleware (https://laravel.com/docs/8.x/middleware for laravel), or chain of responsibility (https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern). Depending on how you have it structured at the moment, this could mean you need to change the entire architecture of your code, which obviously isn't a great solution.
Ideally, you would have a router or some such that you can call here:
}else{
Route::get( ... );
// die(header("location: ".$config_antibot['real']));
}
You don't need to die() into the next portion of your site, you just need the page that they want to load to appear instead of the redirect. This could be done in any number of ways, but the die() portion is probably the least best option of them.

Related

Wordpress programmatic login from 3rd Party site

I'm trying to do a sort of SSO/programmatic login solution for our wordpress site from our separate web application. I don't have a lot of experience with wordpress so I assume there's something I'm missing or have configured incorrectly.
First here is my testing code that works great when I hit it directly IE www.mywordpresssite.com/test_login.php
test_login.php:
<?php
require __DIR__ . '/wp-load.php';
$username = 'myuserid';
$user = get_user_by('login', $username);
if (!is_wp_error( $user )) {
wp_clear_auth_cookie();
wp_set_current_user($user->ID);
wp_set_auth_cookie($user->ID, TRUE);
$redirect_to = user_admin_url();
wp_safe_redirect( $redirect_to );
}
exit();
The above sets the cookies accordingly and logs in the 'myuserid' user no problem. It redirects to user_admin_url() which was fine for my test but unnecessary as my intention is just to go to the home page as the entire site will be locked down for non-logged in users once this is working accordingly.
Now using the same concept that worked in test_login.php I've created prod_login.php which is supposed to apply the same logic via a cURL request from the web application that passes creds via the Authentication header.
prod_login.php:
<?php
require __DIR__ . '/wp-load.php';
$response = array('http_code' => 500, 'message' => 'Failed to update response');
if ($_SERVER['PHP_AUTH_PW'] !== 'password123') {
$response['http_code'] = 401;
$response['message'] = 'Unauthorized login attempt';
echo json_encode($response);
die();
}
$username = $_SERVER['PHP_AUTH_USER'];
$user = get_user_by('login', $username);
// Redirect URL //
if (!is_wp_error( $user )) {
wp_clear_auth_cookie();
wp_set_current_user($user->ID);
wp_set_auth_cookie($user->ID, TRUE);
//$redirect_to = user_admin_url();
//wp_safe_redirect( $redirect_to ); //commented out as unnecessary
$response['http_code'] = 200;
$response['message'] = 'Login Successful';
$response['user'] = $user;
echo json_encode($response);
} else {
$response['http_code'] = 403;
$response['message'] = 'Invalid User';
echo json_encode($response);
}
exit();
Now my cURL request appears to be working fine, I'm consistently getting the http_code === 200 response and the user object is coming back correctly in the cURL response. However, after the redirect to the wordpress site from the web app, the cookies are not set and I am not actually logged in.
web app cURL request:
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERPWD, 'myuserid' . ':' . 'password123');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_URL,'http://mywordpresssite.com/prod_login.php');
$server_output = curl_exec($ch);
if (curl_errno($ch)) {
// handle failed cURL
}
$decoded_response = json_decode($server_output);
if ($decoded_response->http_code === 200) {
// cURL response indicated successful login
// I can consistently get to this point and it will do the redirect but I will not be logged in nor will the cookies be set
header('Location: mywordpresssite.com'); // go to the wp homepage now that we should be logged in
}
I have no idea what I'm doing wrong. I assume it has to do with the cookies getting blown away or not preserved between the cURL and the redirect. Any insight on how to prevent that from happening or what I'm doing incorrectly is appreciated. Is this even possible with a cURL?
I have also tried a multitude of the examples of add_filter(‘auth_cookie_expiration’,... and apply_filters(‘auth_cookie_expiration’,... that are available on the internet to no avail.
From what I can tell, what I was trying to do is not possible.
The cURL request never actually touches the browser, it goes from the web app server to the wordpress site server so there in that context the web app server is the client. So when the redirect happens, the cookie is not set in the browser.
What I've done instead is a GET request passing my tokenized values in the query string. It's not as secure this way as anyone who gets their hands on the token will technically be able to access the site and login but there doesn't appear to be a way around that. At least the tokenized URL is never actually visible in the address bar so the typical user will not know what's happening.

problem when consulting ip through API php

I am using the service of http://ipinfo.io, I use the following code to consult information of my location through my IP, however, in localhost it works correctly but in the production server no, instead of throwing me the ip from the user, it returns the IP of the server from where the query is made.
I want it to detect the ip of the visitor, not the ip from where the request is made
class ipController{
private $token="XXXXXX";
public function __construct(){
$handle = curl_init();
$url = "http://ipinfo.io?token=".$this->token;
// Set the url
curl_setopt($handle, CURLOPT_URL, $url);
// Set the result output to be a string.
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($handle);
//var_dump($output);
curl_close($handle);
$datos = json_decode($output);
var_dump($datos);
//Se setean las propiedades
$this->ip = $datos->ip;
$this->hostname = $datos->hostname;
$this->city = $datos->city;
$this->region = $datos->region;
$this->country = $datos->country;
$this->loc = $datos->loc;
$this->postal = $datos->postal;
$this->org = $datos->org;
}
}
You were getting the server IP address because you were sending your
request with curl and when using the curl, the sever does the
request with its own IP.
In order to get the visitor's IP address you have to use the $_SERVER['REMOTE_ADDR'] or the $_SERVER['REMOTE_HOST'] variables, but this does not return the correct IP address of the visitor sometimes, so you can use the below function to the get the correct IP of the user
function get_ip_address() {
$ipaddress = '';
if (isset($_SERVER['HTTP_CLIENT_IP']))
$ipaddress = $_SERVER['HTTP_CLIENT_IP'];
else if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
$ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
else if(isset($_SERVER['HTTP_X_FORWARDED']))
$ipaddress = $_SERVER['HTTP_X_FORWARDED'];
else if(isset($_SERVER['HTTP_FORWARDED_FOR']))
$ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
else if(isset($_SERVER['HTTP_FORWARDED']))
$ipaddress = $_SERVER['HTTP_FORWARDED'];
else if(isset($_SERVER['REMOTE_ADDR']))
$ipaddress = $_SERVER['REMOTE_ADDR'];
else
$ipaddress = 'UNKNOWN';
return $ipaddress;
}
Then you can just get the ip info with the url this way
$ip = get_ip_address();
$url = "http://ipinfo.io/$ip?token=$token";
//you can the get the data with
$data = url_get_contents($url);
//curl function to send your request
function url_get_contents($Url) {
if (!function_exists('curl_init')){
die('CURL is not installed!');
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $Url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
According to the docs you need to put the ip address in the endpoint. Just the token gives your own ip address which is the server
https://ipinfo.io/developers#ip-address-parameter
ipinfo.io/$visitors_ip?token=$TOKEN
I'd assume it is php making the request to ipinfo hence why you get the servers details

Facebook Like Gate like_status is empty

so basically im trying to get a like gate working but the $like_status variable never changes so my condition to change to the liked content will never work. Does anyone know why this never changes? Have added my app to a page tab on facebook and it gets all the other variables $page_id, $page_admin, $country and $locale but not $like_status.
Thanks Charlie
See Code Below
<?php
enter code here
require_once('AppInfo.php');
// Enforce https on production
if (substr(AppInfo::getUrl(), 0, 8) != 'https://' && $_SERVER['REMOTE_ADDR'] != '127.0.0.1') {
header('Location: https://'. $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
exit();
}
// This provides access to helper functions defined in 'utils.php'
require_once('utils.php');
require 'includes/facebook.php';
// Create our Application instance.
$facebook = new Facebook(array(
'appId' => AppInfo::appID(),
'secret' => AppInfo::appSecret(),
'cookie' => true
));
$signed_request = $facebook->getSignedRequest();
$page_id = $signed_request["page"]["id"];
$page_admin = $signed_request["page"]["admin"];
$like_status = $signed_request["page"]["liked"];
$country = $signed_request["user"]["country"];
$locale = $signed_request["user"]["locale"];
echo "<br>page id = $page_id";
echo "<br>page admin = $page_admin";
echo "<br>like status = $like_status";
echo "<br>country = $country";
echo "<br>locale = $locale";
function grokSignedRequest()
{
if (isset($_REQUEST['signed_request']))
{
$encoded_sig = null;
$payload = null;
list($encoded_sig, $payload) = explode('.', $_REQUEST['signed_request'], 2);
$sig = base64_decode(strtr($encoded_sig, '-_', '+/'));
$data = json_decode(base64_decode(strtr($payload, '-_', '+/'), true));
return $data;
}
return false;
}
// call the function to parse the signed request
$sr_data = grokSignedRequest();
// check like status
if ($sr_data->page->liked==1)
{
include ('includes/index2.php');
}
else
{
include ('includes/index1.php');
}
?>
If you are running your PHP code on a tab page, like_status is probably actually present, but set to a value of 0 (zero). Thus, the echo statement seems to be outputting nothing for $like_status, but in reality, it has a value of zero. To prove this try code like this:
if ($like_status == 0)
echo "it's zero";
else
echo "it's not zero";
Edit: Sorry, I didn´t see that #robbie solved this in the comments of the question
The user must arrive to the App from the page tab, and:
As with a Canvas Page, you will not receive all the user information accessible to your app in the signed_request until the user authorizes your app.
https://developers.facebook.com/docs/appsonfacebook/pagetabs/#integrating

Get a video link from youtube

In one of my application I need to show a YouTube video. If user submits a video then I have to check if that video is alive in YouTube. If OK then I have to save the video id in my database and generate video in web page.
Is there any method for validating YouTube video ?
Use this class to extract and validate youtube video. This works for YT urls like /embed/ , /v/ , ?v= /, youtu.be
class Youtube {
///// Put together by Sugato
////////// $video_id is the youtube video ID /////////////////////////
public $video_id = null;
///////// the Constructer ////////////////////////////////////////
public function __construct($url)
{
if (preg_match('/youtube\.com\/watch\?v=([^\&\?\/]+)/', $url, $id)) {
$this->video_id = $id[1];
} else if (preg_match('/youtube\.com\/embed\/([^\&\?\/]+)/', $url, $id)) {
$this->video_id = $id[1];
} else if (preg_match('/youtube\.com\/v\/([^\&\?\/]+)/', $url, $id)) {
$this->video_id = $id[1];
} else if (preg_match('/youtu\.be\/([^\&\?\/]+)/', $url, $id)) {
$this->video_id = $id[1];
} else {
$this->video_id = NULL;
}
}
/////////// validates if a youtube video actually exists //////////////
function validate()
{
if(empty($this->video_id))
{
return false;
}
else {
$curl = curl_init("http://gdata.youtube.com/feeds/api/videos/" . $this->video_id);
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_exec($curl);
$request = curl_getinfo($curl);
curl_close($curl);
$result = explode(";", $request["content_type"]);
if($result[0] == "application/atom+xml")
{
return true;
} else {
return false;
}
}
}
}
Call the class like this
$yt = new Youtube($your_video_link_here);
$exist = $yt->validate();
if($exist)
{
echo "Yaaaayyyyyy!";
} else
{
echo "nAAAAyyyy!!!";
}
If the user is flat-out submitting a video, you would have to have something like a database which contains hashes for existing videos to compare it with (ex: the SHA checksum), then check if the hash is already present. As far as I know, Google/YouTube provide no such database for the public to use, but you could start your own for the videos that users submit through your service. There are other more advanced techniques you could use, but they would require access to all of the existing video files for analysis... which is not available.
As far as getting the video URL, when you upload a video to YouTube you can link to it or embed it in a webpage.

facebook is redirecting to my site outside of facebook

I'm having trouble working with my redirect uri in the authentication.
If i set it to my site, the user will authenticate, because $_Request['code'] is set, but then the user will be on my site, and I don't want that
If I redirect to apps.facebook.com/myapp, then $_Request['code'] is not set, and the user won't authenticate, but just see a blank page.
is there any way to do this in PHP, I have code running before the page is rendered.
How do you guys solve this issue?
my login function:
public static function login($redirect) {
$app_id = AppInfo::appID();
$app_secret = AppInfo::appSecret();
$home = urlencode(AppInfo::getHome());
// See https://developers.facebook.com/docs/reference/api/permissions/
// for a full list of permissions
$scope = 'user_photos,publish_stream';
session_start();
$code = $_REQUEST["code"];
// If we don't have a code returned from Facebook, the first step is to get
if (empty($code)) {
// CSRF protection - for more information, look at 'Security Considerations'
// at 'https://developers.facebook.com/docs/authentication/'
$state = md5(uniqid(rand(), TRUE));
setcookie(
AppInfo::appID() . '-fb-app',
$state,
$expires = 0,
$path = "",
$domain = "",
$secure = "",
$httponly = true);
// Now form the login URL that you will use to authorize your app
$authorize_url = "https://www.facebook.com/dialog/oauth?client_id=$app_id" .
"&redirect_uri=$home&state=" . $state . "&scope=$scope";
// Now we redirect the user to the login page
echo("<script> window.location.href='" . $authorize_url . "'</script>");
return false;
// Once we have that code, we can now request an access-token. We check to
// ensure that the state has remained the same.
} else if ($_REQUEST['state'] === $_COOKIE[AppInfo::appID() . '-fb-app']) {
$ch = curl_init("https://graph.facebook.com/oauth/access_token");
curl_setopt($ch, CURLOPT_POSTFIELDS,
"client_id=$app_id&redirect_uri=$home&client_secret=$app_secret" .
"&code=$code&scope=$scope");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
// Once we get a response, we then parse it to extract the access token
parse_str($response, $params);
$token = $params['access_token'];
return $token;
// In the event that the two states do not match, we return false to signify
// that something has gone wrong during authentication
} else {
echo("States do not match. CSRF?");
return false;
}
}
If you want to have your app on Facebook, you can just use the signed_request parameter Facebook POSTs to your canvas url. You wouldn't need to read the code once the user has approved your app. Note that Facebook always sends this parameter, even if the current user hasn't approved your app (it contains less info then).
See the documentation

Categories