'Google Chrome 139' stable release, abolishes automatic detection of ISO-2022-JP

The latest stable version of the web browser ' Google Chrome ,' version 139, has been released.
Chrome 139 | Release notes | Chrome for Developers
https://developer.chrome.com/release-notes/139?hl=ja
◆Auto-detection of ISO-2022-JP character code has been removed
ISO-2022-JP is a Japanese character code that conforms to the international character code standard ISO/IEC 2022, and has been widely used alongside Shift JIS code and Japanese EUC code since before the spread of Unicode-based character sets. One of its features is the ability to switch between multiple character sets using 'escape sequences.'

This feature was known to affect the HTML character encoding auto-detection function and could pose a security risk. The purpose of this update is to avoid this risk by excluding ISO-2022-JP from the HTML character encoding auto-detection function.
There are three ways that a browser can determine the HTML character encoding:
- Byte order mark detection
- charset attribute of Content-Type header
・The <meta> tag in an HTML document
However, there are cases where none of these exist, in which case the browser will automatically detect it by checking the content itself. Browsers will automatically detect that an HTML document containing even one ISO-2022-JP escape sequence is in the ISO-2022-JP character encoding. If the detected character encoding differs from the actual character encoding, the document will not be properly sanitized, potentially resulting in an XSS vulnerability. ISO-2022-JP has a character set switching function using escape sequences, and if an attacker exploits this mechanism, it can more easily launch an XSS attack than with other character encodings.
There are two specific attack methods that are envisioned here.
・Method 1: Disable backslash escapes in JavaScript strings
To illustrate this technique, let's imagine a page that references URL parameters and propagates them to an HTML document containing JavaScript. In this example, we'll assume that the HTML document contains only ASCII characters and that the character encoding is not specified, but rather auto-detected.

Even if an attacker tries to insert malicious code into the URL parameters of this page, they will not be affected by normal methods because sanitizing will convert the code into a format that will not execute. In the example below, the attacker inserts a quotation mark into the URL parameter to terminate the JavaScript string there and have the code that follows it loaded as executable, but sanitizing adds a backslash before the quotation mark, which acts as an escape sequence for JavaScript strings (confusingly, this is different from the ISO-2022-JP escape sequence), so the quotation mark is recognized as a character within the string rather than as the end of the string. As a result, even if there is a string that would be recognized as JavaScript code after it, it will be recognized as a string and not as code.

Now, suppose there is another URL parameter embedded before the <script> tag, and the ISO-2022-JP escape sequence 'ESC ( J' is specified for this parameter. In this case, the HTML document will be determined to be ISO-2022-JP by autodetection, and since this escape sequence specifies a switch to 'JIS X 0201 Plane 1 (JIS Latin Code)', everything after the escape sequence will be interpreted as the JIS X 0201 Plane 1 character set, not the ASCII character set.

Since both the ASCII character set and the JIS X 0201 Plane 1 (JIS Latin Character) character set are Latin characters, the switch in character set here may not seem to have any impact at first glance. However, there are subtle but crucial differences between the two. The table below is an area map of the ASCII character set.
Lower 4 bits | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | f | ||
above rank 4 B t to | 0 | 0x00 NUL | 0x01 SOH | 0x02 STX | 0x03 ETX | 0x04 EOT | 0x05 ENQ | 0x06 ACK | 0x07 BEL | 0x08 BS | 0x09 HT | 0x0a LF | 0x0b VT | 0x0c FF | 0x0d CR | 0x0e SO | 0x0f SI |
1 | 0x10 DLE | 0x11 DC1 | 0x12 DC2 | 0x13 DC3 | 0x14 DC4 | 0x15 NAK | 0x16 SYN | 0x17 ETB | 0x18 CAN | 0x19 EM | 0x1a SUB | 0x1b Esc | 0x1c FS | 0x1d GS | 0x1e RS | 0x1f US | |
2 | 0x20 SP | 0x21 ! | 0x22 ' | 0x23 # | 0x24 $ | 0x25 % | 0x26 & | 0x27 ' | 0x28 ( | 0x29 ) | 0x2a * | 0x2b + | 0x2c , | 0x2d - | 0x2e . | 0x2f / | |
3 | 0x30 0 | 0x31 1 | 0x32 2 | 0x33 3 | 0x34 4 | 0x35 5 | 0x36 6 | 0x37 7 | 0x38 8 | 0x39 9 | 0x3a : | 0x3b ; | 0x3c < | 0x3d = | 0x3e > | 0x3f ? | |
4 | 0x40 @ | 0x41 A | 0x42 B | 0x43 C | 0x44 D | 0x45 E | 0x46 F | 0x47 G | 0x48 H | 0x49 I | 0x4a J | 0x4b K | 0x4c L | 0x4d M | 0x4e N | 0x4f O | |
5 | 0x50 P | 0x51 Q | 0x52 R | 0x53 S | 0x54 T | 0x55 U | 0x56 V | 0x57 W | 0x58 X | 0x59 Y | 0x5a Z | 0x5b [ | 0x5c \ | 0x5d ] | 0x5e ^ | 0x5f _ | |
6 | 0x60 ` | 0x61 a | 0x62 b | 0x63 c | 0x64 d | 0x65 e | 0x66 f | 0x67 g | 0x68 h | 0x69 i | 0x6a j | 0x6b k | 0x6c l | 0x6d m | 0x6e n | 0x6f o | |
7 | 0x70 p | 0x71 q | 0x72 r | 0x73 s | 0x74 t | 0x75 u | 0x76 v | 0x77 w | 0x78 x | 0x79 y | 0x7a z | 0x7b { | 0x7c | | 0x7d } | 0x7e ~ | 0x7f DEL |
On the other hand, below is an area map of the JIS X 0201 Plane 1 (JIS Latin characters) character set. You can see that the characters indicated by the green background cells are different from ASCII.
Lower 4 bits | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | f | ||
above rank 4 B t to | 0 | 0x00 NUL | 0x01 SOH | 0x02 STX | 0x03 ETX | 0x04 EOT | 0x05 ENQ | 0x06 ACK | 0x07 BEL | 0x08 BS | 0x09 HT | 0x0a LF | 0x0b VT | 0x0c FF | 0x0d CR | 0x0e SO | 0x0f SI |
1 | 0x10 DLE | 0x11 DC1 | 0x12 DC2 | 0x13 DC3 | 0x14 DC4 | 0x15 NAK | 0x16 SYN | 0x17 ETB | 0x18 CAN | 0x19 EM | 0x1a SUB | 0x1b Esc | 0x1c FS | 0x1d GS | 0x1e RS | 0x1f US | |
2 | 0x20 SP | 0x21 ! | 0x22 ' | 0x23 # | 0x24 $ | 0x25 % | 0x26 & | 0x27 ' | 0x28 ( | 0x29 ) | 0x2a * | 0x2b + | 0x2c , | 0x2d - | 0x2e . | 0x2f / | |
3 | 0x30 0 | 0x31 1 | 0x32 2 | 0x33 3 | 0x34 4 | 0x35 5 | 0x36 6 | 0x37 7 | 0x38 8 | 0x39 9 | 0x3a : | 0x3b ; | 0x3c < | 0x3d = | 0x3e > | 0x3f ? | |
4 | 0x40 @ | 0x41 A | 0x42 B | 0x43 C | 0x44 D | 0x45 E | 0x46 F | 0x47 G | 0x48 H | 0x49 I | 0x4a J | 0x4b K | 0x4c L | 0x4d M | 0x4e N | 0x4f O | |
5 | 0x50 P | 0x51 Q | 0x52 R | 0x53 S | 0x54 T | 0x55 U | 0x56 V | 0x57 W | 0x58 X | 0x59 Y | 0x5a Z | 0x5b [ | 0x5c ¥ | 0x5d ] | 0x5e ^ | 0x5f _ | |
6 | 0x60 ` | 0x61 a | 0x62 b | 0x63 c | 0x64 d | 0x65 e | 0x66 f | 0x67 g | 0x68 h | 0x69 i | 0x6a j | 0x6b k | 0x6c l | 0x6d m | 0x6e n | 0x6f o | |
7 | 0x70 p | 0x71 q | 0x72 r | 0x73 s | 0x74 t | 0x75 u | 0x76 v | 0x77 w | 0x78 x | 0x79 y | 0x7a z | 0x7b { | 0x7c | | 0x7d } | 0x7e ~ | 0x7f DEL |
The problem lies in the difference in the character code '0x5c,' which is defined as a 'backslash' in ASCII, but as a 'yen sign' in JIS X 0201 Plane 1 (JIS Latin characters). Depending on the environment, such as the font being used, a backslash may be displayed as a yen sign, so this may not seem like much of an issue, but the important thing to remember is that JavaScript escape sequences are backslashes, and yen signs are not. As a result, the sanitization does not work as expected, and the quotation marks are recognized as quotation marks, allowing the malicious code following them to execute, as the attacker intended.
・Method 2: Destroying the HTML context
For this example, we will look at a common pattern where a site that supports Markdown to HTML conversion outputs HTML containing the <img> tag from Markdown that displays two images. As with the example in Method 1, we will assume that the generated HTML document consists only of ASCII characters, and the character encoding is not specified, leaving it to be automatically detected.

First, replace the source of the first image with the escape sequence 'ESC $ @'. This causes the string following the escape sequence to be interpreted as the JIS X 0208 1987 (old JIS kanji JIS C 6226-1978) character set. Instead of using the ASCII character set, the code tries to interpret it as a two-byte code, resulting in what is known as 'garbled characters' after the escape sequence, which results in a broken HTML document.

Now, insert another escape sequence, 'ESC ( B', in the plain text between the two images. Doing this will cause the string from that point onwards to be interpreted in the ASCII character set, so although some garbled characters will remain, the HTML document will no longer fail. What is noteworthy here is that the double quotation mark that was the end of the alt attribute value of the first <img> tag has disappeared due to the garbled characters that remain. As a result, the text up to the double quotation mark that is the start of the src attribute value of the second <img> tag will be treated as the alt attribute value.

This causes the src attribute value of the second <img> tag to no longer be an attribute value, creating a potential attacker opportunity to inject an error handler containing JavaScript code.

To fundamentally eliminate these security risks, it was necessary to reconsider the mechanism that automatically detects that an HTML document is encoded in ISO-2022-JP simply because it contains an ISO-2022-JP escape sequence, which led to this change. At the time of writing, it is rare to see sites written in ISO-2022-JP, so it is unlikely that this change will affect many cases. However, if you manage or operate such a site, you should make changes to prevent it from relying on automatic character encoding detection, such as by adding the charset attribute to the Content-Type header.
◆Shortcuts for CSS functions var() and attr()
The CSS functions var() and attr() are evaluated without looking for a fallback value if no fallback occurs. Fallback here means that, for example, when the var() function is used as follows, even if the first argument is an invalid value, the second argument can be used as a fallback value.
--blue: blue;
--a: var(--green, --blue);
With this in mind, consider the following code:
--green: green;
--blue: blue;
--a: var(--green, var(--b));
--b: var(--blue, var(--a));
In this code, the custom property specified in the first argument exists in both --green and --blue, so no fallback occurs. If the second argument set as a fallback value were to be evaluated in this case, a problem would occur. This is because the fallback value for --a is --b, and the fallback value for --b is --a, creating a circular reference. This update resolves this case, and the second argument as a fallback value is never evaluated unless a fallback occurs, so the above code (although it is just an example and should be avoided in the first place) does not cause a problem.
◆CSS caret-animation property
The caret-color property is used to set the color of the input caret (text input cursor) in CSS, and this color setting supports animation. However, the input caret is originally animated by blinking, which can interfere with the animation displayed by caret-color and make it difficult to see. To address this issue, the caret-animation property was added. This property can be set to the following two values:
・auto : Default state (blinking)
manual : Caret animation is controlled by the web developer (blinking disabled)
In the caret-color sample site below, you can understand the behavior of this property by adding the caret-animation property to the CSS input selector and switching its value.
caret-color animation
https://codepen.io/daviddiaz/pen/vYXdXbR
◆CSS corner-shape property
There is an existing CSS property called border-radius that defines the shape of the corners of DOM elements, but the ' corner-shape ' property has been added to allow for even greater flexibility in settings. By using this property, it is now possible to add a variety of different expressions to corner shapes, which previously only had a simple rounded shape with a specified curve radius. Below is a sample animation that demonstrates this expressive power.
corner-shape
https://codepen.io/amit_sheen/pen/pvJKGov/5d14d83481ba74eea561f08d81493614
The corner-shape property can have the following values:
- Round (default): Same circular or elliptical arc shape as before
・Squircle : A shape between a right angle and an arc
・Scoop : Concave circular or elliptical arc shape
・bevel : A shape with a straight cut corner
・notch : A shape where the corner is cut off at a right angle
・square : Shape with no corner changes (border-radius is disabled)

◆CSS custom functions
Custom functions are similar to custom properties, but instead of returning a fixed value, they return different values depending on other custom properties, parameters, and conditions. In the example below, we define a custom variable '--negate' that converts the value of the custom property '--gap' to a negative number.
@function --negate(--value) {
result: calc(var(--value) * -1);
}
div {
--gap: 1em;
margin-top: --negate(var(--gap));
}
◆Other updates
CSS: Changed to continue transition execution when switching transition-related properties to their initial values (same behavior as webkit and gecko)
CSS: Added font-width property and descriptor, font-stretch is now a legacy alias
- Web app: Allows you to specify the algorithms to be updated in the manifest specification
・WebXR : Improved depth sensing performance
API: Allow more characters in JavaScript DOM API (relaxed limit to match HTML parser)
・WebGPU: Supports 3D textures in BC and ASTC compression formats
WebGPU: Added core-features-and-limits feature (indicates that WebGPU adapters and devices support the core features and limits of the specification)
Secure Payment Confirmation (SPC) : Adds cryptographic signatures and provides the securePaymentConfirmationAvailability API
・SVG's <script> element now supports the async attribute
On-device Web Speech API: Allows websites to process speech without sending data to a third-party service.
Audio level of RTC encoded frames: Publishes the audio level of encoded frames published by WebRTC Encoded Transform to the web.
Cross-site navigation: When performing navigation that switches context groups, clear the value of the window.name property to prevent information leakage.
Network: Reduced fingerprinting of Accept-Language header information (send only the most preferred language instead of the complete list of the user's preferred languages)
Network: Randomize TCP port assignments in Windows
- Reduced the time it takes for background pages (and associated workers) to freeze on Android from 5 minutes to 1 minute
Web Apps: Added the scope_extensions manifest field, which allows extending scopes to other origins, allowing sites that control multiple subdomains and top-level domains to be a single web app.
For workers blocked by Content Security Policy (CSP), an error event is now raised asynchronously instead of throwing an exception.
- JSON MIME type detection now conforms to the specification: MIME types with subtypes ending in '+json' have been added.
◆Origin Trial
・Prompt API : Supports input of text, images, and voice into AI language models
- Ability to extend the lifetime of SharedWorker (added constructor option 'extendedLifetime: true')
・Added SoftNavigation performance entries (soft-navigation, interaction-contentful-paint)
New render-blocking attribute full-frame-rate: Runs the renderer at a lower frame rate to free up resources for loading.
Instant web authentication mediation: If the browser has a passkey or password for the site that it immediately recognizes, the browser's login UI will be displayed to the user.
WebGPU compatibility mode: A limited subset of the WebGPU API that allows you to run older graphics APIs such as OpenGL and Direct3D11.
◆ Deprecated features
- End of support for macOS 11
Stop sending the Purpose: prefetch header from prefetching and prerendering
- Automatic fallback to WebGL by SwiftShader is no longer supported: security risk mitigation (phase-out period complete)
Google Chrome 139 also includes 12 security bug fixes .
The next stable version, 'Google Chrome 140,' is scheduled to be released on Tuesday, September 2, 2025 local time.
Related Posts:
in Software, Posted by log1c_sh