github-advanced-security[bot] commented on code in PR #72647:
URL: https://github.com/apache/airflow/pull/72647#discussion_r4066722378
##########
providers/amazon/src/airflow/providers/amazon/aws/auth_manager/routes/login.py:
##########
@@ -59,6 +70,101 @@
log = logging.getLogger(__name__)
login_router = AirflowRouter(tags=["AWSAuthManagerLogin"])
+# Name of the short-lived cookie recording which logins this browser has
started.
+COOKIE_NAME_LOGIN_STATE = "_awsam_login_state"
+
+# The login flow is a redirect to the IdP and back. Ten minutes is generous
for that and
+# keeps a stale request id from lingering.
+LOGIN_STATE_MAX_AGE = 600
+
+# One entry per login started and not yet completed, so opening a second tab
does not
+# invalidate the first. The cap bounds the cookie; the oldest pending login is
dropped.
+MAX_PENDING_LOGINS = 5
+
+LOGIN_MODE_REDIRECT = "login-redirect"
+LOGIN_MODE_TOKEN = "login-token"
+LOGIN_MODES = (LOGIN_MODE_REDIRECT, LOGIN_MODE_TOKEN)
+
+NO_LOGIN_IN_PROGRESS = "No login in progress for this browser. Start the login
from Airflow and try again."
+
+
+def _is_secure_request(request: Request) -> bool:
+ return request.base_url.scheme == "https" or bool(conf.get("api",
"ssl_cert", fallback=""))
+
+
+def _allows_idp_initiated_login() -> bool:
+ return conf.getboolean(CONF_SECTION_NAME,
CONF_ALLOW_IDP_INITIATED_LOGIN_KEY, fallback=False)
+
+
+def _sign_login_state(payload: str) -> str:
+ # The API server secret key is already required to be identical across API
servers, so a
+ # login may start on one instance and finish on another.
+ secret = conf.get("api", "secret_key", fallback="")
+ return hmac.new(secret.encode(), payload.encode(), sha256).hexdigest()
+
+
+def _read_pending_logins(request: Request) -> list[dict[str, Any]]:
+ """
+ Return the logins this browser started and has not yet completed.
+
+ This cookie is the browser's half of the binding: it states that *this*
browser asked for
+ these AuthnRequests. A SAML assertion is signed by the identity provider,
which
+ authenticates *the identity in the response* -- it says nothing about
*which browser
+ asked*. Without this, an assertion obtained by an attacker can be replayed
into a
+ victim's browser, logging the victim into the attacker's account.
+
+ Entries are signed so a response cannot contribute one of its own, and
each carries its
+ own deadline so an abandoned tab expires without affecting the others.
+ """
+ raw = request.cookies.get(COOKIE_NAME_LOGIN_STATE)
+ if not raw:
+ return []
+ payload, _, signature = raw.rpartition(".")
+ if not payload or not hmac.compare_digest(signature,
_sign_login_state(payload)):
+ log.warning("Ignoring a login state cookie that this deployment did
not sign.")
+ return []
+ try:
+ entries = json.loads(base64.urlsafe_b64decode(payload))
+ except (ValueError, binascii.Error):
+ log.warning("Ignoring a login state cookie that could not be decoded.")
+ return []
+ if not isinstance(entries, list):
+ return []
+ now = time.time()
+ return [
+ entry
+ for entry in entries
+ if isinstance(entry, dict) and isinstance(entry.get("exp"), (int,
float)) and entry["exp"] > now
+ ]
+
+
+def _write_pending_logins(request: Request, response: Any, entries:
list[dict[str, Any]]) -> None:
+ cookie_path = get_cookie_path()
+ if not entries:
+ response.delete_cookie(COOKIE_NAME_LOGIN_STATE, path=cookie_path)
+ return
+ payload = base64.urlsafe_b64encode(json.dumps(entries, separators=(",",
":")).encode()).decode()
+ response.set_cookie(
+ COOKIE_NAME_LOGIN_STATE,
+ f"{payload}.{_sign_login_state(payload)}",
Review Comment:
## CodeQL / Construction of a cookie using user-supplied input
Cookie is constructed from a [user-supplied input](1).
Cookie is constructed from a [user-supplied input](2).
[Show more
details](https://github.com/apache/airflow/security/code-scanning/657)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]