Windows tel app problem

I need help with a problem:

I’m making a registration form and I’m trying to use regex preg_match to validate a birthdate. The format is numbers not names: dd mm jj as 01 01 1999. I’m trying to limit the answers to dd mm jj and if first nuber 0 then second number cannot be a zero. Anyway, I’m testing the regex and it is working with [0-9]{2}. However, whenever I entered 02 01 1999 and submitted the form, the output (echo $dd . ’ ’ . $mm . ’ ’ . $jj . ;
:wink: the string 02 01 1999 becomes a hyperlink in Edge browser. ??? then when I click the hyperlink, I see a message from Windows: “You’ll need a new app to open this tel”.

what is this? why does it make my birthday string a hyperlink? I assume that tel means telephone number? this is too much for me to grasp. I have no idea why this is happening. How do I stop this? what If I want to show the user what they have submitted for review? Firefox doesn’t create a hyperlink. This appears to be restricted to IE/Edge.

I’m confused …

I wouldn’t use a regular expression on any date, when you have a Date class that can validate it.

As for the tel anchor, change the format.

[php]$date = “02/01/1999”;
$d = DateTime::createFromFormat(‘d/m/Y’, $date);
echo $d->format(‘F d,Y’);[/php]

http://php.net/manual/en/datetime.createfromformat.php

I spent around 30 minutes researching the tel issue and i see that Microsoft just automatically makes a hyperlink of any numbers that resemble a phone number. very irritating, indeed. I just formatted my output with a period and the link disappeared.

i am new to php and backend programming. my goal is to just make it work and try to make it secure. even if i paid someone to make a login/subscription system for me, that someone cannot guarantee security. so why pay in the first place? i can make an insecure app. thus, i am building this myself. i cannot afford to pay for insecurity either way. i will be the first to admit that my code is novice and sloppy but it gets the job done. my site is going to be subscription based. it is a nature photography, video and audio site. I want to be sure that the subscriber is atleast 18 years of age because i’m not dealing with whiny parents or parents that try to get a refund because the minor is not permitted to spend the money. i prefer to avoid these problems. i also show photos of dead animals or dangerous events. i handle alot of wildlife that can be dangerous, especially to a child. anyway, i don’t know about date methods to validate input, so i use a regular expression. I also limit age to 100 years of age. i highly doubt that anyone older will join my site but they can always call me if they really are 120 years old.

here is my actual code. it isn’t pretty but it works :slight_smile: i only know about the checkdate() function to verify format and help detect a leap year.

[php]
$check18 = date(Y) - 18; $check100 = date(Y) - 100;

if (isset($_POST[‘birthDay’]) && !preg_match(’/^[0-9]{2}$/’, $_POST[‘birthDay’])) { echo ‘birth day not correct.’; exit; } else { $bday = fsan1($_POST[‘dobday’]); }
if (isset($_POST[‘birthMonth’]) && !preg_match(’/^[0-9]{2}$/’, $_POST[‘birthMonth’])) { echo ‘birth month not correct.’; exit; } else { $bmonth = fsan1($_POST[‘dobmonth’]); }
if (isset($_POST[‘birthYear’]) && !preg_match(’/^[0-9]{4}$/’, $_POST[‘birthYear’])) { echo ‘birth year not correct.’; exit; } else { $byear = fsan1($_POST[‘dobyear’]); }
if ($bbyear < $check18 && $byear >= $check100 && checkdate($bmonth, $bday, $byear)) {
$birthDate = $bday . ‘.’ . $bmonth . ‘.’ . $byear;
} else {
$birthError = $bday . ‘.’ . $bmonth . ‘.’ . $byear;
}
if ($byear == $check18) {
if ($bmonth == date(m) && $bday <= date(d) && checkdate($bmonth, $bday, $bbyear)) { $birthDate = $bday . ‘.’ . $bmonth . ‘.’ . $byear; } else { $birthError = $gbt; }
if ($bmonth < date(m) && checkdate($bmonth, $bday, $bbyear)) { $birthDate = $bday . ‘.’ . $bmonth . ‘.’ . $byear; } else { $birthError = $gbt; }
}
[/php]

i probably should be embarrassed about my code but i’m not. atleast it works.

Thank you for always answering my questions astonecipher. You really are a big help to me. maybe someday i can do something for you. Thanks again and i hope that you don’t laugh too much at my code :slight_smile:

sorry for the typos. i’m in a hurry. i have a spider to investigate. the variables are mismatched because i’m trying to recode…

Your are over complicating it, but it is understandable. And you can build more secure systems, when the person knows what they are doing. I previously dealt with health infomatics where I could personally be held liable for security breeches.

Anyway, have a look:
[php]<?php
$dateStrs = [
“02/01/1999”,
“12/01/2003”,
“08/06/1960”,
];

function VerifyOfAge($date) {
$curDate = new DateTime();
$d = DateTime::createFromFormat(‘d/m/Y’, $date);
$interval = $curDate->diff($d);
if($interval->y >=18)
return true;
return false;
}

foreach($dateStrs as $date){
$oldEnough = VerifyOfAge($date) ? “” : " not";
echo “You are{$oldEnough} old enough to subscribe, having a birth date of {$date}.\n”;
}[/php]

very nice code. clean and tight. I didn’t know that the date functions could be so useful. Someday, I’d like to write code like you but it will take me years to reach that level. I’m a newbie. I cannot wait years to make my site. You are a very good coder. how much do you charge for a subscription and login system? just curious.

dissecting 2mm spiders and insects can be difficult. identifying them by genitalia can be even more difficult than dissection. I prefer to focus on my work but i want a site soon. I’ve already submitted my trademark. i am really a novice trying to build a pro website and the stress for me is very high.

I wish that I had more time to study programming. I will try my best to learn a little more everyday. I understand what is happening in your code but i would not have thought about it that way. I have much to learn. I really am a novice. Thanks for time and help. I’m going to analyze your code a bit more and try to focus on the logic, so that i can pickup on how to think about code. very nice example of date verification :slight_smile:

Sent you an email…

Absolute security has at least so far proved to be a non existing thing. I feel confident though that I can guarantee that I’d make a system that was more secure than what you’re doing. And good security must be better than questionable security, right? But! If I had a carpenter build me a new home I’d expect him to go out and buy me a (reasonably) secure lock for it. The same applies to us as developers.

Using an existing authentication layer should add security as it’s written by (hopefully) better programmers than us, and it’s security vetted by a lot more people.

Many of the popular modern frameworks come with a finished authentication layer that you can very easily install and use.
https://laravel.com/docs/master/authentication

There are also authentication services you can use to handle this for you. Ie https://auth0.com/pricing gives you 7000 free active users and they handle pretty much everything and lets you set up “log in with facebook/twitter/google/etc” pretty easily.

Depending on where you are located data privacy laws may also be a good reason to make use of someone elses work.

If you insist on making your own then at least follow the best practices


I strongly suggest you use a service for subscriptions as well. You do not want to handle credit card info etc.

I’ve seen laravel mentioned many times but it is too complex for me to use it. a framework, in theory, should be code that is ready to be implemented with app specific changes. but these frameworks are not designed this way. i have no time to learn the special design in order to implement it. the web server host that i’m looking at does not have laravel and i doubt that they will install it for me but even if they did, i don’t know how to use it. I am selecting the managed dedicated server so that the server employees check the site for hacking every minute of the day.

I have no intentions of storing user info in a db. only user names and hashed passwords. I still have to figure out how to do this because I have no db experience either. I see that i can only log into the server via ftp or ssh. i figure i will have to use a perl script to add users to the db manually and to hash the passwords entered. I am controlling the db myself.

i cannot afford to pay thousands for a login. no dev can guarantee security. it is impossible. i store my files outside of the root but if a hacker can get into the server, then this is useless anyway. further, the hack is a problem of apache, php and the host not my scripts. the host company should stop unauthorized access not me.

i’ve already talked to a high profile attorney and he actually encouraged me to remove my copyright notices and watermarks from my photos. he guarantees thousands when someone violates my copyright. he stressed ‘thousands’. so i figure i encourage hackers to mess with my site. my attorney and the host will eat them alive. it will be like a good ufc match. my attorney specializes in it law. in fact, he informed me that my code cannot be protected. if it can be protected, then it already is protected. otherwise, it is not protectable. i can lift code from established frameworks and work it in.

i really hate to do this alone but i cannot afford it prices. if someone could make a better secure subscription and login for a few hundred, then i would do that. however, i also think about backdoors in the code that i cannot detect. alot like the wordpress, cpanel backdoors discovered recently by fbi agents. you really can’t trust coders either. i hate to brave it alone and i am extremely stressed out but i want my site. i love nature. if i can find success, then i can hire programmers to code for me. meantime, i will keep plugging along.

i try to follow all of the advice from security experts but i’m sure that i will miss something. by the way, i’m not processing credit cards. i only accept wired transfers to my iban.

i’ve copied some of my code for posting here. i really can’t see how my form is vulnerable to any injections or xss. i’ve tried entering commands and the process.php sets the error *which displays nothing on the screen.) my error handling is not implemented. i’m not sure how to proceed with errors: use process php error handler to redisplay a form with erros? then send back to process.php? anyway, my form.php and process.php is still being developed. i am far from finished here. however, i can only see session management as an issue. you cannot enter data into my form that isn’t accepted data. i’ve tried it. the session management needs to be implemented correctly but for a novice, i think that my subscription is very good.

i keep all of my php files in their own directory so file.php is never visible. apache loads index.php
using xampp: http://localhost/subscribe/ is all that you see. likewise, http://localhost/subscribe/process/

here is an edited version of my html in form index.php (subscribe/)

<?php
          header("Cache-Control: no-cache, no-store, must-revalidate");
          header("Pragma: no-cache");
          header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
          header("Content-Type: text/html; charset=utf-8");

          // my apache httpd.config file also has headers in the root directory:
          // Header set X-Frame-Options DENY
          // Header set X-XSS-Protection "1; mode=block"
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="de-DE" dir="ltr">
<head>
  <title>Subscription form</title>
  <meta http-equiv="x-ua-compatible" content="IE=edge" /><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="format-detection" content="telephone-no" />
  <meta http-equiv="Content-Security-Policy" content="script-src 'self'; worker-src 'none'; connect-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self'; media-src 'self'; font-src 'none'; plugin-types 'none'; frame-src 'none'; child-src 'none'; object-src 'none'" />
  <meta name="no-email-collection" content="impressum" /><meta name="distribution" content="IU" /><meta http-equiv="window-target" content="_top" />
  <link rel="Stylesheet" type="text/css" href="main.css" />
</head>
<body>

<!-- my script actually calls a directory to load index.php: action="process/" which loads index.php (here named process.php) -->
<div class="Form" align="center"><form autocomplete="off" accept-charset="UTF-8" action="process.php" method="post">
<input type="hidden" name="token" value="<?php echo hash_hmac('sha512', $sessionKey, $formToken); ?>" /> <!-- stored in $_SESSION['secToken'] for matching -->
<div><input autocomplete="off" name="gender" id="lady" type="radio" value="Frau" required><label class="FormLabel" for="lady">Frau</label><input class="FormRadio" autocomplete="off" name="gender" id="man" type="radio" value="Herr"><label class="FormLabel" for="man">Herr</label><br /></div>
<div><input autocomplete="off" name="title" id="dr" type="radio" value="Dr."><label for="dr">Dr.</label><input class="FormRadio" autocomplete="off" name="title" id="prof" type="radio" value="Prof."><label for="prof">Prof.</label><input autocomplete="off" name="title" id="profdr" type="radio" value="Prof. Dr."><label class="FormLabel" for="profdr">Prof. Dr.</label></div>
<div>
    <label class="FormLabel">* Vorname</label><input autocomplete="off" type="text" name="firstName" placeholder="2 bis 27 buchstabe" required minlength="2" maxlength="27" /><br />
    <label class="FormLabel">* Nachname</label><input autocomplete="off" type="text" name="lastName" placeholder="2 bis 27 buchstabe" required minlength="2" maxlength="27" />
