Skip to content

Instantly share code, notes, and snippets.

@EnoF
Created July 5, 2023 09:12
Show Gist options
  • Save EnoF/20fe992c28333b1fe5c90fe9e36608b9 to your computer and use it in GitHub Desktop.
Save EnoF/20fe992c28333b1fe5c90fe9e36608b9 to your computer and use it in GitHub Desktop.
Example of an vulnerable module

Capabilities and Referenced modules vulnerability

Modules can be brought into scope dynamically. This can be done like:

(defun test(referenced-module:module{interface-of-module})
  (module::a-function-that-is-defined-on-the-interface))

This is useful for it's dynamic nature, but brings potential vulnerabilities with it. If you were to call a referenced module function, you should always try to avoid bringing capabilities into scope that guard private or sensitive functions.

So the following is HIGHLY DISCOURAGED:

(defun test(referenced-module:module{interface-of-module})
  (with-capability (PRIVATE)
    (module::a-function-that-is-defined-on-the-interface)))

Instead if you have a private function you want to call along side the referenced module, make sure to scope it appropiately:

(defun test(referenced-module:module{interface-of-module})
  (module::a-function-that-is-defined-on-the-interface) ; either before
  (with-capability (PRIVATE)
    (some-private-function)) ; but not within the capability scope
  (module::a-function-that-is-defined-on-the-interface)) ; or after
(begin-tx)
(interface foo
(defun bar:bool()))
(module baz G
(defcap G() true)
(implements foo)
(defun bar:bool()
(enforce true "I'm a good module")))
(module vulnerable-module GOVERNANCE
(defcap GOVERNANCE() true)
(defcap WRITE-COUNTER() true)
(defschema counter-schema
counter:integer)
(deftable counter-table:{counter-schema})
(defun some-private-function()
(require-capability (WRITE-COUNTER))
(with-default-read counter-table 'counter
{ 'counter : 0 }
{ 'counter := counter }
(write counter-table 'counter
{ 'counter : (+ counter 1) })))
(defun up-counter(check:module{foo})
(with-capability (WRITE-COUNTER)
(check::bar)
(some-private-function)))
(defun get-counter()
(with-default-read counter-table 'counter
{ 'counter : 0 }
{ 'counter := counter }
counter))
)
(create-table counter-table)
(module hack G
(defcap G() true)
(implements foo)
(defun bar:bool()
(vulnerable-module.some-private-function)
(vulnerable-module.some-private-function)
(vulnerable-module.some-private-function)
(vulnerable-module.some-private-function)
(enforce true "I'm faking to be a good module"))
)
(commit-tx)
(begin-tx)
(expect-failure
"Should not be able to call some-private-function without WRITE-COUNTER capability"
"require-capability: not granted: (vulnerable-module.WRITE-COUNTER)"
(vulnerable-module.some-private-function))
(expect "Counter to not have increased"
0
(vulnerable-module.get-counter))
(commit-tx)
(begin-tx)
(vulnerable-module.up-counter baz)
(expect "Counter to have increased"
1
(vulnerable-module.get-counter))
(commit-tx)
(begin-tx)
(vulnerable-module.up-counter hack)
(expect "Counter to have increased - BUT WAY TOO MUCH!"
6
(vulnerable-module.get-counter))
(commit-tx)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment