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

[feature] Abilty to include headers in the text for changedetection.io - PCI DSS 11.6.1 Compliance: Detecting Unauthorized HTTP Header Changes with Chrome CDP & Changedetection.io #2943

Open
dgtlmoon opened this issue Feb 5, 2025 · 18 comments
Labels
enhancement New feature or request

Comments

@dgtlmoon
Copy link
Owner

dgtlmoon commented Feb 5, 2025

Adding "reply headers" to the "fetchers" would be amazing, this would be very helpful to a lot of people who want to monitor headers. It wouldnt be so hard..

  • Add "reply headers" to the "fetchers"
  • Add a checkbox that prepends the text of the reply headers to the text_json_diff processor

the only bit i'm not sure about is "Provide logs of captured request/response headers from a monitoring system.", because it will just check it and only report if something changes?

Here's what chatgpt says

PCI DSS 4.0 (including 4.0.1) compliance requirement 11.6.1 relates to change detection mechanisms for unauthorized modifications to HTTP headers and payment page content. Specifically, it is designed to detect tampering with e-commerce payment pages, which could indicate a Magecart-style attack (where malicious scripts steal cardholder data).

How Request Headers Are Relevant in PCI DSS 11.6.1

The standard itself does not explicitly say, "You must collect and store request headers." However, the intent of 11.6.1 is to ensure that unauthorized changes to the payment page environment (including HTTP request headers and responses) are detected and logged. This is why security auditors may ask to review request headers.

Breakdown of PCI DSS 11.6.1 Requirements

  • A change detection mechanism must be deployed to identify unauthorized modifications to HTTP headers or payment page content.
  • This applies to pages that directly handle payment details or redirect users to a third-party processor.
  • The mechanism must operate at least every 7 days.
  • Any unauthorized modifications must trigger alerts and investigation.

Why Request Headers Matter

  • Headers can be modified by attackers to inject malicious scripts (e.g., Magecart attacks).
  • A man-in-the-middle (MITM) attack or malicious browser extension could alter headers to modify the payment page.
  • Content security policies (CSP), referrer headers, or other HTTP controls can indicate unauthorized modifications.
  • Ensuring integrity of security-related headers (e.g., Content-Security-Policy, X-Frame-Options) is a key control.

How to Demonstrate Compliance (for Headers)

  1. Monitoring Solutions:

    • Use Changedetection.io (if feasible for your case) or other tools to detect unauthorized header changes.
    • Deploy a Web Application Firewall (WAF) or Content Security Policy (CSP) logging mechanism.
  2. Evidence Collection:

    • Provide logs of captured request/response headers from a monitoring system.
    • Use SIEM (Security Information and Event Management) tools to track and detect anomalies.
    • Show that the change detection tool is periodically reviewing and alerting on changes.
  3. Testing & Reporting:

    • Conduct periodic integrity checks on the headers of payment pages.
    • Document anomalies or incidents where changes were detected and resolved.

Conclusion

The PCI DSS 4.0.1 standard itself does not explicitly require storing request headers, but it requires monitoring for unauthorized changes to HTTP headers and payment pages. If an auditor asks for request headers, they likely want proof that header integrity is being checked as part of compliance with 11.6.1.

Would you like recommendations on tools for automating this monitoring?


For example, playwright (pypuppter-ng), also needs to be handled by requests

    browser = await launch(headless=True)
    page = await browser.newPage()
    
    # Enable network tracking
    await page._client.send('Network.enable')

    # Intercept and log request headers
    page._client.on('Network.requestWillBeSent', lambda req: 
        print("Request Headers:", req['request']['headers'])
    )

    # Intercept and log response headers
    page._client.on('Network.responseReceived', lambda res: 
        print("Response Headers:", res['response']['headers'])
    )

    # Navigate to a test page
    await page.goto('https://example.com')

    await browser.close()

@dgtlmoon dgtlmoon added the enhancement New feature or request label Feb 5, 2025
@hendrickson-tyler
Copy link

This is a fantastic write up, @dgtlmoon! Thank you for raising this enhancement!

Looking through the guidance given on PCI DSS 4.0.1 Requirement 11.6.1, I don't actually see any requirement (or mention, really) for logging the headers. I think you have it exactly right‒it only needs to report if there's a change detected on those headers.

Image

I'm not sure if something additional needs to be checked for the "indicators of compromise" that is mentioned in this requirement... I'll have to ask our PCI assessor about this and if it would require a separate feature to be implemented in changedetection.io.

