Skip to content

Timing for HeaderWriterFilter to writes headers changed in 4.2.5 breaks existing codes. #5193

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

Closed
tan9 opened this issue Apr 2, 2018 · 7 comments
Assignees
Labels
status: duplicate A duplicate of another issue status: waiting-for-triage An issue we've not yet triaged

Comments

@tan9
Copy link
Contributor

tan9 commented Apr 2, 2018

Summary

In Spring Security 4.2.4 or earlier, the HeaderWriterFilter writes headers before filter chin was processed.
However, commit f81b581#diff-57c0f670220b7f4e45a0d1252a99b482 in 4.2.5 changed the timing of header writing to response.onResponseCommitted phase. And this will break existing code which writes custom headers other than those defined in HeaderWriters. For example:

I have some URL intend to be embed in frames. In 4.2.4 or earlier, I can overwrite the default value from XFrameOptionsHeaderWriter as following :

    public ModelAndView relogin(HttpServletResponse response) {
        ModelAndView mav = new ModelAndView();
        mav.setViewName("security/relogin");

        response.setHeader("X-Frame-Options", "SAMEORIGIN"); // overwrite `DENY` in XFrameOptionsHeaderWriter
        return mav;
    }

Now I have no easy way to set X-Frame-Options to SAMEORIGIN in dedicate URLs while applying DENY to rest or the system.

Call sequence illustrated for above code snippet in 4.2.5.RELEASE:

HeaderWriterFilter.doFilterInternal
  filterChain.doFilter
    response.setHeader in contorller     <- manual header writing here (X-Frame-Options=SAMEORIGIN)
  response.onResponseCommitted           <- HeaderWriters writes header here (X-Frame-Options=DENY)

Resulting X-Frame-Options=DENY.

Call sequence illustrated for 4.2.4.RELEASE and earlier:

HeaderWriterFilter.doFilterInternal      <- HeaderWriters writes header here (X-Frame-Options=DENY)
  filterChain.doFilter
    response.setHeader in contorller     <- manual header writing here (X-Frame-Options=SAMEORIGIN)
  response.onResponseCommitted

Resulting X-Frame-Options=SAMEORIGIN as expected.

Actual Behavior

response.setHeader in controller code will not take effect as before.

Expected Behavior

Manual response.setHeader in controller code overwrites headers wrote by HeaderWriters.

Configuration

N/A

Version

4.2.5.RELEASE

Sample

N/A

@tan9
Copy link
Contributor Author

tan9 commented Apr 3, 2018

Hi @rwinch , seems this issue is related to #5004, #5005, #4307, #3975, #2953, it really wired and confusing.

If the behavior is by design, should we document it well for programmer to follow

@jazdw
Copy link

jazdw commented Jun 13, 2018

@tan9 I agree with what you are saying, it definitely seems more obvious to me that the security headers should be set earlier and then the controller should be able to override them.

Another issue with it is that the OnCommittedResponseWrapper just doesn't seem to do its job reliably as I posted here - #3975 (comment)

@rwinch
Copy link
Member

rwinch commented Aug 16, 2018

This does appear to be an issue. I think we need to modify it to check to see if the header is already set and if so not to override it. If anyone is interested in submitting a PR that would help get this issue resolved faster as we are focused on some other tasks at the moment.

@tan9
Copy link
Contributor Author

tan9 commented Aug 16, 2018

@rwinch thanks for your response, I am willing to contribute. Would you please provide some direction how to do it right. Use another responseWrapper within HeaderWriterResponse to prevent headers wrote in filterChain been overwritten by headerWriters?

@rwinch
Copy link
Member

rwinch commented Aug 16, 2018

Thanks for the fast response! I think we should just update the HeaderWriter implementations to only write if the value isn't present.

ankurpathak added a commit to ankurpathak/spring-security that referenced this issue Feb 6, 2019
All HeadersWriter only write Header if its not already
written.

Fixes: spring-projectsgh-6454 spring-projectsgh-5193
jzheaux pushed a commit that referenced this issue Feb 7, 2019
All HeadersWriter only write Header if its not already
written.

Fixes: gh-6454 gh-5193
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label May 7, 2019
@koju
Copy link

koju commented Jun 25, 2020

Workarounds are mentioned in #2953.
JavaConfig: #2953 (comment)
XmlConfig: #2953 (comment)

@rwinch
Copy link
Member

rwinch commented Jun 29, 2020

Closing this as a duplicate of gh-2953

@rwinch rwinch closed this as completed Jun 29, 2020
@rwinch rwinch added the status: duplicate A duplicate of another issue label Jun 29, 2020
@rwinch rwinch self-assigned this Jun 29, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: duplicate A duplicate of another issue status: waiting-for-triage An issue we've not yet triaged
Projects
None yet
Development

No branches or pull requests

5 participants