Welcome Guest, Not a member yet? Register   Sign In
CI checking permitted URI chars....in a perl script?!?!
#1

[eluser]jrlooney[/eluser]
So as to not bloat this post, I wont explain the spaghetti i've been trapped in by having to incorporate an old CMS written in perl.

Here is my issue. The administration screens for my application are written in PHP using CI. Within one of those screens, I execute a system command - calling an old perl script that runs the compile (publish) routine for this old CMS we have. Eventually, that old perl script actually calls another PHP script to generate some nice dropdown navigation for the site being compiled. And that is where the problem hits - when that PHP script is called, CI is actually running the check on permitted characters in the URI (I'm not even sure how CI even has access that deep in this chain of scripts). I am getting the error about "The URI you submitted has disallowed characters"

So first of all, I really don't understand how CI is even running at the point it happens, and I really have no idea how to fix it (other than to completely remove CI from the equation and run this thing in a popup or something). But in case anyone can help, here's the order of execution and pertinent code from each script:

Admin screen is loaded via CI. In that view file I do this ('s' is just a reference to which account to compile):
Code:
$output = shell_exec("perl /home/acuweb/public_html/cgi-bin/aw/compile.pl ".$_GET['s']);

That compile.pl script begins to compile the site. When it gets to the point that it needs page navigation, it calls a PHP file that builds the nav HTML. It is this call that CI is returning the URI error. Code from this .pl script looks like this:
Code:
sub generate_superfish
{
my $phppath = $1 if (AcuLib::cl("/usr/bin/php") =~ /(.+)/);
my $scriptpath = $1 if (AcuLib::cl("/home/acuweb/public_html/cgi-bin/aw/generatesuperfish.php") =~ /(.+)/);
my $scenario = $1 if (AcuLib::cl("$main::form{'s'}") =~ /(.+)/);
my $output = `$phppath $scriptpath $scenario`;
If I dump that $output variable, I am seeing the "The URI you submitted has disallowed characters" error.

So first of all, how is CI even doing this within a completely separate perl script? And how to resolve? I've been trying different things with the
Code:
$config['permitted_uri_chars']
but nothing is working.

If anyone can help that'd be great. Otherwise I may just have to toss it into a popup and remove CI from the equation. Thanks for any help/suggestions
#2

[eluser]TheFuzzy0ne[/eluser]
It looks as if Perl is being used as a bootstrap for CodeIgniter, since it can be run from the command line. How it's doing this exactly? I dunno...

Does CodeIgniter receive it's parameters from your Perl scripts, or does it interface with browser directly? The reason I ask, is that if you're passing the parameters to it via a Perl script, you can probably allow all URI characters.

What's the value of `$phppath $scriptpath $scenario`; when it's been evaluated?

Is there any way you can find out what's actually being passed to it? You can enable logging and have a look to see what's going on.

I know this isn't the answer you were looking for, but hopefully it gives you a good starting point.
#3

[eluser]jrlooney[/eluser]
Hi Fuzzy, thank you for replying. i've been banging my head over this for a couple days so I appreciate any input and attempt to troubleshoot it.

So the interesting thing is that CI calls the perl script and the perl script calls a generic PHP script (not CI), but CI is still doing its thing on that generic PHP call. And that is why i'm weirded out.

So when I output the value of `$phppath $scriptpath $scenario`; I get this (which is correct if I were gonna run that command on command line - "demo" is the scenario for the site I am compiling)

/usr/bin/php /home/acuweb/public_html/cgi-bin/aw/generatesuperfish.php demo

And quite literally that perl script is making a system call to php - but CI is somehow still monitoring things and chokes on that call. Because in the perl script, the system call looks like this:

Code:
my $output = `$phppath $scriptpath $scenario`;

and if i dump out the value of $output immediately after that line, it has the value "Content-type: text/html The URI you submitted has disallowed characters"

Sorry one detail I left out - this set up has been running on my server w/o issue for a couple years now. I am in the process of moving all my code to a new host and that is where this issue is happening. I am using the very same version of CI as I had previously, however this new host has the latest version of PHP running - which might be my issue. HOwever, I still think it's weird that CI is still checking URLs when CI calls a perl script which calls a generic php script.

Also of note, in that CI view file (that sends the system command for the perl script), I also tried setting CI's permitted URI chars at runtime so that it'd ignore them. But then what happens is I get CI's generic 404 error.
Code:
$this->config->set_item('permitted_uri_chars', '');
#4

[eluser]CroNiX[/eluser]
Ah, I bet you're using an older version of CI (Pre v2) and your new host is running PHP 5.3?

If so, and you can't upgrade CI to a more recent version (that is optimized for 5.3), you might try this:
http://riskianawulan.net/2010/11/fixed-t...deigniter/

Another thing you'd want to do is do a global search/replace on the /system dir and change all instances of "=&" to just "=" or you'll have a ton of "assigning by reference has been deprecated" type warnings.

Also comment out set_magic_quotes_runtime() in /system/CodeIgniter.php.
#5

[eluser]CroNiX[/eluser]
And I'd bet your perl script is also calling CI in places to generate things, perhaps using CI's views and that's probably where the uri characters are coming into play. It's not technically in the "uri" because it's being executed via CLI (or via web call), but that's what the built in phrase says regardless as it's checking what is passed to it in order to determine what the controller/method/params are to execute (aka the "uri").

Rereading your 2nd post, I think what I just said could be occurring in this secondary php script you say isn't using CI. Are you sure it's not a rigged bootstrap for running CI on the CLI? CI 2+ has built in ways for running on the CLI, but to get it to do it with earlier versions you had to have an extra bootstrap to process parameters (which is in turn calling CI's regular index.php and sending the controller/method/vars to it after setting some needed $_SERVER settings). Have you taken a closer look at this secondary php script that perl is calling? You might check to see if it's similar to this: http://ellislab.com/forums/viewthread/218538/#1008547
#6

[eluser]TheFuzzy0ne[/eluser]
$this->config->set_item('permitted_uri_chars', ''); won't work, since the URI is checked before the controller is actually run.

Because we like to spoil our members, I'm going to offer you an alternative method of trouble-shooting, which may (or may not) save you from having to upgrade. I suspect CroNiX may may correct in saying that Magic Quotes might be the problem. What I'm interested to know is what URI is being passed to the server.

1) Find ./system/uri.php, and make a copy of it, and name the copy uri.orig.php.
2) Open ./system/uri.php, and find the line that says:
Code:
show_error('The URI you submitted has disallowed characters.', 400);
3) Modify that line so it looks like this:
Code:
show_error('The URI you submitted has disallowed characters. ('.$_SERVER['REQUEST_URI'].')', 400);
4) Navigate to the URL that's causing you the problem, and this time you should see the URI that's causing the problem.
5) Don't forget to delete your edited file and rename uri.orig.php back to uri.php

