I'm using a script, written in PHP and Jquery, that allows to scrape a static website:
<?php
if(isset($_GET['site'])){
$f = fopen($_GET['site'], 'r');
$html = '';
while (!feof($f)) {
$html .= fread($f, 24000);
}
fclose($f);
echo $html;
}
?>
The Jquery part:
$(function(){
var site = $(input).val();
$.get('proxy.php', { site:site }, function(data){
$('#myDiv').append(data);
}, 'html');
});
As you can see the website that needs to be scraped has to be value in input. I want to give my visitors the ability to set there own website to be scraped.
The problem is that I cant figure out how to secure the PHP part. As I understand the input value is a big security risk because anything can be sent with value. I already experienced slow performance and several 'pc crashes' working with this code. Im not sure if the crashes are related but they only happen when I work on the code.
Anyway I would really like to know how to validate the value(from input) sent to my server, only REAL urls should be aloud. I googled for days but I cant figure it out (new at PHP)
ps If you spot any other security risks please let me know..
I think your main security issue, is that you're using fopen to read the content of the url, if the user wants to read a file in your system, then he has to send the path to that file and if the script has enough permissions, then they'll be able to access the content of your hard drive.
I would recommend using other methods like Curl or at least, validating the user input to make sure that it's a valid url, for this, I would check out some regular expressions
Good luck with your code!
Edit on validation
Here is a little example of what I meant by validation.
<?php
if(isset($_GET['site'])){
if(validURL($_GET['site']) {
$f = fopen($_GET['site'], 'r');
$html = '';
while (!feof($f)) {
$html .= fread($f, 24000);
}
fclose($f);
echo $html;
} else {
echo "Invalid URL, please enter a valid web url (i.e: http://www.google.com)";
}
}
function validURL($url){
//here goes your validation code, returns true if the url is valid
}
?>
But if you're too new to understand this, I would suggest going for simpler examples, since this is pretty basic logic.
Its so sad that you could not find anything on the internet about this topic. Its a common thing. Please refer the links below. It may be of help.
PHP validate input alphanumeric plus a few symbols
http://phpmaster.com/input-validation-using-filter-functions/
Related
Just wondering if anyone can point me in the right track to imitating the following Codeigniter method with pure PHP:
$string = $this->load->view('myfile', $data, true); // where $data is an array of info to "fill in" the html on the page
I've started with trying to use fopen, but i can't quite seem to figure out the part of sending data to the file before making it the string variable that i want to eventually send to the "master template".
At current, I'm stumped. I've been looking over their _ci_load method which feeds the above code, but it dives into more CI libs and the whole point of this is to make the "easiest pur php" way. If anyone has any advice, tips, tutorial links, anything I can't already find with Google
When I need something to quickly return part of a template, I use this.
function view($file,$data) {
extract($data);
ob_start();
if (is_file($file)) {
include($file);
}
$return = ob_get_clean();
return $return;
}
You should make sure to secure the contents of $file. Otherwise, anyone can load any file they want and inject it with the data they want. I normally use this only when I'm defining $file by hand, nothing dynamic.
I would recommend you look into using the ob_start(), ob_get_contents(), and ob_end_clean() functions.
This should be very easy, yet it's not working. I would appreciate if someone could point me in the right direction because I kind of hate adobe documentation, and on adobe community forums I guess I hardly will get a straight answer. Anyway, the thing is I've created a fillable form in Acrobat X, and added a button with a submit form action, with the url pointing to my php script. When I view the form in any browser, and submit it, I can see it gets submitted because the network part of the developer tools shows the POST request and everything, with a response code of 200 OK. Yet all I can get from the $_POST superglobal is a notice telling me the indexes I point to do not exist. I've checked thoroughly and those indexes are really the names of my fields on the pdf form. Also, oddly the form is not replaced by the script in the browser, but it stays in the same url. It's driving me crazy because from what I've read everywhere on Google it's supposed to be the way to do it.
my script goes like this (as if it was interesting):
$apes = $_POST['Apellido_Nom'];
$dir = $_POST['Direccion'];
$fp = fopen('formulario.txt', 'w+');
fwrite($fp, 'Nombre, '.$apes.'Dirección, '.$dir);
while(!feof($fp)) {
$buffer=fgets($fp, 4096);
echo $buffer;
}
fclose($fp);
Please don't mind the manners of this question, it's just I've had a really rough day. Oh and by the way I also set the export format of the pdf form as html.
Does anyone know of any tutorials which take you though a step by step process on making a filesharing script I found lots of how to make file uploaders but none of them return a link for other people to download the stuff uploaded.
be great if someone could hit me back with some sort of tutorial for this
thank
Literally all you need is a hyperlink
<?php
//where
$url = "http://www.theurlineed.com";
$myuploadfolder = "/var/www/html/mydir/uploaddir";
if (is_dir($myuploadfolder)) foreach (scandir($myuploadfolder) as $file){
if ($file!="." || $file!=".."){
echo "<p>".$file."</p>\n";
}
}
?>
Almost certainly the issue is actually understanding for yourself the $url and the $myuploadfolder bit at the top. i.e. how to get from "serverland" to "url-land" and no-one can do that for you you have to suck it and see what works.
To start, please pardon my ignorance, I'm not a programmer but rather a student research assistant who happens to need to write some programs.
Right now I'm working on a page that will take user input (eventually will be guesses in a guessing game) and store it in a csv file. The tech guy here warned me about the danger of sql injection and cross site scripting, so I googled them as well as strategies for protection. But it looks like there are MANY strategies, and I'm having a hard time understanding which ones I need to use. For instance, do I even need to be worried about sql injection if I'm not using sql? Am I using sql and I just don't know it? Would it be sufficient to strip all non-alphabet characters from the input using javascript (I really don't need them)?
Can someone please tell me: Which protection strategies do I need to use, given what I'm trying to do?
If it helps, here is my code so far. I'm trying to use Ajax, so I have the following components:
A. HTML: presents text box and buttons to write the input into the csv file (one to write to the same line, one to write to a new line).
<input id="input" type="text"><br>
<input type="button" onClick="javascript:writeToFile(0, document.getElementById('input').value)" value="write on same line"><br>
<input type="button" onClick="javascript:writeToFile(1,document.getElementById('input').value)" value="write on new line"><br>
B. Javascript: Creates an XMLHttpRequest object, opens it with post and specifies the php script, and sends it along with a the user inputted string (I didn't include a callback function here because I'm not changing the html page in response, but if I need one let me know).
function createRequestObject()
{
var ro;
var browser = navigator.appName;
if(browser == "Microsoft Internet Explorer")
{
ro = new ActiveXObject("Microsoft.XMLHTTP");
}
else
{
ro = new XMLHttpRequest();
}
return ro;
}
function writeToFile(newline, content)
{
var ajaxRO = createRequestObject();
content+=", "
var params="newline=" + newline + "&content=" + content
ajaxRO.open("POST", "writer2.php", true);
ajaxRO.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
ajaxRO.send(params);
}
C. PHP: Retrieves the variables from Post (the first tells it if a new line is needed, the second tells it what to write)
<?php
$myFile = "results.csv";
$fh = fopen($myFile, 'a') or die("can't open file");
$toWrite = $_POST['content'];
$newLine = $_POST['newline'];
if($newLine==1)
{
fwrite($fh, "\n");
fwrite($fh, $toWrite);
fclose($fh);
}
else
{
fwrite($fh, $toWrite);
fclose($fh);
}
?>
Thanks so much for any information you can provide!
I'm not sure why you posted HTML/JavaScript thats not really where the problems are. XSS and SQL Injection are a server side problem and you should post PHP code if you need help.(Putting DOM Based XSS aside because its so uncommon).
For SQL Injection you should always use parametrized quires. PDO and ADOB are both good libraries for this.
Cross-Site Scripting defense is a lot more complex. You can't just throw htmlspeicalchars($var,ENT_QUOTES) at every variable you print out and expect to be safe. This is a good practice but should also make sure to TEST EVERYTHING. I suggest using a free service like Sitewatch which will test for xss, sql injection and a lot more. Or you could use Acunetix's free xss scanner.
In terms of the CSV file, thats just slow and cumbersome. You should be using a database for this. If you need to serve the csv file you can select out what you need and print it with PHP.
Validating your input in the server is what you should be doing. Since you're writing to a CSV file, your PHP code should look for commas and new-lines and maybe replace them with spaces or issue an error message back to the user. Also, think about the maximum length that you can accept as input.
After collecting the input, if you display the collected data as output in a page, you should HTML encode it.
This is just the tip of the iceberg, though. Security is never a solved problem, you're just raising the bar for potential attackers.
Your code isn't vulnerable to Cross Site Scripting, and you aren't using SQL, only plain text.
But, watch out for another vulnerability called Cross Site Request Forgery. You must add a token value in the form:
$_SESSION['token'] = md5(rand());
if($_SESSION['token'] != $_POST['token']){
echo 'Invalid Request!';
}
else{
//valid request!
}
Im trying to find a php/js script that will let me take an image, and when clicked, increase the number in a flat file, and save that file.
I know how to include the file to get the vote total.
Im going insane trying to find this to plug and play into my website. Id love to have ip logging, and a cool fade in/out refresh update thing. But at this point ill settle for basics.
Id like to avoid using MySQL, but if its necessary i can work with it.
Your best bet is to use the AJAX support in jQuery to access, but not load to the user, some kind of URL that writes the increment to the file. If you're using any kind of a thorough platform, you should consider doing in the with your database. However, it'd be simple enough to use jQuery's $.get() function to access the URL /increment_number.php?image=whatever.jpg. If you ever start using a database, you'd just have to change this script to perform a DB query. For your case, you'd have a simple script like this (which has been in no way optimized or has any security considerations whatsoever):
$image = $_GET['image'];
$number = file_get_contents('tracker_for_{$image}.txt');
if ($number != ''){
$number = (int) $number + 1
}
$file = fopen('tracker_for_{$image}.txt', 'w');
fwrite($file, $number);
fclose($file);
And just remember to have the following bit of JS on the page with the image:
$(document).ready(function(){
$('img.incrementme').click(function(){
$.get('/increment.php?'+$(this).attr('src'));
});
);
I haven't tested this code so it might not work, but it's in the spirit of what you'd have to do.
Something simple like this won't work?
<?php
// Link to this file: <a href='onclick.php'><img src='yourimg'></a>
$count = file_get_contents("count.file");
$count += 1;
file_put_contents("count.file", $count);
// Possibly log an IP too? open a file
$f = fopen("ipaddresses.file", "a");
fwrite($f, $_SERVER["REMOTE_ADDR"] . "\n");
fclose($f);
?>
If you are doing this for a voting system like Stack Overflow, creating lots of files to store this one bit of information is going to become unwieldy. This is perfect for a database.
That way, you also wouldn't include the file, but perform a query to get the total score.