<p>These are probably coming from the incoming request in the <code>$_SERVER</code> <a href="https://www.php.net/manual/en/language.variables.superglobals.php" rel="nofollow noreferrer">PHP superglobal</a></p>

<p>Yii2 does its best to figure out the incoming request, but that's relying on information coming from the client, which is insecure. Note the warning about potential <a href="https://docs.craftcms.com/v3/sites.html#site-url" rel="nofollow noreferrer">cache poisoning in the Craft CMS docs</a>:</p>

<blockquote>
  <p>Don’t ever use the @web alias when defining your sites’ Base URLs. It could introduce a cache poisoning vulnerability, and Craft won’t be able to reliably determine which site is being requested.</p>
</blockquote>

<p>This is for the same reason; if no explicit <code>siteUrl</code> is provided, it'll try to figure it out from the request.</p>

<p>In your case, <code>craft.rebrand.getLogo().url</code> ends up calling <a href="https://github.com/craftcms/cms/blob/develop/src/web/twig/variables/Rebrand.php#L97" rel="nofollow noreferrer">getImageVariable</a> which then ends up calling the Yii2 asset manager to get the published URL. I think your <code>siteUrl</code> or other aliases may not be set properly.</p>

<pre class="lang-php prettyprint-override"><code>    /**
     * Returns the schema and host part of the current request URL.
     *
     * The returned URL does not have an ending slash.
     *
     * By default this value is based on the user request information. This method will
     * return the value of `$_SERVER['HTTP_HOST']` if it is available or `$_SERVER['SERVER_NAME']` if not.
     * You may want to check out the [PHP documentation](https://secure.php.net/manual/en/reserved.variables.server.php)
     * for more information on these variables.
     *
     * You may explicitly specify it by setting the [[setHostInfo()|hostInfo]] property.
     *
     * &gt; Warning: Dependent on the server configuration this information may not be
     * &gt; reliable and [may be faked by the user sending the HTTP request](https://www.acunetix.com/vulnerabilities/web/host-header-attack).
     * &gt; If the webserver is configured to serve the same site independent of the value of
     * &gt; the `Host` header, this value is not reliable. In such situations you should either
     * &gt; fix your webserver configuration or explicitly set the value by setting the [[setHostInfo()|hostInfo]] property.
     * &gt; If you don't have access to the server configuration, you can setup [[\yii\filters\HostControl]] filter at
     * &gt; application level in order to protect against such kind of attack.
     *
     * @property string|null schema and hostname part (with port number if needed) of the request URL
     * (e.g. `http://www.yiiframework.com`), null if can't be obtained from `$_SERVER` and wasn't set.
     * See [[getHostInfo()]] for security related notes on this property.
     * @return string|null schema and hostname part (with port number if needed) of the request URL
     * (e.g. `http://www.yiiframework.com`), null if can't be obtained from `$_SERVER` and wasn't set.
     * @see setHostInfo()
     */
    public function getHostInfo()
    {
        if ($this-&gt;_hostInfo === null) {
            $secure = $this-&gt;getIsSecureConnection();
            $http = $secure ? 'https' : 'http';

            if ($this-&gt;headers-&gt;has('X-Forwarded-Host')) {
                $this-&gt;_hostInfo = $http . '://' . trim(explode(',', $this-&gt;headers-&gt;get('X-Forwarded-Host'))[0]);
            } elseif ($this-&gt;headers-&gt;has('Host')) {
                $this-&gt;_hostInfo = $http . '://' . $this-&gt;headers-&gt;get('Host');
            } elseif (isset($_SERVER['SERVER_NAME'])) {
                $this-&gt;_hostInfo = $http . '://' . $_SERVER['SERVER_NAME'];
                $port = $secure ? $this-&gt;getSecurePort() : $this-&gt;getPort();
                if (($port !== 80 &amp;&amp; !$secure) || ($port !== 443 &amp;&amp; $secure)) {
                    $this-&gt;_hostInfo .= ':' . $port;
                }
            }
        }

        return $this-&gt;_hostInfo;
    }
</code></pre>