Hope this helps, and no problem if you decide to just upgrade instead.
#7

[eluser]jrlooney[/eluser]
Thank you both.

Cronix - you are right, this application uses an old version of CI, and the new host is running PHP 5.3.x

I checked the link you posted and made the change to the URI library and my config. After doing that, now in place of the permitted characters error, I get a 404 from CI. So I had CI tell me what value it has for $page in the 404 function, and it outputted this:

Code:
404 Page Not Found: a=compileWebsite&s=demo

And that is from the first perl script (compile.pl) making a system call off to another perl script. I know I know - the madness - inheriting old code is SO much fun. Here you can see that call (this is from compile.pl)

Code:
my $command = "/usr/bin/perl -T  acuweb.cgi a=compileWebsite s=$site";
  my $res = `$command`;


Fuzzy - I also did what you suggested (before applying Cronix ideas). What it shows is the call to the actual CI screen that subsequently makes the system call on the first perl script (yes, this application is old and uses query string URI instead of segments).

Code:
The URI you submitted has disallowed characters. (/php/5/cm.php?c=setting&m=publish_site&x=031913133240&s=demo)

So it's odd that it is already on that screen (it is loaded in the browser) and yet CI barfs on it - almost like it's calling everything twice.

**Cronix, also thanks for the link to your cron post. I actually have that same kind of thing set up for my cron jobs that need CI - however all of these issues i'm having now are not running CI on CLI - and yes, that last PHP files that gets called by perl is not a CI call at all - just straight up PHP.

