IBM Domino - internet sites + substitution with '?' in incoming rule errors - xpages

For upcomming larger Xpages project we need to use substitution rules to provide SEO friendly URLs. We need to define rules similar to this one:
Incoming URL pattern: /*/products?*
Replacement pattern: /web.nsf/view.xsp?lang=*&*
This substitution should work with URL e.g.:
/cz/products?start=1&count=20
and substitute to
/web.nsf/view.xsp?lang=cz&start=1&count=20
But we just found out that when incoming rule contains '?' it simply returns Error 404 . We found this reported here http://www-10.lotus.com/ldd/nd8forum.nsf/DateAllFlatWeb/a8162420467d5b45852576c7007fc045?OpenDocument.
Is there any workaround or fix for this situation ? Documentation doesnt mention such limitation ... which is, in fact, very significant because we are not able to redefine the rule to fit our (very common) situation.
Any idea how to fix this?

I do not think you can solve that issue easily.
If you can't find an easy solution I would suggest you to look on these 2 approaches:
You build DSAPI filter and define your custom substitutions there (that way speed won't be affected).
You point requests to single xsp and that xsp will check incoming requests and redirect them to appropriate place (based on your custom substitutions).

Related

How do I create a rule to block all user agents with ModSecurity V3?

I want to add a custom ModSecurity (V3) rule that can block all user agents, and allow me to whitelist certain User Agents from a file.
If this is possible, if someone could share the rule with me, that would be great. I cannot seem to figure out the rule to do this.
Thanks!
This is a bit dangerous what you want to do, but I try to give you some help.
I think CRS rule 913100 would be a good point to start for you.
It's a bit complex if you new in ModSecurity any SecLang, so in short, this would be a possible solution. Create a rule for your WAF, like this:
SecRule REQUEST_HEADERS:User-Agent "!#pmFromFile allowed-user-agents.data" \
"id:9013100,\
phase:1,\
deny,\
t:none,\
msg:'Found User-Agent associated with security scanner',\
logdata:'Matched Data: illegal UA found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}'"
Please note, that you can choose any id for your rule what you want, but there is a reservation list for id's:
https://coreruleset.org/docs/rules/ruleid/#id-reservations
It's highly recommended you choose a right one to avoid the collision with other rules. 9013100 would be a good choice, and it represents where this rule is derived from.
Then you have to make a file with a list of your allowed user agents. Note, that you have to place that list in same directory as the rule conf file exists. The name of file must be (as you can see above) allowed-user-agents.data. You can put an agent per line. Also you can use comments with # at the beginning of the rule - just see the CRS's data file.
How this rule works?
SecRule is a token which tells the engine that this is a rule. REQUEST_HEADERS is a collection (a special variable), what the engine expands from the HTTP request. The : after the name indicates that you want to investigate only the mentioned header, namely User-Agent.
The next block is the operator. As documentation says #pmFromFile "Performs a case-insensitive match of the provided phrases against the desired input value.". This is what you need exactly. There is a ! sign before the operator. This inverts the operator's behavior, so it will be TRUE if the User-Agent isn't there in the file.
The next section is the action's list. id is mandatory, this identifies the rule. phase:1 is optional but very recommended to place one. For more information, see the reference. deny is a disruptive action, it terminates the request immediately. msg will append a message to the log in every cases. logdata will show a detailed info about the rule result.
Why is this a little dangerous
As you can see in the documentation of #pmFromFile operator, it uses patterns. This means you do not have to place the exact User-Agent names, it's enough to put a pattern, like "curl", or "mozilla" - but be careful, a wrong pattern can lead to false positive results, which means - in this case - an attacker can bypass your rule: it's enough to place the pattern to trick it.
Consider you put the pattern my-user-agent into the data file. Now if someone just uses this pattern as User-Agent, the rule won't match.
It is generally true that handling whitelists in this way (in some special contexts, like this) is dangerous, because it's easy to bypass them.

Trying to create seo friendly url

I'm trying to create friendly url for my site but with no success :(( and i have two questions
The first is:
How to change the url from domain.com/page/something.php to domain.com/something
And the second is:
Will the changes make duplicate content and if how to fix the problem.
Thank you for your time,
Have a nice day
Check out the official URL Rewriting guide: http://httpd.apache.org/docs/2.0/misc/rewriteguide.html
You'll be using the simplest use case, Canonical URLs. Assuming you have no other pages that you need to worry about, you can use a rule like this: (note: untested, your usage may vary)
RewriteRule ^/(.*)([^/]+)$ /$1$2.php
While that example might not exactly work for your use case, hopefully reading the guide and my example will help you get you on your way.

Notes 9, rewriting URLs

How do you rewrite a URL in Notes 9 XPages.
Let's say I have:
www.example.com/myapp.nsf/page-name
How do I get rid of that .nsf part:
www.example.com/page-name
I don't want to do lots of manual re-direct because my pages are dynamically formed like wordpress.
I've read this: http://www.ibm.com/developerworks/lotus/library/ls-Web_site_rules/
It does not address the issue.
If you use substitution rules like the following, you can get rid of the db.nsf part and call your XPages directly as example.com/xpage1.xsp:
Rule (substitution): /db.nsf/* -> /db.nsf/*
Rule (substitution): /* -> /db.nsf/*
However, you have to "manually" generate your URLs without the db.nsf part in e.g. menus because the XPages runtime will include the db.nsf part in the URLs if you use for instance the openPage simple action.
To completely control what is going in and out put your Domino behind an Apache HTTP and use mod_rewrite. On Domino 9.0 Windows you can use mod_domino
You can do it with a mix of subsitutions, "URL-pattern" and paritial refresh.
I had the same problem, my customers wants clean URLs for SEO.
My URLs now looks like these:
www.myserver.de/products/financesoftware/anyproduct
First i used one subsitution to cover the folder, database and xpage part of the URL.
My substitution: "/products" -> "/web/techdemo.nsf/product.xsp"
Problem with these is, any update on this site (with in redirect mode) and the user gets back the "dirty" URL.
I solved this with the use of paritial refreshes only.
Last but not least, i uses my own slash pattern at the end of the xpage call (.xsp)
In my case thats the "/financesoftware/anyproduct/" part.
I used facesContext.getExternalContext().getRequestPathInfo() to resolve that URL part.
Currently i used good old RegExp to get the slash separated parameters back out of the url, but i am investigating a REST solution at the moment.
I haven't actually done this, but just saw the option yesterday while looking for something else. In your Xpage, go to All Properties, and look at 'navigationRules' and 'pageBaseUrl'. I think you will find what you are looking for there.

Multiple and Variable parameters URL rewriting

I don't know how to rewrite URLs of this type:
mywebsite/param1-val1-param2-val2-param3-val3-param4-val4.html
that's really simple to do BUT my problem is that my parameters are variables like:
mywebsite/param1-val1-param3-val3-param4-val4.html
or
mywebsite/param3-val3-param4-val4.html
so, the number of parameters is not always the same. It can sometimes be just one, sometimes it can be 10 or more. It redirects to a search script which will grab the parameters through GET querystring.
What I want to do is to not write (on htaccess) a line for every link. The links are pretty simple in that form separated by a -(hyphen) sign.
Rather than rely on complex rewrite rules, I would suggest a simple rewrite rule and then modifying the code of your web application to do the hard part. Supporting this kind of variable parameters is not something that a rewrite rule is going to be very good at on its own.
I would use the following rewrite rule that intercepts any url that contains a hyphen separator and ends in .html
RewriteRule ^(.+[\-].+)\.html$ /query.html?params=$1
Then in your web application can get the parameters from the CGI parameter called params . They look like this now param1-val1-param3-val3-param4-val4. Your code should then split on the hyphens, and then put the parameters into a map. Most web frameworks support some way of adding to or overriding the request parameters. If so, you can do this without doing invasive modifications to the rest of your code.

Hiding URL parameters with .htaccess while still making them available to $_GET

I have a script on my site ('write-review.php') that takes an optional url parameter 'site'. So server-side requests could be:
/reviews/write-review.php
or
/reviews/write-review.php?site=foo
I'm using .htaccess to create search engine friendly URLs and hide my php extensions, so that requests to this script are respectively rewritten as
/reviews/write-a-review/
or
/reviews/write-a-review/foo
I think having 'foo' in the URL may cause confusion for my users, so I'm trying to write an htaccess rewrite rule that removes 'foo' while still passing this variable to my script. Thus, a request to /reviews/write-a-review/foo would be rewritten as /reviews/write-a-review/ but write-review.php would be passed 'foo'.
The rewrite rule I currently have in place is:
RewriteRule ^reviews/write-a-review/?$ reviews/write-review.php
RewriteRule ^reviews/write-a-review/([a-zA-Z0-9_-]+)/?$ reviews/write-review.php?site=$1
Is it even possible to do what I've described above? There are MANY questions on Stack Overflow that are similar to this, and I've read through at least a dozen, but I haven't found a way to do this specifically.
Any help is really appreciated.
Thanks,
Chris
Is it even possible to do what I've described above?
No. To alter the actual URL the user inputs, you'd have to do a header redirect, during which you would lose foo.
This is not possible, except maybe by using ridiculous technical tricks like storing foo in a session variable or something. I would not recommend going that route.

Resources