Page 1 of 2

modsecurity block requests

Posted: Mon May 09, 2022 7:40 pm
by damien
Hello,

I try to install nuBuilder on an Apache2 web server on witch modsecurity is installed.
It raises many 403 errors because it detects risk of SQL/php injection.

Some errors are legitimates because we send php and SQL code to the server especially in development phase.
But some other are more unexpected. For example an error is raised when I return from details view to browser view in a "Browse and edit form" because there is a field "browse_sql" into the json payload that contains some SQL like sentence "SELECT+AAA_id,aaa_name+FROM+aaa\nWHERE+1"

Is there a true risque of SQL injection with nuBuilder when used in "user" only mode (not in design phase obviously) ?

Do you have some advice to deal with it ?

Best regards,
Damien

Re: modsecurity block requests

Posted: Mon May 09, 2022 8:20 pm
by kev1n
Hi,

Can you post the exact error message? It does not necessarily have to be from a form that you have created, it can also be the "user" form, for example.

Re: modsecurity block requests

Posted: Tue May 10, 2022 2:10 pm
by damien
Here is a more detailed example.
I have a simple table "zz_test" and corresponding fast form "Browse and Edit" type.
The reproduction procedure is simple.
I enter the fast form.
I create a new entry or enter into a existing entry.
In the edit window, I just click on the name of the Fast From 1 to return to the "Brower" part.
Then modsecurity block the request with a 403 error.

Image

Here the detailed of the request blocked by modsecurity

Code: Select all

POST http://localhost/TestDB/core/nuapi.php
The raw BODY

Code: Select all

nuSTATE=%7B%22form_id%22%3A%22627a503323e5b8d%22%2C%22redirect_form_id%22%3A%22627a503323e5b8d%22%2C%22record_id%22%3A%22%22%2C%22title%22%3A%22Fast+Form+1%22%2C%22call_type%22%3A%22getform%22%2C%22column_widths%22%3A%5B1868%5D%2C%22filter%22%3A%22%22%2C%22forms%22%3A%5B%5D%2C%22iframe%22%3A0%2C%22lookup_id%22%3A%22%22%2C%22object_id%22%3A%221%22%2C%22page_number%22%3A0%2C%22password%22%3A%22%22%2C%22rows%22%3A20%2C%22row_height%22%3A18%2C%22search%22%3A%22%22%2C%22session_id%22%3A%22s16521825983704%22%2C%22nosearch_columns%22%3A%5B%5D%2C%22sort%22%3A%22-1%22%2C%22sort_direction%22%3A%22desc%22%2C%22subforms%22%3A0%2C%22tab_start%22%3A%5B%5D%2C%22username%22%3A%22%22%2C%22user_id%22%3A%22globeadmin%22%2C%22refreshed%22%3A0%2C%22CLONED_RECORD%22%3A0%2C%22NEW_RECORD%22%3A0%2C%22redirect_other_form_id%22%3A%22%22%2C%22browse_columns%22%3A%5B%7B%22title%22%3A%22text%22%2C%22display%22%3A%22zz_test_text%22%2C%22align%22%3A%22l%22%2C%22width%22%3A%22250%22%2C%22order%22%3A%2210%22%2C%22format%22%3A%22%22%2C%22id%22%3A%22627a50333749098%22%7D%5D%2C%22browse_sql%22%3A%22SELECT+zz_test_id%2Czz_test_text%5Cn+FROM+zz_test%5CnWHERE+1%22%2C%22browse_rows%22%3A%5B%5B%22627a505b908498f%22%2C%22test%22%5D%5D%2C%22browse_table_id%22%3A%22___nu1627a51073517b___%22%2C%22browse_filtered_rows%22%3A%221%22%2C%22browse_title_multiline%22%3A%220%22%2C%22browse_autoresize_columns%22%3Anull%2C%22pages%22%3A1%2C%22form_code%22%3A%22FF1%22%2C%22form_description%22%3A%22Fast+Form+1%22%2C%22form_type%22%3A%22browseedit%22%2C%22run_code%22%3A%22%22%2C%22run_description%22%3A%22%22%2C%22data_mode%22%3Anull%2C%22hash%22%3A%7B%22form_id%22%3A%22627a503323e5b8d%22%2C%22redirect_form_id%22%3A%22627a503323e5b8d%22%2C%22record_id%22%3A%22%22%2C%22title%22%3A%22Fast+Form+1%22%2C%22call_type%22%3A%22%22%2C%22column_widths%22%3A%5B1868%5D%2C%22filter%22%3A%22%22%2C%22forms%22%3A%5B%5D%2C%22iframe%22%3A0%2C%22lookup_id%22%3A%22%22%2C%22object_id%22%3A%221%22%2C%22page_number%22%3A0%2C%22password%22%3A%22%22%2C%22rows%22%3A20%2C%22row_height%22%3A18%2C%22search%22%3A%22%22%2C%22session_id%22%3A%22s16521825983704%22%2C%22nosearch_columns%22%3A%5B%5D%2C%22sort%22%3A%22-1%22%2C%22sort_direction%22%3A%22desc%22%2C%22subforms%22%3A0%2C%22tab_start%22%3A%5B%5D%2C%22username%22%3A%22%22%2C%22user_id%22%3A%22globeadmin%22%2C%22refreshed%22%3A0%2C%22CLONED_RECORD%22%3A0%2C%22NEW_RECORD%22%3A0%2C%22redirect_other_form_id%22%3A%22%22%2C%22browse_columns%22%3A%5B%7B%22title%22%3A%22text%22%2C%22display%22%3A%22zz_test_text%22%2C%22align%22%3A%22l%22%2C%22width%22%3A%22250%22%2C%22order%22%3A%2210%22%2C%22format%22%3A%22%22%2C%22id%22%3A%22627a50333749098%22%7D%5D%2C%22browse_sql%22%3A%22SELECT+zz_test_id%2Czz_test_text%5Cn+FROM+zz_test%5CnWHERE+1%22%2C%22browse_rows%22%3A%5B%5B%22627a505b908498f%22%2C%22test%22%5D%5D%2C%22browse_table_id%22%3A%22___nu1627a51073517b___%22%2C%22browse_filtered_rows%22%3A%221%22%2C%22browse_title_multiline%22%3A%220%22%2C%22browse_autoresize_columns%22%3Anull%2C%22pages%22%3A1%2C%22form_code%22%3A%22FF1%22%2C%22form_description%22%3A%22Fast+Form+1%22%2C%22form_type%22%3A%22browseedit%22%2C%22run_code%22%3A%22%22%2C%22run_description%22%3A%22%22%2C%22data_mode%22%3Anull%2C%22ID%22%3A%22627a505b908498f%22%2C%22nuDelete%22%3A0%2C%22zz_test_text%22%3A%22test%22%7D%2C%22AAA%22%3A%22hw%22%2C%22like%22%3A%22%22%2C%22zz_test_text%22%3A%22test%22%7D
The decoded BODY

