Skip to content

Commit

Permalink
Merge pull request #11 from openshift/master
Browse files Browse the repository at this point in the history
Close HttpSession and validate redirects
  • Loading branch information
coreydaley authored Jun 27, 2023
2 parents 27e08df + 6e6a223 commit 5d7030b
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
import java.io.Serializable;
import java.util.UUID;

import javax.servlet.http.HttpSession;

import org.kohsuke.stapler.HttpRedirect;
import org.kohsuke.stapler.HttpResponse;
import org.kohsuke.stapler.Stapler;
Expand All @@ -50,7 +52,7 @@
* Verifies the validity of the response by comparing the state.
*/
@SuppressWarnings("serial")
public abstract class OAuthSession implements Serializable{
public abstract class OAuthSession implements Serializable {
private static final String OPENSHIFT_ENABLE_REDIRECT_PROMPT = "OPENSHIFT_ENABLE_REDIRECT_PROMPT";
private final AuthorizationCodeFlow flow;
private final String uuid = Base64.encode(UUID.randomUUID().toString().getBytes(UTF_8)).substring(0, 20);
Expand Down Expand Up @@ -111,6 +113,11 @@ protected HttpResponse doRequestAuthorizationCode() {
*/
public HttpResponse doFinishLogin(StaplerRequest request)
throws IOException {
HttpSession session = request.getSession(false);
if (session != null) {
session.invalidate();
}
request.getSession(true);
StringBuffer buf = request.getRequestURL();
if (request.getQueryString() != null) {
buf.append('?').append(request.getQueryString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ public class OpenShiftOAuth2SecurityRealm extends SecurityRealm implements Seria
* transport that will only leverage the JVMs default keystore and allow for the
* jenkins SA cert and the oauth server router cert varying such that SSL
* handshakes will fail if we exclusively use the jenkins SA cert
*
*
*/
private static HttpTransport jvmDefaultKeystoreTransport;

Expand Down Expand Up @@ -877,7 +877,7 @@ protected OAuthSession newOAuthSession(String from, final String redirectOnFinis
LOGGER.info(format("AuthorizationCodeFlow using : authorizationServerURL=[%s], ", authorizationServerURL));
final AuthorizationCodeFlow flow = new AuthorizationCodeFlow.Builder(queryParameters, transportForThisRequest,
JSON_FACTORY, tokenServerURL, clientAuthentication, defaultedClientId, authorizationServerURL)
.setScopes(scopes).build();
.setScopes(scopes).build();
final OpenShiftOAuth2SecurityRealm secRealm = this;
final String url = buildOAuthRedirectUrl(redirectOnFinish);
BearerTokenOAuthSession bearerTokenOAuthSession = new BearerTokenOAuthSession(flow, from, url, redirectOnFinish,
Expand Down Expand Up @@ -1044,11 +1044,28 @@ public HttpResponse loggedOut(@QueryParameter String from, @Header("Referer") fi
return new OpenShiftHttpRedirectWithPrompt("/");
}

/**
* Validate that any possible redirect url begins with the Jenkins instance root
* url.
*/
private boolean isValidRedirect(String url) {
return url.startsWith("/") || url.toLowerCase(DEFAULT_LOCALE_PERMISSION)
.startsWith(Jenkins.getInstance().getRootUrl().toLowerCase(DEFAULT_LOCALE_PERMISSION));
}

/**
* The login process starts from here.
*/
public HttpResponse doCommenceLogin(@QueryParameter String from, @Header("Referer") final String referer)
throws IOException {

if (!from.isEmpty() && !isValidRedirect(from)) {
throw new MalformedURLException("invalid redirect [" + from + "]");
}
if (referer != null && !isValidRedirect(referer)) {
throw new MalformedURLException("invalid redirect " + referer);
}

LOGGER.entering(OpenShiftOAuth2SecurityRealm.class.getName(), START_METHOD, new Object[] { from, referer });
LOGGER.info("doCommenceLogin: Coming from: " + referer);
if (referer.contains(LOGGED_OUT)) {
Expand Down Expand Up @@ -1177,13 +1194,13 @@ protected String getPostLogOutUrl(StaplerRequest req, Authentication auth) {
* @return the computed access token name on the openshift side
*/
public static String tokenToObjectName(String code) {
// for empty string or null, we will return an empty string to avoid any NPE
// for empty string or null, we will return an empty string to avoid any NPE
if (code == null) {
code = EMPTY_STRING;
}
// if the token code doesn't start with SHA256_PREFIX, we will
// return the code itself as the token name. This is the expected behaviour
// with ocp 4.5 and lower. if it starts with the prefix, we
// if the token code doesn't start with SHA256_PREFIX, we will
// return the code itself as the token name. This is the expected behaviour
// with ocp 4.5 and lower. if it starts with the prefix, we
// have to compute the sha_256 digest
if (code.startsWith(SHA256_PREFIX)) {
code = code.substring(SHA256_PREFIX.length());
Expand Down

0 comments on commit 5d7030b

Please sign in to comment.