I guess the correct way would be to pass $atts through shortcode_atts(), but I don’t want to have to always be aware of WordPress modifying get_posts in the future.
After doing some research the data passed into get_posts() is sanitized (I think I knew that), but the drawback is that you give the users the ability to just list a million posts, which can be a drain on resources I guess. So some sanitation is necessary - maybe limit numberposts etc.
Basically the intent was to create a shortcode that lets users drop in their own dynamic templates straight from the editor, something like: