I'm using $_SERVER['HTTP_REFERER'] to generate a dynamic back link.
<a href="<?php echo $_SERVER['HTTP_REFERER'] ?>">Return to..blah</a>
Is it reasonably safe to do so?
I'm using $_SERVER['HTTP_REFERER'] to generate a dynamic back link.
<a href="<?php echo $_SERVER['HTTP_REFERER'] ?>">Return to..blah</a>
Is it reasonably safe to do so?
I applaud your efforts. You must, friendly community member, consider decoupling your operations.
1) Have one function/routine/class/method for filtering input (filter_input_array()
, strip_tags()
, str_ireplace()
, trim()
, etc ...). You may want to create functions that use loops to do filtering. Tricks such as double encoding, one-time-strip-spoofing, and more can defeat single usage of things like strip_tags()
.
Here is a strip_tags()
wrapper method from my Sanitizer
class.
Notice how it compares the old value to the new value to see if they are equal. If they are not equal, it keeps on using strip_tags()
. Although, there is quite of bit of preliminary INPUT_POST / $_POST checking done before this method is executed. Another version of this using trim()
is actually executed before this one.
private function removeHtml(&$value)
{
if (is_scalar($value)) {
do {
$old = $value;
$value = strip_tags($value);
if ($value === $old) {
break;
}
} while(1);
} else if (is_array($value) && !empty($value)) {
foreach ($value as $field => &$string) {
do {
$old = $string;
$string = strip_tags($string);
if ($string === $old) {
break;
}
} while (1);
}
} else {
throw new Exception('The data being HTML sanitized is neither scalar nor in an array.');
}
return;
}
2) Have another one for validating input (filter_var_array()
, preg_match()
, mb_strlen
, etc...)
Then, when your data needs to switch contexts ...
A) For databases, use prepared statements (PDO
, preferably).
B) For returning / transmitting user input to the browser, escape the output with htmlentities()
or htmlspecialchars
accordingly.
In terms of magic quotes, the best thing to do is just disable that in the php.ini
.
Now, with those various constructs having their own areas of responsibility, all you have to do is manage the flow of logic and data inside of your handler file. This includes providing error messages to the user (when necessary) and handling errors/exceptions.
There is no need to use htmlentities()
or htmlspecialchars
immediately if the data is going from the HTML form directly into the database. The point of escaping data is to prevent it from being interpreted as executable instructions inside a new context. There is no danger htmlentities()
or htmlspecialchars
can resolve when passing data to a SQL query engine (that is why you filter and validate the input, and use (PDO
) prepared statements).
However, after the data is retrieved from database tables and is directly destined for the browser, ok, now use htmlentities()
or htmlspecialchars
. Create a function
that uses a for
or foreach
loop to handle that scenario.
Here is a snippet from my Escaper
class
public function superHtmlSpecialChars($html)
{
return htmlspecialchars($html, ENT_QUOTES | ENT_HTML5, 'UTF-8', false);
}
public function superHtmlEntities(&$html)
{
$html = htmlentities($html, ENT_QUOTES | ENT_HTML5, 'UTF-8', false);
}
public function htmlSpecialCharsArray(array &$html)
{
foreach ($html as &$value) {
$value = $this->superHtmlSpecialChars($value);
}
unset($value);
}
public function htmlEntitiesArray(array &$html)
{
foreach ($html as &$value) {
$this->superHtmlEntities($value);
}
unset($value);
}
You'll have to tailor your code to your own personal tastes and situation.
Note, if you plan on processing the data before sending it to the browser, do the processing first, then escape with your handy-dandy htmlentities()
or htmlspecialchars
looping function.
You can do it!
Yes. This is the example for problems with only having implicit user-defined conversions and explicit user-defined conversion operators were practically invented because of this problem and to replace all the safe-bool stuff with something a lot cleaner and more logical.
If all you care about is exception-safety of this operation:
v.reserve(v.size()+1); // reserve can throw, but that doesn't matter
v.push_back(new Foo); // new can throw, that doesn't matter either.
The issue of a vector having responsibility for freeing the objects pointed to by its contents is a separate thing, I'm sure you'll get plenty of advice about that ;-)
Edit: hmm, I was going to quote the standard, but I actually can't find the necessary guarantee. What I'm looking for is that push_back
will not throw unless either (a) it has to reallocate (which we know it won't because of the capacity), or (b) a constructor of T throws (which we know it won't since T is a pointer type). Sounds reasonable, but reasonable != guaranteed.
So, unless there's a beneficial answer over on this question:
Is std::vector::push_back permitted to throw for any reason other than failed reallocation or construction?
this code depends on the implementation not doing anything too "imaginative". Failing that, your solution from the question can be templated up:
template <typename T, typename Container>
void push_back_new(Container &c) {
auto_ptr<T> p(new T);
c.push_back(p.get());
p.release();
}
Usage then isn't too tedious:
struct Bar : Foo { };
vector<Foo*> v;
push_back_new<Foo>(v);
push_back_new<Bar>(v);
If it's really a factory function rather than new
then you could modify the template accordingly. Passing a lot of different parameter lists in different situations would be difficult, though.
If you are talking about someone else's server, then the short answer is no. If third parties could read your PHP source code, that would be quite a security hole, since PHP files tend to contain database passwords, hash keys, proprietary algorithms and other goodies that you don't want falling in the wrong hands.
If you are talking about your own server (ie. that you yourself have access to), then there are simple scripts that you can put on the server, that allow you to specify a path to any file on the server and have it returned as plaintext. However, you NEVER EVER want to place such a script on a production server, for the reasons mentioned above.
Not like that.
It might not be present. (It might be wrong, some personal firewall packages obfuscate the referer for privacy reasons, violating the HTTP spec along the way)
You should run anything coming from outside your system through
htmlspecialchars
to guard against XSS attacks (although, IIRC, the referer should never have any dangerous characters in it as they should be URL safe you should keep in the habit of always being cautious).Browsers come with back buttons though, there is no need to try to duplicate their functionality (especially when, with this, if the user clicks a link marked "back" it doesn't take them back in their history, so clicking the normal back button will conceptually take them forwards).