Thanks again for the help and brain-time. If nothing looks any more worth chasing here, I may just pursue removing that particular button click from CI and shove it in a popup for now. I wish that I could upgrade CI, but my company was just purchased and all I've been given approval to do here is get this code running on their server (of course if that means upgrading CI then maybe they'll approve that).

Thanks guys!
#8

[eluser]TheFuzzy0ne[/eluser]
I have to say, I'm a totally baffled. I don't see how any of those characters should be disallowed. The fact the page is rendering in the browser certainly suggests that it's being run twice. I would suggest enabling logging and checking the logs to see if that really is happening. Obviously, that's to satisfy my own curiosity more than anything - I doubt it's the solution.

I can't help thinking that your Perl script calls CI, which calls a Perl script, which calls a PHP script, which again calls CI.

Can you confirm that there's really only one CodeIgniter application there, and not two that are running from different code bases/configurations?

I think this just goes to show how important it is to comment code so the poor sod that inherits it, doesn't wake up at random intervals at night screaming "NO MORE CODE!!!", eventually falling back to sleep again whilst weeping into his pillow. I hope, for your sake, someone got demoted over that.
#9

[eluser]jrlooney[/eluser]
Thanks again Fuzzy.

So let's see. I can definitely confirm that CodeIgniter loads the inital screen, but all subsequent calls are non CI. The string of calls looks like this:

cm.php (CI, loads a simple view)

Code:
function publish_site()
{
  $this->load->view('header.php',  array('hide_nav'=>true));
  $this->load->view('setting_publish_site_view');
  $this->load->view('footer.php');
}

Within that view (setting_publish_site_view), a system call executes for the first perl script:

Code:
$output = shell_exec("perl /home/acuweb/public_html/cgi-bin/aw/compile.pl ".$_GET['s']);

compile.pl gathers some environment vars and then calls the main perl script that builds the HTML for the site:

Code:
my $command = "/usr/bin/perl -T  acuweb.cgi a=compileWebsite s=$site";

and that perl script is the one that eventually calls the non-CI PHP script that generates the dropdown navigation for the website being compiled:

Code:
my $phppath = $1 if (AcuLib::cl("/usr/bin/php") =~ /(.+)/);
my $scriptpath = $1 if (AcuLib::cl("/home/acuweb/public_html/cgi-bin/aw/generatesuperfish.php") =~ /(.+)/);
my $scenario = $1 if (AcuLib::cl("$main::form{'s'}") =~ /(.+)/);
my $output = `$phppath $scriptpath $scenario`;

*********
I turned on profiling for that controller that loads the initial view. nothing looks weird. Do you know if there is more detailed logging beyond profiler?

Code:
MEMORY USAGE   2,951,704 bytes
BENCHMARKS  
    Loading Time Base Classes   0.0084
    Controller Execution Time ( Setting / Publish Site )   0.3104
    Total Execution Time   0.3189
URI STRING  
    No URI data exists
GET DATA  
    $_GET['c']    setting
    $_GET['m']    publish_site
    $_GET['x']    031913133240
    $_GET['s']    demo
POST DATA  
    No POST data exists
QUERIES (0)  
    No queries were run
#10

[eluser]jrlooney[/eluser]
Hold the presses. I think I just found proof of multiple calls to CI. In the Controller I had it output "here1" in the constructor, 'here2' in the index function and 'here3' in the function used for loading the view i wanted. In browser I get 2 instances of 'here1'. So I had it attached the request-uri each time and i get 2 unique URIs. Woohoo. Now I just have to figure out why CI is calling itself from within itself. Big Grin

I'll post back if I discover anything.




Theme © iAndrew 2016 - Forum software by © MyBB