GET Params - & and ? in one character? - php

So just a quick thought and I understand that there are millions of ways around this 'problem' but I was wondering if there is a character or format for both initiating and separating GET parameters. Let me explain:
I am redirecting the user to a link defined as a variable but adding on a parameter at the end like so:
Header("Location: ".$link."&err=1");
The problem is, some of these links ($link) will contain GET params and some will not. If the link does not already contain GET parameters, '&' will not work as an initiator.
Header("Location: page&err=1");
And if the link does already contain parameters, '?' will not work as a separating character.
Header("Location: page?val=123?err=1");
So again, I know there are many ways around this and I'm not lookign for someone to code a simple check for me but I'm curious about the link formatting aspect and I can't find anything through my own research. I'm honestly expecting that the answer is 'not possible' but I'm intrigued enough to ask now, thanks.

No.
? starts the query string.
& and ; separate key=value pairs in application/x-www-form-urlencoded data which is the format most back ends expect. (; hasn't got as good a level of support).

Will parse_url() not work?
Specifically parse_url($url, PHP_URL_QUERY);
http_build_query() could also be useful

Related

PHP - evaluating param

I have following code:
<?php
$param = $_GET['param'];
echo $param;
?>
when I use it like:
mysite.com/test.php?param=2+2
or
mysite.com/test.php?param="2+2"
it prints
2 2
not
4
I tried also eval - neither worked
+ is encoded as a space in query strings. To have an actual addition sign in your string, you should use %2B.
However, it should be noted this will not perform the actual addition. I do not believe it is possible to perform actual addition inside the query string.
Now. I would like to stress to avoid using eval as if it's your answer, you're asking the wrong question. It's a very dangerous piece of work. It can create more problems than it's worth, as per the manual specifications on this function:
The eval() language construct is very dangerous because it allows
execution of arbitrary PHP code. Its use thus is discouraged. If you
have carefully verified that there is no other option than to use this
construct, pay special attention not to pass any user provided data
into it without properly validating it beforehand.
So, everything that you wish to pass into eval should be screened against a very.. Very strict criteria, stripping out other function calls and other possible malicious calls & ensure that 100% that what you are passing into eval is exactly as you need it. No more, no less.
A very basic scenario for your problem would be:
if (!isset($_GET['Param'])){
$Append = urlencode("2+2");
header("Location: index.php?Param=".$Append);
}
$Code_To_Eval = '$Result = '.$_GET['Param'].';';
eval($Code_To_Eval);
echo $Result;
The first lines 1 through to 4 are only showing how to correctly pass a character such a plus symbol, the other lines of code are working with the data string. & as #andreiP stated:
Unless I'm not mistaking the "+" is used for URL encoding, so it would
be translated to a %, which further translates to a white space.
That's why you're getting 2 2
This is correct. It explains why you are getting your current output & please note using:
echo urldecode($_GET['Param']);
after encoding it will bring you back to your original output to which you want to avoid.
I would highly suggest looking into an alternative before using what i've posted

Security - Die or replace on invalid value for include

I would like to know which of the following solutions is more secure.
if(!ctype_alpha($_GET['a'])){
//another string can be put here if necessary
die('No Hacking!');
}
or
if(!ctype_alpha($_GET['a'])){
//Changed for security in depth, in-case I accidently use $_GET['a'] elsewhere. Designed to simulate header('Location: ./?a=default_value');
$_GET['a'] = 'default_value';
}
something similar to the following happens later in the script:
//make_safe is defined elsewhere, it is security in depth (redundancy) to remove slashes if they get past ctype_alpha using some unknown bug
$var = make_safe($_GET['a']);
require_once("./data/include/$var.php");
In a book I am currently reading, it says that it is best to stop all input not following my rules, instead of correcting. Therefore, my question boils down to does replacing the $_GET['a'] with a default parameter count as stopping the input, or must die() be used?
Die('fu') is a dirty thing.
I prefer your way of sanitizing inputs with default values if needed.
By the way, that's what does major companies (check at google, search something, go to page 2, now change start parameter in the url to something not numeric, you'll be back to page 1).
Plus, when hacking stuff, you'll try to have the application acting in a singular way.
If yours acts always the same, it's very frustrating for hackers, they'll hopefully feel bored quite quickly.

Is it a bad practice to use a GET parameter (in URL) with no value?

I'm in a little argument with my boss about URLs using GET parameters without value. E.g.
http://www.example.com/?logout
I see this kind of link fairly often on the web, but of course, this doesn't mean it's a good thing. He fears that this is not standard and could lead to unexpected errors, so he'd rather like me to use something like:
http://www.example.com/?logout=yes
In my experience, I've never encountered any problem using empty parameters, and they sometimes make more sense to me (like in this case, where ?logout=no wouldn't make any sense, so the value of "logout" is irrelevant and I would only test for the presence of the parameter server-side, not for its value). (It also looks cleaner.)
However I can't find confirmation that this kind of usage is actually valid and therefore really can't cause any problem ever.
Do you have any link about this?
RFC 2396, "Uniform Resource Identifiers (URI): Generic Syntax", §3.4, "Query Component" is the authoritative source of information on the query string, and states:
The query component is a string of information to be interpreted by
the resource.
[...]
Within a query component, the characters ";", "/", "?", ":", "#",
"&", "=", "+", ",", and "$" are reserved.
RFC 2616, "Hypertext Transfer Protocol -- HTTP/1.1", §3.2.2, "http URL", does not redefine this.
In short, the query string you give ("logout") is perfectly valid.
A value is not required for the key to have any effect. It doesn't make the URL any less valid either, the URL RFC1738 does not list it as required part of the URL.
If you don't really need a value, it's just a matter of preference.
http://example.com/?logout
Is just as much a valid URL as
http://example.com/?logout=yes
All difference that it makes is that if you want to make sure that the "yes" bit was absolutely set, you can check for it's value. Like:
if(isset($_GET['logout']) && $_GET['logout'] == "yes") {
// Only proceed if the value is explicitly set to yes
If you just want to know if the logout key was set somewhere in the URL, it would suffice to just list the key with no value assigned to it. You can then check it like this:
if(isset($_GET['logout'])) {
// Continue regardless of what the value is set to (or if it's left empty)
It's perfectly fine, and won't cause any error. Though, nowadays most frameworks are MVC based, so in the URL you need to mention a controller and an action, so it looks more like /users/logout (BTW, also StackOverflow uses that URL to log users out ;).
The statement that it may cause errors to me sounds like your applications manually access the raw $_GET, and I definitely think that building apps without a framework (which usually provides an MVC stack and a router/dispatcher) is the real dangerous thing here.

How to deal with question mark in url in php single entry website

I'm dealing with two question marks in a single entry website.
I'm trying to use urlencode to handle it.
The original URL:
'search.php?query='.quote_replace(addmarks($search_results['did_you_mean'])).'&search=1'
I want to use it in the single entry website:
'index.php?page='.urlencode('search?query='.quote_replace(addmarks($search_results['did_you_mean'])).'&search=1')
It doesn't work, and I don't know if I must use urldecode and where I can use it also.
Why not just rewrite it to become
index.php?page=search&query=...
mod_rewrite will do this for you if you use the [QSA] (query string append) flag.
http://wiki.apache.org/httpd/RewriteQueryString
$_SERVER['QUERY_STRING'] will give you everything after the first "?" in a URL.
From here you can parse using "explode" or common sting functions.
Example:
http://xxx/info.php?test=1?test=2&test=3
$_SERVER['QUERY_STRING'] =>test=1?test=2&test=3
list($localURL, $remoteURL) = explode("?", $_SERVER['QUERY_STRING']);
$localURL => 'test=1'
$remoretURL =>'test=2&test=3'
Hope this helps
I would suggest you to change the logic of the server code to handle simpler query form. This way it is probably going to lead you nowhere in very near future.
Use
index.php?page=search&query=...
as your query format but do not overwrite it with mod_rewrite to your first wanted format just to satisfy your current application logic, but handle it with some better logic on the server side. Write some ifs and thens, switches and cases ... but do not try to put the logic of the application into your URLs. It will make you really awkward URLs and soon you'll see that there is no lot of space in that layer to handle all the logic you will need. :)

Check query string (PHP)

I use a query string, for example test.php?var=1.
How can I check if a user types anything after that, like another string...
I try to redirect to index.php if any other string (query string) follows my var query string.
Is it possible to check this?
For example:
test.php?var=12134 (This is a good link..)
test.php?a=23&var=123 (this is a bad link, redirect to index..)
test.php?var=123132&a=23 (this is a bad link, redirect to index..)
I'm not sure I fully understand what you want, but if you're not interested in the positioning of the parameters this should work:
if ( isset($_GET['var']) && count($_GET) > 1 ) {
//do something if var and another parameter is given
}
Look in $_SERVER['QUERY_STRING'].
Similar to Tom Haigh’s answer, you could also get the difference of the arguments you expect and those you actually get:
$argKeys = array_keys($_GET);
$additionalArgKeys = array_diff($argKeys, array('var'));
var_dump($additionalArgKeys);
test.php?a=23?var=123 (this is a bad link, redirect to index..)
In this case, you only have one variable sent, named "a" containing the value "a?var=123", therefore it shouldn't be a problem for you.
test.php?var=123132&a=23 (this is a bad link, redirect to index..)
In this case you have two variables sent, ("a" and "var").
In general you can check the $_GET array to see how many variables have been sent and act accordingly, by using count($_GET).
I think you are trying to get rid of unwanted parameters. This is usually done for security reasons.
There won't be a problem, however, if you preinitalize every variable you use and only use variables with $_GET['var'], $_POST['var'] or $_REQUEST['var'].

Categories