How to identify if there are any attachments in REQUEST_BODY for creating a ModSecurity exclusion rule - owasp

We are using ModSecurity CRS 3.0.2 and need to exclude rule 930110 which blocks requests if it contains patterns '../' and '..\'(Path Traversal Attack). If we attach a file while submitting the request, this pattern gets matched frequently and request is blocked which we want to avoid.
I was able to exclude the REQUEST_BODY using below:
SecRuleUpdateTargetById 930110 "!REQUEST_BODY"
Is there a way to exclude just the attachment and scan rest of the REQUEST_BODY?
If not, can we identify if REQUEST_BODY contains an attachment and exclude REQUEST_BODY only in this case. I tried string search as below but it doesn't work. 'filename' is a sample string in REQUEST_BODY I see whenever a file is attached.
SecRule REQUEST_BODY "#contains filename"
"id:1001,phase:1,pass,nolog,
ctl:ruleRemoveTargetById=930110;REQUEST_BODY"
REQUEST_URI filter works though
SecRule REQUEST_URI "#beginsWith /process"
"id:1001,phase:1,pass,nolog,
ctl:ruleRemoveTargetById=930110;REQUEST_BODY"

Related

Mailcow sieve script that removes attachments and adds a message to the body

I'm trying to find out how to remove non-whitelisted attachments (by mime type) (f.e. zip, exe, ...)
and append a message about the removed attachments.
I found this: https://superuser.com/a/1502589
And it worked to add a message to the subject.
But I cannot find out how to add a message to the body.
My plan was to use a regex on the attachment mime types and allow f.e.
text/* and application/json etc.
But I cannot find a single example how to change the body.
I'm using mailcow and sieve script (which I'm both new to).
Or is there a better way to "sanitize" emails before the get put into the inbox?
EDIT (2023-02-07) : I found this today:
Extension foreverypart.
Sieve Email Filtering: MIME Part Tests, Iteration, Extraction, Replacement, and Enclosure
https://www.rfc-editor.org/rfc/rfc5703.html \
The "replace" command is defined to allow a MIME part to be replaced
with the text supplied in the command.
Exactly what I try to do.
Now I need to find out how to install the extension and try it out.

which type of request is used for the `delete` button in the REST context?

I am creating a REST API for the Order screen. I have methods:
GET /api/orders
GET /api/orders/{orderId}
I have some buttons on the Order page and I created few endpoints for that:
PATCH /api/order/buttons/mark-as-read
PATCH /api/order/buttons/change-status
Now I need to add the delete button. But I don't understand how to do that. I have 2 options:
DELETE /api/orders/{orderId} - but I should send 2 additional parameters in this request
PATCH /api/order/buttons/delete - I can send my DTO in the body, but it is not a REST approach.
I want to understand which type of request is used for the delete button in the REST context?
PATCH /api/order/buttons/mark-as-read
PATCH /api/order/buttons/change-status
These are a bit strange. PATCH is a method with remote authoring semantics; it implies that you are making a change to the resource identified by the effective target URI.
But that doesn't seem to be the case here; if you are expecting to apply the changes to the document identified by /api/orders/{orderId}, then that should be the target URI, not some other resource.
PATCH /api/orders/1
Content-Type: text/plain
Please mark this order as read.
PATCH /api/orders/1
Content-Type: text/plain
Please change the status of this order to FULFILLED
Of course, we don't normally use "text/plain" and statements that require a human being to interpret, but instead use a patch document format (example: application/json-patch+json) that a machine can be taught to interpret.
I want to understand which type of request is used for the delete button in the REST context?
If the semantics of "delete" belong to the Orders domain (for instance, if it is a button that signals a desire to cancel an order) then you should be using PUT or PATCH (if you are communicating by passing updated representations of the resource) or POST (if you are sending instructions that the server will interpret).
The heuristic to consider: how would you do this on a plain HTML page? Presumably you would have a "cancel my order" form, with input controls to collect information from the user, and possibly some hidden fields. When the user submits the form, the browser would use the form data and HTML's form processing rules to create an application/x-www-form-urlencoded representation of the information, and would then POST that information to the resource identified by the form action.
The form action could be anything; you could use /api/orders/1/cancel, analogous to your mark-as-read and change-status design; but if you can use the identifier of the order (which is to say, the resource that you are changing), then you get the advantages of standardized cache invalidation for free.
It's normal for a single message handler, which has a single responsibility in the transfer of documents over a network domain, ex POST /api/orders/{orderId}, to interpret the payload and select one of multiple handlers (change-status, mark-as-read, cancel) in your domain.
you offer to use something like this: PATCH /api/orders/{orderId} and OrderUpdatesDto as JSON string in the request body?
Sort of.
There are three dials here: which effective request URI to use, which payload to use, which method to use.
Because I would want to take advantage of cache invalidation, I'm going to look for designs that use: /api/order/{orderId} as the effective request URI, because that's the URI for the responses that I want to invalidate.
It's fine to use something like a JSON representation of an OrderUpdate message/command/DTO as the payload of the request. But that's not really a good match for remote authoring. So instead of PATCH, I would use POST
POST /api/orders/1 HTTP/1.1
Content-Type: application/prs.pavel-orderupdate+json
{...}
But you can instead decide to support a remote authoring interface, meaning that the client just edits their local copy of /api/order/1 and then tells you what changes they made.
That's the case where both PUT (send back the entire document) and PATCH (send back a bunch of edits) can make sense. If GET /api/orders/1 returns a JSON document, then I'm going to look into whether or not I can support one of the general purpose JSON patch document formats; JSON Patch or JSON Merge Patch or something along those lines.
Of course, it can be really hard to get from "changes to a document" to a message that will be meaningful to a non-anemic domain. There are reasons that we might prefer supporting a task based experience, but sending a task centric DTO is not a good fit for PUT/PATCH if you also want caching to work the way I've described above.

Mod rewrite test.php?p=one to test/one

I rewrite rules like site.com/product/p1 to site.com/product.php?p=p1 successfully.
Now, I want to the the opposite, convert the query that is received from a form submission site.com/product.php?id=1234&name=test to site.com/product/test/1234 i.e. I don't want the site visitor to see the query parameters.
To make things more clear: on my site I have a form with two text input fields (and a few hidden fields as well); visitors can enter the product id and product name and submit the form. I want the resulting url (after the form submission) to be flat (site.com/product/test/1234) and not include any params.
Of course, I want my script (product.php) to retrieve all the parameters from the form. I guess I could do that in the same fashion that I turn site.com/product/p1 into site.com/product.php?p=p1.
Could anyone help me out?
mod_rewrite will not be flexible enough to do this in general. It's fine when you have one (and only one) query parameter to handle. As you add more, you need to handle every possible combination of query parameters, and have a new rule for each. mod_rewrite is only appropriate if you can no longer serve URLs in the old style, for example if you are upgrading a third-party server you cannot modify, and want to have httpd handle redirecting old bookmarked links to the new locations.
It is best to handle this inside your PHP script itself. The script at the "old" product.php?id=1234&name=test URL should read the GET parameters and return a HTTP 301 response ("Moved Permanently") to the new product/test/1234 URL. This will work if the request goes to product.php, or product.php?name=test, or product.php?id=1234, or product.php?name=test&id=1234. The script determines what to do with missing values, and how to build the replacement URL.
To do the rewrite with just a single query parameter, it will look like the reverse of your successful rewrite rule, e.g.
RewriteCond %{QUERY_STRING} ^p=(.*)$
RewriteRule /product.php /product/%1 [R]

Outlook rest api "synchronize messages" ignores $expand in subsequent calls

I am trying to synchronize an Outlook folder (say the Inbox) using the beta version of the Outlook Rest Api see doc here
I need only to retrieve the property IsRead and the PR_INTERNET_MESSAGE_ID
So following documentation, for the first synchronization my requests look like:
The following Http headers are always added:
request.Headers.Add("Prefer", "odata.track-changes");
request.Headers.Add("Prefer", "odata.maxpagesize=5"); //Use a small page size easier for debugging
The first initial full synchronization request
https://outlook.office365.com/api/beta/Me/MailFolders('inbox')/messages?$select=IsRead&$expand=SingleValueExtendedProperties($filter=(PropertyId eq 'String 0x1035'))
Good results the value array contain what I need.
The second request after the first request uses the deltatoken
https://outlook.office365.com/api/beta/Me/MailFolders('inbox')/messages?$select=IsRead,Subject&$expand=SingleValueExtendedProperties($filter=(PropertyId eq 'String 0x1035'))&$deltatoken=a758b90491954a61ad463ef3a0e690a2
Bad results, no SingleValueExtendedProperties entries
Next requests for paginations with skiptoken...
https://outlook.office365.com/api/beta/Me/MailFolders('inbox')/messages?$select=IsRead,Subject&$expand=SingleValueExtendedProperties($filter=(PropertyId eq 'String 0x1035'))&$skiptoken=e99ad10324464488b6b219ca5ed6be1c
Bad results again, same as 2.
It looks like a bug to me. Can you provide a workaround? From a list of ItemId is possible to retrieve easily the list of corresponding PR_InternetMessage_Id efficiently (not item per item)?
Note also that in the documentation it is written that:
The response will include a Preference-Applied: odata.track-changes
header. If you attempt to sync a resource that is not supported, this
header will not be returned in the response. Check for this header
before processing the response to avoid errors.
It seems that for 2. and 3. calls this response header "Preference-Applied" is not set.
The sync functionality today doesn't support extended properties. However, we are working to enable this and it should start working in a few weeks.
EDIT:
For a workaround for the very special case of the PR_INTERNETMESSAGE_ID look at the comment below.

Pass rest resource output format in url

AFAIK every resource have a url in REST design. for example /user/28 is url of user with id equal to 28 and /users will return all users.
There are some way to represent output format of the resource:
passing a query parameter like format
specify it using extensions(changing /users url to /users.json to get the users in json format)
specifying the requested format(xml, json, xls, ...) by setting Accept http header.
I search the web and it seems the correct way is setting Accept header.
But if you want to have a http link (specified by href) to download list of users in xls format, you can't!Also if you want to download the xls by the browser, you will encounter many problems(you should use ajax so the xls should download using ajax and etc.)
If it is the best way, what is the solution for download link and if its not, which solution is better?
The Accept header is considered 'more correct', but there are plenty examples of all the options you mention. As far as I can tell, none of them is considered "bad". Personally, I'd say that you should honor and prefer the Accept header, but a format query parameter should override it, if present. The downside of the 'extension' method is that each format results in a different resource, which can get ugly.