Stop CRS rule from triggering for a given argument - mod-security

I am an absolute newcomer to OWASP ModSecurity, so please excuse me if this is a simple question! Currently, for an image upload function, I get a bunch of "warnings" like the following:
ModSecurity: Warning. Matched "Operator Rx' with parameter (?i)\s\S\b' against variable ARGS:json.ImageBytes' (Value: data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/4gv4SUNDX1BST0ZJTEUAAQEAAAvoAAAAAAIAAABtbnRyUkdCI (474171 characters omitted)' ) [file "/etc/modsecurity.d/owasp-crs/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf"] [line "139"] [id "941130"] [rev "2"] [msg "XSS Filter - Category 3: Attribute Vector"] [data "Matched Data: ;base64 found within ARGS:json.ImageBytes: data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/4gv4SUNDX1BST0ZJTEUAAQEAAAvoAAAAAAIAAABtbnRyUkdCIFhZWiAH2QADABsAFQAkAB9hY3NwAAA (474141 characters omitted)"] [severity "2"] [ver "OWASP_CRS/3.0.0"] [maturity "1"] [accuracy "8"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-xss"] [tag "OWASP_CRS/WEB_ATTACK/XSS"] [tag "WASCTC/WASC-8"] [tag "WASCTC/WASC-22"] [tag "OWASP_TOP_10/A3"] [tag "OWASP_AppSensor/IE1"] [tag "CAPEC-242"] [hostname "XX.XXX.X.XX"] [uri "/emps/api/emps/UpdateImage"] [unique_id "160217346360.547876"] [ref "o15,7v29,474271t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls"]
I need to prevent rule 941130 from triggering in the case that the argument (ARGS) is "json.ImageBytes".
I dont want to completely exclude the rule, but i am trying to get ModSecurity to ignore in the case of the specified parameter.
Maybe also - is there a way to do this by the URI ("/emps/api/emps/UpdateImage")?
So far i have tried:
SecRuleUpdateTargetById 941130 !ARGS:json.ImageBytes
but to no avail.
I would be very thankful for any help!

Based on the given information, you can create an exclusion rule - just put in in the REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.
The rule like like this:
SecRule REQUEST_URI "#beginsWith /emps/api/emps/UpdateImage" \
"id:9000901,\
phase:1,\
t:none,\
nolog,\
pass,\
ctl:ruleRemoveTargetById=941130;ARGS:json.ImageBytes"
or something similar.

Related

US-ASCII Malformed Encoding XSS Filter - Attack Detected - false alarm while using SUMMERNOTE with Polish characters

