Re: htaccess limits

[email protected] Wed, 13 May 2026 09:22:25 -0400
Newsgroups gmane.comp.apache.user
Message-ID <[email protected]>
--Apple-Mail=_1ECF7927-53CF-4850-BF1E-69B89FEF7BDC
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=utf-8


> Paul,
>=20
> The <LimitExcept GET HEAD> approach would deny all POST/PUT/DELETE
> requests to the cgi-bin directory entirely -- including the legitimate
> ones from your own form. That would effectively break your application
> since your form uses POST.
>=20
> One thing worth checking: you mentioned Require ip 127.0.0.1 is
> "functional" -- are you testing from the server itself, or is there
> a reverse proxy in front of Apache that might be making all requests
> appear to come from localhost? That would explain why it seems to
> work but wouldn't actually protect you from external POSTs arriving
> directly. Worth verifying it still blocks when tested from outside
> your network.
>=20
> If the goal is to block external actors while allowing your form's
> POST through, you have a few practical options in order of robustness:
>=20
> 1. CSRF tokens (as Nutchanon described) -- the strongest solution,
>    but requires modifying your Perl script.
>=20
> 2. Referer check via mod_rewrite -- lighter-weight, can be done
>    in .htaccess:
>=20
>        RewriteEngine On
>        RewriteCond %{REQUEST_METHOD} POST
>        RewriteCond %{HTTP_REFERER} !^https?://your.domain.com/ [NC]
>        RewriteRule ^cgi-bin/ - [F,L]
>=20
>    This isn't bulletproof (Referer can be spoofed), but it stops
>    casual abuse.
>=20
> 3. Require expr with Referer (an alternate Apache 2.4 native =
approach):
>=20
>        <Directory "/www/mysite/cgi-bin">
>            <If "%{REQUEST_METHOD} =3D=3D 'POST' && %{HTTP_REFERER} !~ =
m#^https?://your.domain.com/#">
>                Require all denied
>            </If>
>        </Directory>
>=20
> For a production system, CSRF is the right long-term answer, but
> option 2 or 3 gives you an immediate improvement over the
> Require ip 127.0.0.1 approach while you implement that.
>=20
> -- Rich


=E2=80=94=20
Rich Bowen
[email protected]





--Apple-Mail=_1ECF7927-53CF-4850-BF1E-69B89FEF7BDC
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html;
	charset=utf-8

<html aria-label=3D"message body"><head><meta http-equiv=3D"content-type" =
content=3D"text/html; charset=3Dutf-8"></head><body =
style=3D"overflow-wrap: break-word; -webkit-nbsp-mode: space; =
line-break: after-white-space;"><div =
class=3D"Apple-Mail-URLShareUserContentTopClass"><br></div><div =
class=3D"Apple-Mail-URLShareWrapperClass" style=3D"position: relative =
!important;"><blockquote type=3D"cite" style=3D"border-left-style: none; =
color: inherit; padding: inherit; margin: inherit;">

Paul,<br><br>The &lt;LimitExcept GET HEAD&gt; approach would deny all =
POST/PUT/DELETE<br>requests to the cgi-bin directory entirely -- =
including the legitimate<br>ones from your own form. That would =
effectively break your application<br>since your form uses =
POST.<br><br>One thing worth checking: you mentioned Require ip =
127.0.0.1 is<br>"functional" -- are you testing from the server itself, =
or is there<br>a reverse proxy in front of Apache that might be making =
all requests<br>appear to come from localhost? That would explain why it =
seems to<br>work but wouldn't actually protect you from external POSTs =
arriving<br>directly. Worth verifying it still blocks when tested from =
outside<br>your network.<br><br>If the goal is to block external actors =
while allowing your form's<br>POST through, you have a few practical =
options in order of robustness:<br><br>1. CSRF tokens (as Nutchanon =
described) -- the strongest solution,<br><span =
class=3D"Apple-converted-space">&nbsp;&nbsp;</span> but requires =
modifying your Perl script.<br><br>2. Referer check via mod_rewrite -- =
lighter-weight, can be done<br><span =
class=3D"Apple-converted-space">&nbsp;&nbsp;</span> in =
.htaccess:<br><br><span =
class=3D"Apple-converted-space">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span=
> RewriteEngine On<br><span =
class=3D"Apple-converted-space">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span=
> RewriteCond %{REQUEST_METHOD} POST<br><span =
class=3D"Apple-converted-space">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span=
> RewriteCond %{HTTP_REFERER} !^https?://your.domain.com/ [NC]<br><span =
class=3D"Apple-converted-space">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span=
> RewriteRule ^cgi-bin/ - [F,L]<br><br><span =
class=3D"Apple-converted-space">&nbsp;&nbsp;</span> This isn't =
bulletproof (Referer can be spoofed), but it stops<br><span =
class=3D"Apple-converted-space">&nbsp;&nbsp;</span> casual =
abuse.<br><br>3. Require expr with Referer (an alternate Apache 2.4 =
native approach):<br><br><span =
class=3D"Apple-converted-space">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span=
> &lt;Directory "/www/mysite/cgi-bin"&gt;<br><span =
class=3D"Apple-converted-space">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;</span> &lt;If "%{REQUEST_METHOD} =3D=3D 'POST' =
&amp;&amp; %{HTTP_REFERER} !~ =
m#^https?://your.domain.com/#"&gt;<br><span =
class=3D"Apple-converted-space">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> Require all =
denied<br><span =
class=3D"Apple-converted-space">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;</span> &lt;/If&gt;<br><span =
class=3D"Apple-converted-space">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span=
> &lt;/Directory&gt;<br><br>For a production system, CSRF is the right =
long-term answer, but<br>option 2 or 3 gives you an immediate =
improvement over the<br>Require ip 127.0.0.1 approach while you =
implement that.<br><br>-- Rich

</blockquote></div><br><br><div>
<meta charset=3D"UTF-8"><div dir=3D"auto" style=3D"caret-color: rgb(0, =
0, 0); color: rgb(0, 0, 0); letter-spacing: normal; text-align: start; =
text-indent: 0px; text-transform: none; white-space: normal; =
word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: =
none; overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: =
after-white-space;"><div>=E2=80=94&nbsp;</div><div>Rich =
Bowen</div><div>[email protected]</div><div><br></div></div><br =
class=3D"Apple-interchange-newline"><br =
class=3D"Apple-interchange-newline">
</div>
<br></body></html>=

--Apple-Mail=_1ECF7927-53CF-4850-BF1E-69B89FEF7BDC--