Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot use relative link #22

Open
smartmeta opened this issue Oct 8, 2020 · 4 comments
Open

Cannot use relative link #22

smartmeta opened this issue Oct 8, 2020 · 4 comments

Comments

@smartmeta
Copy link

smartmeta commented Oct 8, 2020

I'm trying to set up a relative link

grafik

The link is displayed:

grafik

But I get

grafik

What do I need to configure that the simple link /test.html works?

(Adding the Protocol/Host/Port is not possible because jenkins is also available via ssh tunnel with other host/port.)

@KalleOlaviNiemitalo
Copy link
Contributor

KalleOlaviNiemitalo commented Feb 27, 2022

When this issue was filed in October 2020, Sidebar Link 1.11.0 was the latest version.

The "disabled" message matches what is in LinkAction/index.jelly. This template doesn't seem to contain any logic for whether the "disabled" message should be displayed or not. I think the idea is that, if the link is not safe, then LinkAction.getUrlName() returns a string that includes a hash code like "unsafeLink-123456789", and if a user then clicks the link, the browser uses that string as a relative URI reference, and Jenkins then displays LinkAction/index.jelly because the HTTP request URI now matches what getUrlName() returns.

LinkAction.getUrlName() calls LinkProtection.verifyUrl(String urlString), which allows relative URI references:

// Let's check if the scheme is allowed
String scheme = uri.getScheme();
if (scheme != null) { // we do not check undefined schemes like relative links
String toCheck = scheme.toLowerCase();
if (!ALLOWED_URI_SCHEMES.contains(toCheck)) {
StringBuilder bldr = new StringBuilder("URI scheme \"");
bldr.append(toCheck).append("\" is not allowed. Allowed schemes: ");
bldr.append(getAllowedUriSchemes());
return FormValidation.error(bldr.toString());
}
}

When you get the "disabled" message, does the URI of the page include "unsafeLink", or does it match the "test.html" URI to which you wanted to link? Maybe the Sidebar Link plugin considers the relative URI reference safe and returns "/test.html" from LinkAction.getUrlName(), but when the Web browser tries to follow the link, this same getUrlName method causes Jenkins to map the request to the LinkAction object and not to the item to which you wanted to link. If that theory is correct, then perhaps the problem can be fixed by making getUrlName() always return an absolute URI when the link is safe, by combining the configured relative URL reference with the request URI.

@KalleOlaviNiemitalo
Copy link
Contributor

KalleOlaviNiemitalo commented Feb 27, 2022

Action.getUrlName() javadoc:

If the returned string starts with '/', like '/foo', then it's assumed to be relative to the context path of the Jenkins webapp.

Returns:
null if this action object doesn't need to be bound to web (when you do that, be sure to also return null from getIconFileName().

I think LinkAction.getUrlName() should just always return null, so that incoming HTTP requests can never be mapped to LinkAction objects. There should instead be a LinkAction/action.jelly file that takes over the rendering when included from actions.jelly in core. For unsafe links, there could be a dedicated RootAction that just displays the error message, and LinkAction/action.jelly would link to that.

@KalleOlaviNiemitalo
Copy link
Contributor

Actionable.getDynamic seems to distinguish "/test.html" from "test.html" though. I don't see how this could map "https://jenkins.example/test.html" to LinkAction if LinkAction.getUrlName() returns "/test.html". Should try it in practice.

@KalleOlaviNiemitalo
Copy link
Contributor

Oh, Jenkins.getDynamic has a looser comparison that matches even if Action.getUrlName() returns a string that starts with a slash. So, I think "/test.html" currently fails if set as a sidebar link in the global configuration, but works if set in the configuration of a job, folder, or agent. "/userContent/test.html" should work everywhere, though. Also, "test.html#" should work around the problem because the incoming HTTP request URI won't ever contain a fragment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants