At register level, there is an IDR (input data register) and ODR (output data register). They both work independently, i.e. you can read back the IO value with IDR while in output "mode".
This works with HAL as well:
So you might setup a GPIO pin as open-drain output with a pull-up in the chip configuration or code:
If Open Drain is not an option because of its inherent limitations, you can of course change the "direction" of given pin simply by changing its respective GPIO_MODER field.
I don't think this is something easily clickable in CubeMX, though.