Code: Select all

nuSTATE = {
    "form_id": "627a503323e5b8d",
    "redirect_form_id": "627a503323e5b8d",
    "record_id": "",
    "title": "Fast+Form+1",
    "call_type": "getform",
    "column_widths": [1868],
    "filter": "",
    "forms": [],
    "iframe": 0,
    "lookup_id": "",
    "object_id": "1",
    "page_number": 0,
    "password": "",
    "rows": 20,
    "row_height": 18,
    "search": "",
    "session_id": "s16521825983704",
    "nosearch_columns": [],
    "sort": "-1",
    "sort_direction": "desc",
    "subforms": 0,
    "tab_start": [],
    "username": "",
    "user_id": "globeadmin",
    "refreshed": 0,
    "CLONED_RECORD": 0,
    "NEW_RECORD": 0,
    "redirect_other_form_id": "",
    "browse_columns": [{
            "title": "text",
            "display": "zz_test_text",
            "align": "l",
            "width": "250",
            "order": "10",
            "format": "",
            "id": "627a50333749098"
        }
    ],
    "browse_sql": "SELECT+zz_test_id,zz_test_text\n+FROM+zz_test\nWHERE+1",
    "browse_rows": [["627a505b908498f", "test"]],
    "browse_table_id": "___nu1627a51073517b___",
    "browse_filtered_rows": "1",
    "browse_title_multiline": "0",
    "browse_autoresize_columns": null,
    "pages": 1,
    "form_code": "FF1",
    "form_description": "Fast+Form+1",
    "form_type": "browseedit",
    "run_code": "",
    "run_description": "",
    "data_mode": null,
    "hash": {
        "form_id": "627a503323e5b8d",
        "redirect_form_id": "627a503323e5b8d",
        "record_id": "",
        "title": "Fast+Form+1",
        "call_type": "",
        "column_widths": [1868],
        "filter": "",
        "forms": [],
        "iframe": 0,
        "lookup_id": "",
        "object_id": "1",
        "page_number": 0,
        "password": "",
        "rows": 20,
        "row_height": 18,
        "search": "",
        "session_id": "s16521825983704",
        "nosearch_columns": [],
        "sort": "-1",
        "sort_direction": "desc",
        "subforms": 0,
        "tab_start": [],
        "username": "",
        "user_id": "globeadmin",
        "refreshed": 0,
        "CLONED_RECORD": 0,
        "NEW_RECORD": 0,
        "redirect_other_form_id": "",
        "browse_columns": [{
                "title": "text",
                "display": "zz_test_text",
                "align": "l",
                "width": "250",
                "order": "10",
                "format": "",
                "id": "627a50333749098"
            }
        ],
        "browse_sql": "SELECT+zz_test_id,zz_test_text\n+FROM+zz_test\nWHERE+1",
        "browse_rows": [["627a505b908498f", "test"]],
        "browse_table_id": "___nu1627a51073517b___",
        "browse_filtered_rows": "1",
        "browse_title_multiline": "0",
        "browse_autoresize_columns": null,
        "pages": 1,
        "form_code": "FF1",
        "form_description": "Fast+Form+1",
        "form_type": "browseedit",
        "run_code": "",
        "run_description": "",
        "data_mode": null,
        "ID": "627a505b908498f",
        "nuDelete": 0,
        "zz_test_text": "test"
    },
    "AAA": "hw",
    "like": "",
    "zz_test_text": "test"
}
Here are the 3 error.log generated by modsecurity

Code: Select all

[Tue May 10 13:45:35.074863 2022]
[:error]
[pid 80936]
[client 127.0.0.1:38622]
[client 127.0.0.1] ModSecurity: Warning. Pattern match "(?i:(?:[\\"'`](?:;?\\\\s*?(?:having|select|union)\\\\b\\\\s*?[^\\\\s]|\\\\s*?!\\\\s*?[\\"'`\\\\w])|(?:c(?:onnection_id|urrent_user)|database)\\\\s*?\\\\([^\\\\)]*?|u(?:nion(?:[\\\\w(\\\\s]*?select| select @)|ser\\\\s*?\\\\([^\\\\)]*?)|s(?:chema\\\\s*?\\\\([^\\\\)]*?|elect.*?\\\\w?user\\\\()|in ..." at ARGS:nuSTATE. [file "/usr/share/modsecurity-crs/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf"]
[line "190"]
[id "942190"]
[msg "Detects MSSQL code execution and information gathering attempts"]
[data "Matched Data: \\x22SELECT z found within ARGS:nuSTATE: {\\x22form_id\\x22:\\x22627a503323e5b8d\\x22,\\x22redirect_form_id\\x22:\\x22627a503323e5b8d\\x22,\\x22record_id\\x22:\\x22\\x22,\\x22title\\x22:\\x22Fast Form 1\\x22,\\x22call_type\\x22:\\x22getform\\x22,\\x22column_widths\\x22:[1868],\\x22filter\\x22:\\x22\\x22,\\x22forms\\x22:[],\\x22iframe\\x22:0,\\x22lookup_id\\x22:\\x22\\x22,\\x22object_id\\x22:\\x221\\x22,\\x22page_number\\x22:0,\\x22password\\x22:\\x22\\x22,\\x22rows\\x22:20,\\x22row_height\\x22:18,\\x22search\\x22:\\x22\\x22,\\x22session_id\\x22..."]
[severity "CRITICAL" [hostname "localhost"]
[uri "/TestDB/core/nuapi.php"]
[unique_id "YnpQX8obhO@5wJDUtq@BFwAAAAE"], referer: http://localhost/TestDB/index.php?i=0&opener=16521830929241002

Code: Select all

[Tue May 10 13:45:35.076147 2022]
[:error]
[pid 80936]
[client 127.0.0.1:38622]
[client 127.0.0.1] ModSecurity: Access denied with code 403 (phase 2). Operator GE matched 5 at TX:anomaly_score. [file "/usr/share/modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf"]
[line "91"]
[id "949110"]
[msg "Inbound Anomaly Score Exceeded (Total Score: 5)"]
[severity "CRITICAL"]
[tag "application-multi"]
[tag "language-multi"]
[tag "platform-multi"]
[tag "attack-generic"]
[hostname "localhost"]
[uri "/TestDB/core/nuapi.php"]
[unique_id "YnpQX8obhO@5wJDUtq@BFwAAAAE"], referer: http://localhost/TestDB/index.php?i=0&opener=16521830929241002

Code: Select all

[Tue May 10 13:45:35.085381 2022]
[:error]
[pid 80936]
[client 127.0.0.1:38622]
[client 127.0.0.1] ModSecurity: Warning. Operator GE matched 5 at TX:inbound_anomaly_score. [file "/usr/share/modsecurity-crs/rules/RESPONSE-980-CORRELATION.conf"]
[line "86"]
[id "980130"]
[msg "Inbound Anomaly Score Exceeded (Total Inbound Score: 5 - SQLI=5,XSS=0,RFI=0,LFI=0,RCE=0,PHPI=0,HTTP=0,SESS=0): individual paranoia level scores: 5, 0, 0, 0"]
[tag "event-correlation"]
[hostname "localhost"]
[uri "/TestDB/core/nuapi.php"]
[unique_id "YnpQX8obhO@5wJDUtq@BFwAAAAE"], referer: http://localhost/TestDB/index.php?i=0&opener=16521830929241002
I suspect that the folowing part of the BODY trig the error because it looks like an SQL injection attacks.

Code: Select all

 "browse_sql": "SELECT+zz_test_id,zz_test_text\n+FROM+zz_test\nWHERE+1",
What is the usage of such field in a simple browsing sequence ?

Re: modsecurity block requests

Posted: Tue May 10, 2022 2:21 pm
by kev1n
damien wrote: Tue May 10, 2022 2:10 pm I suspect that the folowing part of the BODY trig the error because it looks like an SQL injection attacks.

Code: Select all

 "browse_sql": "SELECT+zz_test_id,zz_test_text\n+FROM+zz_test\nWHERE+1",
What is the usage of such field in a simple browsing sequence ?
The Browse SQL is initially generated by nuBuilder and only an administrator can modify it. The SQL in your example isn't using any variables / parameters and therefore no SQL injection is possible.

Re: modsecurity block requests

Posted: Wed May 11, 2022 11:38 am
by damien
I have check the same navigation scheme using a user account, not the administrator and the "browse_sql" is also present into the JSON payload.
So I do not understand what you mean by
kev1n wrote:The Browse SQL is initially generated by nuBuilder and only an administrator can modify it.
In the nominal way the "browse-sql" is generated by nuBuilder, but as it is send from the client, it can be forged by a client.

What is the usage of the "browse_sql" sentence at PHP side ?

Re: modsecurity block requests

Posted: Wed May 11, 2022 12:02 pm
by kev1n
browse_sql is not sent from the client. It's retrieved from the database and then sent to the client.

Re: modsecurity block requests

Posted: Wed May 11, 2022 1:34 pm
by damien
kev1n wrote: Wed May 11, 2022 12:02 pm browse_sql is not sent from the client. It's retrieved from the database and then sent to the client.
Ok so if it is useless for the front end and the returned value is not used by the backend it can be removed ?

I propose the 2 following mitigations.

At the root level in the php code , in the nuform.php remove the line 455:

Code: Select all

$f->browse_sql = nuObjKey($B,2,0);;
If it is used by the front, null the browse_sql reference before sending it back to the server in the Ajax request:

Code: Select all

function nuAjax(w,successCallback,errorCallback){
	// --- Remove useless SQL sentence to avoid modsecurity filtering
	w.browse_sql = null; 
	w.hash.browse_sql = null;
	// ---
	w	= nuAddEditFieldsToHash(w);

	w	= JSON.stringify(w);
	....
With a simple test it seems to works fine.
What do you think about it ?

Re: modsecurity block requests

Posted: Wed May 11, 2022 1:50 pm
by kev1n
Normal users won't use browse_sql but globeadmin would need it in these 2 cases:

To use "Print": nuRunHTML()
To view the generated SQL for debugging purposes (Option Menu -> Form Info).

Therefore, I'd be OK to remove f->browse_sql = nuObjKey($B,2,0); for normal users but not for globeadmin.
nuAjax() could be changed for both.

IMO, there's no problem when passing browse_sql from the server to the client but not vice versa.

Re: modsecurity block requests

Posted: Wed May 11, 2022 3:42 pm
by damien
kev1n wrote: Wed May 11, 2022 1:50 pm IMO, there's no problem when passing browse_sql from the server to the client but not vice versa.
Yes, I confirm, the issue raised by modsecurity is due to the request form the client to the server only.
So the PHP code can be keept as is for the debug purpose.
The nuAjax modification is sufficient to avoid the SQL injection detection by modsecurity.
Do you think that such modification could be deployed into the official version ?

Re: modsecurity block requests

Posted: Wed May 11, 2022 3:54 pm
by kev1n
Yes, I think so. I'll do some more tests to ensure that that there's no adverse impact.