CC BY-SA 4.0
2019-11-14T09:35:32.910Z
Thank you! I was using `@web` alias in my baseUrl. I changed to environmental variable and the issue's gone. I also replaced the `@web` alias with  `{{ craft.app.sites.primarySite.baseUrl }}` in my templates.
krzk
CC BY-SA 4.0
2019-11-14T19:40:12.303Z
You could also just use `@web` but explicitly define it, as per here: https://github.com/nystudio107/devmode/blob/master/config/general.php#L16
andrew.welch
CC BY-SA 4.0
2019-11-19T12:35:30.547Z
@andrew-welch Unfortunately it didn't help. I just edited my question, please can you advise?
krzk
CC BY-SA 4.0
2019-11-19T15:32:23.243Z
I edited my answer a bit, see if that helps
andrew.welch
CC BY-SA 4.0
2019-11-19T15:53:51.410Z
Thanks for speedy reply. However, I really don't think that's the problem here - I put the Base URL manually in the Admin Panel > Settings > Sites. So now it's just like `https://www.my-website.com` and it's not being overwritten. If I understood correctly, in this configuration we can exclude the 'wrong siteUrl or alias' case? Also, this happens **only** for these two assets.
krzk
CC BY-SA 4.0
2019-11-19T20:17:05.737Z
Yes, because only those assets are published on the frontend via the Asset Manager
andrew.welch
CC BY-SA 4.0
2019-11-26T09:21:16.610Z
Hmm, I looked into this again and here's my setup: `'siteUrl' => getenv('SITE_URL')` in config.php, I set `SITE_URL` as the environment variable in my docker-compose file. I will hardcode the URL in the config file and test it. But looks like I've got everything configured properly, especially since all the other assets (user photos for example) are being served properly.
krzk
CC BY-SA 4.0
2019-11-13T02:13:01.423Z
2019-11-19T15:31:54.263Z
2019-11-19T15:31:54.263Z
andrew.welch
<p>I'm running Craft CMS 3.3.11 on an EC2 machine with Apache and Load Balancer. </p>

<p>After upgrading to Craft 3, I'm having issues with caching. </p>