</div>
<div>
    <label class="FormLabel">* Tag</label><input autocomplete="off" name="dobday" id="dobyear" type="text" placeholder="TT wie 01 oder 23" minlength="2" maxlength="2" title="nn" pattern="[0-9]{2}" required><br />
    <label class="FormLabel">* Monat</label><input autocomplete="off" name="dobmonth" id="dobyear" type="text" placeholder="MM wie 01 oder 12" required minlength="2" maxlength="2" title="nn" pattern="[0-9]{2}"><br />
    <label class="FormLabel">* Jahr</label><input autocomplete="off" name="dobyear" id="dobyear" type="text" placeholder="JJJJ wie 1981 oder 2015" required minlength="4" maxlength="4" title="nnnn" pattern="[0-9]{4}">
</div>
<div><input value="Submit" name="submit" type="submit" /></div>
</form></div>

</div>

</div></body>
</html>

<?php
 exit; //exit the php script for security.
?>

then my process/ index.php file

<?php  // process subscription form data

if ($_SERVER["REQUEST_METHOD"] == "POST") {

//paranoid and don't know how to handle requests that may get by the if conditional
$_GET = array(); $_SERVER["QUERY_STRING"] = NULL;

// be sure that the ini file is in my favor. still need to implement a conditional to exit if not set
ini_set('session.use_strict_mode', 1);
ini_set('session.use_cookies', 1);
ini_set('session.use_only_cookies', 1);
ini_set('session.use_trans_sid', 0);
ini_set('session.cookie_lifetime', 0);
ini_set('session.cookie_httponly', TRUE);
ini_set('session.gc_maxlifetime', 1800);

session_cache_limiter('nocache');
session_cache_expire(3);
session_start();
session_regenerate_id(true); // elevation, so regenerate

// still need to implement an isset check for the submit button. maybe not?

  // unset the token to enforce a one-at-a-time gateway
  if (hash_equals($_SESSION['secToken'], $_POST['token'])) { unset($_SESSION['secToken']); unset($_POST['token']);

    // still need to handle cookie comparisons and timestamps
    if ($_SERVER['REMOTE_ADDR'] == $_SESSION['userIP'] && $_SERVER['HTTP_USER_AGENT'] == $_SESSION['userAgent']) {

         // maybe variables are breadcrumbs? avoid variables in form processing? can they be accessed by hackers?
         $birthDay = $birthMonth = $birthYear =  $gbt = NULL;
         $fnErr = $lnErr = $birthDayErr = $birthMonthErr = $birthYearErr = FALSE;
         $check100 = date(Y) - 100; $check18 = date(Y) - 18;

         // analyze, sanitize and validate gender and titles. exit if not what is set because they are tampered data
         if (!( ($_POST['gender'] == 'Frau') || ($_POST['gender'] == 'Herr') )) { echo 'error'; $_POST = array(); $_SESSION = array(); session_destroy(); exit; } else { sanStrings($_POST['gender']); }
         if (isset($_POST['title'])) {
             if (!( ($_POST['title'] == 'Dr.') || ($_POST['title'] == 'Prof.') || ($_POST['title'] == 'Prof. Dr.') )) { echo 'error'; $_POST = array(); $_SESSION = array(); session_destroy(); exit; } else { sanStrings($_POST['title']); }
         }

         // analyze, sanitize and validate first and last names. astonecipher recommends a function. thus, credit goes to astonecipher when function is implemented
         // to astonecipher: i will place a credit at the bottom of the form page. Thank You for helping a novice.
         if (isset($_POST['firstName']) && !preg_match('/^[a-zA-Z]{2,27}$/', $_POST['firstName'])) { $fnErr = TRUE; } else { sanStrings($_POST['firstName']); }
         if (isset($_POST['lastName']) && !preg_match('/^[a-zA-Z]{2,27}$/', $_POST['lastName'])) { $lnErr = TRUE; } else { sanStrings($_POST['lastName']); }  

         // analyze, sanitize and validate date of birth
         if (isset($_POST['dobday']) && !preg_match('/^[0-9]{2}$/', $_POST['dobday'])) { $birthDayErr = TRUE; } else { $birthDay = sanInteger($_POST['dobday']); }
         if (isset($_POST['dobmonth']) && !preg_match('/^[0-9]{2}$/', $_POST['dobmonth'])) { $birthMonthErr = TRUE; } else { $birthMonth = sanInteger($_POST['dobmonth']); }
         if (isset($_POST['dobyear']) && !preg_match('/^[0-9]{4}$/', $_POST['dobyear'])) { $birthYearErr = TRUE; } else { $birthYear = sanInteger($_POST['dobyear']); }
         if ($birthYear < $check18 && $birthYear >= $check100 && checkdate($birthMonth, $birthDay, $birthYear)) { $gbt = $birthDay . '.' . $birthMonth . '.' . $birthYear; } else { $birthYearErr = TRUE; }
         if ($birthYear == $check18) {
            if ($birthMonth == date(m) && $birthDay <= date(d) && checkdate($birthMonth, $birthDay, $birthYear)) { $gbt = $birthDay . '.' . $birthMonth . '.' . $birthYear; } else { $birthYearErr = TRUE; }
            if ($birthMonth < date(m) && checkdate($birthMonth, $birthDay, $birthYear)) { $gbt = $birthDay . '.' . $birthMonth . '.' . $birthYear; } else { $birthYearErr = TRUE; }
         }

         echo '<big><b>form submission successful!</b></big><br>';
         echo '<big><b>' . $_POST['gender'] . ' ' . $_POST['title'] . ' ' . $_POST['firstName'] . ' ' . $_POST['lastName'] . '</b></big><br>';
         echo '<big><b>' . $gbt . '</b></big><br>';

         // not sure but clearing data should prevent a hijacker from following user here and seeing this info. yes? no?
         $_POST = array();
         $_SESSION = array();
         session_destroy();

    } else {
       echo 'Error authenticating session user.'; //token is not a match or a bypass has been thwarted.
       $_POST = array();
       $_SESSION = array();
       session_destroy();
       exit;
    }

  } else {  //stop refresh from resubmitting data
     $_SESSION = array();
     //$params = session_get_cookie_params(); sec experts say to delete the cookies. here is example code for later
     //setcookie(session_name(), '', time() - 4200, $params["domain"], $params["path"], $params["httponly"], $params["secure"]);
     session_destroy();
     echo '<big><b>the form has been submitted or the session has expired.</b></big>';
     exit;
  }

} else { // use invalid request error page from root page that calls process.php or simply redirect to the agreement page. so exit here.
    exit;
}

// begin functions =================================================================== should be at the top of the page?

  function sanStrings($s) { //sanitize string also FILTER_SANITIZE_EMAIL
      $s = trim($s);
      $s = stripslashes($s);
      $s = filter_var($s, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_BACKTICK, FILTER_FLAG_ENCODE_AMP, ENT_QUOTES);
      $s = htmlspecialchars($s);
    return $s;
  }

  function sanInteger($n) { //sanitize number
      $n = trim($n);
      $n = stripslashes($n);
      $n = filter_var($n, FILTER_SANITIZE_NUMBER_INT);
      $n = htmlspecialchars($n);
    return $n;
  }

?>
 // paranoid so added an extra exit to avoid a running automobile script waiting for a thief
<?php exit; ?>

you should be able to test it by setting a token and session in the subscribe/ index.php

actually, my files are located outside of the root. subscribe/ has an index.php which calls the actual script.
but starting a session and setting a sha512 token will allow the scripts to be tested.

This is starting to look like I troll post but I’ll go along for now

Fair enough

Most people don’t want everything laid out for them as each app has its own business rules / feature set. Laravel, Symfony etc are as close to it as you’re probably going to get in PHP. You run a command and have a working site and just enter your app code in the controller methods you need and create the views you need.

Fair enough

The web host does not have to install Laravel. As long as they have a modern version of PHP you can upload pretty much any modern PHP framework app.

