Open m-erhardt opened 1 month ago
The way I read it is that the apiKey only needs VIEW_BADGES permission. If such a key leaks, it's no worse than the current unauthenticated badge?
I agree, IF a user configures this correctly it does not matter if API keys with only an VIEW_BADGE
permission are exposed.
That's why I opened this issue as an "enhancement", not an actual security issue.
My thinking however follows the principle of Poka yoke. A system should be designed in a way that prevents the user from making dangerous mistakes.
InfoSec guys have tried educating developers and admins for years that API keys should be kept secret and how not to expose them.
Now DependencyTrack implements a feature that forces users to expose some API keys and expects every developer to always be fully aware of DependencyTracks security model.
My experience tells me it is probably a matter of weeks rather than months until a user accidentially exposes an API key with additional permissions this way.
Simple solution proposal: If a group gets VIEW_BADGES Permission, ensure no other permission can be assigned additionally. If another one was assigned already, prevent assigning of VIEW_BADGES with some hint.
@rkg-mm : not perfect but certainly a huge step in the right direction.
I could still think of developers trying to implement a badge for their repo, seeing the apiKey
-parameter and accidentially using an API key that was given to them i.e. for SBOM uploads.
So your proposed solution would make them aware of the mishap AFTER they've accidentialy exposed a more powerful API key.
As research from the past years has shown it takes malicious crawlers only minutes to pick up leaked secrets from public repos and start using them.
So to prevent further damage an immediate rollover of the exposed API key would still be required.
I see how this adds a new angle for human error. But what are realistic safeguards for an API that shares sensitive information but is also typically used publicly?
One of your proposed solutions, allowing an admin to disable authentication for badges on an instance level, is already there. It's planned to be an temporary feature, but unauthenticated access to badges could be kept around. Though I'm not sure what the use case for that would sound like...in case you don't trust your users to handle API keys or violates company compliance on exposing security keys?
The past option to entirely disable badges could be put back in too, if you want to lock down your instance more.
EDIT: That is already possible, if you switch on authentication for badges but don't give any team the VIEW_BADGES
permission.
As for disabling it on a project basis, that should already be possible through Portfolio Access Control if your admin uses separate teams for badges.
But that is all irrelevant if you don't trust either users/clients to use the right API key or admins to create and/or hand out a key that doesn't accidentally have more permission than intended.
The other proposed solutions here suggest introducing a separate authentication methods (nonces) or an additional permission assignment logic that's exclusive to VIEW_BADGES
. That would be a way, but just for badges?
Are there other enhancement proposals for Dependency-Track's current authentication and authorization that could benefit from additional methods and logic? @valentijnscholten
As for how other tools do it, I know of SonarQube, that presents a badge url generation UI under a project's settings, which creates a project specific badge URL with a project specific and renewable token. It separates the process from the usual permission management, reducing the chances of human error. But it still hands out a token to the user/client.
What is the use-case of having authentication on badges? I can understand you might not want to share this information "publicly". But if you put a secret in the url, you'll more or less lost straightaway? Are there use-cases where having a secret in the url to display badges makes sense? Honest question.
Either way, the apiKey is meant to interact with the API. The secret in the url is not really matching that purpose. Might it make more sense to just have a per project settings to show badges publicly/with-a-secret/not-at-all?
Well, one first needs to find where badges from your DT instance are used. Not a huge hurdle, but a hurdle compared to open access to anyone who knows the address of your instance and project names and versions. But if you combine it with portfolio access control, you can really limit access properly, along with the ability to revoke keys and access granularly on a project basis. At least that's how Steve's original suggestion for it made sense to me.
The lack of the ability to limit access to projects' evaluations, i.e. exposing all of my DT instance's projects' vulnerability counts, was what kept me from turning badges on on my instance. Steve's suggestion was a welcome and natural one, given DT's current access control system. Doesn't mean alternatives couldn't be implemented with badges in mind...up to DT's maintainers to decide.
API keys are the current way to authorise requests, i.e. connect them to teams, and thus make use of DT's current implementation of access control to projects. Using that, it is already possible to control "with-a-secret/not-at-all." Offering access publicly (without a secret) on a project basis would need to be implemented as a new feature. But what would be the use case of that? Some projects being more sensitive than others?
@SaberStrat : It's not that I generally do not trust my users to handle secrets. Not every user is always fully aware of the differentiated security model of every system they use. So sometimes when educating users/developers we need to oversimplify.
An oversimplification that works pretty good is "treat all API keys/passwords/credentials/private keys as secrets and store them as such".
It is visually impossible to distinct an API key which grants full administrative permssions to a system from an API key that only grants read-only access to a particular feature.
That's why the idea that some DependencyTrack API keys can and need to be exposed while others need to remain secret bothers me so much. It just bears a huge potential for mishaps.
The security model of my DependencyTrack instance would allow me to run the badge API endpoint without any authentification but I agree that other, internet-accessible instances, have this requirement as it is a potential "information disclosure weakness".
That's why I suggested an alternative authentification mechanism (nonces) in the first place.
The security model of my DependencyTrack instance would allow me to run the badge API endpoint without any authentification but I agree that other, internet-accessible instances, have this requirement as it is a potential "information disclosure weakness".
That's why I suggested an alternative authentification mechanism (nonces) in the first place.
Interesting points of view, thank you for explaining.
What do you think @nscuro, should we
@SaberStrat I am still interested to know how you would use these urls with a secret in it to authenticate for badges. Let's say you have the URL https://dt.com/project/12345/badges?token=9876. What will you do with it? Will it be put in a README? On an intranet? Some dashboard or scorecard? Or only in emails? Is there a scenario where you can use these without "leaking" the token too broadly?
@sschuberth I am still interested to know how you would use these urls
I guess you meant @SaberStrat?
Correct, fixed.
@valentijnscholten I don't know yet what the best implementation might be be, and it's not guaranteed I will before 4.13, which was originally intended to be the version to remove unauthenticated access to badges. But since @m-erhardt has a use case where unauthenticated access is safer for him than working with API keys, there might be reason to postpone the removal (or even keep it altogether).
Will have to read up how nonces work and could work here.
Off the top of my head, I'm indeed thinking of some URL containing a project-specific (or project-version-specific) token. It should be possible to use it in Markdown docs (e.g. READMEs), HTML docs, so should be a URL without the need of a header. But I'm not all that versed with all use cases of badges either, so I can't say for sure if there aren't other formats that would be sufficiently universal too and safer than what URL allow. But, if targeted for use in committed files, whether that project specific token is likely to leak or not would be up to the way the DT instance is used. The badge API as it is now, could be kept around and can be used with an API key.
Badges are by nature things that are potentially shown off publicly. Vulnerabilities don't have to be shared with the public, but can - like this project does here on GitHub for example. So it should be possible to display them in public, but should be possible to limit what can be accessed with that URL.
Current Behavior
I've just upgraded my DependencyTrack instance to 4.12 and read about the the new "authenticated Badge API" feature (#3596, #4059) in the changelog.
Whilst I am a strong supporter of security I am deeply concerned about the way this feature is implemented (in combination with how Git hosting platforms have implemented badge support).
Most Git repo hosting platforms like GitLab, GitHub, Gitea, Forgejo, etc embed badge-URLs in the HTML-DOM of the page (either via an explicit Badge-feature like GitLab or embedding an image in a Markdown file within the repo) and clients load the badge-svg directly from DependencyTrack.
Given the way the feature is implemented I would have to append an
apiKey
-URL-parameter to the badge URL which would then leak to all users/clients, even with readonly support to the repo. Plus I would need to commit the API key to the repo for platforms which only support badges via embedded images in Markdown.This might be unproblematic and only require a secret-scanning exception when using a properly scoped API token which only has the
VIEW_BADGES
permission but considering the nature of users it is only a matter of time until a user uses/leaks an API key with way more permissions this way - putting the security of my DependencyTrack instance in a worse place than before the "authenticated Badge API" feature.Is there anyone else sharing my concerns?
Proposed Behavior
This could potentially be resolved by
Checklist