1

I am getting the following error on a site I occasionally manage, and it has only appeared recently, AFAIK. Things were working fine, but since it is a side project, I haven't monitored it in over a year, and don't know exactly when it appeared. It is most likely due to some security changes in the browser or server software. Anyway, here is what the error says:

<head><title>Not Acceptable!</title></head><body><h1>Not Acceptable!</h1><p>An appropriate representation of the requested resource could not be found on this server. This error was generated by Mod_Security.</p></body></html>

The code that is calling this is something like this (shortened for clarity):

    $.ajax({
    url: "lus.php",
    data: { "SU": SU, // This is any alphanumeric string without spaces or special characters
            "LU": $("#LongURI").val() // This a URI e.g. https://example.com/abc.html
    },
    success: function(data) {
        alert(data);
    },
    error: function(jqXHR, exception) {
        var msg = '';
        if (jqXHR.status === 0) {
            msg = 'Not connected. Verify Network.';
        } else if (jqXHR.status == 404) {
            msg = 'Requested page not found. [404]';
        } else if (jqXHR.status == 500) {
            msg = 'Internal Server Error [500].';
        } else if (exception === 'parsererror') {
            msg = 'Requested JSON parse failed.';
        } else if (exception === 'timeout') {
            msg = 'Time out error.';
        } else if (exception === 'abort') {
            msg = 'Ajax request aborted.';
        } else {
            msg = 'Uncaught Error.\n' + jqXHR.responseText;
        }
        alert('There was an error! ' + msg);
    },

    type: 'GET'
});

If I remove the "://" in the LU variable it works! That means I need to encode it, right, but that did not work (see below). I could strip the "https://" or "http://" and then add it back but that begs the question as to how I would pass "https://" or "http://" (it could be either) to the lus.php file.

Here's what I have tried so far:

  1. Added the following lines to .htaccess
<IfModule mod_security.c>
  SecFilterEngine Off
  SecFilterScanPOST Off
</IfModule>

based on this answer. Didn't work.

  1. Removed all the code from lus.php (in steps) to ensure there is no problem with the php code. No change.

  2. Encoded this line

             "LU": $("#LongURI").val()
    

to this:

            "LU": encodeURI($("#LongURI").val())

and also tried with and without the following change in the php code.

if(isset($_GET['LU']))
    $LU = trim(urldecode(($_GET['LU'])));

No dice.

  1. Changed GET to POST (getting desperate here). This gave me an Internal Server Error (500) instead of the error message above. However, there is no further information because in developer tools, the Response is empty.

EDIT: 5. I have several rewrite conditions in my .htaccess file. So I renamed that file and tried the same operation. Same result/same error.

Any ideas on how to fix this?

Chiwda
  • 1,233
  • 7
  • 30
  • 52
  • You can access to the server error logs? – Tonio Nov 19 '21 at 07:19
  • Which logs? Web server logs? It's shared hosting, BTW. – Chiwda Nov 19 '21 at 07:20
  • The web server error logs. You can look at the specific modsecurity error code. I can see it in my shared hosting. – Tonio Nov 19 '21 at 07:26
  • If ModSecurity blocks the request, you get a 403 (or 400 - depends the rule's config) answer. You wrote: "Mod Security error caused by encoding issue?" - but how do you know that ModSecurity gives the error, if you can't see the logs? – airween Nov 19 '21 at 09:07
  • The error message shows that. See the code snippet at the top of my question. "This error was generated by Mod_Security" – Chiwda Nov 19 '21 at 10:37
  • You definitely don't need to url encode the url, jQuery does it for you. That being said, it would be nice if you copy the request and response from chrome dev tools (Copy as HAR) and paste it here (after redacting some information). – Salman A Nov 22 '21 at 13:08
  • @SalmanA The request says "No payload for this request" and the response is exactly the error message in my question. One interesting thing that bothers me (and it may not be relevant) is that it is fully formed except that there is no starting HTML tag. Also, another item that may/may not be relevant is the header(s): Status 406 Not Acceptable VersionHTTP/2 Transferred394 B (226 B size) Referrer Policystrict-origin-when-cross-origin But I have not put any policies in place and the file called from Ajax is in the same directory. – Chiwda Nov 22 '21 at 14:46

2 Answers2

1

If you can, take a look at your apache error logs (in my case there are located at $HOME/logs/apache.error.log). You can see something like this.

Fri Nov 19 08:35:22.757764 2021] [:error] [pid 16443:tid 140407413257984] [client ****] [client ****] ModSecurity: Access denied with code 403 (phase 2). Pattern match "<script\\\\b" at REQUEST_URI. [file "/etc/modsecurity/07_XSS_XSS.conf"] [line "65"] [id "212620"] [rev "3"] [msg "WAF: Cross-site Scripting (XSS) Attack||webs.ccnorte.es|F|2"] [data "Matched Data: <script found within REQUEST_URI: /panel/?q=\\x22><script>alert(1)</script>"] [severity "CRITICAL"] [tag "CWAF"] [tag "XSS"] [hostname "****"] [uri "***"] [unique_id "YZdTulJinXUAAEA7KdcAAABC"]

Look for the modsecurity rule id. In this example it is [id "212620"], related with a XSS Attack.

Then you can remove this rule in your htaccess or modify your code knowing exactly the cause of the error.

# .htaccess
SecRuleRemoveById 212620
Tonio
  • 1,642
  • 1
  • 4
  • 10
0

It turns out that my hosting provider had blocked the page being called (lus.php). It took a lot of probing and two chat sessions. In case someone is having this problem and can quickly rule out the basics, check with your hosting provider or UFW rules if it is your own server.

Chiwda
  • 1,233
  • 7
  • 30
  • 52