Invisible security requires friction first

Because a security decision without friction is just resilience without reality.

Since I’ve been more involved in blue team operations and the corresponding decision making processes, it has been similar to the experience of waking up, going into the shower, turning on the hot water and being shocked into reality with an avalanche of ice cubes.

That feeling of reality being the opposite of your expectation, reminded me of when I stood on the side lines as an advisor or when I performed offensive operations and had to agree on rules of engagement, scope and if we would attack production or not. There are many opinions on if you should target production or not, my personal opinion is that performing attacks on production are the the only way to have the most assurance that all measures and processes are working as intended. With this, I don’t exclude performing certain tests on test or acceptance environments first due to many reasons we are all well aware of.

Now, the above paragraph is an example of the reluctance of touching production. This reluctance and paradox on improvement versus impact, exists as well and even more on the defense side as we will see later on in this blog post.

This fear is usually exhibited, with the following question:

…but what if you bring the system down or disrupt our business process?

Which on itself is a very valid question to ask. However, what usually followed, in the same breath, always seemed a bit off for me. Because in a lot of situations it ended with:

We cannot permit the slightest down-time or business impact due to security testing.

Which, again, on itself is a valid concern or statement. However, if we add the context of: are you then prepared to quickly recover if it goes down due to an actual attacker? It changes what a valid answer could be.

For me back then that answer provided an unexpected insight. We feel more comfortable prioritizing a stable environment based on assumptions, than a resilient environment based on reality.

What I was and still am really missing is the replacement of fear with the realisation that it is an opportunity to improve the resilience of those systems and processes. You have the best ingredients to achieve this, since you know and work with the attackers.
If something goes down you CAN actually perform root cause analysis with the ‘attackers’ being part of that process. Yes, you will still incur business loss or said in business terms ‘paying your resilience premium’. However, if properly executed and used as an opportunity to improve you will have less losses during a real attack.

The usual way forward is of course to build in a myriad of cautious technical & process steps to minimize the chances of the security test bringing down the system in scope and/or impact the business process. Which basically leaves the brittleness in the same state as before the test.
There is no friction for the decision maker, the entirety of the risk can in the offensive example be offloaded to the testers or the systems can be taken out of scope, that’s it, problem solved.

If we now switch back to the blue team side, I see that same frictionless decision making playing out. A different example, but the same thought process, is the classical:

* Allow response on all employees
* Exclude certain employees due to business impact

The second decision is frictionless you don’t have to take any further action or think about it. You’ll just deal with it, if it ever happens. The first decision creates friction since it forces you to think about:

* What parts of the work flow of that employee are the really important aspects of their workflow and how can you facilitate that workflow while at the same time responding to an incident on their workstation or account?

For example, what if the critical process of their workflow is email. And we would be able to understand that 30m of email downtime is acceptable? This would give the blue team 30m to isolate and if not resolved at least allow the email connection to carry-on, accepting the risk of that being part of the attacker communication flow, but preventing all other communication.

The answer is a lot of time “business impact” without really fully defining it, since after all, it is easier to choose the option with the least amount of friction.

We must start to define 'business impact' together; the business and the security teams. Otherwise we will forever be stuck in a frictionless decision process.

As long as we don’t change this mindset on the blue team side, no amount of tools will truly help us. AI as well as many other forms of automation have the capability to change the game at scale for defense, but they won’t achieve their full potential if we don’t change our decision making processes.

Makes you ponder if the following could be true, since instinctively it contradicts the mantra of making security frictionless to achieve greater outcome. My personal opinion is that to get to invisible & effective security you need to put in the effort (friction) to truly understand the problem space.

The Law of Frictionless Security: If a security decision requires no change to a business process, it likely provides no change to your actual resilience.

Recon your patents with GenAI?

I recently came across MindYourPass.io and my curiosity was triggered on how it worked. So I read the website which sounded intruiging, but did not seem to contain a lot of nitty gritty technical details. The website does mention that the solution is based on patented technology.

Now this sounds like a nice opportunity to brush op on potential legal-speak as well as understanding a software solution by reading instead of going down the technical route. As an added bonus, we can take one of those fancy GenAI things for a spin and see if it helps to quickly digest patent text.

Do note that since a patent walks a fine line between claiming the idea and not giving away all the information, that my conclusions and interpretation may be incorrect. This risk is increased due to the use of GenAI. Which is used as an experiment to better understand the advantages or limitations of using GenAI for summarization and interpretation of patents.