Trust me they don’t.

That’s also personal information. Happy to see you mentioning hashed passwords!

That’s way enough. FTP for simple file transfers and SSH to log in and debug stuff, install stuff etc

Any server side code could do this. If you’re going to add register/login forms to your website you might as well make the server code for them in php (guess that’s why you’re here).

Have you gotten quotes?

You keep repeating this but it makes no sense. There is no such thing as perfect security - but the closer you get based on your budget/threat model the better it is - right?

Why worry about the files? Lots of large apps and projects have their files publically available on sites like github.

Hacks are usually done because of problems with the scripts. But they can of course also be because of vulnerabilities in the services running on the server, the server hardware, bad employees, hacked employees, etc.

That sounds strange

So you trust him with a ridiculous claim like that but you do not trust coders? How is he supposed to get thousands of dollars from a guy in russia sharing your photos?

I’m sure having such a plan wouldn’t help your case if they figured out you were hoping for it

Yes it can, to some extent. But why would you care to protect your code? If you aren’t making some game changing algorithms in game design or similar I don’t see what some code is to protect.

This doesn’t make sense at all.

The programming world in general encourage using 3rd party code and PHP is no exception. Have a look into composer and how it can install and manage 3rd party code for you. Do note that you can’t just use any code, check that the license allows it.

I could make you a simple symfony site with register/login, a professional theme from themeforest and stripe subscription integration for a few hundred. So could many others as well

No, as said perfect security does not exist.

That’s horrible UX for both you and your users.

When you’re finished with the form you are probably doing something with the data and on error showing the data back in the form for the user to edit it. That’s where injection and XSS vulnerabilities come from.

This doesn’t add anything but clutter to the code.

This makes no sense. It will also break your site for anyone who has disabled cookies in their browser as PHP will then add PHPSESSID as a GET param.

This should be in the server config and not in your script

Definitely not, it breaks some older browsers as they don’t submit the button

IP != person. An IP can change at any time so this might break your site for some confused users.

I’m not sure what you mean. If a hacker controls your server he controls everything on that server.

No. Not sure what you want to protect against here spesifically but clearing the variables don’t do anything. The PHP garbage collector also handles this very well so no reason from a technical perspective.

These lines could surely be simplified, if you’ve checked that the string only contain letters and is of a spesific length you don’t really have to do much more with it. You enforce way too many rules on names though. Many people add their middle names to their first name and you don’t allow spaces. Many people have less than 2 letters or more than 27 letters in their name. And most of all, a lot of people have other characters than a-z in their name, like us here in scandinavia. This is a great resource https://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/

Also the call to sanStrings returns a sanitized string, it doesn’t set the original variable.

?

i will keep working on my site and if i fall flat on my face, then i will have to hire someone.
however, any login that i purchase has to work around my own html css design. no themes or template designs.
simply implement a login. i am happy with my website design and i refuse to change it.
i am only trying to implement a login and subscription form to my html css website.

any login/subscription that i use has to be designed with the following in mind:
I don’t support older browsers. IE11+ Ffox57+ latest Chrome, latest Safari only. no negotiations.
No cookies or javascript, then no access to my site. no negotiations. it is in my user agreement.

speaking of Scandinavia, i just read about a Norwegian that paid thousands for using a copyright German photo. the lawyer mentionbs that as long as ownership is clearly stated on the website, then i can collect damages.
i tried to copyright my unique css3 navigation menu and the attorney refused. i yelled at him about it saying that it is ridiculous but he insists that code is already copyright when it is created but not all code is protectable. my menu is not protectable. i move on. he is right i guess.
he just says that if the entire site were copied, then he can stop it. otherwise, noone can protect a css menu. the guy is an IT only lawyer, so he should know the EU laws well. I stopped arguing with him. I had to pay 250 euro per hour. no sense in arguing with him wasting time and money. i figure that he is correct.
i’m not an attorney so i guess that he is correct and i am moving on. i’m a bit upset about this idea but it is what it is.

i am used to be called a troll and being banned by people that disagree with me.
if this forum is for hiring php programmers, then i suppose that asking for help is ‘trolling’.
i will stop p[osting here before you decide to ban me for speaking my opinion.
i just think that anyone supporting older browsers cannot possibly design a secure login for my site. it is like allowing http 1.0 or 0.9. i prefer to hire someone but i cannot support old browsers.

well, i am disappointed that you call me a troll but i will leave here quietly.

sorry for causing problems. Thank You for letting me join and ask for help.
I’ll leave now. I hope that you have a wonderful day.

The trolling feel came from you getting worked up and making a big deal about very strange things that really doesn’t make much sense.

If you don’t think what I’m posting is helpful I’ll just leave the thread. No reason for you to leave the forums. For all we know I might be the weird one ^^ This is not my forums btw

Good luck, I’m out

Sponsor our Newsletter | Privacy Policy | Terms of Service