Assuming these values must appear as full comma-separated entries, you can use
where str ~ '^(?=.*(?:,|^)foo(?:,|$))(?=.*(?:,|^)bar(?:,|$))'
Here, it will match strings that contain foo and bar in any order using the ~ (regex matching) operator. Details:
^ - start of string
(?=.*(?:,|^)foo(?:,|$)) - immediately on the right, there should be any zero or more chars, as many as possible, and then a foo string (either at the start of string or right after a comma and followed with a comma or end of string position)
(?=.*(?:,|^)bar(?:,|$)) - immediately on the right, there should be any zero or more chars, as many as possible, and then a bar string (either at the start of string or right after a comma and followed with a comma or end of string position)
Assuming these values must appear as whole words you can replace the non-capturing groups with \y word boundaries and use
where str ~ '^(?=.*\yfoo\y)(?=.*\ybar\y)'
See the online DB fiddle:
CREATE TABLE string_entries
(str character varying)
;
INSERT INTO string_entries
(str)
VALUES
('aaa,bbbb,foo,zzz,bar'),
('bar,ccc,ddddd,foo,iiiii'),
('aaa,eeeee,foo,rrrrrr,hhhhhh'),
('ooooo,ii,sssss,bar,xxxx')
;
select str from string_entries where str ~ '^(?=.*(?:,|^)foo(?:,|$))(?=.*(?:,|^)bar(?:,|$))';
