Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

uri->getHost() #815

Closed
nowackipawel opened this issue Nov 7, 2017 · 10 comments
Closed

uri->getHost() #815

nowackipawel opened this issue Nov 7, 2017 · 10 comments

Comments

@nowackipawel
Copy link
Contributor

I'm trying to get host name from class which implements FilterInterface...
In before() method I'm using RequestIterface to get hostname:

I've got in $_SERVER array:
SERVER_NAME: www.domain.com
HOST_NAME: adm.domain.com

so I thought host returned by ->getHost() will be adm.domain.com but it is www.domain.com instead...

I'm using php7.1.11 and the newest nginx.
Nginx is configured with multiple names of server_name for the same directory.

@nowackipawel
Copy link
Contributor Author

IncomingRequest class -> detectURI()
! empty($_SERVER['SERVER_NAME']) ? (isset($_SERVER['SERVER_NAME']) ? $this->uri->setHost($_SERVER['SERVER_NAME']) : null) : (isset($_SERVER['HTTP_HOST']) ? $this->uri->setHost($_SERVER['HTTP_HOST']) : null);
I am wondering why someone pick SERVER_NAME as an default way to set hostname?

@lonnieezell
Copy link
Member

Trusting either of those to be safe from malicious user intent is bad, but of the two, SERVER_NAME is a bit safer from what I understand. Though, as this post points out, at least under Apache, it can still be potentially set to what the user wants it to be. The best bet is to not use that, and have an environment variable set that tells you what server your on, or environment (production? development?), etc, instead of relying on the the server to tell you.

@nowackipawel
Copy link
Contributor Author

It is true but as long as your app runs only on one domain name or should runs exactly the same on all domains.

@lonnieezell
Copy link
Member

It can still function the same on all domains safely if you use the .env file, or something similar, to set an environment variable for that server listing the domain. If you need something that it's not currently providing you still have access to $_SERVER directly.

That said, I can't recall if this is something I implemented or brought over from CI3 so I might need to revisit it since it's not pulling in the sub-domain. Also - note to self - I need to ensure redirect is using base_url since it's manually set by the developer to help protect against phishing attacks when someone does use HTTP_HOST or SERVER_NAME.

@natanfelles
Copy link
Contributor

Hey, @lonnieezell

What about to enable the usage of an array as App::$baseURL ? Then auto get it by the site_url(), base_url(), etc. Since is possible to limit routes by hostname...

@natanfelles
Copy link
Contributor

Otherwise, what will be the best way to set the App::$baseURL if an app is available in many domains? Let it empty or 'http://' . $_SERVER['SERVER_NAME'] . '/'?

@lonnieezell
Copy link
Member

I'm a little confused on usage here.

But there is one problem if I'm understanding you correctly: both site_url and base_url rely up on the value in baseURL to build the resulting URL.

As for the best way to handle an app that works under multiple domains - hard to say without knowing if you controlled all of the domains or if it was to be installed by multiple users (like with a CMS). Even then, I don't know I can truly say there is any "best" way.

Out of the box, we have to be as secure as possible and for most applications build be freelancers and agencies, I would say this method works well. For other cases like you're mentioning here, people might have to balance their business needs and security. Heck, people have been using $_SERVER[HTTP_HOST] for years without any problems that I'm aware of, so that's probably the best you could do in that situation. However - I'm not a security professional, so that answer with a grain of salt. :)

@natanfelles
Copy link
Contributor

Thanks for reply.

The usage I think is having multiple Virtual Hosts pointing the root dir to the same CI public dir.

On CI 3 is possible to use an conditional like:

$domain = strtolower($_SERVER['HTTP_HOST']);

switch($domain)
{
    case 'admin.site.com':
        $config['base_url'] = 'https://admin.site.com/';
        break;
    case 'api.site.com':
        $config['base_url'] = 'http://api.site.com/';
        break;
    default:
        $config['base_url'] = 'http://site.com/';
        break;
}

This prevent the default usage of $_SERVER['HTTP_HOST'] and force the URL be site.com if something is wrong.

Then, now in CI 4 having the possibility to use routes by hostnames and subdomains I thinked if is possible to check it by default.

@lonnieezell
Copy link
Member

You could still do that same block in the constructor of Config\App.php:

public function __construct()
{
    parent::__construct();

   $domain = strtolower($_SERVER['HTTP_HOST']);

    switch($domain)
    {
        case 'admin.site.com':
            $this->baseURL = 'https://admin.site.com/';
            break;
        case 'api.site.com':
            $this->baseURL = 'http://api.site.com/';
            break;
        default:
            $this->baseURL = 'http://site.com/';
            break;
        } 
}

@natanfelles
Copy link
Contributor

Oh, yeah. Thank you! Sorry for this untested and badly thought out question.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants