It doesn’t work, because attribute selectors “match elements which have certain attributes defined in the source document” (Attribute selectors in CSS 2.1). Things are a bit more complicated really, because calling setAttribute('value','password') on the input element causes a match in many browsers (not IE). But this is irrelevant if you don’t use JavaScript.
There is, however, an indirect way, though it is mostly theoretical for the time being, due to limited browser support and to complications in implementations. You could write:
<style>
input:valid { border: 1px solid red; }
</style>
<input pattern=password id=x>
This uses the HTML5 pattern attribute, in this case specifying a regular expression that is merely a fixed string with no wildcards, and the CSS3 Basic UI :valid pseudo-class that tests whether the element’s state satisfies validity constraints. This is not suitable for normal use (e.g., no support in IE 9), but in special situations in controlled environments, things like this might be usable.
However, browsers that support such features tend to have their own reporting of validity errors, like special color around the box when the value is invalid, and I don’t think you can change that in CSS – JavaScript might help, but… So the reporting might conflict with your goals here. Moreover, it seems that browsers supporting these features treat the element’s state as valid when the box is empty. This is odd, and attempts to work around this my making the input obligatory (HTML5 attribute required) seem to open new cans of worms rather than fix. But maybe in some cases you could use just some initial value, say value="?", that the user is expected to replace by this input.