First, the Arduino Uno has 32 KB of flash, but only 1 KB of RAM. So, to be able to store the new program in a string means your new program can only be, at most, 1kb.
Secondly, only the bootloader can write to flash. So you could write a new bootloader that downloads the new program (in parts) and writes it to the flash. You would however need quite a big bootloader, leaving less space for actual code. Also the main program still needs to access the server to see if it needs to "reboot" so the bootloader can run the update process.
An example of an OTA bootloader can be found at https://www.rotwang.co.uk/projects/bootloader.html which might be a good starting point. Similar idea https://ncrmnt.org/2014/02/27/rf24boot-a-universal-over-the-air-bootloader-for-all-those-ucs/
Another option is to write the new firmware to an external EEPROM. Then your modified bootloader only has to read the new firmware from EEPROM, making it a lot simpler and smaller. There is some useful info in the question OTA updates for Arduino using nRF24L01+
MySensors.org already made such a bootloader: https://www.mysensors.org/about/bootloader
I know there exists another bootloader that does just that, but I can't seem to find it.