I use summernote to put some formatted text into a database.
When I put a text without Polish characters or with just a few, it works fine, but when I use more Polish characters I got an error message from php script [HTTP/1.1 403 Forbidden 24ms].
I reviewed /var/log/httpd/modsec_audit.log file and I found these warnings/errors:
Message: Warning. Pattern match
"\xbc[^\xbe>][\xbe>]|<[^\xbe]\xbe" at ARGS:opis. [file
"/etc/httpd/modsecurity.d/activated_rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf"]
[line "546"] [id "941310"] [msg "US-ASCII Malformed Encoding XSS
Filter - Attack Detected"] [data "Matched Data: \xbcno\xc5\x9bci od
tego jak doprawiony jest bulion. zup\xc4\x99 ju\xc5\xbc na talerzu
mieszamy z oliwa. found within ARGS:opis: warzywa zalewamy
bulionem warzywnym. gotujemy do mi\xc4\x99kko\xc5\x9bci, miksujemy,
solimy w zale\xc5\xbcno\xc5\x9bci od tego jak doprawiony jest bulion.
zup\xc4\x99 ju\xc5\xbc na talerzu mieszamy z oliwa. "] [severity
"CRITICAL"] [ver "OWASP_CRS/3.3.0"] [tag "application-multi"] [tag
"language-multi"] [tag "platform-tomcat"] [tag "attack-xss"] [tag
"paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/152/242"]
Message: Access denied with code 403 (phase 2). Operator GE matched 5
at TX:anomaly_score. [file
"/etc/httpd/modsecurity.d/activated_rules/REQUEST-949-BLOCKING-EVALUATION.conf"]
[line "93"] [id "949110"] [msg "Inbound Anomaly Score Exceeded (Total
Score: 5)"] [severity "CRITICAL"] [ver "OWASP_CRS/3.3.0"] [tag
"application-multi"] [tag "language-multi"] [tag "platform-multi"]
[tag "attack-generic"] Message: Warning. Operator GE matched 5 at
TX:inbound_anomaly_score. [file
"/etc/httpd/modsecurity.d/activated_rules/RESPONSE-980-CORRELATION.conf"]
[line "91"] [id "980130"] [msg "Inbound Anomaly Score Exceeded (Total
Inbound Score: 5 -
SQLI=0,XSS=5,RFI=0,LFI=0,RCE=0,PHPI=0,HTTP=0,SESS=0): individual
paranoia level scores: 5, 0, 0, 0"] [ver "OWASP_CRS/3.3.0"] [tag
"event-correlation"] Apache-Error: [file "apache2_util.c"] [line 273]
[level 3] [client 192.168.101.12] ModSecurity: Warning. Pattern match
"\\\\xbc[^\\\\xbe>][\\\\xbe>]|<[^\\\\xbe]\\\\xbe"
at ARGS:opis. [file
"/etc/httpd/modsecurity.d/activated_rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf"]
[line "546"] [id "941310"] [msg "US-ASCII Malformed Encoding XSS
Filter - Attack Detected"] [data "Matched Data:
\\xbcno\\xc5\\x9bci od tego jak doprawiony jest bulion.
zup\\xc4\\x99 ju\\xc5\\xbc na talerzu mieszamy z oliwa.
found within ARGS:opis: warzywa zalewamy bulionem warzywnym. gotujemy
do mi\\xc4\\x99kko\\xc5\\x9bci, miksujemy, solimy w
zale\\xc5\\xbcno\\xc5\\x9bci od tego jak doprawiony jest
bulion. zup\\xc4\\x99 ju\\xc5\\xbc na talerzu mieszamy z
oliwa. "] [severity "CRITICAL"] [ver "OWASP_CRS/3.3.0"] [tag
"application-multi"] [tag "language-multi"] [tag "platform-tomcat"]
[tag "attack-xss"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag
"capec/1000/152/242"] [hostname "somehostname.pl"] [uri
"/somescript.php"] [unique_id
"Y0peIxMWSyQpE#SPNKJmngAAAAs"]
There are more messages...
As I understand this is some kind of false alarm from apache2 mod_security.
Can you please advice on how to solve this issue and keep mod_security ON in the same time (if possible).
Thanks
UPDATE:
I have identified one polish character 'ż' (utf-8 \xc5\xbc) that causes the issue.
Other characters work OK.
Log message looks like this:
Message: Warning. Pattern match
"\xbc[^\xbe>][\xbe>]|<[^\xbe]\xbe" at ARGS:opis. [file
"/etc/httpd/modsecurity.d/activated_rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf"]
[line "546"] [id "941310"] [msg "US-ASCII Malformed Encoding XSS
Filter - Attack Detected"] [data "Matched Data: \xbc found within
ARGS:opis: \xc5\xbc"] [severity "CRITICAL"] [ver
"OWASP_CRS/3.3.0"] [tag "application-multi"] [tag "language-multi"]
[tag "platform-tomcat"] [tag "attack-xss"] [tag "paranoia-level/1"]
[tag "OWASP_CRS"] [tag "capec/1000/152/242"] Message: Access denied
with code 403 (phase 2). Operator GE matched 5 at TX:anomaly_score.
[file
"/etc/httpd/modsecurity.d/activated_rules/REQUEST-949-BLOCKING-EVALUATION.conf"]
[line "93"] [id "949110"] [msg "Inbound Anomaly Score Exceeded (Total
Score: 5)"] [severity "CRITICAL"] [ver "OWASP_CRS/3.3.0"] [tag
"application-multi"] [tag "language-multi"] [tag "platform-multi"]
[tag "attack-generic"] Message: Warning. Operator GE matched 5 at
TX:inbound_anomaly_score. [file
"/etc/httpd/modsecurity.d/activated_rules/RESPONSE-980-CORRELATION.conf"]
[line "91"] [id "980130"] [msg "Inbound Anomaly Score Exceeded (Total
Inbound Score: 5 -
SQLI=0,XSS=5,RFI=0,LFI=0,RCE=0,PHPI=0,HTTP=0,SESS=0): individual
paranoia level scores: 5, 0, 0, 0"] [ver "OWASP_CRS/3.3.0"] [tag
"event-correlation"] Apache-Error: [file "apache2_util.c"] [line 273]
[level 3] [client 192.168.101.12] ModSecurity: Warning. Pattern match
"\\\\xbc[^\\\\xbe>][\\\\xbe>]|<[^\\\\xbe]\\\\xbe"
at ARGS:opis. [file
"/etc/httpd/modsecurity.d/activated_rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf"]
[line "546"] [id "941310"] [msg "US-ASCII Malformed Encoding XSS
Filter - Attack Detected"] [data "Matched Data: \\xbc found
within ARGS:opis: \\xc5\\xbc"] [severity "CRITICAL"] [ver
"OWASP_CRS/3.3.0"] [tag "application-multi"] [tag "language-multi"]
[tag "platform-tomcat"] [tag "attack-xss"] [tag "paranoia-level/1"]
[tag "OWASP_CRS"] [tag "capec/1000/152/242"] [hostname "somehost.pl"]
[uri "/somescript.php"] [unique_id
"Y0qHleWp5HLoLWSFDV218QAAAEU"]
UPDATE2
I have reported the issue and found similar issue. As far as I can understand solution will be available in 3.4/dev branch and for current systems some solution can be downloaded from here.
I do not have much experience with installing/updating CRS, so could anybody advice please on how to install currently available solution on the top of CRS 3.3.0.

custom body message email triggering in Riemann

I want to trigger a mail with custom body message. I can parse timestamp in my body, but i want to add the string in my body when i try to add string value in body i'm unable to reproduce it. can anyone help me to resolve it. I'm in very critical implementation.
Please find my sample code below,
(let [email (mailer {:host "cccc"
:port 25
:user "111111"
:pass "111111"
:auth "true"
:subject (fn [events] "1DD Monitoring - Response time SLA breach")
:body (fn [events]
(apply str "Hello Team, now the time is" (:**silo** events) "Thank You!"))
:from "xxx#xxxx.com"})]
I'm sending value from logstash to riemann in silo field and i want to print silo field value in body
IMHO the handle function that you define for :body, has a wrong syntax. According to the doc, you must define a function that takes a sequence of events and return a string. For example:
(defn prn-str [& events]
...)
So you have a :**silo** key in your event. But in the :body function, you will have a list of events. (:**silo** events) will be nil.
You can for example get the :**silo** values separated by a comma with:
:body (fn [events]
(str "Hello Team, now the time is "
(clojure.string/join "," (map #(:**silo** %) events))
" Thank You!"))

Clojure - combine pedestal routes

How do I combine routes in Pedestal ?
(defroutes api-routes [...])
(defroutes site-routes [...])
(combine-routes api-routes site-routes) ;; should be a valid route as well
Note : This is a similar question as Combining routes in Compojure, but for Pedestal.
It's as easy as
(def all-routes (concat api-routes site-routes))
The explanation starts from here https://github.com/pedestal/pedestal/blob/master/guides/documentation/service-routing.md#defining-route-tables, it is stated that
A route table is simply a data structure; in our case, it is a sequence of maps.
pedestal team calls that sequence of maps route table form as verbose format and they design a terse format of route table which is what we supply to defroute. The defroute then transform our terse format to the verbose format.
You can check for yourself in the repl
;; here we supply a terse route format to defroutes
> (defroutes routes
[[["/" {:get home-page}
["/hello" {:get hello-world}]]]])
;;=> #'routes
;; then we pretty print the verbose route format
> (pprint routes)
;;=>
({:path-parts [""],
:path-params [],
:interceptors
[{:name :mavbozo-pedestal.core/home-page,
:enter
#object[io.pedestal.interceptor$eval7317$fn__7318$fn__7319 0x95d91f4 "io.pedestal.interceptor$eval7317$fn__7318$fn__7319#95d91f4"],
:leave nil,
:error nil}],
:path "/",
:method :get,
:path-re #"/\Q\E",
:route-name :mavbozo-pedestal.core/home-page}
{:path-parts ["" "hello"],
:path-params [],
:interceptors
[{:name :mavbozo-pedestal.core/hello-world,
:enter
#object[io.pedestal.interceptor$eval7317$fn__7318$fn__7319 0x4a168461 "io.pedestal.interceptor$eval7317$fn__7318$fn__7319#4a168461"],
:leave nil,
:error nil}],
:path "/hello",
:method :get,
:path-re #"/\Qhello\E",
:route-name :mavbozo-pedestal.core/hello-world})
So, because pedestal route is just a sequence of maps, we can easily combine multiple non-overlapping routes with concat.
That is what I like about one of clojure's principles which pedestal team follows: generic data manipulation which in this case, a verbose formatted route table is just a map--a ordinary clojure's data structure which can be inspected and manipulated with regular clojure.core's data structure manipulation functions such as concat. Even the terse format is also a plain clojure data structure and can easily inspected and manipulated with the same means.

core.typed - Trying to annotate a Record in dependency

I'm trying to annotate the Element record in clojure.data.xml which is:
(defrecord Element [tag attrs content])
I've annotated it as follows:
(t/ann-record Element [tag :- t/Keyword attrs :- (t/HMap :complete? false)
content :- (t/Vec Element)])
And I have the following function which doesn't type check:
(t/ann get-content [Element -> (t/Vec Element)])
(defn get-content [xml]
(:content xml))
with 'Expected: t/Vec clojure.data.xml.Element Actual: t/Any'
I've also tried replacing that with (get xml :content) but it fails with the same output.
I wonder what I'm doing wrong :D
It might be that you need to fully qualify Element in your ann-record call (I'm assuming your code is not actually in the clojure.data.xml namespace).
The docs for ann-record say
...
; a record in another namespace
(ann-record another.ns.TheirRecord
[str :- String,
vec :- (Vec Number)])
...
So in this particular case:
(t/ann-record clojure.data.xml.Element
[tag :- t/Keyword
attrs :- (t/HMap :complete? false)
content :- (t/Vec Element)])

Serving binary files from the database with compojure

I have the following routes definition:
(require '[compojure.core :as ccore]
'[ring.util.response :as response])
(def *main-routes*
(ccore/defroutes avalanche-routes
(ccore/GET "/" [] "Hello World 2")
(ccore/GET "/images/:id" [id] (get-image-response id))))
In this example, requesting / works like a charm and returns the expected Hello World 2.
The get-images-response method is defined like this:
(defn get-image-response
[id]
(let [record (db/get-image id false)]
(-> (response/response (:data record))
(response/content-type (:content-type record))
(response/header "Content-Length" (:size record)))))
I get a 404 though, so the serving of binary files doesn't quite work yet. Any ideas why?
Edit:
Ok, the issue relates to the fact that images are being requested on /images/name.jpg. As soon as I remove the .jpg the handler gets called. So the question becomes how do I match on anything but the extension?
Compojure uses clout for route matching. The dot character has a special meaning in clout routes. It represents a token separator, similarly to the slash character. The following characters all have this meaning in clout: / . , ; ?.
That means that a route like "/images/:id" will not match a uri of the form /images/name.jpg since images, name and jpg each represent a separate token in clout.
In order to match it, you could compose your route in a number of different ways, depending on your need.
If all your images have the .jpg extension, the easiest thing to do would be:
(GET "/images/:id.jpg" [id] ...)
If the extension varies you could do the following:
(GET "/images/:name.:extension" [name extension] ...)
If you want to restrict the extension, you can pass compojure/clout a regular expression:
(GET ["/images/:name.:ext", :ext #"(jpe?g|png|gif)"] [name ext] ...)
You could also go with a wildcard, which is less precise and would match any uri starting with /images/:
(GET "/images/*" [*] ...)
The real answer in this case was that there was a bug in the clojure-couchdb library. The patch is available on github here.
It boils down to adding the {:as :byte-array} map parameter and value to the request sent via clj-http to couch's api.
The other issue in my code was that ring doesn't really know what to do with byte-arrays when it's rendering them. Rather than patching ring, I just wrapped the byte-array into a java.io.ByteArrayInputStream. Here is the complete code for handling the download:
(defn get-image-response
[id]
(let [record (db/get-image id false)]
(-> (response/response (new java.io.ByteArrayInputStream (:data record)))
(response/content-type (:content-type (:content-type record)))
(response/header "Content-Length" (:size record)))))