.htaccess 在传递所需的 X-Requested-With 时拒绝 iOS 连接

huangapple go评论65阅读模式
英文:

.htaccess rejecting iOS connections when passing required X-Requested-With

问题

我想在调用我的服务器API时,在请求头中使用X-Requested-With。服务器在.htaccess文件中有一行代码,用来查找X-Requested-With字段中的特定值,即:X-Requested-with: com.myApp - 如果未找到,则拒绝连接。是的,我知道X-Requested-With可以被伪造,不是一个可靠的安全方法,但它是我应用/服务器安全的第一道防线。

以下的.htaccess条件适用于Android设备,但是对于iOS设备,连接被拒绝了。在iOS中,我可以看到X-Requested-With被传递,并且具有正确的值,那么为什么服务器只会拒绝iOS的连接呢?我该如何在iOS上解决这个问题?

.htaccess:

RewriteCond %{HTTP:X-Requested-With} !^com.myapp$ [NC]
RewriteRule ^ - [F]

我尝试过多个条件,它们都失败了:

RewriteCond %{HTTP:X-Requested-With} !^com.myapp [NC]
RewriteCond %{HTTP:X-Requested-With} !com.myapp [NC]
RewriteCond %{HTTP:X-Requested-With} !com\.myapp [NC]
RewriteCond %{HTTP:X-Requested-With} !myapp [NC]

我的服务器连接都是HTTPS的,但是上述规则在Android上(只使用HTTP时)是有效的。如果我将它改为HTTPS,它也会破坏Android的连接。这让我感到困惑,因为所有的连接都是HTTPS的。为什么会这样?

在iOS的请求头中(所有版本),我还看到:Origin: ionic//myapp,但在Android上只有Origin: http://localhost,我该如何让Android也显示Origin: ionic//myapp或类似的内容?如果我能让Android显示与iOS相同的内容,也许我的.htaccess可以查找Origin而不是X-Requested-With?

最后,是否有可能编写一个条件性的.htaccess规则;一个用于Android,使用X-Requested-With,另一个用于iOS,使用Origin,我该如何做到这一点?即:

RewriteCond %{HTTP:X-Requested-With} !^com.myapp$ OR %{HTTP:Origin} !^ionic//myapp$ [NC]
RewriteCond ^ - [F]
英文:

I want to use X-Requested-With in the headers when calling my server API. The server has an .htaccess line to look for a specific value in the X-Requested-With field, ie: X-Requested-with: com.myApp - if not found, reject the connection. Yes, I know X-Requested-With can be spoofed and is not a secure method to rely on, but it is a first line of defense in my app/server security.

The below htaccess condition is working for Android devices, but for iOS devices the connection is being rejected. In iOS, I can see X-Requested-With being passed, with the correct value, so why would the server reject the connection ONLY with for iOS? And how can I resolve this on iOS?

.htaccess:

RewriteCond %{HTTP:X-Requested-With} !^com.myapp$ [NC]
RewriteRule ^ - [F]

I have tried multiple conditions, and they all fail:

RewriteCond %{HTTP:X-Requested-With} !^com.myapp [NC]
RewriteCond %{HTTP:X-Requested-With} !com.myapp [NC]
RewriteCond %{HTTP:X-Requested-With} !com\.myapp [NC]
RewriteCond %{HTTP:X-Requested-With} !myapp [NC]

My server connections are all HTTPS, but the above rule was working (using just HTTP) for Android. If I change it to HTTPS it breaks connections for Android too. Which I find odd since all the connections are HTTPS. Why is this?

In the iOS Request headers (all versions), I also see: Origin: ionic//myapp, but on Android its just Origin: http://localhost, how can I get Android to also show Origin: ionic//myapp or similar? If I could get Android to show the same as iOS then maybe my htaccess could look for Origin instead of X-Requested-With?

And last, is it possible to write a conditional htaccess rule; one for Android using X-Requested-With and one for iOS Origin, how can I do that? ie:

RewriteCond %{HTTP:X-Requested-With} !^com.myapp$ OR %{HTTP:Origin} !^ionic//myapp$ [NC]
RewriteCond ^ - [F]

答案1

得分: 1

  • In iOS, I can see X-Requested-With being passed, with the correct value, so why would the server reject the connection ONLY with for iOS?

    在iOS中,我可以看到X-Requested-With被传递,并且值正确,那么为什么服务器只会拒绝iOS的连接?

  • The only reason why this would fail (and the request is blocked) is if the request that your server receives does not contain the header as expected.

    唯一可能导致失败(并且请求被阻止)的原因是服务器接收到的请求不包含预期的标头。

  • So that would seem to imply that the request received from the iOS device does not contain the expected header. Maybe the app is sending the header but an intermediary proxy is removing/modifying it before it reaches your server?

    这似乎意味着从iOS设备接收的请求不包含预期的标头。也许应用程序发送了标头,但中间代理在它到达服务器之前删除/修改了它?

  • You should be able to determine what headers your application is actually receiving on the HTTP request.

    您应该能够确定您的应用程序在HTTP请求上实际收到的标头是什么。

  • My server connections are all HTTPS, but the above rule was working (using just HTTP) for Android. If I change it to HTTPS it breaks connections for Android too. Which I find odd since all the connections are HTTPS. Why is this?

    我的服务器连接都是HTTPS,但上面的规则在Android上仅使用HTTP时有效。如果我将其更改为HTTPS,它也会破坏Android的连接。我觉得这很奇怪,因为所有连接都是HTTPS。为什么会这样?

  • The %{HTTP:<header>} syntax refers to the HTTP request header by that name. This is regardless of whether the request is over HTTP or HTTPS. HTTPS is simply HTTP over SSL/TLS. It's still an "HTTP header". There is no such thing as %{HTTPS:<header>} - if this doesn't result in an error then it will simply return an empty string and your negated condition will be successful (thus blocking the request).

    %{HTTP:<header>} 语法指的是该名称的HTTP请求标头。这不论请求是通过HTTP还是HTTPS。HTTPS只是在SSL/TLS上的HTTP。它仍然是一个“HTTP标头”。没有%{HTTPS:<header>} 这种东西 - 如果这不会导致错误,那么它将简单地返回一个空字符串,并且您的否定条件将成功(从而阻止请求)。

  • In the iOS Request headers (all versions), I also see: Origin: ionic//myapp, but on Android its just Origin: http://localhost, how can I get Android to also show Origin: ionic//myapp or similar? If I could get Android to show the same as iOS then maybe my htaccess could look for Origin instead of X-Requested-With?

    在iOS请求标头(所有版本)中,我还看到:Origin: ionic//myapp,但在Android上只有Origin: http://localhost,如何让Android也显示Origin: ionic//myapp或类似的内容?如果我能让Android显示与iOS相同的内容,那么也许我的htaccess可以查找Origin而不是X-Requested-With?

  • You have no control over the setting of the Origin header; this is determined by the User-Agent (browser, app engine, etc.).

    您无法控制Origin标头的设置;这由用户代理(浏览器、应用引擎等)确定。

  • But you can presumably check for (not) either. For example:

    但您可以检查(不检查)任何一个。例如:

  • You can use the OR flag on the RewriteCond directive. However, the logic should be AND, not OR, when dealing with negated conditions. If you perform a logical OR on two negated conditions, then the condition will always be successful, and the request will always be blocked.

    您可以在RewriteCond指令上使用OR标志。但是,在处理否定条件时,逻辑应该是 AND 而不是 OR。如果在两个否定条件上执行逻辑OR,那么条件将始终成功,并且请求将始终被阻止。

  • For example, it should be something like:

    例如,应该是这样的:

  • The two conditions are implicitly AND'd.

    这两个条件隐含地是AND的。

英文:

> In iOS, I can see X-Requested-With being passed, with the correct value, so why would the server reject the connection ONLY with for iOS?
>
> RewriteCond %{HTTP:X-Requested-With} !^com.myapp$ [NC]
> RewriteRule ^ - [F]

The only reason why this would fail (and the request is blocked) is if the request that your server receives does not contain the header as expected.

So that would seem to imply that the request received from the iOS device does not contain the expected header. Maybe the app is sending the header but an intermediary proxy is removing/modifying it before it reaches your server?

You should be able to determine what headers your application is actually receiving on the HTTP request.

> RewriteCond %{HTTP:X-Requested-With} !myapp [NC]
>
> My server connections are all HTTPS, but the above rule was working (using just HTTP) for Android. If I change it to HTTPS it breaks connections for Android too. Which I find odd since all the connections are HTTPS. Why is this?

The %{HTTP:<header>} syntax refers to the HTTP request header by that name. This is regardless of whether the request is over HTTP or HTTPS. HTTPS is simply HTTP over SSL/TLS. It's still an "HTTP header". There is no such thing as %{HTTPS:<header>} - if this doesn't result in an error then it will simply return an empty string and your negated condition will be successful (thus blocking the request).

> In the iOS Request headers (all versions), I also see: Origin: ionic//myapp, but on Android its just Origin: http://localhost, how can I get Android to also show Origin: ionic//myapp or similar? If I could get Android to show the same as iOS then maybe my htaccess could look for Origin instead of X-Requested-With?

You have no control over the setting of the Origin header, this is determined by the User-Agent (browser, app engine, etc.)

But you can presumably check for (not) either. For example:

RewriteCond %{HTTP:Origin} !^(http://localhost|ionic//myapp)$ [NC]

Or, splitting into two conditions:

RewriteCond %{HTTP:Origin} !=http://localhost
RewriteCond %{HTTP:Origin} !=ionic//myapp

This second example uses the = prefix operator to make it an exact string match (lexicographical comparison), as opposed to a regex.

> RewriteCond %{HTTP:X-Requested-With} !^com.myapp$ OR %{HTTP:Origin} !^ionic//myapp$ [NC]
> RewriteCond ^ - [F]

You can use the OR flag on the RewriteCond directive. However, the logic should be AND , not OR, when dealing with negated conditons. If you perform a logical OR on two negated conditions then the condition will always be successful and the request will always be blocked.

For example, it should be something like:

RewriteCond %{HTTP:X-Requested-With} !^com\.myapp$ [NC]
RewriteCond %{HTTP:Origin} !^ionic//myapp$ [NC]
RewriteRule ^ - [F]

The two conditions are implicitly AND'd.

huangapple
  • 本文由 发表于 2023年3月3日 22:08:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/75628123.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定