Allow Mod-Security for request uri - mod-security

I am trying to add exemption for Mod-security rule in REQUEST-900-before file for the following request :-
`1668035916.075452 [00] [client 127.0.0.1] ModSecurity: Access denied with code 403 (phase 2). 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:queryEditor. [file "/etc/modsecurity/owasp-modsecurity-crs/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf"] [line "183"] [id "942190"] [msg "Detects MSSQL code execution and information gathering attempts"] [data "Matched Data: \x22SELECT . found within ARGS:queryEditor: {\x22title\x22:\x22Untitled Query 1\x22,\x22dbId\x22:null,\x22schema\x22:null,\x22autorun\x22:false,\x22sql\x22:\x22SELECT ...\x22,\x22queryLimit\x22:1000}"] [severity "CRITICAL"] [ver "OWASP_CRS/3.3.0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-sqli"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/152/248/66"] [tag "PCI/6.5.2"] [hostname "a938b1191f37"] [uri "http://iq.haproxy.xyz/tabstateview/"] [unique_id "0A000806:E240_AC110002:01BB_636C354C_0033:0024"]`
Is there any-way of just saying to Mod-security allow this request
I have tried this : -
`SecRule REQUEST_URI "^http://iq\.haproxy\.xyz/tabstateview/$" \
"id:1000,\
phase:2,\
pass,\
nolog,\
ctl:ruleRemoveTargetById=942190;ARGS:queryEditor"`
Not able to make it work

REQUEST_URI does NOT contain a domain name, see:
https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-(v2.x)#request_uri
If you want an exclusion rule that si tied also to the domain name, i suggest this rule:
SecRule SERVER_NAME "#streq iq.haproxy.xyz" \
"id:1000,\
phase:1,\
pass,\
t:none,\
nolog,\
chain"
SecRule REQUEST_FILENAME "#streq /tabstateview/" \
"t:none,\
ctl:ruleRemoveTargetById=942190;ARGS:queryEditor"

Related

Datomic invalid connection config

I tried the following code to create a datomic database and connect to it:
(let [cfg (-> env :datomic-cfg)
client (d/client cfg)]
(do
(d/create-database
client
{:db-name "humboi-march-2021"})
(d/connect client {:db-name "humboi-march-2021"})))
However, I’m getting the following error:
Execution error (ExceptionInfo) at datomic.client.impl.pro/create-spi (pro.clj:72).
Invalid connection config: {:server-type :peer-server, :access-key "key-0680cb34675d5fd59", :secret "<ELIDED>", :endpoint "http://entry.humboi-2021.us-east-1.datomic.net:8182", :validate-hostnames false}
How to fix this?
Your uri has to be a string, for example I use:
(let [uri "datomic:free://localhost:4334/name"]
(d/create-database uri)
(d/connect uri))

wrap-cors middleware not working with system.components

I have the following system.components middleware config, in which I'm using the ring.middleware wrap-cors, to allow for redirects to an external server:
(defn config []
{:http-port (Integer. (or (env :port) 5000))
:middleware [[wrap-defaults api-defaults]
wrap-with-logger
wrap-gzip
ignore-trailing-slash
[wrap-reload {:dir "../../src"}]
[wrap-trace :header :ui]
wrap-params
wrap-keyword-params
wrap-cookies
[wrap-cors :access-control-allow-headers #{"accept"
"accept-encoding"
"accept-language"
"authorization"
"content-type"
"origin"}
:access-control-allow-origin [#"https://some-url"]
:access-control-allow-methods [:delete :get
:patch :post :put]]
]})
And this is supposed to insert headers into every response. But instead, on a request from the client which leads to a redirect to https://some-url, I get the following error in the client browser:
Access to XMLHttpRequest at 'https://someurl' (redirected from 'http://localhost:5000/some-uri') from origin 'http://localhost:5000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Why aren't the correct headers in the response despite adding the middleware?
-- EDIT --
I've also tried the [jumblerg.middleware.cors] wrap-cors middleware like so:
(defn config []
{:http-port (Integer. (or (env :port) 5000))
:middleware [[wrap-defaults api-defaults]
wrap-with-logger
wrap-gzip
ignore-trailing-slash
[wrap-reload {:dir "../../src"}]
[wrap-trace :header :ui]
wrap-params
wrap-keyword-params
wrap-cookies
[wrap-cors #".*"]
]})
And have added the headers using liberator like so:
(defresource some-route [redirect-uri]
:available-media-types ["application/json"]
:allowed-methods [:post]
:post-redirect? true
:as-response (fn [d ctx]
;; added headers
(-> (as-response d ctx)
(assoc-in [:headers "Access-Control-Allow-Origin"] "*")
(assoc-in [:headers "Access-Control-Allow-Headers"] "Content-Type")
)
)
;; redirect uri
:location redirect-uri
)
But still get the ````No 'Access-Control-Allow-Origin' header is present on the requested resource.``` error
Try this library to (wrap-cors):
[jumblerg/ring-cors "2.0.0"]
like this:
(wrap-cors your-routes identity)
Note the third parameter is a function to determine if an origin is allowed (or a list of reg exp)
You might have to add a manual route though:
(OPTIONS "/yourendpoint" req {:headers {"Access-Control-Allow-Headers" "*"}})

post-redirect? not working in liberator or Preflight response is not successful

I have the following code:
defresource handle-sign-in [redirect-uri]
:available-media-types ["application/json"]
:allowed-methods [:post]
:post! (prn "welcome to post")
:post-redirect? (fn [_] ;;(ring-response
{:location redirect-uri}
;;)
)
)
When I send the request, I get the errors Preflight response is not successful and XMLHttpRequest cannot load [authorize-uri] due to access control checks.
When I wrap the redirect location map around ring-response, however, I don't get the errors but neither do I get the redirect in the browser. What am I doing wrong?
-- EDIT --
This is my system.components config.
(defn config []
{:http-port (Integer. (or (env :port) 5000))
:middleware [[wrap-defaults api-defaults]
wrap-with-logger
wrap-gzip
ignore-trailing-slash
[wrap-reload {:dir "../../src"}]
[wrap-trace :header :ui]
wrap-params
wrap-keyword-params
wrap-cookies
[wrap-cors #".*"]
]})
and this is what my new resource looks like:
(defresource handle-sign-in [authorize-uri]
:available-media-types ["application/json"]
:allowed-methods [:post]
:post-redirect? true
:as-response (fn [d ctx]
(-> (as-response d ctx) ;; default implementation
(assoc-in [:headers "Access-Control-Allow-Origin"] "*")
(assoc-in [:headers "Access-Control-Allow-Headers"] "Content-Type")
)
)
:location authorize-uri
)
But I still get the "No 'Access-Control-Allow-Origin' header is present on the requested resource." error.
Please read about CORS. You'd need to either implement the OPTIONS method in the resource or wrap your handler with appropriate middleware, e.g. ring-cors.

Send gzip requests with clj-http

How do I send a gzipped request using the dakrone/clj-http client? So far I have:
(http/post <<REDACTED>>
{:body (->> <<REDACTED>>
cheshire.core/generate-string
.getBytes
clj-http.util/gzip)
:content-type "application/json"
:content-encoding "gzip"
:as :json})
But elasticsearch (the server in my case) is giving 500 errors Illegal character ((CTRL-CHAR, code 31)): only regular white space.
Any ideas?
I guess that you need to enable HTTP compression on the server, e. g. in the Elasticsearch config:
http.compression: true

Clojure, Compojure-api: Access Request headers

I am trying to implement request end point authentication. For that I want to access accessToken value from request headers.
My GET request end Point is
CURL Command
curl -X GET \
'http://localhost:3000/hello?id=10' \
-H 'accesskey: 23423sfsdfsdfsfg' \
-H 'cache-control: no-cache' \
-H 'content-type: application/json' \
-H 'postman-token: f69b34e6-4888-ec31-5fbc-b734e176571b' \
-d '{
"artwork": {id" : 1}
}'
HTTP Command
GET /hello?id=10 HTTP/1.1
Host: localhost:3000
Content-Type: application/json
accessKey: 23423sfsdfsdfsfg
Cache-Control: no-cache
Postman-Token: b974719d-5e1d-4d68-e910-e9ca50562b2f
My Code for GET Method Implementation
(defapi app
(GET ["/hello/:id", :id #"[0-9]+" ] [id]
(log/info "Function begins from here")
(def artworkData (logic/artwork-id (->> id (re-find #"\d+") Long/parseLong)))
(def data (if (not-empty artworkData)
{:data artworkData :status 200}
{:data [] :status 201}))
(ok data)))
I want to fetch accessKey: 23423sfsdfsdfsfg from request header.
Is there any way to get the value and use in my GET Method?
I am using POSTMAN to test all API end points.
Compojure has custom destructuring syntax (i.e., different from Clojure proper) for the parameters. You can bind the whole request map using keyword :as
(defapi app
(GET ["/hello/:id", :id #"[0-9]+" ] [id :as request]
If you want only request headers, the following should work
(defapi app
(GET ["/hello/:id", :id #"[0-9]+" ] [id :as {:headers headers}]
Note that this still allows you to bind path parameter id.
The Compojure Sweet API functions like [compojure.api.sweet :refer [defroutes GET PUT context]] let us bind the whole request or bind select headers. In the snippet below [:as request] makes the whole request available to me.
(GET
"/download/:id"
[:as request]
:header-params [{x-http-request-id :- X-Http-Request-Id nil}]
:path-params [id :- (describe String "The encoded id of the image")]
:summary "Download the image bytes"
:description "This endpoint responds 307 - Temporary Redirect to a cacheable presigned S3 URL for the actual bytes."
(let [http-response (->> request
walk/keywordize-keys
util/extract-base-url
(transform/generate-resource-url (util/decode-key id))
status/temporary-redirect)
expire-time (-> 3 hours from-now coerce/to-date ring-time/format-date)]
(log/infof "x-http-request-id is %s" x-http-request-id)
(response/header http-response "Expires" expire-time)))
The vector beginning :header-params [{x-http-request-id :- X-Http-Request-Id nil}] makes the value of the "X-HTTP-REQUEST-ID" header in the request available to my function directly as x-http-request-id.
The squiglies thing {...} makes the presence of x-http-request-id header optional in the request.
The :- X-Http-Request-Id nil stuff gives it a Schema which is defined somewhere else like (s/defschema X-Http-Request-Id (rss/describe String "Request ID for tracing calls")).
Once you've got those kids bound to names you just work with the names. The compojure folks don't do a great job at documenting everything you can do there. Poke around their examples and you'll find stuff like this.
I have figured out solution to the issue. Please check solution here.
(ns clojure-dauble-business-api.core
(:require [compojure.api.sweet :refer :all]
[ring.util.http-response :refer :all]
[clojure-dauble-business-api.logic :as logic]
[clojure.tools.logging :as log]
[clojure-dauble-business-api.domain.artwork]
[cheshire.core :as json])
(:import [clojure_dauble_business_api.domain.artwork Artwork]))
(defapi app
(GET ["/hello/:id", :id #"[0-9]+"] [id :as request]
(log/info "Function begins from here" request)
(def jsonString (json/generate-string (get-in request [:headers])))
(log/info "Create - Access Key is " (get-in (json/parse-string jsonString true) [:accesskey]))
(def artworkData (logic/artwork-id (->> id (re-find #"\d+") Long/parseLong)))
(def data (if (not-empty artworkData)
{:data artworkData :status 200}
{:data [] :status 201})))
I don't think it is smart way.
Can you anybody look into my solution and tell me Is there another way to get accesskey?