<p>I use relative paths to resources/assets in my templates (i.e. <code>href="/resources/logo.svg"</code></p>

<p>After some time, the relative paths in the template are not handled properly - instead of domain name in the URLs I get the server's IP address. It's impossible to fetch data using IP address, so the website is loading forever, the assets won't show up and it logs an error to the dev console:</p>

<blockquote>
  <p>Mixed Content: The page at ‘<a href="https://example.com/" rel="nofollow noreferrer">https://example.com/</a>’ was loaded over HTTPS, but requested an insecure image ‘<a href="http://172.xx.xx.xx/cpresources/8f9c0f5e/logo.svg?v=1572966078" rel="nofollow noreferrer">http://172.xx.xx.xx/cpresources/8f9c0f5e/logo.svg?v=1572966078</a>’. This content should also be served over HTTPS.</p>
</blockquote>

<p>When I clear caches, everything works properly again. </p>

<p>Adding <code>{{ siteUrl }}</code> before all the relative paths seems to be the easiest fix, but I wonder if maybe I have some configuration issues that should be fixed to prevent this in future? </p>

<p>Server's IP isn't stored neither in the database nor the template files - where does it come from? </p>

<p>Suggestions? </p>

<p>EDIT</p>

<p>Unfortunately it still doesn't work properly.</p>

<p>Here's my code: </p>

<pre><code>                    &lt;img src="{{ craft.rebrand.getLogo().url }}" alt="{{ siteName }}"
                         class="brand-logo"&gt;
                {% endif %}


                {% if craft.rebrand.isIconUploaded() %}
                    &lt;img src="{{ craft.rebrand.getIcon().url }}" alt="{{ siteName }}"
                         class="brand-icon"&gt;
                {% endif %}
</code></pre>

<p>For these assets Craft is using server's IP... Can someone please advise? </p>

<craft3><cache>
Server's IP in URLs in cached templates
# Server's IP in URLs in cached templates

(Asked by: username_0 on 2019-11-11)

I'm running Craft CMS 3.3.11 on an EC2 machine with Apache and Load Balancer. 
After upgrading to Craft 3, I'm having issues with caching. 
I use relative paths to resources/assets in my templates (i.e. href="/resources/logo.svg"
After some time, the relative paths in the template are not handled properly - instead of domain name in the URLs I get the server's IP address. It's impossible to fetch data using IP address, so the website is loading forever, the assets won't show up and it logs an error to the dev console:

Mixed Content: The page at ‘https://example.com/’ was loaded over HTTPS, but requested an insecure image ‘http://172.xx.xx.xx/cpresources/8f9c0f5e/logo.svg?v=1572966078’. This content should also be served over HTTPS.

When I clear caches, everything works properly again. 
Adding {{ siteUrl }} before all the relative paths seems to be the easiest fix, but I wonder if maybe I have some configuration issues that should be fixed to prevent this in future? 
Server's IP isn't stored neither in the database nor the template files - where does it come from? 
Suggestions? 
EDIT
Unfortunately it still doesn't work properly.
Here's my code: 
                    
                {% endif %}


                {% if craft.rebrand.isIconUploaded() %}
                    
                {% endif %}

For these assets Craft is using server's IP... Can someone please advise?

**Tags:** craft3, cache


---

## 1 answers

### Answer by username_1 on 2019-11-13. Score: 2

These are probably coming from the incoming request in the $_SERVER PHP superglobal
Yii2 does its best to figure out the incoming request, but that's relying on information coming from the client, which is insecure. Note the warning about potential cache poisoning in the Craft CMS docs:

Don’t ever use the @web alias when defining your sites’ Base URLs. It could introduce a cache poisoning vulnerability, and Craft won’t be able to reliably determine which site is being requested.

This is for the same reason; if no explicit siteUrl is provided, it'll try to figure it out from the request.
In your case, craft.rebrand.getLogo().url ends up calling getImageVariable which then ends up calling the Yii2 asset manager to get the published URL. I think your siteUrl or other aliases may not be set properly.
    /**
     * Returns the schema and host part of the current request URL.
     *
     * The returned URL does not have an ending slash.
     *
     * By default this value is based on the user request information. This method will
     * return the value of `$_SERVER['HTTP_HOST']` if it is available or `$_SERVER['SERVER_NAME']` if not.
     * You may want to check out the [PHP documentation](https://secure.php.net/manual/en/reserved.variables.server.php)
     * for more information on these variables.
     *
     * You may explicitly specify it by setting the [[setHostInfo()|hostInfo]] property.
     *
     * > Warning: Dependent on the server configuration this information may not be
     * > reliable and [may be faked by the user sending the HTTP request](https://www.acunetix.com/vulnerabilities/web/host-header-attack).
     * > If the webserver is configured to serve the same site independent of the value of
     * > the `Host` header, this value is not reliable. In such situations you should either
     * > fix your webserver configuration or explicitly set the value by setting the [[setHostInfo()|hostInfo]] property.
     * > If you don't have access to the server configuration, you can setup [[\yii\filters\HostControl]] filter at
     * > application level in order to protect against such kind of attack.
     *
     * @property string|null schema and hostname part (with port number if needed) of the request URL
     * (e.g. `http://www.yiiframework.com`), null if can't be obtained from `$_SERVER` and wasn't set.
     * See [[getHostInfo()]] for security related notes on this property.
     * @return string|null schema and hostname part (with port number if needed) of the request URL
     * (e.g. `http://www.yiiframework.com`), null if can't be obtained from `$_SERVER` and wasn't set.
     * @see setHostInfo()
     */
    public function getHostInfo()
    {
        if ($this->_hostInfo === null) {
            $secure = $this->getIsSecureConnection();
            $http = $secure ? 'https' : 'http';

            if ($this->headers->has('X-Forwarded-Host')) {
                $this->_hostInfo = $http . '://' . trim(explode(',', $this->headers->get('X-Forwarded-Host'))[0]);
            } elseif ($this->headers->has('Host')) {
                $this->_hostInfo = $http . '://' . $this->headers->get('Host');
            } elseif (isset($_SERVER['SERVER_NAME'])) {
                $this->_hostInfo = $http . '://' . $_SERVER['SERVER_NAME'];
                $port = $secure ? $this->getSecurePort() : $this->getPort();
                if (($port !== 80 && !$secure) || ($port !== 443 && $secure)) {
                    $this->_hostInfo .= ':' . $port;
                }
            }
        }

        return $this->_hostInfo;
    }

> **Comments:**
> **username_0**: Thank you! I was using `@web` alias in my baseUrl. I changed to environmental variable and the issue's gone. I also replaced the `@web` alias with  `{{ craft.app.sites.primarySite.baseUrl }}` in my templates.  
> **username_1**: You could also just use `@web` but explicitly define it, as per here: https://github.com/nystudio107/devmode/blob/master/config/general.php#L16  
> **username_0**: @andrew-welch Unfortunately it didn't help. I just edited my question, please can you advise?  
> **username_1**: I edited my answer a bit, see if that helps  
> **username_0**: Thanks for speedy reply. However, I really don't think that's the problem here - I put the Base URL manually in the Admin Panel > Settings > Sites. So now it's just like `https://www.my-website.com` and it's not being overwritten. If I understood correctly, in this configuration we can exclude the 'wrong siteUrl or alias' case? Also, this happens **only** for these two assets.  
> **username_1**: Yes, because only those assets are published on the frontend via the Asset Manager  
> **username_0**: Hmm, I looked into this again and here's my setup: `'siteUrl' => getenv('SITE_URL')` in config.php, I set `SITE_URL` as the environment variable in my docker-compose file. I will hardcode the URL in the config file and test it. But looks like I've got everything configured properly, especially since all the other assets (user photos for example) are being served properly.  

---

