Codeigniter : Protect folder from direct access - php

Hello guys I have a small project connected with a database.I own a function for
uploading files into a folder and also save files path to the database.
In my index page I read files path from database and output a table with links to these files for downloading.
Everything works fine and files are able to be downloaded unless,
the problem is that I forgot to secure this folder and yesterday realized that I should protect it somehow because people can download files directly with links
and I need to check if user is logged to be able to download it.
So my question is:
How to protect the folder with these files from direct access and make only logged users
to be able to download files from this folder
My upload path is ./uploads/ inside this folder I had htaccess file
order deny,allow
deny from all
In controller I have
public function viewAllPersons()
{
if($this->ion_auth->logged_in())
{
if(!$this->ion_auth->in_group(1)){
show_404();
}
else {
$data = array();
$data['persons'] = $this->get_persons(); // get all persons from database as array
$this->load->view('admin/header_view');
$this->load->view('admin/persons_view',$data); // pass data to the view
$this->load->view('admin/footer_view');
}
} else {
redirect(base_url());
}
}
My view file contains this
{
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<h1 class="page-header"><span class="glyphicon glyphicon-th-list"></span> Archive</h1>
<h2 class="sub-header pull-left">All records db</h2>
<span class="glyphicon glyphicon-plus-sign"></span> Add new record
<form class="navbar-form navbar-right" method="post" action="<?=site_url('dashboard/persons');?>" name="searchform" >
<div class="form-group">
<input type="text" id="search" name="search" class="form-control" placeholder="" autocomplete="off">
</div>
<button type="submit" class="btn btn-default"><span class="glyphicon glyphicon-search"></span></button>
</form>
<div class="clearfix"></div>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>Firstname</th>
<th>Middlename</th>
<th>Lastname</th>
<th>ID</th>
<th>Filename</th>
<th>Data</th>
<th>Options</th>
</tr>
</thead>
<tbody>
<?php
$counter = 1;
foreach($persons as $person) { ?>
<tr>
<td><?=$person['person_id'];?></td>
<td><?=$person['first_name'];?></a></td>
<td><?=$person['middle_name'];?></td>
<td><?=$person['last_name'];?></td>
<td><?=$person['personal_number'];?></td>
<td><?=$person['document_path'];?></td> <!-- show links to files for each row !-->
<td><?=$person['created_on'];?></td>
<td>
<a href="<?=base_url('/dashboard/persons/edit/'.$person['person_id'])?>">
<span class="glyphicon glyphicon-pencil edit-icon"></span>
</a>
</td>
</tr>
<?php $counter++; } ?>
</tbody>
</table>
<div class="row">
<?php if(isset($links)) {
echo $links;
}?>
</div>
</div>
</div>
<?php } ?> }
Here is my problem when I output links to files I need to check if user is logged before to be able to download files using the links saved in database
Example of project -- picture
Because people can download files with direct link
Example
http://website.com/uploads/document.docx
Once I have htaccess file I`m unable to download a file need maybe a function to rewrite rules or
to give access to logged users somehow
I also tried a download helper from codeigniter but download files only if I remove the htaccess rules If rules exist inside htaccess file download helper is unable to download the file.
Thanks in Advance!

You have a few possibilities, the simplest one would be to have control of the access of these folders with a Controller.
You need a file table with minimum : id, path.
Let's say user A wants file ABC.jpg (with the id of 1337) : Instead of serving him http://example.com/uploads/ABC.jpg, you give him http://example.com/files?id=1337.
This route calls the index of controller Files and in the index you can do this pseudo-code :
function index() {
//Check if logged in
if (!$user->logged()) {
redirect('/404');
}
//Get file from database
$file = $this->db->query('SELECT * FROM file WHERE id='.$this->input->get("id"))->result();
//Then serve the file
header("Content-type: image/jpeg");
readfile($file->path);
}
EDIT :
I will try to explain it in other terms :
Create a table of uploaded files called file. Something like
CREATE TABLE file (id INT NOT NULL AUTO_INCREMENT, path VARCHAR(100) NOT NULL, PRIMARY KEY ( id ))
Update your person table so that it doesn't have the document_path but file_id instead. And when you upload a file, you save it's path in the table file then assign the file id to the person (in table person of course).
Instead of <?php echo base_url('/uploads/'.$person["document_path"]);?>, you need to do <?php echo base_url('/file?id='.$pseron['file_id']);?>
This is because we want the user to go to a specific controller that you need to create File.php (the controller).
In this controller, the function index (the default function of the controller File) must do something like I showed you before the edit. It means you retrieve from the database the file path based from the file id, then you serve the file. This is called PHP serving instead of Apache (default) serving of files.

I was facing the same problem because my files were directly accessed by the users. especially uploads files and images. I was working on a PHP framework.
I simply added one line of code in the .htaccess file. and it was done.
If you don't have one in your WEBSITE FOLDER then create a .txt file and name it as .htaccess (if you are not using any framework).
then open the .htccess file and simply write: Options -Indexes
NOTE: DON'T PUT .htaccess file in any folder just simply open your website folder in htdocs and create .htaccess

Related

What is the correct way to reference image files from a header file that is referenced by multiple .html/.php files in different sub directories?

I have my header file for my website and a bunch of images that are inside the header that I want to link to various pages within the website.
I'm currently referencing the images from within the header file like this:
<header>
<div id="menu">
<div class="table">
<ul id="horizontal-list">
<li> <img src="../home page/home.png" alt="Home Page" width=150 /></li>
<li> <img src="../dashboard page/dashboard.png" alt="User Dashboard" width=150 style="padding-left: 35px;" /></li>
</ul>
</div>
</header>
The problem with this approach, since those file paths are relative, they don't work if I reference the header file from a sub directory that upon traversing those relative file paths, it's unable to find the files located.
Since I have my web pages all inside different directories, using this approach means that while the files in one directory will be able to find the images for the header file perfectly ok, the web pages inside another directory aren't able to find the images.
I tried changing my relative file paths to absolute file paths like so:
change
"../home page/home.php"
"../home page/home.png"
to
"C:/xampp/htdocs/login/website php version/home page/home.php"
"C:/xampp/htdocs/login/website php version/home page/home.png"
but this didn't work either

Creating Module for Admin and Clients with Perfex CRM - Assistance Required

I am working on creating a module for prefex CRM. What this module will be doing is pretty simple, but is quickly turning into more than I anticipated. Allow me to explain what I'm doing and where I'm stuck. I am hoping someone can offer some advice.
Admin View
Admin Module that adds menu item 'Mail' to the side nav bar
When clicking this menu item, a page loads that uses the already uses the drag & drop file upload feature prefex CRM has built in.
When a staff member uploads a file, a modal launches with a form that asks users who the upload should be assigned to. It should use autocomplete to select the customer to attach the file to.
The upload date/time is recorded in database and the record entry in the DB is given a GUID
Client View
Client module that adds menu item 'Mail' to the client navbar
When clicking this menu item, a page loads that displays a table. This table shows all of the entries of file uploads from the admin view. The table should have an image of the scanned mail, the day/time received, and another column that will be blank for now.
So that's what I'm trying to accomplish. In an effort to understand structure of Prefex CRM modules better, I deconstructed the Prefex CRM Employee Chat module. It's hard to compare apples to oranges in this case, but it did help me to develop a file structure which is as follows:
-assets
--css
--js
--module_includes
-controllers
--admin_controller
--client_controller
-models
-uploads
-views
--admin_view
--client_view
mail.php
index.php
install.php
Now that you have an understanding of what I'm doing this is where I need assistance-
Where I'm stuck: I'm looking to recycle the file upload feature that is already built inside of Prefex CRM. Where the file is stored normally is fine and does not need to be changed. I'm unsure of how to reuse these built in functions to create the Mail_ClientsController.php and Mail_Controller.php, as well as some uncertaintly on the mail_admin_view.php, and mail_clients_view.php
Could anyone share some examples of some working modules for Perfex that could shed some light on how to connect these?
mail.php page
<?php
/**
* Ensures that the module init file can't be accessed directly, only within the application.
*/
defined('BASEPATH') or exit('No direct script access allowed');
/*
Module Name: Mail
Description: Client online mailbox module for Perfex CRM system
Version: 2.3.0
Requires at least: 2.3.*
*/
define('BSSI_MAIL_MODULE_NAME', 'bssi_mail');
define('BSSI_MAIL_MODULE_UPLOAD_FOLDER', module_dir_path(BSSI_MAIL_MODULE_NAME, 'uploads'));
$CI = &get_instance();
/**
* Register the activation
*/
register_activation_hook(BSSI_MAIL_MODULE_NAME, 'bssi_mail_activation_hook');
/**
* The activation function
*/
function bssi_mail_activation_hook()
{
require(__DIR__ . '/install.php');
}
/**
* Register new menu item in admin sidebar menu
*/
if (staff_can('view', BSSI_MAIL_MODULE_NAME)) {
if (get_option('bssi_staff_can_delete_messages') == '1') {
$CI->app_menu->add_sidebar_menu_item('bssi_mail', [
'name' => 'BSSI Mail',
'href' => admin_url('bssi_mail/mail_admin_view'),
'icon' => 'fa fa-envelope',
'position' => 6,
]);
}
}
Mail_ClientsController.php (unsure of which functions to put here for upload feature)
<?php defined('BASEPATH') or exit('No direct script access allowed');
class Prchat_ClientsController extends ClientsController
{
}
Mail_Clients_View.php
<?php defined('BASEPATH') or exit('No direct script access allowed'); ?>
<div class="bssiClient">
<div class="container">
<div class="row">
<div class="col">
<table class="bssiMailTable">
<thead>
<th>Mail Image</th>
<th>Date Received</th>
<th>Actions</th>
</thead>
<tr>
<td>Image Query</td>
<td>Get Date Query</td>
<td>Action Items</td>
</tr>
</table>
</div>
</div>
</div>
</div>
Mail_admin_view.php
<?php defined('BASEPATH') or exit('No direct script access allowed'); ?>
<div class="bssiAdmin">
<div class="container">
<div class="row">
<div class="col">
<table class="bssiAdminMailTable">
<thead>
<th>Mail Image</th>
<th>Date Received</th>
<th>Actions</th>
</thead>
<tr>
<td>Image Query</td>
<td>Get Date Query</td>
<td>Action Items</td>
</tr>
</table>
</div>
</div>
</div>
</div>
So in your controller/model you would need to load in the standard email model within your construct method. Perfex has a standard model it uses for distributing emails (can be seen under root > application > models > Emails_model.php)
$this->load->model('emails_model');
or if it's being called from outside of the admin controller (e.g. via a cron)
$this->ci->load->model('emails_model');
Within the standard Emails_model.php there is a function "send_simple_email()" which will allow you to send an email to any email address directly from Perfex
E.G.
$email = 'your_email#email.com';
$subject = 'Email Subject';
$message = 'Your Message';
$this->ci->emails_model->send_simple_email($email, $subject, $message);
For file upload, you should be looking at the standard file upload procedure within Perfex (take a look inside upload_helper.php, and you'll find a number of functions which will help you get a file uploaded.

Passing segment data from view to controller and then to a new view

Hi i am using Codeigniter(i am fairly new) and i have a problem displaying data(actually a path from the database) to View B but lets take it from the beggining. I am making a cinema web page and I want a user to click on a link and then get the appropriate redirect to another link which will display the movie that clicked. I am getting the movie name from the database and manage to send it to the Controller B as a parameter and get the image path that i want to display in order to show the picture. But the web page does not show the picture although the path is already sent(i have checked it on Firefox fire bug and to a blank page just to make sure the the path is sent) Btw when i load the page the method and parameter appears on the url but when i delete the parameter and the method from the url and hit enter the path works perfectly displaying the image. Any help?
ps I am a rookie
This is from view a
<div class="movie__images">
<a href="<?php echo base_url()?>movie_page_full/get_user_click_info/<?php echo $movie_data[6]->title ?>" class="movie-beta__link">
<img alt='' src=<?php echo $now1 ?>>
</a>
</div>
This is from controller b
public function get_user_click_info(){
$this->load->model('movie_page_full_model');
$decoded_movie_name = $this->uri->segment(3);
$query_data = $this->movie_page_full_model->get_single_movie_data($decoded_movie_name);
$data['path'] = $query_data[0]->path;
$this->load->view('templates/header');
$this->load->view('Home/view_movie_page_full',$data);
$this->load->view('templates/footer_movie_page_full');
}
This is from the view b where i send the path from the controller b
<div class="col-sm-4 col-md-3 movie-mobile">
<div class="movie__images">
<img alt="" src=<?php echo $path ?>>
</div>
</div>
A proof that the path is send to the HTML code but does not show it
The url (Gravity is the name of the movie)
I found the answer to my question. I discovered that when i was changing controllers and loading the image, the path was displaying properly but actually it was missing the full url as i was leaving from the homepage that i set as the base url so the only thing that i had to do, was to use the variable that contains the path inside the codeigniter base url. Base url actually appends the rest of missing part. Below is the correct code block.
<div class="col-sm-4 col-md-3 movie-mobile">
<div class="movie__images">
<img alt="" src=<?php echo base_url($path)?>>
</div>
</div>

Wordpress logo image in header.php

I'm trying to create a custom theme in Wordpress, and currently I'm working on my header.php file. However, I'm unable to display my logo image. Here's the code for the same:
<body>
<div class = "container">
<div class = "five columns">
<img src = "<?php bloginfo('template_url'); ?>/img/sem.jpg" title = "<?php bloginfo('title'); ?>">
</div>
</div>
</body>
The sem.jpg image is stored inside the img folder inside my root project directory. However, the logo doesn't seem to be displayed on my webpage. I have also tried using images of other formats, but none of them seems to work. I have also called the get_header() function inside my index.php.
What seems to be wrong in my code?
The reason seems a permissions problem.
You can set permission 777 to the logo image via command line, typyng:
chmod 777 /path_to_your_file
or set using right click on the logo file, and change properties.
You can't view your image because you have got set wrong permissions on your image. Open your FTP client, connect to your site and find your image, right click it and chosse Change file permissions and change them to 644.
File permissions should look like this:
http://s12.postimg.org/rxb25ziy5/Untitled.png
Try This.
<body <?php body_class(); ?>>
<div class = "container">
<div class = "five columns">
<img src="<?php echo get_template_directory_uri(); ?>/img/sem.jpg" alt="<?php bloginfo('title'); ?" />
</div>
</div>
</body>
Enjoy..!!
user this wordpress plugin
it will help yo upload logo using wordpress admin and you can change any time with edit header.php file.
Use below function to print logo
echo theme_logo();

Tooltip not functioning when routed to a new url path

I have template php files for dates and sharing. 1 file is like this:
date-share.php:
<div class="date"><?php echo date('M d'); ?><span><?php echo date('Y'); ?></span></div>
<span class="plus"></span>Share
<!-- Tooltip -->
<div class="tooltip-social-network clearfix" style="margin-top: -10px">
<span class='st_facebook_large' displayText='Facebook'></span>
<span class='st_twitter_large' displayText='Tweet'></span>
<span class='st_googleplus_large' displayText='Google +'></span>
<span class='st_pinterest_large' displayText='Pinterest'></span>
<span class='st_instagram_large' displayText='Instagram Badge' st_username='mews'></span>
<span class='st_email_large' displayText='Email'></span>
</div>
I php include it to one of my views to avoid too much clutter, instead of putting it there.
<?php include('templates/date-share.php')?>
This is how it would look like in the view when the SHARE button is clicked.
The social media icons group is just a tooltip.
However, I rerouted the view to a new url path. So I added a PHP echo base_url to all the links to maintain the root path. But I'm not sure how to apply with the php include, so I didn't add any. It still appeared but the share button can't show the tooltip anymore.
Edit: added pic for clicked SHARE without the tooltip - rerouted to a different url path
You can use view method inside view to load other view/partials.
Make sure your date-share.php under following path `application/views/template/date-share.php'
Now inside your main view load your date-share.php as below.
$this->load->view('template/date-share.php');

Categories