How can I solve the warning "Warning: array_key_exists."? - session

I'm using Hybridauth social login, and upon a user authenticating with Facebook, I receive the following error:
Warning: array_key_exists() [function.array-key-exists]: The second
argument should be either an array or an object in
/hybridauth/Hybrid/thirdparty/Facebook/base_facebook.php on line 1328
My guess (probably wrong) to why this may be happening is because the parameters used to pass to Hybridauth come from the browser URL, and I have two - page=register & connected_with=facebook. Hybridauth only requires the second one...
It actually authenticates, but I want rid of this error. Why does this warning occur? Is there a way to hide it?
This is the bit that errors:
/**
* Get the base domain used for the cookie.
*/
protected function getBaseDomain() {
// The base domain is stored in the metadata cookie
// if not we fallback to the current hostname
$metadata = $this->getMetadataCookie();
if (array_key_exists('base_domain', $metadata) &&
!empty($metadata['base_domain'])) {
return trim($metadata['base_domain'], '.');
}
return $this->getHttpHost();
}
It's this code the warning comes from:
/**
* Destroy the current session
*/
public function destroySession() {
$this->accessToken = null;
$this->signedRequest = null;
$this->user = null;
$this->clearAllPersistentData();
// JavaScript sets a cookie that will be used in getSignedRequest
// that we need to clear if we can
$cookie_name = $this->getSignedRequestCookieName();
if (array_key_exists($cookie_name, $_COOKIE)) {
unset($_COOKIE[$cookie_name]);
if (!headers_sent()) {
$base_domain = $this->getBaseDomain();
setcookie($cookie_name, '', 1, '/', '.'.$base_domain);
} else {
// #codeCoverageIgnoreStart
self::errorLog(
'There exists a cookie that we wanted to clear that we couldn\'t '.
'clear because headers was already sent. Make sure to do the first '.
'API call before outputting anything.'
);
// #codeCoverageIgnoreEnd
}
}
}

It looks like getMetadataCookie() does not always return an array, possibly because the cookie has not yet been set. You may want to check that it's actually an array before using it as such;
if (is_array($metadata) && array_key_exists('base_domain', $metadata) &&
For the added code, the same would apply to array_key_exists() in the new code. If you're unsure if it's actually set to an array if the cookie is not set, check first.

Related

Return Image as http-response from Listener Symfony2

This listener sends me reports on all kinds of exceptions that occur on the website. Sometimes I get reports of images that have been deleted but are still consulted by search engines and others.
I want to do, instead of displaying an error message " 404 Not Found " return the correct image. To do this I created a database table that stores the old links and new links of the images that have been deleted, moved or changed its name.
then, this listener find in db the links to fallen and gets the new links of images . The goal is to return the image as http-response with header content-type as image.
My code is:
class ExceptionListener
{
private $service_container;
private $router;
function __construct(Container $service_container, $router){
$this->service_container = $service_container;
$this->router = $router;
}
public function onKernelException(GetResponseForExceptionEvent $event){
$exception = $event->getException();
$request = $this->service_container->get('request');
...
$document_root = $request->server->get('DOCUMENT_ROOT');
$filename = realpath($document_root . '/'. '/path/to/new_image.jpg');
$response = new \Symfony\Component\HttpFoundation\Response();
$response->headers->set('Content-type', 'image/jpeg');
$response->headers->set('Content-Disposition', 'inline; filename="' . basename($filename) . '";');
$response->headers->set('Content-length', filesize($filename));
$response->sendHeaders();
$response->setContent(file_get_contents($filename));
return $response;
...
}
}
The following error occurs:
In the browser you can see a small box , it is as if trying to show the image but the image source could not be obtained . But if the same code is testing on controller , its working properly and the image is displayed .
What can I do to return image from a listener ? thanks
There's few things wrong about the code snippet from your question.
Firstly, you should never use the request service. It's deprecated since Symfony 2.4 and was removed in Symfony 3.0. Use the request stack (request_stack) instead.
Secondly, do not send the response yourself, but let the framework do it. Symfony events system is designed for flexibility (see the docs). In your case it's enough to set the response on the event object.
Finally, you don't need the service container to access the request at all, as it's available on the event.
Moreover, instead of the standard Response class you can use the BinaryFileResponse. It's purpose is to serve files (have a look at the docs).
You can greatly simplify your listener:
use Symfony\Component\HttpFoundation\BinaryFileResponse;
class ExceptionListener
{
private $router;
function __construct($router)
{
$this->router = $router;
}
public function onKernelException(GetResponseForExceptionEvent $event)
{
$exception = $event->getException();
// request is avialable on the event
$request = $event->getRequest();
// ...
$file = 'path/to/file.txt';
$response = new BinaryFileResponse($file);
// ... set response parameters ...
// finally, set the response on your event
$event->setResponse($response);
}
}

How to prevent additional page requests after response sent

I have configured a listener on kernel.request which sets a new response with redirect when the session time has reached a certain value. The listener works fine and redirects to a certain page, on the next request, after the session has ended. But my problem is on the page I have many links and if I press multiple times the same link, the initial request with the redirect is cancelled/stopped and a new request is made with the last link pressed and so it passes my redirect even though the session has ended and is destroyed. So, my question is how to prevent additional requests/link presses after the firs request is made?
Here is my code:
public function onKernelRequestSession(GetResponseEvent $event)
{
$request = $event->getRequest();
$route = $request->get('_route');
$session = $request->getSession();
if ((false === strpos($route, '_wdt')) && ($route != null)) {
$session->start();
$time = time() - $session->getMetadataBag()->getCreated();
if ($route != 'main_route_for_idle_page') {
if (!$session->get("active") && $route == 'main_route_for_site_pages') {
$session->invalidate();
$session->set("active", "1");
} else {
if ($time >= $this->sessionTime) {
$session->clear();
$session->invalidate();
$event->setResponse(new RedirectResponse($this->router->generate('main_route_for_idle_page')));
}
}
} else {
if ($session->get("activ")) {
$session->clear();
$session->invalidate();
}
}
}
}
Thak you.
Idea #1: Simple incremental counter
Each request sends sequence number as param which is being verified as expected at the server.
Server increments the number and sends it back via response
the new number is used in future requests
Basically, if server expects the SEQUENCE number to be 2 and client sends 1 the request is to be rejected.
Idea #2: Unique hash each time
Similar to the idea above, but uses unique hashes to eliminate predictive nature of incremental sequence.
I resolved the issue using JQuery: when a link was pressed I disabled the other ones and so only one request is made from the page:
var isClicked = false;
$(".menu-link").click(function(e) {
if(!isClicked) {
isClicked = true;
} else {
e.preventDefault();
}
});
Thanks.

Codeigniter Flexi Auth library loads sometimes

I am working on the log in system for a site using Flexi Auth in Codeigniter V 2.1.4. I am trying to pass a user's log in status to a menu that changes dynamically depending whether a user is logged in or not. This is the code i am using:
public function create_page($pgName = 'home')
{
$this->config->load('tera_site', TRUE);
$this->load->library('flexi_auth_lite');
// Cunstruct Page data
$data['pgName'] = $pgName;
if ($this->session->userdata('admin') === FALSE){$data['admin'] = 0;}else{$data['admin'] = $this->session->userdata('admin');}
$data['siteTitle'] = $this->config->item('siteTitle','tera_site');
// This is the line the Error is thrown from:
$data['loggedIn'] = $this->flexi_auth_lite->is_logged_in();
$data['header'] = $this->load->view('include/header', $data, TRUE);
$data['pages'] = $this->config->item('pages','tera_site');
$data['footer'] = $this->load->view('include/footer', False, TRUE);
$data['sideBar'] = $this->load->view('include/side_bar_view', $data, TRUE);
$this->load->model('page_model');
$data['pgData'] = $this->page_model->getPage($pgName);
// load the Catcha Library
$this->load->library('captcha_my');
if($data['pgData']['Captcha'] = 1) {
$data['Captcha'] = $this->captcha_my->createCaptcha();
} else if ($this->session->userdata('captchaCheck') == true) {
$data['Captcha'] = $this->captcha_my->createCaptcha();
}
return $data;
This is the error:
Severity: Notice
Message: Undefined property: Main::$flexi_auth_lite
Fatal error: Call to a member function is_logged_in() on a non-object
The code worked at one time, but even when it did it threw the same error when i called the function is_admen() from flexi_auth. Flexi_auth.php and Flexi_auth_lite.php are in application/libraries directory.
if you look into the demo files, there is a controller 'auth_lite.php'
it says
// IMPORTANT! This global must be defined BEFORE the flexi auth library is loaded!
// It is used as a global that is accessible via both models and both libraries, without it, flexi auth will not work.
$this->auth = new stdClass;
// Load 'lite' flexi auth library by default.
// If preferable, functions from this library can be referenced using 'flexi_auth' as done below.
// This prevents needing to reference 'flexi_auth_lite' in some files, and 'flexi_auth' in others, everything can be referenced by 'flexi_auth'.
$this->load->library('flexi_auth_lite', FALSE, 'flexi_auth');

CI Route Issue Not Getting Variable

I'm having an issue with this route and not sure what my problem is exactly.
My page is located at http://www.kansasoutlawwrestling.com/kowmanager/pmsystem/viewmessage/1 where 1 is the message id.
I set up a route to look like
$route['pmsystem/viewmessage/(:num)'] = 'pmsystem/viewmessage/$1';
and I'm still getting a error message like this
A PHP Error was encountered
Severity: Warning
Message: Missing argument 1 for Pmsystem::viewmessage()
Filename: controllers/pmsystem.php
Line Number: 76
// View A Message
function viewmessage($message_id)
{
//Config Defaults Start
$msgBoxMsgs = array();//msgType = dl, info, warn, note, msg
$cssPageAddons = '';//If you have extra CSS for this view append it here
$jsPageAddons = '<script src='.base_url().'../assets/js/cpanel/personalmessages.js></script><script src='.base_url().'assets/js/mylibs/jwysiwyg/jquery.wysiwyg.js></script>';//If you have extra JS for this view append it here
$metaAddons = '';//Sometimes there is a need for additional Meta Data such in the case of Facebook addon's
$siteTitle = '';//alter only if you need something other than the default for this view.
//Config Defaults Start
//examples of how to use the message box system (css not included).
//$msgBoxMsgs[] = array('msgType' => 'dl', 'theMsg' => 'This is a Blank Message Box...');
/**********************************************************Your Coding Logic Here, Start*/
// Checks to see if a session is active for user and shows corresponding view page
if (!$this->loggedin->chkLoginStatus() === FALSE)
{
if( ! $this->uri->segment(3))
{
redirect('error', 'refresh');
}
}
else
{
redirect('login', 'refresh');
}
$bodyContent = 'viewpm';//which view file
$bodyType = "full";//type of template
/***********************************************************Your Coding Logic Here, End*/
//Double checks if any default variables have been changed, Start.
//If msgBoxMsgs array has anything in it, if so displays it in view, else does nothing.
if(count($msgBoxMsgs) !== 0)
{
$msgBoxes = $this->msgboxes->buildMsgBoxesOutput(array('display' => 'show', 'msgs' =>$msgBoxMsgs));
}
else
{
$msgBoxes = array('display' => 'none');
}
if($siteTitle == '')
{
$siteTitle = $this->metatags->SiteTitle(); //reads
}
//Double checks if any default variables have been changed, End.
$this->data['msgBoxes'] = $msgBoxes;
$this->data['cssPageAddons'] = $cssPageAddons;//if there is any additional CSS to add from above Variable this will send it to the view.
$this->data['jsPageAddons'] = $jsPageAddons;//if there is any addictional JS to add from the above variable this will send it to the view.
$this->data['metaAddons'] = $metaAddons;//if there is any addictional meta data to add from the above variable this will send it to the view.
$this->data['pageMetaTags'] = $this->metatags->MetaTags();//defaults can be changed via models/metatags.php
$this->data['siteTitle'] = $siteTitle;//defaults can be changed via models/metatags.php
$this->data['bodyType'] = $bodyType;
$this->data['bodyContent'] = $bodyContent;
$this->data['user_data'] = $this->users->getUserByUserId($this->session->userdata('user_id'));
$this->data['users'] = $this->loggedin->getUserList();
$this->data['personal_messages'] = array($this->pmmodel->getTotalMessages($this->session->userdata('user_id')), $this->pmmodel->getTotalUnreadMessages($this->session->userdata('user_id')), $this->pmmodel->getLast5Messages($this->session->userdata('user_id')));
$this->data['messages'] = array($this->pmmodel->getInboxMessages($this->session->userdata('user_id')), $this->pmmodel->getSentMessages($this->session->userdata('user_id')));
//$this->data['message_data'] = $this->pmmodel->getPmMessage($this->uri->segment(3));
$this->load->view('cpanel/index', $this->data);
}
UPDATE
// Checks to see if a session is active for user and shows corresponding view page
if (!$this->loggedin->chkLoginStatus() === FALSE)
{
if (!is_numeric($this->uri->segment(3)))
{
$this->data['message_data'] = 'Invalid message id!';
}
else
{
$this->data['message_data'] = $this->pmmodel->getPmMessage($this->uri->segment(3));
}
$bodyContent = 'viewpm';//which view file
}
else
{
redirect('login', 'refresh');
}
$bodyType = "full";//type of template
This route is unnecessary - it doesn't change anything.
$route['pmsystem/viewmessage/(:num)'] = 'pmsystem/viewmessage/$1';
You can remove that route. The problem is here:
function viewmessage($message_id) // no default value means it's required
{
// your code
}
Your controller methods literally accept user input as arguments (whatever's in the address bar). You always have to account for those required arguments not being present in CI controller methods.
function viewmessage($message_id = NULL)
{
if ( ! $message_id) show_404();
// your code
}
This will silence the errors and show a 404 if the required $message_id is not there. Additionally, $this->uri->segment(3) is unnecessary because it should have the same value as $message_id.
I highly discourage redirecting to an error page when you really want a 404, but that's up to you. It sure doesn't help the user realize their mistake when the address is lost after the redirect, and you're sending the wrong HTTP headers by doing so.

The session id is too long or contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,'

How to solve :
Warning: session_start() [function.session-start]: The session id is too long or contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,' in ..... on line 3
Warning: session_start() [function.session-start]: Cannot send session cookie - headers already sent by (output started at ......:3) in ..... on line 3
Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at .....:3) in ..... on line 3
It is an information vulnerability: a malicious attacker may alter the cookies and assign illegal characters to PHPSESSID to expose this PHP warning, which in fact contains juicy information like the file path and the username!
There is a bug report for this problem (https://bugs.php.net/bug.php?id=68063)
You can check the success of your session_start and generate the id if needed:
$ok = #session_start();
if(!$ok){
session_regenerate_id(true); // replace the Session ID
session_start();
}
have a look at this session_start() discussion for a work-around:
session_start() generate a warning if PHPSESSID contains illegal characters
Warning: session_start() [function.session-start]: The session id contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,' in /home/para/dev/mon_site/header.php on line 17
To avoid i wrote this :
<?php
function my_session_start()
{
if (ini_get('session.use_cookies') && isset($_COOKIE['PHPSESSID'])) {
$sessid = $_COOKIE['PHPSESSID'];
} elseif (!ini_get('session.use_only_cookies') && isset($_GET['PHPSESSID'])) {
$sessid = $_GET['PHPSESSID'];
} else {
session_start();
return false;
}
if (!preg_match('/^[a-z0-9]{32}$/', $sessid)) {
return false;
}
session_start();
return true;
}
?>
I edited Andron's previous solution! (fix returned value) and added the evaluation output of my_session_start(). Previous solution solve problem with error message, but I need have to session started.
/**
* #return boolean return TRUE if a session was successfully started
*/
function my_session_start()
{
$sn = session_name();
if (isset($_COOKIE[$sn])) {
$sessid = $_COOKIE[$sn];
} else if (isset($_GET[$sn])) {
$sessid = $_GET[$sn];
} else {
return session_start();
}
if (!preg_match('/^[a-zA-Z0-9,\-]{22,40}$/', $sessid)) {
return false;
}
return session_start();
}
if ( !my_session_start() ) {
session_id( uniqid() );
session_start();
session_regenerate_id();
}
I suggest to use "more correct" version of the function.
Several notes:
More correct regular expression (allows characters in the range a-z A-Z 0-9 , (comma) and - (minus)) as described here.
Regular expression depends on the php ini settings, like described here and here.
Use session name method
So updated version looks like this:
<?php
function my_session_start()
{
$sn = session_name();
if (isset($_COOKIE[$sn])) {
$sessid = $_COOKIE[$sn];
} else if (isset($_GET[$sn])) {
$sessid = $_GET[$sn];
} else {
session_start();
return false;
}
if (!preg_match('/^[a-zA-Z0-9,\-]{22,40}$/', $sessid)) {
return false;
}
session_start();
return true;
}
?>
If you don't care about other users (for example: if it's a private interface), just check you browser, find the cookie PHPSESSID (or the name you gave it), delete it, and refresh.
I came with up this simple method, just try and catch the session start, and if there is a problem regenerate the session.
try {
session_start();
} catch(ErrorExpression $e) {
session_regenerate_id();
session_start();
}

Resources