ignite icon indicating copy to clipboard operation
ignite copied to clipboard

`withContext` can bypass security plugins

Open icode opened this issue 8 months ago • 4 comments

ignite.context().security().withContext function can bypass security plugins!

ignite.context().security().withContext should call authenticate(context: AuthenticationContext) function!

ignite version: 2.17.0

ignite.context().security().withContext((ignite.cluster().forRemotes().node() ?: ignite.localNode()).id())
// then can query not authenticated cache
val cache = ignite.cache<String, Any>("DataSource")
// this `size` function not call `authenticate(context: AuthenticationContext)`
println("1. //////////////////////////// ${cache.size()}")
try {
// this `forEach` function not call `authenticate(context: AuthenticationContext)`
    cache.forEach {
        println(it)
    }
} catch (e: Exception) {
    println("e. ////////////////////////////")
    e.printStackTrace()
}
println("2. ////////////////////////////")
    override fun authenticatedSubject(subjId: UUID): SecuritySubject? {
        val n = ctx.discovery().node(subjId)
        if (n != null) {
            return this.nodeSecurityContext(n)!!.subject()
        }
    }

    private fun nodeSecurityContext(node: ClusterNode): SecurityContextImpl? {
        val subjBytesV2 = node.attribute<Any?>(IgniteNodeAttributes.ATTR_SECURITY_SUBJECT_V2) as ByteArray?
        if (subjBytesV2 == null) {
            val subj = SecuritySubjectImpl(
                node.id(),
                SecuritySubjectType.REMOTE_NODE,
                address = InetSocketAddress(node.addresses().first(), 0),
                permissions = SecurityPermissionSetBuilder.ALL_PERMISSIONS,
                nodeId = node.id()
            )
            return SecurityContextImpl(subj)
        } else {
            return U.unmarshal<Any?>(
                this.marsh,
                subjBytesV2,
                U.resolveClassLoader(ctx.config())
            ) as SecurityContextImpl?
        }
    }

icode avatar Apr 15 '25 17:04 icode

@icode , why should cache operations call #authenticate? Authentication occurs during node join to the cluster. Once joined, the node is already authenticated.

shishkovilja avatar Sep 23 '25 18:09 shishkovilja

@icode , why should cache operations call #authenticate? Authentication occurs during node join to the cluster. Once joined, the node is already authenticated.

So, can 'withContext' be used to bypass any role and permission? The 'withContext' interface should not be disguised as any node.

icode avatar Sep 24 '25 01:09 icode

"Role" and "permission" are parts of authorization, not authentication. You should take this into account in your plugin.

shishkovilja avatar Sep 24 '25 06:09 shishkovilja

"Role" and "permission" are parts of authorization, not authentication. You should take this into account in your plugin.

The withContext interface not callback authorize and SecurityPermission enum no has withContext permission, any authenticated's client can be disguised as any node. Perhaps I couldn't find the interface for checking, please let me know if there is.

icode avatar Sep 24 '25 09:09 icode