Firewalling your code
61–70 of 82 posts
Re: Firewalling your code
#62- Not using ES modules which is compounded by: - Creating a random "bag of crap" as I call it by throwing all the functions into an exported object - Can't even get static build time feedback about the functions you're calling or if they even eixst which you would if:
The better alternatives here are:
- Just have plain exported *functions* in an ES module - If you need shared state both functions access then export a plain class in an ES module
Re: Firewalling your code
#63I think the general concept here is putting in place restrictions on what code can do in service of making software more reliable and maintainable. The analogy I like to use is construction. If buildings were built like software, you'd see things like a light switch in the penthouse accidentally flushing a toilet in the basement. Bugs like that don't typically happen in construction because the laws of physics impose…
The concept is quite old, and it's called software architecture.
All established software architechture patterns implicitly and explicitly address the problems of managing dependencies between modules. For example, the core principle of layered/onion architecture or even Bob Martin's Clean Architecture is managing which module can be called by which module.
In compiled languages this is a hard constraint due to linking requirements and symbol resolution, but interpreted languages also benefit from these design principles.
Re: Firewalling your code
#64Earlier quoted context omitted.
Letting a static analyzer do these checks is a sane approach! The runtime detection of code files is really weird and would fail with bundling etc.
Runtime is important if security matters. Assume an attacker has already compromised your program - how much damage can they do? If you check at runtime you can prevent the compromised code from calling your functions. Well maybe, we don't know what code was compromised or how it was, but many compromises are a buffer overflow that only runs a few hundred bytes of code (overflow more than that and you clobber somethi…
Re: Firewalling your code
#65Sounds similar to capabilities: https://en.wikipedia.org/wiki/Capability-based_security
Capabilities is what you get if you keep traveling down this road, deal with the resulting issues, tune the approach, and iterate on it a lot. It doesn't take long to figure out that partitioning permissions by "what functions can be called" is a nice start, and I don't mean to criticize it as a start, but it is only a start. It isn't the correct dimension of the code to cut on. Capabilities is, in my opinion, the bi…
Re: Firewalling your code
#66I think the general concept here is putting in place restrictions on what code can do in service of making software more reliable and maintainable. The analogy I like to use is construction. If buildings were built like software, you'd see things like a light switch in the penthouse accidentally flushing a toilet in the basement. Bugs like that don't typically happen in construction because the laws of physics impose…
> I think the general concept here is putting in place restrictions on what code can do in service of making software more reliable and maintainable. The analogy I like to use is construction. The concept is quite old, and it's called software architecture. All established software architechture patterns implicitly and explicitly address the problems of managing dependencies between modules. For example, the core pri…
Re: Firewalling your code
#67Earlier quoted context omitted.
I love how the comments are split along the lines of, "wait, some people don't do this?" and "this is a maintenance nightmare!" If you know, you know.
> this is a maintenance nightmare! Yeah, it's a pain to maintain, but it is damn secure.
Re: Firewalling your code
#68Earlier quoted context omitted.
> this is a maintenance nightmare! Yeah, it's a pain to maintain, but it is damn secure.
Assuming reasonable factoring, maintenance is only a problem when trying to seriously cheat the layers, eg your controller wants to modify the template engine’s internals for a single request. Better to just be honest about it by punching a hole in the abstraction that is appropriately named and using that.
For example, I stop creating SQL, after the first layer above the DB access layer. Everything above that, is a function-based abstraction, so there's no SQL, in most of the stack.
Some layers are meant to introduce "replacement points," so you could swap out the SQL for a NoSQL solution, if you want.
Most layers have a fair bit of validation and permission-checking, etc.
But making sure that I stick to the rules for each layer can be a pain. I stick to them, anyway.
Re: Firewalling your code
#69Always feels like you're in a dysfunctional place when you have to program this defensively. I had an acquaintance who was writing library code for a few dozen data engineers in python, and she had to resort to locking down private methods by checking the call stack after engineers repeatedly got hold of private objects, or objects that are only there sometimes (e.g. when not running clustered). I adopted a similar s…
Were these leaky abstractions built on top of other libs?
Re: Firewalling your code
#70For example, you can ensure lower-level packages don't import higher-level ones:
[importlinter:contract:my-layers-contract]
name = Layered architecture
type = layers
layers =
mypackage.cli # can import anything
mypackage.services # can't import from mypackage.cli
mypackage.models # can't import from .cli or .services