For compliance, I'm also wondering if we need to provide changedetection.io with what the "authorized" headers for each request would be. Could that be implemented, if needed?

@dgtlmoon
Copy link
Owner Author

dgtlmoon commented Feb 5, 2025

For compliance, I'm also wondering if we need to provide changedetection.io with what the "authorized" headers for each request would be. Could that be implemented, if needed?

can you elaborate, or give some technical example? :)

I'll have to ask our PCI assessor about this and if it would require a separate feature to be implemented in changedetection.io.

that would be super, please update this thread with what you find out :)

@dgtlmoon
Copy link
Owner Author

dgtlmoon commented Feb 5, 2025

@hendrickson-tyler readin https://cheq.ai/blog/pci-dss-11-6-1-tamper-header/ , so it talks about that the header check is on the actual payment page, i'm wondering, does it mean you need to add products to a cart and do the checkout etc?

actually they have a nice way to solve it with some JS injection

@hendrickson-tyler
Copy link

can you elaborate, or give some technical example? :)

I think this would be setting something in changedetection.io like:

For responses from GET https://api.payment.link/abcdefg, these are the response headers that are "authorized" (i.e. expected):

Header Value
Content-Type application/json; charset=utf-8
Strict-Transport-Security max-age=31536000; includeSubDomains; preload;

And we'd just enumerate the different requests that we expect to make in the page. If it's not in the list, then an alert would be given for that request.

@hendrickson-tyler readin https://cheq.ai/blog/pci-dss-11-6-1-tamper-header/ , so it talks about that the header check is on the actual payment page, i'm wondering, does it mean you need to add products to a cart and do the checkout etc?

actually they have a nice way to solve it with some JS injection

That's correct, the change detection mechanism would essentially fill out the payment form on our side and complete a test payment, monitoring the headers and page contents along the way. Minus the headers, I believe changedetection.io has that functionality already, right?

Yeah, there are essentially two methods of implementing this mechanism: agent-less (synthetic/external monitoring, like changedetection.io) or agent-based (embedding a monitoring script, like this CHEQ solution). Each comes with pros and cons. I think a combination of both is ideal, but we're personally looking at agent-less to begin with. Changedetection.io seems so close to being a great solution for this, so we're definitely excited about the potential to monitor for headers 🙂

@hendrickson-tyler
Copy link

@dgtlmoon This isn't related to the headers, but there's one other piece of the requirement I may have missed. We need to be notified if the contents of the scripts on our payment page have changed:

To alert personnel to unauthorized modification (including indicators of compromise, changes, additions, and deletions) to the security-impacting HTTP headers and the script contents of payment pages as received by the consumer browser.

Essentially, this would just be comparing the response of a GET request against an expected value. Like requests to GET https://secure.payment.io/services/proxynization.js should always return the same response text. If not, we get alerted.

Is this something achievable with changedetection.io?

@dgtlmoon
Copy link
Owner Author

dgtlmoon commented Feb 10, 2025

Essentially, this would just be comparing the response of a GET request against an expected value. Like requests to GET https://secure.payment.io/services/proxynization.js should always return the same response text. If not, we get alerted.

If i understand correctly, you should be able todo this already as a watch with source: prepended. https://changedetection.io/tutorial/source-code-monitor-how-get-alerts-changes-html-source-code

but please not changedetection.io is not going to tell you if there was a network error or the file could not be read, and you should enable "empty pages are a change" option too

source:https://secure.payment.io/services/proxynization.js

changedetection will not scrape those URLs for you from your page (although it could!)

@hendrickson-tyler
Copy link

I see, so to make sure I'm understanding right:

There's not really a way to monitor individual requests that the page makes through changedetection.io (maybe beyond the project scope). For example, not a way to say, "when the page makes a GET to https://some.url, check that the returned content is "xyz""

Instead, the way to do this would be to separately monitor https://some.url itself and checked the returned content through prepending source:, as you mentioned? Does that sound right?

@dgtlmoon
Copy link
Owner Author

Hmm so you need to monitor all in one 'watch'

  • the page HTML
  • the initial page headers (request/reply)
  • the headers, url of extra resources the page requests (image, js, css, etc etc)
  • the content of any extra resources (image, js, css etc ect)

this is quickly turning into something else :)

can you clarify those last 2?

@hendrickson-tyler
Copy link

We definitely need to monitor the content of JS resources that the page requests. I'm not sure about headers for JS resources... The requirements are very vague. Separately monitoring those URLs for changes with changedetection.io may satisfy this though. Even if the other URLs aren't scraped from the page, I think that should be okay since we'll know them upfront anyway.

I think the only problem is if we do need to check contents/headers of multiple resource types on a granular level. For example, monitoring Fetch/XHR POST requests that the page makes would be challenging, I'm sure. If it comes to that, would you see that as out of scope for changedetection.io?

Still trying to get some clarification from our QSA on the specifics, but I know he's doing several other evaluations currently. PCI DSS 4.0 is a bit of a mess 😅

@dgtlmoon
Copy link
Owner Author

But any script on your page, if its meant to be "secure" should only be referenced using "Subresource Integrity (SRI), which ensures that only a script with a known checksum is executed. The correct way to do this is by adding the integrity attribute to your <script> tag."

ie

<script src="https://example.com/script.js" 
        integrity="sha384-SOME-KEY-ID" 
        crossorigin="anonymous"></script>

@hendrickson-tyler
Copy link

hendrickson-tyler commented Feb 11, 2025

SRI is a useful way to make sure that the script content hasn't been modified whatsoever. We're personally looking at this for our use case (for requirement 6.4.3), but it's not for everyone. Payment providers often update their scripts, and whenever that happens, it would break the payment page since the script wouldn't execute. So there is some inherent risk, unless mitigated by other means.

Even using SRI though, it seems that the requirement to "alert personnel to unauthorized modification ... to the security-impacting HTTP headers and the script contents of payment pages as received by the consumer browser" still applies in 11.6.1. I think because SRI could still be disabled if an attacker was able to change the page content.

But I feel pretty confident that setting up a new change detection watch for the scripts themselves should satisfy this part. It's watching the same URL that the payment page requests anyway, so I don't see there being any functional difference.

@dgtlmoon
Copy link
Owner Author

hmm also we dont support anything inside <iframe> at the moment, and many payment gateways still embed their content that way

@hendrickson-tyler
Copy link

Luckily for iframes, responsibility for monitoring the scripts falls to the payment provider. I believe all we have to do there is monitor that iframe URL for content/header changes, which seems easy enough to do by setting up another watch

@dgtlmoon
Copy link
Owner Author

What ChatGPT says about PCI-DSS-v4_0_1.pdf

PCI-DSS-v4_0_1.pdf

Image

@dgtlmoon
Copy link
Owner Author

I think #2962 is going to be important here too, it should always trigger notifications/changes against a chosen version rather than just the last checked

@hendrickson-tyler
Copy link

I think #2962 is going to be important here too, it should always trigger notifications/changes against a chosen version rather than just the last checked

Yeah, I would agree. Pinning a version would be the best way to demonstrate what changes are unauthorized

@hendrickson-tyler
Copy link

@dgtlmoon FYI, sharing a response from the forensics VP of the company we're working with on PCI compliance. I originally stated that the solution would check all response headers, but then clarified it would just check the initial document load (in addition to the headers for the scripts):

I like their previous version that monitors any changes and all response headers. The checkout page is a dynamic environment and malware can hide far beyond the initial request/response header. We often see the exfiltration of card data occur long after initial page load. For best results they should be monitoring all changes to the DOM.

It sounds like this is becoming more of an E2E test, rather than a static change detection method. Just curious on your thoughts on the level of effort for the above? Either as part of changedetection.io or some additional integration

@hendrickson-tyler
Copy link

@dgtlmoon Sorry to keep pinging you. A bit of an update on the above. Received this response recently:

Again, strict interpretation of 11.6.1 may lead a merchant to conclude that they do not need to monitor all request headers after the initial page is finished loading. While that might meet the letter of the law, the current malware that we are seeing often does not make an appearance until the customer is typing in their credit card. Till then, it may be invisible to monitors that only look at the initial request/response headers. Attackers will hide their malicious calls in those subsequent request/response HTTP GETs and POSTs. We've also recently seen exploits with credit cards going out via web sockets being opened. Things like WSS, and AJAX can thwart monitoring that ends right after the page load event. We encourage all of our forensic customers to implement a solution that monitors all activity in the DOM, even after page load is complete.

We are interpreting this as "checking initial page headers/content do meet the minimum requirements for 11.6.1, but we encourage customers to do more to further avert risk". They have never told us a flat-out "no", so I think the approach with changedetection.io is a valid path to pursue here. 👍

Is header support something you think could be ready in March? Our audit is on March 18, so we're hoping to have some of these loose ends tied up before then. Appreciate all your help on this!

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

No branches or pull requests

2 participants