After talking a bit with Gemini I was pretty amazed that it summarized the gist of the patent pretty well. I skimmed through the patent myself and without verifying all details it seems to make sense (yes I know the devil is in the details). It didn’t even take that many questions to obtain a general understanding of the key components of the patent. The following questions represent my entire conversation:

  • are you familiar with mindyourpass?
  • Do you have any sources for a whitepaper and corresponding patents?
    • yes, I would like to have a more technical summary
  • does the patent describe which factors are used exactly and in which order they are processed?
  • Would it be fair to summarize this invention as a Key Derivation Function, which retrieves the inputs from different places?
  • Can you represent the patent in a python function? Since after all, it concerns a KDF as the basis for the concept?

The code result for the last question can be seen below:

import hashlib

def calculate_mindyourpass_password(
    user_master_secret: str,     # Factor 1: The key known only by the user
    application_domain: str,     # Factor 2: Uniquely identifies the website (e.g., 'amazon.com')
    device_id_token: str,        # Factor 3: Unique key from the authorized device
    backend_static_salt: str,    # Factor 4: Key retrieved from the backend (distributed secret)
    password_policy: dict        # Factors 5/6: Formatting rules (min_len, special chars, etc.)
) -> str:
    """
    Conceptual implementation of the MindYourPass deterministic, distributed KDF.
    
    This function simulates the process described in US11947658B2:
    It takes distributed inputs, hashes them deterministically, and formats the output.
    """
    
    # --- Step 1: Combine Distributed Factors ---
    # The actual proprietary formula uses 6 factors combined in a specific, secret order.
    # We conceptually concatenate the primary inputs here.
    
    # We include the application's required length/policy to ensure the hash input 
    # changes if the requirements change (e.g., a site updates its minimum length).
    policy_str = f"len:{password_policy.get('min_length', 16)}_chars:{password_policy.get('charset_type', 'complex')}"
    
    # The factors are combined deterministically (order is crucial)
    combined_input = (
        user_master_secret + 
        application_domain + 
        device_id_token + 
        backend_static_salt + 
        policy_str
    )
    
    # Encode the input string to bytes for hashing
    input_bytes = combined_input.encode('utf-8')

    # --- Step 2: Cryptographic Hashing (SHA-512) ---
    # The patent specifies 512-bit SHA2 hashing.
    raw_hash_output = hashlib.sha512(input_bytes).hexdigest()

    # --- Step 3: Formatting & Post-Processing ---
    
    # The final password must conform to the target application's policy.
    # This example truncates and enforces a simple character set conversion.
    
    target_length = password_policy.get('min_length', 16)
    
    # Truncate and use as the deterministic password (e.g., first 16 chars)
    password = raw_hash_output[:target_length]
    
    # NOTE: The actual implementation involves sophisticated mapping 
    # to enforce capitalization and special characters dynamically. 
    # This step is highly complex in the real product.

    return password

# --- Example Usage ---

# 1. Define the distributed inputs (retrieved from different places)
USER_KEY = "MyEasyToRememberPhrase!"
SITE_ID = "MyBankingSite.com"
DEVICE_TOKEN = "ABCD-1234-EFGH-5678"  # Only this device can generate it
SERVER_SALT = "aHk57gJmT8pQ4zR"       # A distributed secret key

# 2. Define the application's policy rules
BANK_POLICY = {
    'min_length': 20,
    'charset_type': 'complex'
}

# 3. Calculate the password
derived_password = calculate_mindyourpass_password(
    USER_KEY, 
    SITE_ID, 
    DEVICE_TOKEN, 
    SERVER_SALT, 
    BANK_POLICY
)

print(f"Input: {USER_KEY}, {SITE_ID}, {SERVER_SALT[:5]}...")
print(f"Generated Password (Length {len(derived_password)}): {derived_password}")

Of course, this is an over simplification, since I’m assuming that the actual software uses more cryptography for individual steps to for example slow down potential attacks that might involve brute forcing parts of the process. However the core concepts does become pretty clear, pretty fast.

All in all, using patents as part of your reconnaissance into software was always a good idea. Now with GenAI it has become even more accessible and more important, it has become fast! You still need to manually revise the patent, to understand if GenAI makes sense, but the big picture can be obtained pretty darn fast.