On 07/11/2020 23:30, Michael Haardt via Exim-users wrote:
Ok, have had a 5 minute scan read ... seems that tainted data is a
{potential} problem, but in my case the variables that I use to build a
path in transport 'local_delivery':
[...]
have already been used as keys in a database look-up previously in the
router that cause the transport to be called:
That's not how things work.  The variable will stay tainted even when
looked up.

Agreed - but see below.


Can we have, instead, a directive that allows us to assert 'untainted'
over one or more variables:
Previously, a single lookup that checked both local part and domain to
let the router match was popular.  Now that's fighting against the design.

Use two lookups, one for local_parts and one for domains, even if both
perform the same lookup, to set $local_part_data and $domain_data as
side effect, and things are easy from there.  It's a new way of thinking
about routers: You do not just need a condition to let the router match
the address, you also need to set the *_data variables as side effect.

You can work around the *_data variables, but it will make everything
complicated.

Just untainting variables without verification is a bad idea.

Agreed, but in my case they are verified (see below)

   One could
argue if there shouldn't be a verifier option for variables instead of
setting the *_data copies, so a single lookup could verify und untaint
two variables, but some check is required.  Before I used generic
conditions to verify variables and another condition to match the router,
now I use local_parts and domains, which I never did before.  It is about
as readable, once you get used to it.

I get the purpose of tainted data and preventing its use, however if you look at my router:

#
# Normal local delivery
#
local_delivery:
        driver = accept
        condition = ${lookup mysql{SELECT CONCAT(users.username,'@',domains.domain) AS email FROM \                 users LEFT JOIN domains ON users.domain_id=domains.id WHERE \
                users.username='${quote_mysql:$local_part}' AND \
                domains.domain='${quote_mysql:$domain}' AND \
                users.active=1 AND \
                domains.active=1}{yes}{no}}
        transport = local_delivery
        user = mail
        group = mail

when the condition checks my work email address (mike.tu...@thorcom.co.uk):

    users.username == mike.tubby
    domains.domain == thorcom.co.uk

and it has to be a perfect match, character for character, hence my assertion is that transport = local_delivery is only ever called if the condition is true and for the condition to be true $local_part and $domain have matched what is in my database and are therefore 'verified' safe.  Well this is true for my use case, at least.

Now it looks like I have to use additional look-ups, perhaps something like this:

    $domain_data = ${lookup mysql{SELECT domains.domain AS domain FROM \
                users LEFT JOIN domains ON users.domain_id=domains.id WHERE \
                users.username='${quote_mysql:$local_part}' AND \
                domains.domain='${quote_mysql:$domain}' AND \
                users.active=1 AND \
                domains.active=1}}

    $local_part_data = ${lookup mysql{SELECT users.username AS username FROM \                 users LEFT JOIN domains ON users.domain_id=domains.id WHERE \
                users.username='${quote_mysql:$local_part}' AND \
                domains.domain='${quote_mysql:$domain}' AND \
                users.active=1 AND \
                domains.active=1}}

to simply send my 'already known good' keys $local_part and $domain round in circles and get the duplicate data (same values) from the database rather than use them, directly?


Mike


Michael




--
## List details at https://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/

Reply via email to