Vikjuna: Webhook BasicAuth Credentials Exposed to Read-Only Project Collaborators via API
The GET /api/v1/projects/:project/webhooks endpoint returns webhook BasicAuth credentials (basic_auth_user and basic_auth_password) in plaintext to any user with read access to the project. While the existing code correctly masks the HMAC secret field, the BasicAuth fields added in a later migration were not given the same treatment. This allows read-only collaborators to steal credentials intended for authenticating against external webhook receivers.
When listing project webhooks, the ReadAll method in pkg/models/webhooks.go (line 203) only requires project read access:
```go
// pkg/models/webhooks.go:203-244
func (w *Webhook) ReadAll(s *xorm.Session, a web.Auth, _ string, page int, perPage int) (result interface{}, resultCount int, numberOfTotalItems int64, err error) {
p := &Project{ID: w.ProjectID}
can, _, err := p.CanRead(s, a) // Only requires read permission
if err != nil {
return nil, 0, 0, err
}
if !can {
return nil, 0, 0, ErrGenericForbidden{}
}
// ... fetches webhooks from DB ...
for _, webhook := range ws {
webhook.Secret = "" // HMAC secret is masked
// BasicAuthUser and BasicAuthPassword are NOT masked
if createdBy, has := users[webhook.CreatedByID]; has {
webhook.CreatedBy = createdBy
}
}
return ws, len(ws), total, err
}
```
The Webhook struct defines both fields with JSON serialization tags, so they are included in API responses:
```go
// pkg/models/webhooks.go:63-64
BasicAuthUser string xorm:"null" json:"basic_auth_user"
BasicAuthPassword string xorm:"null" json:"basic_auth_password"
```
The BasicAuth fields were added in migration 20260123000717 ("Add basic auth to webhooks"), but the credential masking logic at line 238 was not updated to include these new fields.
The same issue exists in the user webhook listing at pkg/routes/api/v1/user_webhooks.go:65, where Secret is masked but BasicAuth fields are not. This is lower impact since users only see their own webhooks.
1. As User A (project admin), create a project and a webhook with BasicAuth credentials:
```bash
# Create a webhook with BasicAuth on project 1
curl -X PUT "http://localhost:3456/api/v1/projects/1/webhooks" \
-H "Authorization: Bearer $TOKEN_A" \
-H "Content-Type: application/json" \
-d '{
"target_url": "https://external-service.example.com/hook",
"events": ["task.created"],
"secret": "my-hmac-secret",
"basic_auth_user": "service-account",
"basic_auth_password": "S3cretP@ssw0rd!"
}'
```
2. As User B (read-only collaborator on the same project), list webhooks:
```bash
curl -s "http://localhost:3456/api/v1/projects/1/webhooks" \
-H "Authorization: Bearer $TOKEN_B" | jq '.[0] | {secret, basic_auth_user, basic_auth_password}'
```
3. Expected output (secret is masked, but BasicAuth is leaked):
```json
{
"secret": "",
"basic_auth_user": "service-account",
"basic_auth_password": "S3cretP@ssw0rd!"
}
```
In pkg/models/webhooks.go, add masking for BasicAuth fields alongside the existing Secret masking (around line 237):
```go
for _, webhook := range ws {
webhook.Secret = ""
webhook.BasicAuthUser = ""
webhook.BasicAuthPassword = ""
if createdBy, has := users[webhook.CreatedByID]; has {
webhook.CreatedBy = createdBy
}
}
```
Apply the same fix in pkg/routes/api/v1/user_webhooks.go (around line 64):
```go
for _, w := range ws {
w.Secret = ""
w.BasicAuthUser = ""
w.BasicAuthPassword = ""
if createdBy, has := users[w.CreatedByID]; has {
w.CreatedBy = createdBy
}
}
```
This issue can be reached over the network, attack complexity is low, an attacker needs low-level privileges on the target. No user interaction is required. The scope is unchanged, so the impact stays within the vulnerable component. Rated impact: confidentiality high, integrity none, availability none.
The score comes from this vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
CVE-2026-33677 is classified as CWE-200: Exposure of Sensitive Information. Information that should stay internal is disclosed to someone who is not authorised to see it.
CVE-2026-33677 is recorded against 2 packages.
Published on 25 March 2026 and last revised on 26 March 2026. No public exploit is currently recorded for this entry. Record sourced from NVD.
github.com (Web)
nvd.nist.gov (Advisory)
github.com (Package)
vikunja.io (Web)
code.vikunja.io/api has other advisories on record. If you are patching this one, these are worth checking on the same host:
These advisories are the same class of weakness (CWE-200: Exposure of Sensitive Information) in other software:
Details
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Affected Packages
| Software | From version | Fixed in |
|---|---|---|
| code.vikunja.io/api | — | — |
| vikunja | — | 2.2.1 |
References
Similar Threats
Vulnerability Monitoring
CVE-2026-33677 is rated CVSS 6.5 Medium. BotEraser monitors your WordPress installation and notifies you when software you use appears in our vulnerability database.
Set Up Free Alerts →No credit card required · Results in minutes
ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.
Stay up to date with the latest from Boteraser.
We use cookies to improve your experience on our site. By using our site, you consent to cookies.
Manage your cookie preferences below:
Essential cookies enable basic functions and are necessary for the proper function of the website.
CloudFlare provides web performance and security solutions, enhancing site speed and protecting against threats.
Service URL: developers.cloudflare.com (opens in a new window)
These cookies are needed for adding comments on this website.
These cookies are used for managing login functionality on this website.
Statistics cookies collect information anonymously. This information helps us understand how visitors use our website.
Google Analytics is a powerful tool that tracks and analyzes website traffic for informed marketing decisions.
Service URL: policies.google.com (opens in a new window)
You can find more information in our Cookie Policy and Privacy Policy.