Preventing certain actions within a block (e.g network access)

I have a recurring idea, that I believe could be of value in a number of
circumstances, and wanted to solicit feedback from the list before
attempting to build it.

My use-case would be a superset of something like WebMock which prevents
HTTP requests by monkey patching common libraries.

without_networking do
   # anything on the network in this block raises an exception
end

In general, I suppose this could be mostly implemented by simply taking the
Webmock approach and monkey patching or refining common Socket operations.
I fear however that this wouldn't necessarily be comprehensive. At least C
extensions would easily bypass this, and perhaps already opened sockets
would still be usable within the block.

My ideas range from "a wrapper binary that uses LD_PATH to inject a syscall
interceptor" (which can be toggled on-and-off from Ruby), this seems
fraught with issues. Alternatively leveraging TracePoint to catch a large
portion of the calls to libraries (this still leaves the C extension issue)

The concept here isn't for security, but to avoid developer mistakes by
doing a dynamic analysis on running code during tests, or even in
"production" code to ensure that "side-effects" are isolated to a few key
places in the code.

Possibly I'm trying to bend Ruby too far here, and would be better served
by a language that models effects comprehensively.

Does anyone on the list have suggestions?

Kind regards,

Lee Hambley
http://lee.hambley.name/
+49 (0) 170 298 5667

Hi, Lee -- that's a very interesting idea. I'm guessing you could go far
with Module extends/includes, hooking into const loading, or maybe using
refinements. It depends on how implicit/explicit you the prohibitions to be
and/or how you want the blocks to behave. For example, can they access
their outer scope or do they need all values passed in?

You mentioned isolating side-effects in production to certain areas of
code, which seems like the opposite behavior. Only inside the blocks would
a side-effect be allowed.

I wonder if folks would engage in a new (empty) Github repo using issues or
README/documentation PRs as a lightweight RFC process?

Good luck!

Ryan

···

On Mon, Feb 10, 2020 at 1:54 PM Lee Hambley <lee.hambley@gmail.com> wrote:

I have a recurring idea, that I believe could be of value in a number of
circumstances, and wanted to solicit feedback from the list before
attempting to build it.

My use-case would be a superset of something like WebMock which prevents
HTTP requests by monkey patching common libraries.

without_networking do
   # anything on the network in this block raises an exception
end

In general, I suppose this could be mostly implemented by simply taking
the Webmock approach and monkey patching or refining common Socket
operations. I fear however that this wouldn't necessarily be comprehensive.
At least C extensions would easily bypass this, and perhaps already opened
sockets would still be usable within the block.

My ideas range from "a wrapper binary that uses LD_PATH to inject a
syscall interceptor" (which can be toggled on-and-off from Ruby), this
seems fraught with issues. Alternatively leveraging TracePoint to catch a
large portion of the calls to libraries (this still leaves the C extension
issue)

The concept here isn't for security, but to avoid developer mistakes by
doing a dynamic analysis on running code during tests, or even in
"production" code to ensure that "side-effects" are isolated to a few key
places in the code.

Possibly I'm trying to bend Ruby too far here, and would be better served
by a language that models effects comprehensively.

Does anyone on the list have suggestions?

Kind regards,

Lee Hambley
http://lee.hambley.name/
+49 (0) 170 298 5667

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

--
Ryan Cook
Simple and to everyplace but the point.
720.319.7660

Hi Ryan,

Good suggestion, but I tried a bit, made some OK progress with TracePoint
for doing this, but decided against it ultimately. In a laguage where
referring to a constant can change the way math works, any notion of trying
to prevent, or limit, or even put guard-rails on side-effects is an
exercise in futility.

It's a shame, really, I think it could be really useful, but keeping tabs
on those things is just unreasonably difficult and tracepoint won't work
properly for C extensions anyway.

Thanks for engaging with me non the less,

Lee Hambley

+49 (0) 170 298 5667

···

On Mon, 17 Feb 2020 at 03:53, Ryan Cook <cookrn@gmail.com> wrote:

Hi, Lee -- that's a very interesting idea. I'm guessing you could go far
with Module extends/includes, hooking into const loading, or maybe using
refinements. It depends on how implicit/explicit you the prohibitions to be
and/or how you want the blocks to behave. For example, can they access
their outer scope or do they need all values passed in?

You mentioned isolating side-effects in production to certain areas of
code, which seems like the opposite behavior. Only inside the blocks would
a side-effect be allowed.

I wonder if folks would engage in a new (empty) Github repo using issues
or README/documentation PRs as a lightweight RFC process?

Good luck!

Ryan

On Mon, Feb 10, 2020 at 1:54 PM Lee Hambley <lee.hambley@gmail.com> wrote:

I have a recurring idea, that I believe could be of value in a number of
circumstances, and wanted to solicit feedback from the list before
attempting to build it.

My use-case would be a superset of something like WebMock which prevents
HTTP requests by monkey patching common libraries.

without_networking do
   # anything on the network in this block raises an exception
end

In general, I suppose this could be mostly implemented by simply taking
the Webmock approach and monkey patching or refining common Socket
operations. I fear however that this wouldn't necessarily be comprehensive.
At least C extensions would easily bypass this, and perhaps already opened
sockets would still be usable within the block.

My ideas range from "a wrapper binary that uses LD_PATH to inject a
syscall interceptor" (which can be toggled on-and-off from Ruby), this
seems fraught with issues. Alternatively leveraging TracePoint to catch a
large portion of the calls to libraries (this still leaves the C extension
issue)

The concept here isn't for security, but to avoid developer mistakes by
doing a dynamic analysis on running code during tests, or even in
"production" code to ensure that "side-effects" are isolated to a few key
places in the code.

Possibly I'm trying to bend Ruby too far here, and would be better served
by a language that models effects comprehensively.

Does anyone on the list have suggestions?

Kind regards,

Lee Hambley
http://lee.hambley.name/
+49 (0) 170 298 5667

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

--
Ryan Cook
Simple and to everyplace but the point.
720.319.7660

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;