-
-
Notifications
You must be signed in to change notification settings - Fork 10k
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
[🐛] ngx-cookie-service makes CSRF challenge hard to solve #1592
Comments
Hands down, this is probably the best bug report I've ever read in my entire professional and open source carreer... 😆 🏁 Looks like we're looking for a slightly less security aware cookie module then! Ideas are welcome. |
Thanks for the excellent bug report and suggestion! You mean if replacing |
Exactly!
At the moment I am not considering to fix it myself, as I have basically no clue about Angular development and no knowledge which other cookie libraries are used in realistic production applications. |
@bkimminich |
I have been trying to replace |
@chinggg |
For me any cookie module is fine that works with Angular. If the syntax changes for the components then this just needs to be migrated along with the PR. So feel free to try out and pick the one with the least obstructing impact. |
Okay @bkimminich! |
Once this is fixed, we also have a chance to re-enable the deactivated e2e test: it is possible to tell Chrome that it should default to For my local test, I simply downgraded ngx-cookie-service from version 11.0.2 to 2.4.0. Together with the aforementioned argument in the Protractor configuration, the e2e test for the CSRF challenge then passes successfully. But I still think that switching to another up-to-date library which leaves |
@dnull |
I have been trying to migrate from
I cannot understand why this just does not work for the |
|
I don't know the difference between the two modules since I cannot read through the whole source code to analysis it. I have opened an issue to |
Did you try switching that test to use a Jasmine mock instead and did that make any difference? That might be the easiest approach maybe... |
Any luck with this (or another) approach? |
@bkimminich Sorry, I will have final exams of winter semester in the next two days so I am preparing for the exam now. Btw, I have created an issue to
describe('MyService', () => {
// ...
let service: MyService;
let cookieServiceSpy: SpyObj<CookieService>;
beforeEach(waitForAsync(() => {
// ...
cookieServiceSpy = jasmine.createSpyObj<CookieService>('CookieService', ['put', 'get']);
TestBed.configureTestingModule({
providers: [
// ...
{provide: CookieService, useValue: cookieServiceSpy}
]
})
.compileComponents()
}));
it('should set some cookies in some case', () => {
service.methodThatLeadsToSavingACookie();
expect(cookieServiceSpy.put).toHaveBeenCalled();
});
}); And I also found that the errors are not just about I will continue to work on it after the exam. And I also have interests in this year's GSoC |
hi @bkimminich I would like to work on it. Please suggest me a way to get started. |
@bkimminich I found that these errors are caused by + let localBackupService: any
providers: [
+ { provide: LocalBackupService, useValue: localBackupService },
] (But why there are no errors when using |
@chinggg Warning messages related to I am happy to test your changes, if you point me to a repository and branch which contains them. |
@dnull Thanks! I thought there may be some rookie
|
@chinggg I was successfully able to solve the CSRF challenge using your changes. You should be able to do the same when trying to solve the challenge with Firefox. Once you are confident that your changes are ready for a pull request (I have only verified that the CSRF is solvable and nothing else), it would be great if you could also re-enable the e2e test for the CSRF challenge, which are located in |
@dnull To change Chrome's default behavior, I add this line in capabilities: {
browserName: 'chrome',
proxy: proxy,
chromeOptions: {
args: [
'--window-size=1024,768',
+ '--disable-features=SameSiteByDefaultCookies'
]
}
}, In Btw, I have been executing |
One last thing: If I remove the first step (install Firefox from 2017) from the CSRF solution (https://pwning.owasp-juice.shop/appendix/solutions.html) then all else works like before for that solution, right? |
@bkimminich I think it works fine like before since the e2e test remains the same and the challange is solved successfully. @dnull can test it again. And I think the browser used to solve this challenge could be not limited to Firefox since Chrome has the option to |
The solution does no longer require such an old Firefox version, current Firefox releases should work fine. But when at some point in the future Mozilla follows Google with the new default policy of
I will try to prepare a pull request this week with such an update to the documentation. |
This thread has been automatically locked because it has not had recent activity after it was closed. 🔒 Please open a new issue for regressions or related bugs. |
🐛 Bug report
Description
Sorry for the long description, but I think this is a tricky one...
Current situation
The CSRF Challenge is hard to solve in its current state, as it requires the use of seriously outdated browsers (see issue #1421) for the attack to work. While this was initially thought to be a consequence of changing cookie defaults (
SameSite=Lax
instead ofSameSite=None
) advocated by initiatives such as Incrementally Better Cookies (see #1421), the behavior cannot be attributed only to this.Another explanation
A closer look revealed the following connection to a third-party dependency:
ngx-cookie
tongx-cookie-service
for the handling of cookies in the JavaScript frontend, see commit 1c68c55.ngx-cookie-service
switched the default for new cookies toSameSite=Lax
, see stevermeister/ngx-cookie-service@0cb4839.This resulted in a changed behavior when setting new cookies.
Role of e2e tests
As Google gradually rolled out
SameSite=Lax
in Chrome during the same time, the failure in the e2e test as discussed in #1421 was attributed to that rollout and not to the changed behavior ofngx-cookie-service
.Current impact on the CSRF challenge
The frontend sets the token cookie using the
set
method ofCookieService
: https://github.com/bkimminich/juice-shop/blob/e07059edd3b4ed0527add13d0dd5c8570daa3bcc/frontend/src/app/login/login.component.ts#L78The optional
SameSite
parameter is not specified by the frontend, which causesngx-cookie-service
to set it toLax
before passing the call to the cookie API of the browser. The default behavior of the browser does thus not matter, as it is only considered when the value forSameSite
is left unspecified.Overall, the CSRF challenge is thus unnecessarily hard to solve, as it requires very old browser versions which do not have support for the
SameSite
attribute (e.g. Firefox versions < 60). In comparison, even versions of Firefox as of February 2021 still set cookies withSameSite=None
by default and it should thus still be reasonably easy to solve the challenge.Suggested solution
To make the challenge solvable with more browsers, the frontend should use a cookie library which keeps the
SameSite
attribute unspecified when setting the token cookie.ngx-cookie-service
will always specify a value before calling the browser API and is thus not suitable. Explicitly specifyingSameSite=None
is not an option, as it also forces theSecure
flag to be set, which breaks usage onlocalhost
and other unencrypted deployment scenarios.Is this a regression?
No. The issue exists since the CSRF challenge was released in Juice Shop 10.1.0.
🔬 Minimal Reproduction
SameSite=None
, e.g. using https://samesite-sandbox.glitch.me/ - the entry for "Cross-site?" in the first line should say "set".🔥 Exception or Error
The exception for missing session cookie is shown.
🌳 Your Environment
Tested with release 10.1.0 and the latest develop branch.
Additional Information
Tested with Firefox 73.3.0esr on Kali Linux.
The text was updated successfully, but these errors were encountered: