Im trying to create some links depending on the GET parametre currently set.
My URL looks like this:
http://mysite.com/index.php?bar=test&page=page
In my code I do the following:
$bar = $_REQUEST['bar'];
<a href="index.php?bar=<?php echo $bar?>&page=anotherpage"
But every time I click the link, it adds the whole string to the URL again.
Like first click would give me this URL:
http://mysite.com/index.php?bar=test&page=anotherpagepage=anotherpage
And next click creates:
http://mysite.com/index.php?bar=test&page=anotherpagepage=anotherpagepage=anotherpage
And so on.
Is there any way to only get the request once so that the URL always looks like this:
http://mysite.com/index.php?bar=test&page=anotherpage
No matter how many times I click the link?
Thanks a lot!
You missed an ampersand in your first example. (&). Give this a try:
$bar = $_REQUEST['bar'];
<a href="index.php?bar=<?php echo $bar?>&page=anotherpage"
Or even better, escape your variables before use to prevent XSS, Cross Site Scripting security vulnerability. Use urlencode() for URLs.
http://nl.php.net/manual/en/function.urlencode.php:
$bar = $_REQUEST['bar'];
<a href="index.php?bar=<?=urlencode($bar)?>&page=anotherpage"
You should take a look on the php function http_build_query
That enables you to construct your array first, like this:
$query = array("bar"=>$_REQUEST['bar'], "page"=>"anotherpage")
echo 'Link';
Related
I am trying to sanitize my GET variables but Accuntrix is still complaining for some reason.
So I visit a page and the URL contains parameters. I pass these parameters between pages. To do this I do
something like the following
<a class="navbar-brand" href="https://someDomain/someFolder/someFile.php?WT.var1=<?php echo $_GET['WT_var1']; ?>&var2=<?php echo $_GET['var2']; ?>&var3=<?php echo $_GET['var3']; ?>&var4=<?php echo $_GET['var4']; ?>" title="logo"><img src="logo.png"></a>
I have lots of links like this on the page, and when I first ran the page it was vunerable to cross site scripting because
I was not sanitizing the GET requests. So at the top of the page, I put
<?php
$_GET['WT_var1'] = htmlspecialchars($_GET['WT_var1']);
$_GET['var2'] = htmlspecialchars($_GET['var2']);
$_GET['var3'] = htmlspecialchars($_GET['var3']);
$_GET['var4'] = htmlspecialchars($_GET['var4']);
?>
Initially, this seemed to work. But I have recently run another scan, and every single link like the above shows up as a high.
The details look something like this
URL encoded GET input WT.var1 was set to 1}body{acu:Expre/**/SSion(prompt(926954))}
The input is reflected inside a text element.
And the exploit looks like this
/someFolder/someFile.php?WT.var1=1%7dbody%7bacu:Expre/**/SSion(prompt(941830))%7d&var2=&var3=&var4=
Is that not showing a sanitized url though? Is this something I need to fix or is it a false/negative?
Thanks
htmlspecialchars() encodes your variable for output as content in an html page. If you need to pass your variables through the url, you need urlencode(().
So for example:
...someFolder/someFile.php?WT.var1=<?php echo urlencode($_GET['WT_var1']); ?>&var2...
I'd like to create a link that changes a PHP $_GET variable. For example:
URL: http://site.com/index&variable=hello&anothervariable=dontchangeme
Click me
(after click)
URL: http://site.com/index&variable=world&anothervariable=dontchangeme
I know you can do this to just change the page (href="1.html"), but I'd like to do the same thing while maintaining the GET variables that were already there.
$query = array('variable' => 'world') + $_GET;
printf('Click me', http_build_query($query));
See http://php.net/http_build_query. That's the easy to understand minimal version. Correctly you need to also HTML-escape the generated query string (because you're putting it into HTML):
printf('Click me', htmlspecialchars(http_build_query($query)));
You can simply redirect the user changing the variable value and using header()..
if(isset($_GET['variable'] && $_GET['variable'] == 'hello') {
header('Location: http://site.com/index&variable=world');
exit;
}
this should do it.
Click me
the variable or parameter in a url is preceded with a ? and then they are separated by &.
To get what you want just use this link:
Click me
but this is hardcoded and not dynamic in the sense that you can change the value of the parameter dynamically so my answer is probably not the best.
One solution to automatically building navigation for a site is by scanning a folder for documents like this:
foreach(glob('pages/*.pg.php') as $_SITE_NAV_filePath):
$_SITE_NAV_filePath = explode('.pg',pathinfo($_SITE_NAV_filePath,PATHINFO_FILENAME));
$_SITE_NAV_fileName = $_SITE_NAV_filePath[0];
$_SITE_NAV_qv = preg_replace('/([A-Z])/','-$1',$_SITE_NAV_fileName); $_SITE_NAV_qv = trim($_SITE_NAV_qv,'-');
$_SITE_NAV_name = preg_replace('/([A-Z])/',' $1',$_SITE_NAV_fileName);
?>
<li><?=$_SITE_NAV_name?></li>
<?php
endforeach;
This code will turn "AnAwesomePage.pg.php" into a menu item like this :
<li>An Awesome Page</li>
This might be bad practice (?).
Anyway; I don't use this method very often since most of the time the sites have a database, and with that comes better solutions...
But my question is this:
Is there a way to prefix the filename with a integer followed by and underscore (3_AnAwesomePage.pg.php), for sorting order purposes, and pass it somehow to the destination page outside of the querystring and without any async javascript?
I could just explode the filename once again on "_" to get the sort order and store it somewhere, somehow?
This is the code for handeling the page query request:
$_SITE_PAGE['qv'] = $_GET['page'];
if (empty($_SITE_PAGE['qv'])){ $_SITE_PAGE['qv'] = explode('-','Home'); }
else { $_SITE_PAGE['qv'] = explode('-',$_GET['page']); }
$_SITE_PAGE['file'] = 'pages/'.implode($_SITE_PAGE['qv']).'.pg.php';
This code turns "An-Awesome-Page" back into "AnAwesomePage.pg.php" so it's possible to include it with php.
But with a prefix, it's not so easy.
The probliem is; Now there's no way to know what prefix number there was before since it has been stripped away from the query string. So I need to send it somehow along in the "background".
One very bad solution I came up with was to transform the navigation link into a form button and just _POST the prefix interger along with the form. At fist it sounded like a nice solution, but then I realized that once a user refreshes their page, it didn't look very good. And after all, that's not what forms are for either...
Any good solutions out there?
Or some other and better way for dealing with this?
There are two ways to keep that number saved, you can use cookies or php session variables.
But in this case, if user first enter the url in the browser or in a new browser, then he should be taken to default number.
Like you have:
1_first-page.php
2_first-page.php
3_first-page.php
If user enter the url like: domain.com/?page=first-page, you have to take him to 1_first-page.php to any number which you want to be default.
I'm doing a website. There's a pagination, you click on links and they take you to the page you need, the links pass $_GET variable ( a href="?pn=2" ) and that works fine.
However when i add the category links (also contain $_GET variable
(a href="?sort=english") on the same page, which kind of sort the content on the page, and click it, the system simply overrides the url and deletes all the previous $_GET's.
For example, I'm on page 2 (http://website.com/index.php?pn=2)
and then I click this sorting link and what I'm expecting to get is this (http://website.com/index.php?pn=2&sort=english), but what I get is this:
(http://website.com/index.php?sort=english). It simply overrides the previous $_GET, instead of adding to it!
A relative URI consisting of just a query string will replace the entire existing query string. There is no way to write a URL that will add to an existing query. You have to write the complete query string that you want.
You can maintain the existing string by adding it explicitly:
href="?foo=<?php echo htmlspecialchars($_GET['foo']); ?>&bar=123"
Try using this:
$_SERVER['REQUEST_URI'];
On this link you can see examples. And on this link I have uploaded test document where you can try it yourself, it just prints out this line from above.
EDIT: Although this can help you get the current parameters in URL, I think it's not solution for you. Like Quentin said, you will have to write full link manually and maintain each parameter.
You could create a function that will iterate through your $_GET array and create a query string. Then all you would have to do is change your $_GET array and generate this query string.
Pseudocode (slash I don't really know PHP but here's a good example you should be able to follow):
function create_query_string($array) {
$kvps = array();
for ($key in $array) {
array_push($kvps, "$key=$array[$key]");
}
return "?" . implode("&", $kvps);
}
Usage:
$_GET["sort"] = "english";
$query_string = create_query_string($_GET);
You need to maintain the query parameters when you create the new links. The links on the page should be something like this:
Sort by English
The HTTP protocol is stateless -- it doesn't remember the past. You have to remind it of what the previous HTTP parameters were via PHP or other methods (cookies, etc). In your case, you need to remind it what the current page number is, as in the example above.
I have a small issue with manipulating the current URL query string to add an extra parameter at the end.
Per example, say there's a category layout for products, the URL would be:
index.php?category=3&type=5
Now, on that page I have a link for a layout that is either a table or a grid. In those URLs I currently have:
<a href="index.php?<?php echo preg_replace($array,'',$_SERVER['QUERY_STRING']); ?>&layout=grid" ...
Then, I do the same for the table href as well. Also in my array I have just:
$array = array ( '/&layout=table/', '/&layout=grid/' )
Is this the right way, or is there a better way for doing this? I'm asking because without preg_replace, it will continue adding that same layout parameter everytime it is clicked, so it will also show the previous parameter, then the next, then the next.. without removing the previous layout parameters.
Any insight on this will be much appreciated.
EDIT:
Thanks to the answers below, I have created a little function:
function buildQuery($key,$value) {
$params = $_GET;
$params[$key] = $value;
return http_build_query($params);
}
Then its only a matter off:
grid
this might seem pointless but i like to have my view / template files without the extra set vars. Im a clean freak. I might even return the 'index.php?' with it just so i can be more lazy, anyways something to play with now :)..
If you want to modify the query string, it's easier to simply modify the GET variables and rebuild the query string:
$params = $_GET;
$params['layout'] = 'new_layout';
Then:
...
Although you could also do:
...
Think about directly parsing the $_GET paramaters to build your url.
I think what you want to do is have the link going to index.php with all the same parameters as you have at the moment, but changing layout to grid. I'd suggest you do something like this:
<?php
// make a copy of the $_GET array with all the parameters from the query string
$params = $_GET;
// set layout=grid regardless of whether layout was set before or its value
$params['layout'] = 'grid';
// generate a query string to append to your urls.
// Note that & is used as the arg separator; this is necessary for XHTML and advised for HTML
$queryString = http_build_query($params, '', '&');
?>
href="index.php?<?php echo $queryString; ?>">
This is much easier than trying to edit and fix the $_SERVER['QUERY_STRING'] yourself.