Closed Sjord closed 5 days ago
You argue that the impact is lower if the attacker has access to a session token instead of an API key. Regardless as whether that is true or not, that is not the whole picture.
We don't control what data the attacker compromises. Using session tokens does not mean that the credentials are now necessarily more secure. An application can put credentials in a log file whether it uses a session mechanism or not.
Risk does not only consist of impact but also of probability. The probability that either the session token or the credentials are exposed is very small. I don't think the probability of credentials being intercepted scales linearly with the number of times they are used. In my opinion, it does not make much sense to reduce the number of times credentials are used.
The cost of a session mechanism is non-zero, both in terms of performance as in security. It adds multiple round trips to set up and tear down the session. It also requires keeping state, or doing cryptography, to manage session tokens. This can introduce additional bugs.
A world where an attacker has a session token may be preferable to a world where they have an API key. But that is not sufficient to say that session tokens are more secure than API keys.
If an attacker gets access to an individual request
This is not part of my threat model, and probably also not of ASVS threat model. We don't propose to do client-side password hashing, for example.
the question is whether you have a problem with one or both and how we can bridge that gap
I have a problem with both. I think you need to have a good reason to disallow fixed API keys. The current motivation seems insufficient to me.
What could possibly convince me are examples of attacks that would have been prevented by these requirements, or more arguments about the probability and attack scenarios and why the costs of a session mechanism way up against the risk.
You argue that the impact is lower if the attacker has access to a session token instead of an API key. Regardless as whether that is true or not, that is not the whole picture.
We don't control what data the attacker compromises. Using session tokens does not mean that the credentials are now necessarily more secure. An application can put credentials in a log file whether it uses a session mechanism or not.
Yes but it is a lot less likely if they are just using the credentials infrequently to generate the session as opposed to sending the credential on every request.
Risk does not only consist of impact but also of probability. The probability that either the session token or the credentials are exposed is very small. I don't think the probability of credentials being intercepted scales linearly with the number of times they are used. In my opinion, it does not make much sense to reduce the number of times credentials are used.
There are also options such as mTLS or locally generated in which the credentials are never transmitted so the probability of exposure in transit or in request leakage becomes zero.
The cost of a session mechanism is non-zero, both in terms of performance as in security. It adds multiple round trips to set up and tear down the session. It also requires keeping state, or doing cryptography, to manage session tokens. This can introduce additional bugs.
This depends on the implementation and certainly this is a well explored problem with minimal need to reinvent the wheel.
A world where an attacker has a session token may be preferable to a world where they have an API key. But that is not sufficient to say that session tokens are more secure than API keys.
They are certainly more secure in isolation. I think your point is more a question of does it justify the investment and what is the risk of other security vulnerabilities arising in the session mechanism. I think that having this as a L2 or L3 requirement reflects that trade off.
If an attacker gets access to an individual request
This is not part of my threat model, and probably also not of ASVS threat model. We don't propose to do client-side password hashing, for example.
I think I didn't explain myself clearly. My point is that with static keys, it is enough for an attacker to gain access to any individual request out of the 10s or 100s of requests which are sent to the API. If we are not using static keys then the attacker either has to gain access to the specific authentication request or there may be no authentication request to gain access to in the first place.
What could possibly convince me are examples of attacks that would have been prevented by these requirements, or more arguments about the probability and attack scenarios and why the costs of a session mechanism way up against the risk.
Leakage of sensitive data into logs is endemic and often a hard problem to solve. With static keys this is potentially even more problematic because even if a request body is not being logged then the headers may well be (where the fixed key will almost certainly be transmitted in a header).
For static keys there is also no defined standard for where they should be sent.
For example, in this GitLab documentation a static key can be sent in the following locations which logging sanitization of secrets would potentially have to take into account:
private_token
query parameterPRIVATE-TOKEN:
headerAuthorization: Bearer
headerjob_token
query parameterJOB-TOKEN:
headerGitHub seems to have less token types and be more consistent on the use of an Authorization:
header.
In summary, static API or intra-service secrets are significantly more exposed than other solutions. I don't think it is unreasonable to have an L2 or L3 requirement on service creators for a more secure mechanism. I also don't think it is unreasonable to have a L3 on service consumers to use the most secure method available.
Yes but it is a lot less likely if they are just using the credentials infrequently
My point is that with static keys, it is enough for an attacker to gain access to any individual request out of the 10s or 100s of requests which are sent to the API. If we are not using static keys then the attacker either has to gain access to the specific authentication request
You seem to suggest that if you only send the credentials in 1% of the requests, the chance of compromise is reduced by ~100. Is that correct? This assumes that there is a non-zero per-message probability that it is compromised. I don't think that's true.
I consider TLS connections perfectly secure. I don't think it's possible "for an attacker to gain access to any individual request". Even if TLS weren't secure, the connection would be compromised, not a single HTTP interaction. In practice, f there is some TLS bug or misconfigurations, probably all connections would be compromised.
Both session tokens and credentials are being logged. You can log credentials, whether you use sessions or not. I am not sure that using sessions reduces the chance of logging credentials. If a log is compromised, it probably contains both the setup and use of the session.
I don't think it is as simple that using credentials less often directly reduces the risk that they are compromised.
Feels in the loop...
I'm not convinced we need it as a requirement, it seems to be so edge-case and 2nd or 3rd layer of defense. From the ASVS side, the risk for me is - if we put this as a requirement to solve one certain problem for some edge-case scenario, we create a rule that is not suitable or is not really needed for other situations. But, maybe I missed something.
Likelihood
For this defense mechanism to be relevant, an attacker must have gained a level of access or visibility into the system that allows them to intercept or access static credentials. This could involve:Network sniffing or man-in-the-middle attacks to intercept credentials in transit. Accessing improperly secured storage where credentials are kept. Exploiting a vulnerability in one of the services that exposes sensitive information. The likelihood is tied to the assumption that the attacker is either within the network or has compromised a component of the system to a degree where they can attempt to access or intercept credentials.
What risk does it solve vs. what risk does it create to implement it?
Solves: Reduces the risk of credential compromise by ensuring that credentials are not static and are difficult to reuse even if they are intercepted. Limits the time window an attacker has to exploit stolen credentials. Increases the complexity of targeted attacks, as attackers must constantly gain access to the updated credentials.
Creates: Implementation complexity, including the need for a secure and robust system to manage the rotation and distribution of credentials. Potential performance overhead due to more frequent authentication processes. The risk of system outages or service disruptions if the dynamic secret management system fails or if there are synchronization issues.
Situations and solutions it is suitable for:
High-security environments where the risk of internal or sophisticated external attacks is significant. Systems that are already employing layered security measures and where the infrastructure supports secure secret management solutions (e.g., services with built-in support for secret rotation and management like AWS Secrets Manager, HashiCorp Vault).
Situations and solutions where it is not suitable:
Small-scale or low-risk environments where the implementation overhead does not justify the security benefits. Legacy systems that cannot support dynamic secrets management without significant refactoring. Environments where the operational complexity and cost of managing dynamic secrets outweigh the potential security benefits.
In essence, while rotating intra-service secrets can significantly enhance security, it requires a careful balance between security benefits and operational feasibility. The decision to implement such a measure should be based on a thorough risk assessment, considering the specific threats, security posture, and operational capabilities of the organization.
Thanks for sharing a very interesting discussion, I hope this will contribute!
When my colleagues and I do security reviews and advise customers on service-to-service communication (without user interaction) we often highlight the risk of not rotating secrets.
Having a plan for rotating secrets ("service credentials", not personal user passwords) is important for secure service integrations over time and I believe it would be a good thing if ASVS included a requirement for that (perhaps L2 or L3).
If a secret is well-protected and there are additional layers of defense, like least privilege secret scope, proper network segmentation, end-to-end securely configured TLS, monitoring and alarms on secret usage, then you could argue that a particular secret could be rotated less frequently, compared to a powerful secret for a service accessible from public internet (without additional defenses.)
But (I my opinion) all secrets should have an expiration and rotation plan (at least for L3.) In example this is recommended/required for all secrets managed in services like Azure Key Vault https://learn.microsoft.com/en-us/azure/governance/policy/samples/cis-azure-1-1-0#ensure-that-the-expiration-date-is-set-on-all-secrets
Given this background and experiences, I have always interpreted that the key aspect of 2.10.1 is "unchanging", so a suggestion is to have a L2 or L3 requirement in ASVS that more clearly capture that, like this:
"Verify that for all secrets (except personal user account passwords) there is a plan to rotate the secret according to applicable threat models, policies and requirements. "
This does not address the "how often" question, as it depends...and is hard to express in a good way, for some scenarios a reasonable plan might be once a year or when someone leaves the group having access to the key (as part of an off-boarding procedure)
Hope this was good input!
Seems, that Jim's chatbot kind of agrees with my views.
@tghosth - the discussion here is quite long and contains many different topics (sessions, rotating creds, etc). Just in case please repeat your latest proposals, to be sure that everyone is talking about and commenting on the same thing.
Some comments from Twitter:
Client Assertion Grant....can be used e2e without the issues we see with mTLS termination gaps And get Vault to manage the short lived certs
https://twitter.com/j_w_holland/status/1775519957964460360
I think it is a relatively useless debate. Risk appropriate secrets management is the control. Static keys in code are bad. Static restricted per application keys pulled from a vault as needed are not the same thing.
https://twitter.com/wimremes/status/1775419262934352068
Asymmetrical signed JWT + JWKS, with auto key pair rotation monthly + a NONCE claim attribute (ideally).
https://twitter.com/darraghduffy/status/1775633935365472590
I am going to close this as it seems it has been resolved. @tghosth
The text is currently as follows. If there are still concerns, ping me here and I will reopen:
# | Description | L1 | L2 | L3 | CWE |
---|---|---|---|---|---|
14.7.1 | [MODIFIED, MOVED FROM 2.10.1, MERGED FROM 1.2.2] Verify that communications between back-end application components which don't support the application's standard user session mechanism, including APIs, middleware and data layers, are authenticated. Authentication should use individual service accounts, short-term tokens or certificate based authentication and not unchanging credentials such as passwords, API keys or shared accounts with privileged access. | ✓ | ✓ | 287 |
2.10.1:
What does this mean? How should you authenticate to other services? My application currently authenticates to the database server using username and password, and uses API keys to access several API's. Is that in violation of this requirement?
What is the proper way to do manage intra-service secrets? Can we rephrase this to a positive requirement instead of a negative requirement?
What does it mean for a secret to rely on credentials? When are credentials unchanging?
What was the original purpose of this requirement?
See also https://github.com/OWASP/ASVS/issues/763.