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

fix: properly replace integrity tags in script resources when experimentalModifyObstructiveThirdPartyCode is true #23820

Merged
merged 10 commits into from
Sep 20, 2022

Conversation

AtofStryker
Copy link
Contributor

User facing changelog

Fixes an error with incorrect JS source rewriting when the experimentalModifyObstructiveThirdPartyCode flag is enabled

Additional details

When running their test suite with experimentalModifyObstructiveThirdPartyCode enabled, user was getting a left hand assignment syntax error, which was the result of a third party recaptcha script being rewritten to nullify script integrity, resulting in the below error:

// results in a syntax error
obj.cypress-stripped-integrity='sha384-XiV6bRRw9OEpsWSumtD1J7rElgTrNQro4MY/O4IYjhH+YGCf1dHaNGZ3A2kzYi/C'

With added tests and changed to the regex-rewritter, this is now yeilding the following correctly:

obj['cypress-stripped-integrity']='sha384-XiV6bRRw9OEpsWSumtD1J7rElgTrNQro4MY/O4IYjhH+YGCf1dHaNGZ3A2kzYi/C'

Steps to test

How has the user experience changed?

PR Tasks

  • Have tests been added/updated?
  • Has the original issue (or this PR, if no issue exists) been tagged with a release in ZenHub? (user-facing changes only)
  • Has a PR for user-facing changes been opened in cypress-documentation?
  • Have API changes been updated in the type definitions?

@cypress-bot
Copy link
Contributor

cypress-bot bot commented Sep 13, 2022

Thanks for taking the time to open a PR!

@AtofStryker AtofStryker self-assigned this Sep 13, 2022
@AtofStryker AtofStryker added the experimental: modify third party code Issues when using experimentalModifyObstructiveThirdPartyCode label Sep 13, 2022
@AtofStryker AtofStryker changed the title Fix/stripped integrity dynamic fix: properly replace integrity tags in script resources when experimentalModifyObstructiveThirdPartyCode is true Sep 13, 2022
@AtofStryker AtofStryker marked this pull request as ready for review September 13, 2022 19:52
@AtofStryker
Copy link
Contributor Author

does not look to have an impact on recaptchas in regards to #23728

@cypress
Copy link

cypress bot commented Sep 13, 2022



Test summary

4768 0 373 0Flakiness 0


Run details

Project cypress
Status Passed
Commit d7a3839
Started Sep 20, 2022 7:30 PM
Ended Sep 20, 2022 7:45 PM
Duration 15:07 💡
OS Linux Debian - 11.3
Browser Electron 102

View run in Cypress Dashboard ➡️


This comment has been generated by cypress-bot as a result of this project's GitHub integration settings. You can manage this integration in this project's settings in the Cypress Dashboard

@chrisbreiding chrisbreiding removed their request for review September 14, 2022 18:40
@@ -49,7 +62,7 @@ export function stripStream ({ modifyObstructiveThirdPartyCode }: Partial<Securi
jiraTopWindowGetterRe,
jiraTopWindowGetterUnMinifiedRe,
...(modifyObstructiveThirdPartyCode ? [
integrityTagReplacementRe,
buildIntegrityReplacementRe(isHtml),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can buildIntegrityReplacementRe & returnReplacedIntegrityExpression return the array ?

...(modifyObstructiveThirdPartyCode ?   buildIntegrityReplacementRe(isHtml) : []

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They cannot since they need to be used in the regular strip function above, which doesn't leverage arrays to replace. The good part is once this does become GA with modifyObstructiveCode, we can just merge this into the already flat array

const integrityTagReplacementRe = new RegExp(`(${STRIPPED_INTEGRITY_TAG}|integrity)(=(?:\"|\')sha(?:256|384|512)-.*?(?:\"|\'))`, 'g')
const buildIntegrityReplacementRe = (isHtml = true) => {
if (!isHtml) {
// only replace integrity if a trailing period (.) or string exists inside JS/Other resources
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add more code comments here to help explain why there is a difference? My head already hurts just trying to parse these regexes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can give it a shot. I am having issues thinking of something useful though so I'm going to try typing my thoughts out 😆 . The main goal here is only replace integrity in JavaScript if the word integrity or cypress-stripped-integrity is preceded by a . or quotes. So something like

foo.integrity = 'sha256-some-hash'
var integrity = 'sha256-some-hash'

becomes

foo['cypress-stripped-integrity'] = 'sha256-some-hash'
var integrity = 'sha256-some-hash'

It isn't so much what we match on as much as it is what we replace it with (the brackets vs the tagname). At some point in the future I am starting to think we might want to apply both of these because JS like above could be in HTML, but I am a bit hesitant to try it because it could have side effects we aren't testing for, and we haven't run into that problem yet. Now that I think about it I might want to go. Did any of that make sense or is it more of a jumbled ramble?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I gave it ago and it's complicated with some added lookbacks 😄. I think we might want to hold off on that for now until it actually surfaces as a problem (if it even is one). Maybe we can meet up on Monday to see if we can improve the documentation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually got it to work! I tried adding some docs in 41e82c8 but I don't think they are really great. It also means the regex is more complicated, but handles more cases correctly without sacrificing performance. Regardless of resource type, both regex functions need to execute because HTML can have nested javascript inside of it, and both regexes need to run to rewrite correctly

@AtofStryker AtofStryker force-pushed the fix/stripped-integrity-dynamic branch 2 times, most recently from 18e7e3a to 41e82c8 Compare September 17, 2022 03:09
packages/proxy/lib/http/util/regex-rewriter.ts Outdated Show resolved Hide resolved
packages/proxy/lib/http/util/regex-rewriter.ts Outdated Show resolved Hide resolved
packages/proxy/lib/http/util/regex-rewriter.ts Outdated Show resolved Hide resolved
packages/proxy/lib/http/util/regex-rewriter.ts Outdated Show resolved Hide resolved
packages/proxy/lib/http/util/regex-rewriter.ts Outdated Show resolved Hide resolved
@AtofStryker AtofStryker merged commit fd94102 into develop Sep 20, 2022
@AtofStryker AtofStryker deleted the fix/stripped-integrity-dynamic branch September 20, 2022 20:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
experimental: modify third party code Issues when using experimentalModifyObstructiveThirdPartyCode
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unable to complete e2e test using paypal payment (on sanbox test website)
4 participants