-
Notifications
You must be signed in to change notification settings - Fork 121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: added new parameters for parameterized query #597
Conversation
Hi @nekomeowww, DetailsInstructions for interacting with me using comments are available here. |
/auto-cc |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could probably add a new feature gate to differentiate from the AllowRawSQLQuery
/whereSQL
functionality, this pr would allow us to avoid sql injection if the user is using it properly
The whereSQL will be deprecated (tracked by other issues and prs) and removed for 1.0
d304c9b
to
54b349b
Compare
e85ab16
to
7704b60
Compare
7704b60
to
4f30cd5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, Thanks for your contribution
decb06d
to
a4c3ae8
Compare
1. added new `whereSQLStmt` for parameterized query statement 2. added new `whereSQLParams` for parameterized query parameters 3. added new `whereSQLJSONParams` for parameterized query parameters in JSON format with base64 encoding Signed-off-by: Neko Ayaka <neko@ayaka.moe>
Signed-off-by: Neko Ayaka <neko@ayaka.moe>
a4c3ae8
to
e19c45f
Compare
What type of PR is this?
/kind bug
What this PR does / why we need it
As
clusterpedia/pkg/storage/internalstorage/util.go
Lines 58 to 65 in 630cf19
has stated. There are potential SQL injection vulnerabilities of current implementation while users cannot easily defend it due to the lack of support to parameterized query.
This Pull Request
Where(...)
which GORM supports and will pass the required parameters fromwhereSQLParam
andwhereSQLJSONParams
field whenwhereSQLStatement
was used. Newly added fields:whereSQLStatement
, drop-in replacement of the existingwhereSQL
field whilewhereSQL
will be deprecated in the future release.whereSQLParam
, for callers of Clusterpedia API to pass the parameters for the raw SQL. Users can send raw queries more safely by using?
as the placeholder of parameters (which is compatible for GORM) and then include all the corresponding parameters with either one of the newly added fieldwhereSQLParam
andwhereSQLJSONParams
.whereSQLJSONParams
, useful when users need more than juststring
type of values of parameters (e.g.IN
andNOT IN
).AllowParameterizedSQLQuery
feature gate to enable the support ofwhereSQLStatement
,whereSQLParam
, andwhereSQLJSONParams
when transitioning and migrating fromwhereSQL
before its deprecation.For more about the SQL injection of GORM, please read it more here: https://gorm.io/docs/security.html
Disclaimer: the potentials of SQL injection will NEVER be resolved if implementations of caller still use string concatenation to concat the raw SQL query with parameters directly without
whereSQLParam
orwhereSQLJSONParams
when usingwhereSQLStatement
. End users are responsible for defensing and protecting the resources from malicious access at all the time. This Pull Request will only introduce new parameters to help users to defend with parameterized queries.Besides parameterized query, even though the overall security will be improved with this patch, Clusterpedia cannot guarantee there will be no potential threats of SQL injections in the future and should never be when raw SQL involves.
End users should check, validate, monitor and restrict the scope of database access as much as possible to reduce the damage and limit the attacking surface even when it failed to defense.
Which issue(s) this PR fixes
None. This is a known issue.
Special notes for your reviewer
Does this PR introduce a user-facing change?
Test cases
Assumes we have the following resources:
GET
withwhereSQLStatement
and singlewhereSQLParam
with SQL injection statementsCase 1
Parameters with
whereSQLStatement
namespace IN (?)
whereSQLParam
default) OR \( = \
you can test it with
curl --location 'https://localhost:8443/apis/clusterpedia.io/v1beta1/resources/apis/apps/v1/deployments?whereSQLStatement=namespace%20IN%20(%3F)&whereSQLParam=default)%20OR%20%5C(%20%3D%20%5C'
and it will eventually be sent to database and executed like this:
you will get the following resources that returned by database:
Case 2
Parameters with
whereSQLStatement
namespace IN (?)
whereSQLParam
"any" OR 1 = 1) #
you can test it with
curl --location 'https://localhost:8443/apis/clusterpedia.io/v1beta1/resources/apis/apps/v1/deployments?whereSQLStatement=namespace%20IN%20(%3F)&whereSQLParam=%22any%22%20OR%201%20%3D%201)%20%23'
and it will eventually be sent to database and executed like this:
you will get the following resources that returned by database:
GET
withwhereSQLStatement
and singlewhereSQLParam
Parameters with
whereSQLStatement
(namespace IN (?))
whereSQLParam
default
you can test it with
curl --location 'https://localhost:8443/apis/clusterpedia.io/v1beta1/resources/apis/apps/v1/deployments?whereSQLStatement=(namespace%20IN%20(%3F))&whereSQLParam=default'
and it will eventually be sent to database and executed like this:
you will get the following resources that returned by database:
hello-node
default
GET
withwhereSQLStatement
and multiplewhereSQLParam
Case 1
Parameters with
whereSQLStatement
(namespace IN (?, ?))
whereSQLParam
default
whereSQLParam
kube-system
Note
The reason why the query in
whereSQLStatement
consists two?
(question mark) is becausewhereSQLParam
will be parsed as array of strings by default and use the spread syntax in Go to pass the values in to the actual query.Therefore it will be equivalent to
instead of
that you may think of.
you can test it with
curl --location 'https://localhost:8443/apis/clusterpedia.io/v1beta1/resources/apis/apps/v1/deployments?whereSQLStatement=(namespace%20IN%20(%3F%2C%20%3F))&whereSQLParam=default&whereSQLParam=kube-system'
and it will eventually be sent to database and executed like this:
hello-node
default
coredns
kube-system
Case 2
Parameters with
whereSQLStatement
(namespace = (?) OR namespace = (?))
whereSQLParam
default
whereSQLParam
kube-system
you can test it with
curl --location 'https://localhost:8443/apis/clusterpedia.io/v1beta1/resources/apis/apps/v1/deployments?whereSQLStatement=(namespace%20%3D%20(%3F)%20OR%20namespace%20%3D%20(%3F))&whereSQLParam=default&whereSQLParam=kube-system'
and it will eventually be sent to database and executed like this:
hello-node
default
coredns
kube-system
GET
withwhereSQLStatement
andwhereSQLJSONParams
As you may noticed, users must explicitly write down how many variables/parameters have with the same number of
?
(question mark) when usingwhereSQLParam
. This is not flexible enough for users who may want to treat any length of arrays as a single variable/parameter and represent it with a single?
(question mark). This is wherewhereSQLJSONParams
might be helpful for such use case and scenario.Parameters with
whereSQLStatement
(namespace IN (?))
whereSQLJSONParams
W1siZGVmYXVsdCIsImt1YmUtc3lzdGVtIl1d
(the base64 encoded of[ [ "default", "kube-system" ] ]
)you can test it with
curl --location 'https://localhost:8443/apis/clusterpedia.io/v1beta1/resources/apis/apps/v1/deployments?whereSQLStatement=(namespace%20IN%20(%3F))&whereSQLJSONParams=W1siZGVmYXVsdCIsImt1YmUtc3lzdGVtIl1d'
and it will eventually be sent to database and executed like this: