Archive

Posts Tagged ‘books’

Fixing Chrome’s “Aw, Snap!” STATUS_ACCESS_VIOLATION in CDP Automation

How a race condition between page navigation and JavaScript execution causes STATUS_ACCESS_VIOLATION crashes — and how to fix it properly.

C# · .NET·Puppeteer / CDP·Chrome Automation 💥

😬 Aw, Snap! Something went wrong displaying this page.

Chrome’s infamous crash page — and the Windows error behind it: STATUS_ACCESS_VIOLATION (0xC0000005). If you’re automating Chrome via CDP and seeing this, a race condition is likely the culprit.

If you’ve built a browser automation system using the Chrome DevTools Protocol — whether through Puppeteer, Playwright, or a custom CDP client — you may have encountered Chrome processes dying with a STATUS_ACCESS_VIOLATION error. The browser just vanishes. No clean exception, no useful log output. Just Chrome’s “Aw, Snap!” page, or worse, a completely dead process.

This error code (0xC0000005 on Windows) means the process attempted to read or write memory it doesn’t own. It’s a hard native crash, well below the level where .NET exception handling can help you. A try/catch around your CDP call won’t save you.

The Usual Suspects

Most writeups on this error point to GPU driver issues, sandbox misconfiguration, or DLL injection from antivirus software — and those are all valid causes. The standard advice is to throw flags like --disable-gpu, --no-sandbox, and --disable-dev-shm-usage at the problem until it goes away.

But there’s another cause that gets far less attention: injecting JavaScript into a page that’s mid-navigation. This is a timing issue, and it’s surprisingly easy to introduce.

The Race Condition

Consider a common automation pattern: click a button, wait for the resulting page to load, then execute some JavaScript on the new page. A naive implementation might look like this:

problematic// Click a button that triggers navigation
await ExecuteJavascript("document.querySelector('button').click();");

// Arbitrary delay, then poll readyState
await Task.Delay(1000);
while (true)
{
    await Task.Delay(500);
    var readyState = await ExecuteJavascript("document.readyState");
    if (readyState == "complete") break;
}

This pattern has a fundamental flaw. After clicking the button, Chrome begins tearing down the current document and loading a new one. There is a window — however brief — where the old document is gone but the new one isn’t yet attached. If ExecuteJavascript fires a CDP Runtime.evaluate command into that gap, Chrome is asked to execute JavaScript in a context that no longer exists.

The result isn’t a clean error. Chrome’s internal state becomes inconsistent, and the access violation follows.

Why does it only crash sometimes? Because the race condition is non-deterministic. On a fast machine or a fast network, the new page loads before the poll fires and everything works. On a slower day, the poll lands in the gap and Chrome crashes. This makes the bug look intermittent and hardware-dependent, when it’s actually a logic error.

What the Timeline Looks Like

Button click dispatched

CDP sends Runtime.evaluate with the click expression. Navigation begins.

⚠ Danger zone begins

Old document is being torn down. New document not yet attached to the frame.

document.readyState polled

If Runtime.evaluate fires here, Chrome has no valid document context to evaluate against.

STATUS_ACCESS_VIOLATION

Chrome dereferences a null or freed pointer. Process dies. “Aw, Snap!”

New document attached (if we were lucky)

If the poll happened to land here instead, readyState returns “loading” or “complete” and everything works fine.

The Fix: Let Chrome Tell You

The correct solution is to stop guessing when navigation is complete and instead subscribe to Chrome’s own navigation events. CDP exposes Page.loadEventFired precisely for this purpose — it fires when the new page’s load event has completed, meaning the document is fully attached and ready for JavaScript execution.

fixedprivate async Task WaitForPageLoad(ChromeSession session, int timeoutMs = 30000)
{
    var tcs = new TaskCompletionSource<bool>();

    session.Subscribe<LoadEventFiredEvent>(e => tcs.TrySetResult(true));

    var timeoutTask = Task.Delay(timeoutMs);
    var completed = await Task.WhenAny(tcs.Task, timeoutTask);

    if (completed == timeoutTask)
        throw new TimeoutException("Page load timed out");
}

Critically, the subscription must be set up before triggering navigation — not after. Otherwise there’s a small window where the event fires before you’re listening:

usage// Subscribe FIRST, then trigger navigation
var pageLoad = WaitForPageLoad(chromeSession);

await ExecuteJavascript("document.querySelector('button').click();");

// Now wait — Chrome will signal when it's actually ready
await pageLoad;

// Safe to execute JavaScript on the new page
await ExecuteJavascript("/* your code here */");

Why Not Just Catch the Exception?

A STATUS_ACCESS_VIOLATION is a native Windows exception originating inside the Chrome process itself. It is entirely outside the .NET runtime. Wrapping your CDP calls in try/catch does nothing — there is no managed exception to catch. The Chrome process simply dies.

Similarly, adding more Task.Delay calls doesn’t fix the race condition — it just makes it less likely to trigger on any given run, while leaving the underlying problem completely intact.

Applies to Puppeteer and Other CDP Clients Too

This issue isn’t specific to C# or any particular CDP library. The same race condition can occur in Node.js with Puppeteer, Python with pyppeteer, or any system that drives Chrome via the DevTools Protocol. Puppeteer’s page.waitForNavigation() and page.waitForLoadState() exist precisely to solve this problem — they’re wrappers around the same loadEventFired event.

If you’re rolling a custom CDP client in any language, the principle is the same: never rely on arbitrary delays or polling to determine when a page is ready for JavaScript execution. Subscribe to Page.loadEventFired or Page.frameStoppedLoading, and let Chrome do the signalling.


Summary

Root cause: JavaScript injected via CDP (Runtime.evaluate) during a page transition hits Chrome in an inconsistent internal state, causing a STATUS_ACCESS_VIOLATION native crash.

Why it’s intermittent: The race condition depends on timing — fast loads mask it, slow loads expose it.

The fix: Subscribe to Page.loadEventFiredbefore triggering navigation, and await the event before executing any JavaScript. Never use Task.Delay or document.readyState polling as a substitute for proper navigation events. Chrome DevTools Protocol · Browser Automation · STATUS_ACCESS_VIOLATION

Categories: Uncategorized Tags: , , ,

Complete Guide to the UK Vehicle Registration #API: Access #DVLA Data, #MOT History, and More

Are you developing an application that needs instant access to UK vehicle information? The UK Vehicle Registration API provides comprehensive access to DVLA data, MOT history, tax information, and vehicle specifications through a simple integration. This powerful tool allows developers to retrieve detailed vehicle information using just a Vehicle Registration Mark (VRM). Here: https://regcheck.org.uk/

What is the UK Vehicle Registration API?

The UK Vehicle Registration API is a SOAP-based web service that provides instant access to official UK vehicle data. By simply entering a vehicle registration number (VRM), you can retrieve comprehensive information about cars, motorcycles, and commercial vehicles registered with the DVLA.

Key Features:

  • Instant VRM lookups for all UK-registered vehicles
  • Complete MOT history with test results and failure reasons
  • Tax status information including expiry dates
  • Comprehensive vehicle specifications including make, model, engine details
  • Support for special territories including Isle of Man and Jersey
  • Both XML and JSON response formats

UK Vehicle Data Available

Standard Vehicle Information

When you query the UK endpoint using a vehicle registration number, you’ll receive:

  • Make and Model – Manufacturer and specific vehicle model
  • Year of Registration – When the vehicle was first registered
  • VIN Number – Complete Vehicle Identification Number
  • ABI Code – Association of British Insurers classification code
  • Body Style – Vehicle type (saloon, hatchback, SUV, etc.)
  • Engine Size – Displacement in cubic centimeters
  • Number of Doors – Vehicle door configuration
  • Transmission Type – Manual or automatic
  • Fuel Type – Petrol, diesel, electric, hybrid
  • Immobiliser Status – Security system information
  • Number of Seats – Seating capacity
  • Driver Side – Left or right-hand drive
  • Vehicle Color – Primary exterior color

Example Response for UK Vehicle Data

{
  "ABICode": "32130768",
  "Description": "MERCEDES-BENZ E220 SE CDI",
  "RegistrationYear": "2013",
  "CarMake": {
    "CurrentTextValue": "MERCEDES-BENZ"
  },
  "CarModel": {
    "CurrentTextValue": "E220 SE CDI"
  },
  "EngineSize": {
    "CurrentTextValue": "2143"
  },
  "FuelType": {
    "CurrentTextValue": "Diesel"
  },
  "Transmission": {
    "CurrentTextValue": "Automatic"
  },
  "NumberOfDoors": {
    "CurrentTextValue": "4DR"
  },
  "BodyStyle": {
    "CurrentTextValue": "Saloon"
  },
  "Colour": "WHITE",
  "VehicleIdentificationNumber": "WDD2120022A899877"
}

MOT History API – Complete Test Records

One of the most valuable features of the UK Vehicle API is access to complete MOT history data. This service covers all UK cars (excluding Northern Ireland) and provides detailed test information including:

MOT Data Includes:

  • Test Date – When each MOT was conducted
  • Test Result – Pass or Fail status
  • Odometer Reading – Mileage at time of test
  • Test Number – Official MOT test reference
  • Failure Reasons – Detailed list of any failures
  • Advisory Notes – Items that need attention
  • Expiry Date – When the MOT certificate expires

MOT History Response Example

[
  {
    "TestDate": "8 November 2016",
    "ExpiryDate": "16 November 2017",
    "Result": "Pass",
    "Odometer": "61,706 miles",
    "TestNumber": "2754 6884 4000",
    "FailureReasons": [],
    "Advisories": []
  },
  {
    "TestDate": "8 November 2016",
    "Result": "Fail",
    "Odometer": "61,703 miles",
    "TestNumber": "5901 3690 4542",
    "FailureReasons": [
      "Nearside Rear Brake pipe excessively corroded (3.6.B.2c)",
      "Offside Rear Brake pipe excessively corroded (3.6.B.2c)"
    ],
    "Advisories": []
  }
]

Extended Vehicle Information with Tax Data

The API also provides enhanced vehicle information including tax and emissions data:

  • Make and Registration Date
  • Year of Manufacture
  • CO2 Emissions – Environmental impact rating
  • Tax Status – Current road tax status
  • Tax Due Date – When road tax expires
  • Vehicle Type Approval – EU approval classification
  • Wheelplan – Axle configuration
  • Weight Information – Gross vehicle weight

UK Motorcycle Support

For motorcycles registered in the UK, use the dedicated CheckMotorBikeUK endpoint. This returns motorcycle-specific information:

  • Make and Model – Manufacturer and bike model
  • Year of Registration
  • Engine Size – Engine displacement
  • Variant – Specific model variant
  • Colour – Primary color
  • VIN – Complete chassis number
  • Engine Number – Engine identification

Motorcycle Response Example

{
  "Description": "HONDA ST1300 A",
  "RegistrationYear": "2005",
  "CarMake": {
    "CurrentTextValue": "HONDA"
  },
  "CarModel": {
    "CurrentTextValue": "ST1300 A"
  },
  "EngineSize": {
    "CurrentTextValue": "1261"
  },
  "BodyStyle": {
    "CurrentTextValue": "Motorbike"
  },
  "FuelType": {
    "CurrentTextValue": "PETROL"
  },
  "Colour": "YELLOW",
  "VehicleIdentificationNumber": "JH2SC51A92M007472"
}

Isle of Man Vehicle Support

Vehicles registered in the Isle of Man (identified by “MN”, “MAN”, or “MANX” in the registration) return enhanced data including:

  • Standard vehicle information (make, model, engine size)
  • Version details – Specific trim level
  • CO2 emissions – Environmental data
  • Tax status – “Active” or expired
  • Tax expiry date – When road tax is due
  • Wheelplan – Vehicle configuration

Isle of Man Response Example

{
  "Description": "HONDA JAZZ",
  "RegistrationYear": 2012,
  "CarMake": {
    "CurrentTextValue": "HONDA"
  },
  "Version": "I-VTEC ES",
  "Colour": "SILVER",
  "Co2": "126",
  "RegistrationDate": "06/07/2012",
  "WheelPlan": "2-AXLE Rigid",
  "Taxed": "Active",
  "TaxExpiry": "31/07/2018"
}

Integration and Implementation

API Endpoint

The service is available at: https://www.regcheck.org.uk/api/reg.asmx

WSDL Definition

Access the service definition at: https://www.regcheck.org.uk/api/reg.asmx?wsdl

Authentication

All API calls require a valid username. You can obtain a test account with 10 free credits after email verification.

Sample Implementation (PHP)

<?php
$username = 'Your_Username_Here';
$regNumber = 'AB12CDE';

$xmlData = file_get_contents("https://www.regcheck.org.uk/api/reg.asmx/Check?RegistrationNumber=" . $regNumber . "&username=" . $username);

$xml = simplexml_load_string($xmlData);
$strJson = $xml->vehicleJson;
$json = json_decode($strJson);

echo "Vehicle: " . $json->Description;
echo "Year: " . $json->RegistrationYear;
echo "Fuel: " . $json->FuelType->CurrentTextValue;
?>

Use Cases for UK Vehicle API

For Businesses:

  • Insurance Companies – Instant vehicle verification and risk assessment
  • Car Dealers – Vehicle history checks and specifications
  • Fleet Management – MOT tracking and compliance monitoring
  • Automotive Marketplaces – Automated vehicle data population
  • Garage Services – Customer vehicle information lookup

For Developers:

  • Mobile Apps – Vehicle checking applications
  • Web Platforms – Integrated vehicle lookup features
  • Compliance Tools – MOT and tax reminder systems
  • Data Validation – Verify vehicle registration details

Benefits of Using the UK Vehicle Registration API

  1. Official DVLA Data – Access to authoritative government vehicle records
  2. Real-time Information – Instant access to current vehicle status
  3. Comprehensive Coverage – Supports cars, motorcycles, and commercial vehicles
  4. Historical Data – Complete MOT history with detailed records
  5. Multiple Formats – Both XML and JSON response options
  6. Reliable Service – High uptime and consistent performance
  7. Cost Effective – Credit-based pricing with free test options

Getting Started

To begin using the UK Vehicle Registration API:

  1. Sign up for a free test account at regcheck.org.uk
  2. Verify your email address to receive 10 free credits
  3. Test the API with sample vehicle registration numbers
  4. Purchase additional credits as needed for production use
  5. Implement the API in your application using provided documentation

Security and Compliance

The API includes several security features:

  • IP Address Restrictions – Lock access to specific IP addresses
  • Credit Monitoring – Balance alerts and daily usage limits
  • Secure Connections – HTTPS encryption for all API calls
  • Data Protection – Compliance with UK data protection regulations

Conclusion

The UK Vehicle Registration API provides developers and businesses with comprehensive access to official DVLA data, MOT records, and vehicle specifications. Whether you’re building a consumer app for vehicle checks or integrating vehicle data into business systems, this API offers the reliability and data coverage needed for professional applications.

With support for standard UK vehicles, motorcycles, and special territories like the Isle of Man, plus detailed MOT history and tax information, the UK Vehicle Registration API is the most complete solution for accessing UK vehicle data programmatically.

Ready to get started? Visit the RegCheck website to create your free account and begin exploring UK vehicle data today.

Understanding TLS fingerprinting.

TLS fingerprinting is a way for Bot discovery software to help discover the difference between a browser and a bot. It works transparently and fast, but not infallable. What it depends on, is that when a secure HTTPS connection is made between client and server, there is an exchange of supported cyphers. based on the cyphers supported, this can be compared against the “claimed” user agent, to see if this would be the cyphers supported by this user-agent (Browser).

It’s easy for a bot to claim to be Chrome, just set the user agent to be the same as a modern version of Chrome, but it’s more difficult to support all the cyphers supported by Chrome, and thus, if the HTTP request says it’s Chrome, but doesn’t support all of Chrome’s Cyphers, then it probably isn’t Chrome, and it’s a Bot.

There is a really handy tool here; https://tls.peet.ws/api/all – which lists the cyphers used in the connection. If you use a browser, like Chrome, you’ll see this list of cyphers:

 "ciphers": [
      "TLS_GREASE (0xEAEA)",
      "TLS_AES_128_GCM_SHA256",
      "TLS_AES_256_GCM_SHA384",
      "TLS_CHACHA20_POLY1305_SHA256",
      "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
      "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
      "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
      "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
      "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
      "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
      "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
      "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
      "TLS_RSA_WITH_AES_128_GCM_SHA256",
      "TLS_RSA_WITH_AES_256_GCM_SHA384",
      "TLS_RSA_WITH_AES_128_CBC_SHA",
      "TLS_RSA_WITH_AES_256_CBC_SHA"
    ]

Wheras if you visit it using Firefox, you’ll see this;

 "ciphers": [
      "TLS_AES_128_GCM_SHA256",
      "TLS_CHACHA20_POLY1305_SHA256",
      "TLS_AES_256_GCM_SHA384",
      "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
      "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
      "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
      "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
      "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
      "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
      "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
      "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
      "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
      "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
      "TLS_RSA_WITH_AES_128_GCM_SHA256",
      "TLS_RSA_WITH_AES_256_GCM_SHA384",
      "TLS_RSA_WITH_AES_128_CBC_SHA",
      "TLS_RSA_WITH_AES_256_CBC_SHA"
    ],

Use CURL or WebClient in C#, and you’ll see this

 "ciphers": [
      "TLS_AES_256_GCM_SHA384",
      "TLS_AES_128_GCM_SHA256",
      "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
      "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
      "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
      "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
      "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
      "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
      "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
      "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
      "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
      "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
      "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
      "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
      "TLS_RSA_WITH_AES_256_GCM_SHA384",
      "TLS_RSA_WITH_AES_128_GCM_SHA256",
      "TLS_RSA_WITH_AES_256_CBC_SHA256",
      "TLS_RSA_WITH_AES_128_CBC_SHA256",
      "TLS_RSA_WITH_AES_256_CBC_SHA",
      "TLS_RSA_WITH_AES_128_CBC_SHA"
    ],

So, even with a cursory glance, you could check for TLS_GREASE or TLS_CHACHA20_POLY1305_SHA256 and see if these are present, and declar the user as a bot if these cyphers are missing. More advanced coding could check the version of Chrome, the Operating System, and so forth, but the technique is that.

However, using the library TLS-Client in Python allows for more cyphers to be exchanged, and the TLS fingerprint looks much more similar (if not indistinguishable) from Chrome.

https://github.com/infiniteloopltd/TLS

    session = tls_client.Session(
        client_identifier="chrome_120",
        random_tls_extension_order=True
    )
    page_url = "https://tls.peet.ws/api/all"
    res = session.get(
        page_url
    )
    print(res.text)

I am now curious to know If I can apply the same logic to C# …