-
-
Notifications
You must be signed in to change notification settings - Fork 735
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
Implement Content Security Policy, including moving all CSS and JS to external files #966
Implement Content Security Policy, including moving all CSS and JS to external files #966
Conversation
a50dc6c
to
d0cf7cb
Compare
@evernat have you had a chance to look at this PR? I'm eager to address any feedback in order to get this work merged - thank you again! |
javamelody-core/src/main/java/net/bull/javamelody/Parameter.java
Outdated
Show resolved
Hide resolved
I looked at the PR, thank you for that. There is much to read and to test. |
Yeah, it's a big one... Is there anything I can do to help? As I mentioned, I'm quite eager to get this merged :) |
The PR is not bad, but there are things broken by the PR. It needs tests and I will try to list some issues. |
🎉
:( I'm eager to eager what so I can address those issues.
Do you mean some kind of automated tests are required? I don't see any testing framework in JavaMelody. |
When having Maven versions in the webapp and when choosing a period by version at the top of the main report, it does nothing. It should refresh the page with the period of the version. |
There is junit. But given it's JS and CSP, I was speaking of manual tests. |
When clicking on "Execute the garbage collector", the confim message displays |
In the Threads details, clicking on the "Send a thread interrupt signal" or "Kill the tread" actions display a confirm message "null" instead of "Do you confirm ..." and "... Do you really want ..." |
about:blank works for all browsers and doesn't use inline javascript therefore doesn't violate a content security policy which prohibits inline script.
innerHTML is unsafe; use document.createElement to create elements then set attributes on them.
Move the BOOMR.init call to boomerang.min.js and include boomerang.min.js using a script tag. Use attributes on the script tag to pass necessary data to the script which is used to call BOOMR.init.
Avoid a CSP inline script violation. See: prototypejs/prototype#320
Move all inline CSS and inline Javascript to monitoring.css and monitoring.js
Since no javascript is dynamically generated, methods to escape javascript are no longer necessary or used.
I missed
Fixed
Fixed I've now addressed everything you reported; if you have any more findings or other feedback, please let know! |
d0cf7cb
to
2a643c5
Compare
Happy 2021! 🥳 I have my 🤞 that the merging of this PR will be a great new start to the new year! |
@evernat could you please take another look at this PR? |
Hello @evernat - please let me know if there's anything I can do to help this PR along |
I have made some tests and there are some issues:
|
I've pushed a fix for this issue.
I've pushed a fix for this issue.
I can't reproduce this one. I moved the slider and I can see that the image src keep changing, and does do in the same way as the demo site does.
I've pushed a fix for this issue. Thanks again for pointing out these issue - hopefully we're close to being able to merge this now 🤞 |
@evernat friendly bump - I'd love to make progress and get this change merged, thanks again! |
@evernat is there anything I can do to help this along? |
Sorry for the delay.
|
Hi, So my plan is:
The work in this PR is already huge and probably the bigger I have seen in a PR for javamelody. It's not bad if it is not ready yet given the task that it is. |
The I'm sorry I keep having issues... without comprehensive tests and since I'm not fully familiar with all of the functionality across the entire interface, it's really hard for me to find all the problems. I'm trying though! Do you have any other issues? I'll happily fix them. If you'd like the commits rebased for clarity, I can do that. I was (and still am) unclear on if you intend to squash all the commits. I really want to get this into JavaMelody. I've been trying for almost 6 months; it's important to myself and my colleagues. Can we do anything to accelerate the process? |
Given the number of commits in the branch, yes the commits would be squashed to be merged. |
@@ -197,16 +198,16 @@ private void writeJCacheKeys(JCacheInformations jcacheInformations) throws IOExc | |||
writeDirectly(htmlEncodeButNotSpace(myKey)); | |||
writeDirectly("</td>"); | |||
if (systemActionsEnabled) { | |||
writeDirectly("<td class='noPrint' style='text-align: center;'>"); | |||
writeDirectly("<td class='noPrint containingIcon'"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
>
was missing here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch, thank you!
Is there a status on the merge of the rest of this branch? I'm seeing that the css and js externalize work was merged, but has the CSP implementation been pushed through? |
@evernat Do you know the state of this merged code? |
This hasn't actually been merged to master - it's been "merged" to a branch: https://github.com/javamelody/javamelody/tree/content-security-policy I don't know if or when @evernat intends to merge this work to master and include it in a release, nor do I know what's blocking it. I've been trying to get this done for 7 months but @evernat is very slow to respond and I'm honestly not sure how to progress this. I'm starting to think CSP will simply never happen in JavaMelody, despite my dedication to it. :-( |
Generally speaking, you could note that my time to work on that is not infinite. And that it could not be merged if there are known issues or if after many reviews / fixes, review for merge is needed to be sure to avoid blocking regressions for a lot of users. See PR #1012 for example, where fixes of about one line of code out of five has a review, just to scratch the surface. In this PR #966 thanks to @candrews, work and changes were risky and big as the needed reviews. You may look at other major opensource projects, where most issues are not answered for years and closed without explanation, to compare with javamelody. |
+ "' onclick=\"javascript:return confirm('" | ||
+ getStringForJavascript("confirm_purge_caches") + "');\">"); | ||
writeln("<a class='confirm' href='?action=clear_caches" + getCsrfTokenUrlPart() | ||
+ "' data-confirm=\"" + I18N.htmlEncode("confirm_purge_caches", false, false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The message is not translated anymore here.
writeDirectly(cacheNameEncoded); | ||
writeDirectly("&cacheKey="); | ||
writeDirectly(urlEncode(myKey)); | ||
writeDirectly(csrfTokenUrlPart); | ||
writeDirectly("' onclick=\"javascript:return confirm('"); | ||
writeDirectly("' data-confirm\""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
=
is missing here
writeDirectly(confirmClearCache); | ||
writeDirectly("');\">"); | ||
writeDirectly("\");\">"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
\");
should not be here
write(id); | ||
write("'>"); | ||
write("<em><img src='?graph=" + graph + "&width=100&height=50' id='"); | ||
write("id" + graph); | ||
write("' alt='graph'/></em>"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
after this change, these images are no longer lazy loaded when onmouseover
}); | ||
|
||
$$('.deploymentPeriod').invoke("observe", "click", function(event){ | ||
showHide('customPeriod'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if this was used, it would have displayed the custom period form instead of the deployment period form
var test = document.createElement('input'); test.type = 'date'; | ||
if(test.type === 'text') { | ||
document.customPeriodForm.pattern.value = ''; | ||
document.getElementById('customPeriodPattern').style.display='inline'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it would have been better to not remove comments on this code
return false; | ||
} | ||
if (periodForm.endDate.value.length == 0) { | ||
alert('Dates are mandatory'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is no longer translated. Moreover the translations for "Dates are mandatory" are left in properties files for nothing.
@@ -212,62 +210,24 @@ private void writeHtmlHeader(boolean includeSlider, boolean includeCssInline) | |||
if (includeSlider) { | |||
writeln("<script type='text/javascript' src='?resource=slider.js'></script>"); | |||
} | |||
writeln("<script type='text/javascript' src='?resource=monitoring.js'></script>"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when includeCssInline above, includes of prototype.js and monitoring.js are missing
writer.write("');location.href='"); | ||
writer.write(redirectTo); | ||
writer.write("';</script>"); | ||
writeHtmlBegin(writer); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same writeHtmlBegin(writer);
is missing in the writeMessage method.
final String endOnClickConfirm = "\">"; | ||
writeln("<a class='confirm' href='?action=pause_job&jobId=all" | ||
+ getCsrfTokenUrlPart() + onClickConfirm | ||
+ I18N.htmlEncode(getString("confirm_pause_all_jobs"), false, false) | ||
+ endOnClickConfirm); | ||
writeln("<img src='?resource=control_pause_blue.png' width='18' height='18' alt=\"#Pause_all_jobs#\" /> #Pause_all_jobs#</a>"); | ||
writeln(" "); | ||
writeln("<a href='?action=resume_job&jobId=all" + getCsrfTokenUrlPart() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
class='confirm'
is missing here
final String onClickConfirm = "' onclick=\"javascript:return confirm('"; | ||
final String endOnClickConfirm = "');\">"; | ||
final String onClickConfirm = "' data-confirm=\""; | ||
final String endOnClickConfirm = "\">"; | ||
writeln("<a href='?action=pause_job&jobId=" + jobInformations.getGlobalJobId() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
class='confirm'
is also missing here
writeln("<a href='?action=pause_job&jobId=" + jobInformations.getGlobalJobId() | ||
+ getCsrfTokenUrlPart() + onClickConfirm | ||
+ getStringForJavascript("confirm_pause_job") + endOnClickConfirm); | ||
+ I18N.htmlEncode(getString("confirm_pause_job"), false, false) | ||
+ endOnClickConfirm); | ||
writeln("<img src='?resource=control_pause_blue.png' width='18' height='18' alt=\"#Pause_job#\" title=\"#Pause_job#\" /></a>"); | ||
write("</td> <td align='center' class='noPrint'>"); | ||
writeln("<a href='?action=resume_job&jobId=" + jobInformations.getGlobalJobId() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
class='confirm'
is also missing here
+ getStringForJavascript("ramasse_miette_desactive") + "');return false;\">"); | ||
writeln("<a class='alert' href='?part=heaphisto&action=gc" + getCsrfTokenUrlPart() | ||
+ "' data-alert=\"" | ||
+ I18N.htmlEncode(getString("ramasse_miette_desactive"), false, false) + "\">"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
alert is not displayed instead of calling the action
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
by lack of case in monitoring.js
write("<a href='?action=gc" + getCsrfTokenUrlPart() + "' onclick=\"javascript:alert('" | ||
+ getStringForJavascript("ramasse_miette_desactive") + "');return false;\">"); | ||
write("<a class='alert' href='?action=gc" + getCsrfTokenUrlPart() + "' data-alert=\"" | ||
+ I18N.htmlEncode(getString("ramasse_miette_desactive"), false, false) + "\">"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
alert is not displayed here neither instead of calling the action
based on PR javamelody#966 by @candrews + fixes
A strict content security policy is increasingly required and expected. This PR allows JavaMelody to function when a strict CSP is set, and in also sets a strict CSP for JavaMelody itself by default.
I've tested this pretty well on my own system, clicking around and checking various things to ensure everything looks and works correctly. There are no functional or visual changes; if I've done this right, you shouldn't be able to tell that I've done anything at all. :)
Completes the work started in #782